]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/i2c/omap24xx_i2c.c
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / drivers / i2c / omap24xx_i2c.c
1 /*
2  * Basic I2C functions
3  *
4  * Copyright (c) 2004 Texas Instruments
5  *
6  * This package is free software;  you can redistribute it and/or
7  * modify it under the terms of the license found in the file
8  * named COPYING that should have accompanied this file.
9  *
10  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
11  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
12  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * Author: Jian Zhang jzhang@ti.com, Texas Instruments
15  *
16  * Copyright (c) 2003 Wolfgang Denk, wd@denx.de
17  * Rewritten to fit into the current U-Boot framework
18  *
19  * Adapted for OMAP2420 I2C, r-woodruff2@ti.com
20  *
21  */
22
23 #include <common.h>
24
25 #include <asm/arch/i2c.h>
26 #include <asm/io.h>
27
28 #define inw(a) __raw_readw(a)
29 #define outw(a,v) __raw_writew(a,v)
30
31 static void wait_for_bb (void);
32 static u16 wait_for_pin (void);
33 static void flush_fifo(void);
34
35 void i2c_init (int speed, int slaveadd)
36 {
37         u16 scl;
38
39         outw(0x2, I2C_SYSC); /* for ES2 after soft reset */
40         udelay(1000);
41         outw(0x0, I2C_SYSC); /* will probably self clear but */
42
43         if (inw (I2C_CON) & I2C_CON_EN) {
44                 outw (0, I2C_CON);
45                 udelay (50000);
46         }
47
48         /* 12Mhz I2C module clock */
49         outw (0, I2C_PSC);
50         speed = speed/1000;                 /* 100 or 400 */
51         scl = ((12000/(speed*2)) - 7);  /* use 7 when PSC = 0 */
52         outw (scl, I2C_SCLL);
53         outw (scl, I2C_SCLH);
54         /* own address */
55         outw (slaveadd, I2C_OA);
56         outw (I2C_CON_EN, I2C_CON);
57
58         /* have to enable intrrupts or OMAP i2c module doesn't work */
59         outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
60               I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
61         udelay (1000);
62         flush_fifo();
63         outw (0xFFFF, I2C_STAT);
64         outw (0, I2C_CNT);
65 }
66
67 static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
68 {
69         int i2c_error = 0;
70         u16 status;
71
72         /* wait until bus not busy */
73         wait_for_bb ();
74
75         /* one byte only */
76         outw (1, I2C_CNT);
77         /* set slave address */
78         outw (devaddr, I2C_SA);
79         /* no stop bit needed here */
80         outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
81
82         status = wait_for_pin ();
83
84         if (status & I2C_STAT_XRDY) {
85                 /* Important: have to use byte access */
86                 *(volatile u8 *) (I2C_DATA) = regoffset;
87                 udelay (20000);
88                 if (inw (I2C_STAT) & I2C_STAT_NACK) {
89                         i2c_error = 1;
90                 }
91         } else {
92                 i2c_error = 1;
93         }
94
95         if (!i2c_error) {
96                 /* free bus, otherwise we can't use a combined transction */
97                 outw (0, I2C_CON);
98                 while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
99                         udelay (10000);
100                         /* Have to clear pending interrupt to clear I2C_STAT */
101                         outw (0xFFFF, I2C_STAT);
102                 }
103
104                 wait_for_bb ();
105                 /* set slave address */
106                 outw (devaddr, I2C_SA);
107                 /* read one byte from slave */
108                 outw (1, I2C_CNT);
109                 /* need stop bit here */
110                 outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
111                       I2C_CON);
112
113                 status = wait_for_pin ();
114                 if (status & I2C_STAT_RRDY) {
115                         *value = inw (I2C_DATA);
116                         udelay (20000);
117                 } else {
118                         i2c_error = 1;
119                 }
120
121                 if (!i2c_error) {
122                         outw (I2C_CON_EN, I2C_CON);
123                         while (inw (I2C_STAT)
124                                || (inw (I2C_CON) & I2C_CON_MST)) {
125                                 udelay (10000);
126                                 outw (0xFFFF, I2C_STAT);
127                         }
128                 }
129         }
130         flush_fifo();
131         outw (0xFFFF, I2C_STAT);
132         outw (0, I2C_CNT);
133         return i2c_error;
134 }
135
136 static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
137 {
138         int i2c_error = 0;
139         u16 status, stat;
140
141         /* wait until bus not busy */
142         wait_for_bb ();
143
144         /* two bytes */
145         outw (2, I2C_CNT);
146         /* set slave address */
147         outw (devaddr, I2C_SA);
148         /* stop bit needed here */
149         outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
150               I2C_CON_STP, I2C_CON);
151
152         /* wait until state change */
153         status = wait_for_pin ();
154
155         if (status & I2C_STAT_XRDY) {
156                 /* send out two bytes */
157                 outw ((value << 8) + regoffset, I2C_DATA);
158                 /* must have enough delay to allow BB bit to go low */
159                 udelay (50000);
160                 if (inw (I2C_STAT) & I2C_STAT_NACK) {
161                         i2c_error = 1;
162                 }
163         } else {
164                 i2c_error = 1;
165         }
166
167         if (!i2c_error) {
168                 int eout = 200;
169
170                 outw (I2C_CON_EN, I2C_CON);
171                 while ((stat = inw (I2C_STAT)) || (inw (I2C_CON) & I2C_CON_MST)) {
172                         udelay (1000);
173                         /* have to read to clear intrrupt */
174                         outw (0xFFFF, I2C_STAT);
175                         if(--eout == 0) /* better leave with error than hang */
176                                 break;
177                 }
178         }
179         flush_fifo();
180         outw (0xFFFF, I2C_STAT);
181         outw (0, I2C_CNT);
182         return i2c_error;
183 }
184
185 static void flush_fifo(void)
186 {       u16 stat;
187
188         /* note: if you try and read data when its not there or ready
189          * you get a bus error
190          */
191         while(1){
192                 stat = inw(I2C_STAT);
193                 if(stat == I2C_STAT_RRDY){
194                         inw(I2C_DATA);
195                         outw(I2C_STAT_RRDY,I2C_STAT);
196                         udelay(1000);
197                 }else
198                         break;
199         }
200 }
201
202 int i2c_probe (uchar chip)
203 {
204         int res = 1; /* default = fail */
205
206         if (chip == inw (I2C_OA)) {
207                 return res;
208         }
209
210         /* wait until bus not busy */
211         wait_for_bb ();
212
213         /* try to read one byte */
214         outw (1, I2C_CNT);
215         /* set slave address */
216         outw (chip, I2C_SA);
217         /* stop bit needed here */
218         outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
219         /* enough delay for the NACK bit set */
220         udelay (50000);
221
222         if (!(inw (I2C_STAT) & I2C_STAT_NACK)) {
223                 res = 0;      /* success case */
224                 flush_fifo();
225                 outw(0xFFFF, I2C_STAT);
226         } else {
227                 outw(0xFFFF, I2C_STAT);  /* failue, clear sources*/
228                 outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */
229                 udelay(20000);
230                 wait_for_bb ();
231         }
232         flush_fifo();
233         outw (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/
234         outw(0xFFFF, I2C_STAT);
235         return res;
236 }
237
238 int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
239 {
240         int i;
241
242         if (alen > 1) {
243                 printf ("I2C read: addr len %d not supported\n", alen);
244                 return 1;
245         }
246
247         if (addr + len > 256) {
248                 printf ("I2C read: address out of range\n");
249                 return 1;
250         }
251
252         for (i = 0; i < len; i++) {
253                 if (i2c_read_byte (chip, addr + i, &buffer[i])) {
254                         printf ("I2C read: I/O error\n");
255                         i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
256                         return 1;
257                 }
258         }
259
260         return 0;
261 }
262
263 int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
264 {
265         int i;
266
267         if (alen > 1) {
268                 printf ("I2C read: addr len %d not supported\n", alen);
269                 return 1;
270         }
271
272         if (addr + len > 256) {
273                 printf ("I2C read: address out of range\n");
274                 return 1;
275         }
276
277         for (i = 0; i < len; i++) {
278                 if (i2c_write_byte (chip, addr + i, buffer[i])) {
279                         printf ("I2C read: I/O error\n");
280                         i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
281                         return 1;
282                 }
283         }
284
285         return 0;
286 }
287
288 static void wait_for_bb (void)
289 {
290         int timeout = 10;
291         u16 stat;
292
293         outw(0xFFFF, I2C_STAT);  /* clear current interruts...*/
294         while ((stat = inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
295                 outw (stat, I2C_STAT);
296                 udelay (50000);
297         }
298
299         if (timeout <= 0) {
300                 printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
301                         inw (I2C_STAT));
302         }
303         outw(0xFFFF, I2C_STAT);  /* clear delayed stuff*/
304 }
305
306 static u16 wait_for_pin (void)
307 {
308         u16 status;
309         int timeout = 10;
310
311         do {
312                 udelay (1000);
313                 status = inw (I2C_STAT);
314         } while (  !(status &
315                    (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
316                     I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
317                     I2C_STAT_AL)) && timeout--);
318
319         if (timeout <= 0) {
320                 printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
321                         inw (I2C_STAT));
322                         outw(0xFFFF, I2C_STAT);
323 }
324         return status;
325 }