1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <common.h>
19#if defined(CONFIG_AT91FAMILY)
20#include <asm/io.h>
21#include <asm/arch/hardware.h>
22#include <asm/arch/at91_pio.h>
23#ifdef CONFIG_ATMEL_LEGACY
24#include <asm/arch/gpio.h>
25#endif
26#endif
27#include <i2c.h>
28#include <asm/global_data.h>
29#include <linux/delay.h>
30
31#if defined(CONFIG_SOFT_I2C_GPIO_SCL)
32# include <asm/gpio.h>
33
34# ifndef I2C_GPIO_SYNC
35# define I2C_GPIO_SYNC
36# endif
37
38# ifndef I2C_INIT
39# define I2C_INIT \
40 do { \
41 gpio_request(CONFIG_SOFT_I2C_GPIO_SCL, "soft_i2c"); \
42 gpio_request(CONFIG_SOFT_I2C_GPIO_SDA, "soft_i2c"); \
43 } while (0)
44# endif
45
46# ifndef I2C_ACTIVE
47# define I2C_ACTIVE do { } while (0)
48# endif
49
50# ifndef I2C_TRISTATE
51# define I2C_TRISTATE do { } while (0)
52# endif
53
54# ifndef I2C_READ
55# define I2C_READ gpio_get_value(CONFIG_SOFT_I2C_GPIO_SDA)
56# endif
57
58# ifndef I2C_SDA
59# define I2C_SDA(bit) \
60 do { \
61 if (bit) \
62 gpio_direction_input(CONFIG_SOFT_I2C_GPIO_SDA); \
63 else \
64 gpio_direction_output(CONFIG_SOFT_I2C_GPIO_SDA, 0); \
65 I2C_GPIO_SYNC; \
66 } while (0)
67# endif
68
69# ifndef I2C_SCL
70# define I2C_SCL(bit) \
71 do { \
72 gpio_direction_output(CONFIG_SOFT_I2C_GPIO_SCL, bit); \
73 I2C_GPIO_SYNC; \
74 } while (0)
75# endif
76
77# ifndef I2C_DELAY
78# define I2C_DELAY udelay(5)
79# endif
80
81#endif
82
83
84
85DECLARE_GLOBAL_DATA_PTR;
86
87#ifndef I2C_SOFT_DECLARATIONS
88# define I2C_SOFT_DECLARATIONS
89#endif
90
91
92
93
94#define RETRIES 0
95
96#define I2C_ACK 0
97#define I2C_NOACK 1
98
99
100#ifdef DEBUG_I2C
101#define PRINTD(fmt,args...) do { \
102 printf (fmt ,##args); \
103 } while (0)
104#else
105#define PRINTD(fmt,args...)
106#endif
107
108
109
110
111#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
112static void send_reset (void);
113#endif
114static void send_start (void);
115static void send_stop (void);
116static void send_ack (int);
117static int write_byte (uchar byte);
118static uchar read_byte (int);
119
120#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
121
122
123
124
125
126static void send_reset(void)
127{
128 I2C_SOFT_DECLARATIONS
129 int j;
130
131 I2C_SCL(1);
132 I2C_SDA(1);
133#ifdef I2C_INIT
134 I2C_INIT;
135#endif
136 I2C_TRISTATE;
137 for(j = 0; j < 9; j++) {
138 I2C_SCL(0);
139 I2C_DELAY;
140 I2C_DELAY;
141 I2C_SCL(1);
142 I2C_DELAY;
143 I2C_DELAY;
144 }
145 send_stop();
146 I2C_TRISTATE;
147}
148#endif
149
150
151
152
153static void send_start(void)
154{
155 I2C_SOFT_DECLARATIONS
156
157 I2C_DELAY;
158 I2C_SDA(1);
159 I2C_ACTIVE;
160 I2C_DELAY;
161 I2C_SCL(1);
162 I2C_DELAY;
163 I2C_SDA(0);
164 I2C_DELAY;
165}
166
167
168
169
170static void send_stop(void)
171{
172 I2C_SOFT_DECLARATIONS
173
174 I2C_SCL(0);
175 I2C_DELAY;
176 I2C_SDA(0);
177 I2C_ACTIVE;
178 I2C_DELAY;
179 I2C_SCL(1);
180 I2C_DELAY;
181 I2C_SDA(1);
182 I2C_DELAY;
183 I2C_TRISTATE;
184}
185
186
187
188
189static void send_ack(int ack)
190{
191 I2C_SOFT_DECLARATIONS
192
193 I2C_SCL(0);
194 I2C_DELAY;
195 I2C_ACTIVE;
196 I2C_SDA(ack);
197 I2C_DELAY;
198 I2C_SCL(1);
199 I2C_DELAY;
200 I2C_DELAY;
201 I2C_SCL(0);
202 I2C_DELAY;
203}
204
205
206
207
208static int write_byte(uchar data)
209{
210 I2C_SOFT_DECLARATIONS
211 int j;
212 int nack;
213
214 I2C_ACTIVE;
215 for(j = 0; j < 8; j++) {
216 I2C_SCL(0);
217 I2C_DELAY;
218 I2C_SDA(data & 0x80);
219 I2C_DELAY;
220 I2C_SCL(1);
221 I2C_DELAY;
222 I2C_DELAY;
223
224 data <<= 1;
225 }
226
227
228
229
230 I2C_SCL(0);
231 I2C_DELAY;
232 I2C_SDA(1);
233 I2C_TRISTATE;
234 I2C_DELAY;
235 I2C_SCL(1);
236 I2C_DELAY;
237 I2C_DELAY;
238 nack = I2C_READ;
239 I2C_SCL(0);
240 I2C_DELAY;
241 I2C_ACTIVE;
242
243 return(nack);
244}
245
246
247
248
249
250static uchar read_byte(int ack)
251{
252 I2C_SOFT_DECLARATIONS
253 int data;
254 int j;
255
256
257
258
259 I2C_TRISTATE;
260 I2C_SDA(1);
261 data = 0;
262 for(j = 0; j < 8; j++) {
263 I2C_SCL(0);
264 I2C_DELAY;
265 I2C_SCL(1);
266 I2C_DELAY;
267 data <<= 1;
268 data |= I2C_READ;
269 I2C_DELAY;
270 }
271 send_ack(ack);
272
273 return(data);
274}
275
276
277
278
279static void soft_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
280{
281#if defined(CONFIG_SYS_I2C_INIT_BOARD)
282
283
284
285 i2c_init_board();
286#else
287
288
289
290
291
292
293 send_reset ();
294#endif
295}
296
297
298
299
300
301
302static int soft_i2c_probe(struct i2c_adapter *adap, uint8_t addr)
303{
304 int rc;
305
306
307
308
309
310 send_start();
311 rc = write_byte ((addr << 1) | 0);
312 send_stop();
313
314 return (rc ? 1 : 0);
315}
316
317
318
319
320static int soft_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
321 int alen, uchar *buffer, int len)
322{
323 int shift;
324 PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n",
325 chip, addr, alen, buffer, len);
326
327#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
328
329
330
331
332
333
334
335
336
337
338
339 chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
340
341 PRINTD("i2c_read: fix addr_overflow: chip %02X addr %02X\n",
342 chip, addr);
343#endif
344
345
346
347
348
349
350
351 send_start();
352 if(alen > 0) {
353 if(write_byte(chip << 1)) {
354 send_stop();
355 PRINTD("i2c_read, no chip responded %02X\n", chip);
356 return(1);
357 }
358 shift = (alen-1) * 8;
359 while(alen-- > 0) {
360 if(write_byte(addr >> shift)) {
361 PRINTD("i2c_read, address not <ACK>ed\n");
362 return(1);
363 }
364 shift -= 8;
365 }
366
367
368
369
370
371
372#ifdef CONFIG_SOFT_I2C_READ_REPEATED_START
373 send_start();
374#else
375 send_stop();
376 send_start();
377#endif
378 }
379
380
381
382
383
384 write_byte((chip << 1) | 1);
385 while(len-- > 0) {
386 *buffer++ = read_byte(len == 0);
387 }
388 send_stop();
389 return(0);
390}
391
392
393
394
395static int soft_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
396 int alen, uchar *buffer, int len)
397{
398 int shift, failures = 0;
399
400 PRINTD("i2c_write: chip %02X addr %02X alen %d buffer %p len %d\n",
401 chip, addr, alen, buffer, len);
402
403 send_start();
404 if(write_byte(chip << 1)) {
405 send_stop();
406 PRINTD("i2c_write, no chip responded %02X\n", chip);
407 return(1);
408 }
409 shift = (alen-1) * 8;
410 while(alen-- > 0) {
411 if(write_byte(addr >> shift)) {
412 PRINTD("i2c_write, address not <ACK>ed\n");
413 return(1);
414 }
415 shift -= 8;
416 }
417
418 while(len-- > 0) {
419 if(write_byte(*buffer++)) {
420 failures++;
421 }
422 }
423 send_stop();
424 return(failures);
425}
426
427
428
429
430U_BOOT_I2C_ADAP_COMPLETE(soft00, soft_i2c_init, soft_i2c_probe,
431 soft_i2c_read, soft_i2c_write, NULL,
432 CONFIG_SYS_I2C_SOFT_SPEED, CONFIG_SYS_I2C_SOFT_SLAVE,
433 0)
434