to make u-boot work for fat32 filesystem
[jz_uboot.git] / cpu / mips / jz_i2c.c
blob4d237a77f848b1046ca31d91323d28cbde0cb340
1 /*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your
5 * option) any later version.
6 */
9 #include <config.h>
11 #if defined(CONFIG_JZ4730) || defined(CONFIG_JZ4740) || defined(CONFIG_JZ5730)
13 #include <common.h>
14 #include <malloc.h>
15 #include <net.h>
16 #include <command.h>
17 #include <asm/io.h>
18 #if defined(CONFIG_JZ4730)
19 #include <asm/jz4730.h>
20 #endif
21 #if defined(CONFIG_JZ4740)
22 #include <asm/jz4740.h>
23 #endif
24 #if defined(CONFIG_JZ5730)
25 #include <asm/jz5730.h>
26 #endif
29 /* I2C protocol */
30 #define I2C_READ 1
31 #define I2C_WRITE 0
33 #define TIMEOUT 1000
35 #define ETIMEDOUT 1
38 static inline void my_udelay(int n )
40 int i;
41 i=n*100;
42 while ( i-- )
48 * I2C bus protocol basic routines
50 static int i2c_put_data(unsigned char data)
52 unsigned int timeout = TIMEOUT*10;
54 __i2c_write(data);
55 __i2c_set_drf();
56 while (__i2c_check_drf() != 0);
57 while (!__i2c_transmit_ended());
58 while (!__i2c_received_ack() && timeout)
59 timeout--;
61 if (timeout)
62 return 0;
63 else
64 return -ETIMEDOUT;
67 static int i2c_get_data(unsigned char *data, int ack)
69 int timeout = TIMEOUT*10;
71 if (!ack)
72 __i2c_send_nack();
73 else
74 __i2c_send_ack();
76 while (__i2c_check_drf() == 0 && timeout)
77 timeout--;
79 if (timeout) {
80 if (!ack)
81 __i2c_send_stop();
82 *data = __i2c_read();
83 __i2c_clear_drf();
84 return 0;
85 } else
86 return -ETIMEDOUT;
90 * I2C interface
92 void i2c_open(void)
94 __i2c_set_clk(CFG_EXTAL, 10000); /* default 10 KHz */
95 __i2c_enable();
98 void i2c_close(void)
100 my_udelay(300); /* wait for STOP goes over. */
101 __i2c_disable();
104 void i2c_setclk(unsigned int i2cclk)
106 __i2c_set_clk(CFG_EXTAL, i2cclk);
109 int i2c_lseek(unsigned char device, unsigned char offset)
111 __i2c_send_nack(); /* Master does not send ACK, slave sends it */
112 __i2c_send_start();
113 if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
114 goto device_err;
115 if (i2c_put_data(offset) < 0)
116 goto address_err;
117 return 0;
118 device_err:
119 printf("No I2C device (0x%02x) installed.\n", device);
120 __i2c_send_stop();
121 return -1;
122 address_err:
123 printf("No I2C device (0x%02x) response.\n", device);
124 __i2c_send_stop();
125 return -1;
128 int i2c_read(unsigned char device, unsigned char *buf,
129 unsigned char address, int count)
131 int cnt = count;
132 int timeout = 5;
134 L_try_again:
136 if (timeout < 0)
137 goto L_timeout;
139 __i2c_send_nack(); /* Master does not send ACK, slave sends it */
140 __i2c_send_start();
141 if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
142 goto device_werr;
143 if (i2c_put_data(address) < 0)
144 goto address_err;
146 __i2c_send_start();
147 if (i2c_put_data( (device << 1) | I2C_READ ) < 0)
148 goto device_rerr;
149 __i2c_send_ack(); /* Master sends ACK for continue reading */
150 while (cnt) {
151 if (cnt == 1) {
152 if (i2c_get_data(buf, 0) < 0)
153 break;
154 } else {
155 if (i2c_get_data(buf, 1) < 0)
156 break;
158 cnt--;
159 buf++;
162 __i2c_send_stop();
163 return count - cnt;
164 device_rerr:
165 device_werr:
166 address_err:
167 timeout --;
168 __i2c_send_stop();
169 goto L_try_again;
171 L_timeout:
172 __i2c_send_stop();
173 printf("Read I2C device 0x%2x failed.\n", device);
174 return -1;
177 int i2c_write(unsigned char device, unsigned char *buf,
178 unsigned char address, int count)
180 int cnt = count;
181 int cnt_in_pg;
182 int timeout = 5;
183 unsigned char *tmpbuf;
184 unsigned char tmpaddr;
186 __i2c_send_nack(); /* Master does not send ACK, slave sends it */
188 W_try_again:
189 if (timeout < 0)
190 goto W_timeout;
192 cnt = count;
193 tmpbuf = (unsigned char *)buf;
194 tmpaddr = address;
196 start_write_page:
197 cnt_in_pg = 0;
198 __i2c_send_start();
199 if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
200 goto device_err;
201 if (i2c_put_data(tmpaddr) < 0)
202 goto address_err;
203 while (cnt) {
204 if (++cnt_in_pg > 8) {
205 __i2c_send_stop();
206 my_udelay(1000);
207 tmpaddr += 8;
208 goto start_write_page;
210 if (i2c_put_data(*tmpbuf) < 0)
211 break;
212 cnt--;
213 tmpbuf++;
215 __i2c_send_stop();
216 return count - cnt;
217 device_err:
218 address_err:
219 timeout--;
220 __i2c_send_stop();
221 goto W_try_again;
223 W_timeout:
224 printf("Write I2C device 0x%2x failed.\n", device);
225 __i2c_send_stop();
226 return -1;
229 #endif /* CONFIG_JZ4730 || CONFIG_JZ4740 || CONFIG_JZ5730 */