summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c b/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c
new file mode 100644
index 0000000000..1fbf1fc19e
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c
@@ -0,0 +1,240 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Maurus Cuelenaere
11 *
12 * based on linux/arch/mips/jz4740/i2c.c
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24/*
25 * Jz4740 I2C routines.
26 *
27 * Copyright (C) 2005,2006 Ingenic Semiconductor Inc.
28 * Author: <lhhuang@ingenic.cn>
29 *
30 * This program is free software; you can distribute it and/or modify it
31 * under the terms of the GNU General Public License (Version 2) as
32 * published by the Free Software Foundation.
33 *
34 * This program is distributed in the hope it will be useful, but WITHOUT
35 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37 * for more details.
38 *
39 * You should have received a copy of the GNU General Public License along
40 * with this program; if not, write to the Free Software Foundation, Inc.,
41 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
42 *
43 */
44
45#include "config.h"
46#include "system.h"
47#include "jz4740.h"
48#include "logf.h"
49#include "generic_i2c.h"
50
51
52/* I2C protocol */
53#define I2C_READ 1
54#define I2C_WRITE 0
55
56#define TIMEOUT 1000
57
58/*
59 * I2C bus protocol basic routines
60 */
61static int i2c_put_data(unsigned char data)
62{
63 unsigned int timeout = TIMEOUT*10;
64
65 __i2c_write(data);
66 __i2c_set_drf();
67 while (__i2c_check_drf() != 0);
68 while (!__i2c_transmit_ended());
69 while (!__i2c_received_ack() && timeout)
70 timeout--;
71
72 if (timeout)
73 return 0;
74 else
75 return -1;
76}
77
78static int i2c_put_data_nack(unsigned char data)
79{
80 unsigned int timeout = TIMEOUT*10;
81
82 __i2c_write(data);
83 __i2c_set_drf();
84 while (__i2c_check_drf() != 0);
85 while (!__i2c_transmit_ended());
86 while (timeout--);
87
88 return 0;
89}
90
91static int i2c_get_data(unsigned char *data, int ack)
92{
93 int timeout = TIMEOUT*10;
94
95 if (!ack)
96 __i2c_send_nack();
97 else
98 __i2c_send_ack();
99
100 while (__i2c_check_drf() == 0 && timeout)
101 timeout--;
102
103 if (timeout)
104 {
105 if (!ack)
106 __i2c_send_stop();
107 *data = __i2c_read();
108 __i2c_clear_drf();
109 return 0;
110 }
111 else
112 return -1;
113}
114
115/*
116 * I2C interface
117 */
118void i2c_open(void)
119{
120 /* TODO */
121 //__i2c_set_clk(jz_clocks.extalclk, 10000); /* default 10 KHz */
122 __i2c_enable();
123}
124
125void i2c_close(void)
126{
127 udelay(300); /* wait for STOP goes over. */
128 __i2c_disable();
129}
130
131void i2c_setclk(unsigned int i2cclk)
132{
133 /* TODO */
134 //__i2c_set_clk(jz_clocks.extalclk, i2cclk);
135}
136
137int i2c_read(int device, unsigned char *buf, int count)
138{
139 int cnt = count;
140 int timeout = 5;
141
142 device &= 0xFF;
143
144L_try_again:
145 if (timeout < 0)
146 goto L_timeout;
147
148 __i2c_send_nack(); /* Master does not send ACK, slave sends it */
149
150 __i2c_send_start();
151 if (i2c_put_data( (device << 1) | I2C_READ ) < 0)
152 goto device_err;
153
154 __i2c_send_ack(); /* Master sends ACK for continue reading */
155
156 while (cnt)
157 {
158 if (cnt == 1)
159 {
160 if (i2c_get_data(buf, 0) < 0)
161 break;
162 }
163 else
164 {
165 if (i2c_get_data(buf, 1) < 0)
166 break;
167 }
168 cnt--;
169 buf++;
170 }
171
172 __i2c_send_stop();
173 return count - cnt;
174
175device_err:
176 timeout--;
177 __i2c_send_stop();
178 goto L_try_again;
179
180L_timeout:
181 __i2c_send_stop();
182 logf("Read I2C device 0x%2x failed.", device);
183 return -1;
184}
185
186int i2c_write(int device, unsigned char *buf, int count)
187{
188 int cnt = count;
189 int timeout = 5;
190
191 device &= 0xFF;
192
193 __i2c_send_nack(); /* Master does not send ACK, slave sends it */
194
195W_try_again:
196 if (timeout < 0)
197 goto W_timeout;
198
199 cnt = count;
200
201 __i2c_send_start();
202 if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
203 goto device_err;
204
205#if 0 //CONFIG_JZ_TPANEL_ATA2508
206 if (address == 0xff)
207 {
208 while (cnt)
209 {
210 if (i2c_put_data_nack(*buf) < 0)
211 break;
212 cnt--;
213 buf++;
214 }
215 }
216 else
217#endif
218 {
219 while (cnt)
220 {
221 if (i2c_put_data(*buf) < 0)
222 break;
223 cnt--;
224 buf++;
225 }
226 }
227
228 __i2c_send_stop();
229 return count - cnt;
230
231device_err:
232 timeout--;
233 __i2c_send_stop();
234 goto W_try_again;
235
236W_timeout:
237 logf("Write I2C device 0x%2x failed.", device);
238 __i2c_send_stop();
239 return -1;
240}