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