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