]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/i2c/omap1510_i2c.c
drivers/i2c: Update fti2c010.[ch], i2c_core.c to use SPDX identifiers
[karo-tx-uboot.git] / drivers / i2c / omap1510_i2c.c
1 /*
2  * Basic I2C functions
3  *
4  * Copyright (c) 2003 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  */
20
21 #include <common.h>
22
23 static void wait_for_bb (void);
24 static u16 wait_for_pin (void);
25
26 void i2c_init (int speed, int slaveadd)
27 {
28         u16 scl;
29
30         if (inw (I2C_CON) & I2C_CON_EN) {
31                 outw (0, I2C_CON);
32                 udelay (5000);
33         }
34
35         /* 12MHz I2C module clock */
36         outw (0, I2C_PSC);
37         outw (I2C_CON_EN, I2C_CON);
38         outw (0, I2C_SYSTEST);
39         /* have to enable intrrupts or OMAP i2c module doesn't work */
40         outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
41               I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
42         scl = (12000000 / 2) / speed - 6;
43         outw (scl, I2C_SCLL);
44         outw (scl, I2C_SCLH);
45         /* own address */
46         outw (slaveadd, I2C_OA);
47         outw (0, I2C_CNT);
48         udelay (1000);
49 }
50
51 static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
52 {
53         int i2c_error = 0;
54         u16 status;
55
56         /* wait until bus not busy */
57         wait_for_bb ();
58
59         /* one byte only */
60         outw (1, I2C_CNT);
61         /* set slave address */
62         outw (devaddr, I2C_SA);
63         /* no stop bit needed here */
64         outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
65
66         status = wait_for_pin ();
67
68         if (status & I2C_STAT_XRDY) {
69                 /* Important: have to use byte access */
70                 *(volatile u8 *) (I2C_DATA) = regoffset;
71                 udelay (20000);
72                 if (inw (I2C_STAT) & I2C_STAT_NACK) {
73                         i2c_error = 1;
74                 }
75         } else {
76                 i2c_error = 1;
77         }
78
79         if (!i2c_error) {
80                 /* free bus, otherwise we can't use a combined transction */
81                 outw (0, I2C_CON);
82                 while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
83                         udelay (10000);
84                         /* Have to clear pending interrupt to clear I2C_STAT */
85                         inw (I2C_IV);
86                 }
87
88                 wait_for_bb ();
89                 /* set slave address */
90                 outw (devaddr, I2C_SA);
91                 /* read one byte from slave */
92                 outw (1, I2C_CNT);
93                 /* need stop bit here */
94                 outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
95                       I2C_CON);
96
97                 status = wait_for_pin ();
98                 if (status & I2C_STAT_RRDY) {
99                         *value = inw (I2C_DATA);
100                         udelay (20000);
101                 } else {
102                         i2c_error = 1;
103                 }
104
105                 if (!i2c_error) {
106                         outw (I2C_CON_EN, I2C_CON);
107                         while (inw (I2C_STAT)
108                                || (inw (I2C_CON) & I2C_CON_MST)) {
109                                 udelay (10000);
110                                 inw (I2C_IV);
111                         }
112                 }
113         }
114
115         return i2c_error;
116 }
117
118 static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
119 {
120         int i2c_error = 0;
121         u16 status;
122
123         /* wait until bus not busy */
124         wait_for_bb ();
125
126         /* two bytes */
127         outw (2, I2C_CNT);
128         /* set slave address */
129         outw (devaddr, I2C_SA);
130         /* stop bit needed here */
131         outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
132               I2C_CON_STP, I2C_CON);
133
134         /* wait until state change */
135         status = wait_for_pin ();
136
137         if (status & I2C_STAT_XRDY) {
138                 /* send out two bytes */
139                 outw ((value << 8) + regoffset, I2C_DATA);
140                 /* must have enough delay to allow BB bit to go low */
141                 udelay (30000);
142                 if (inw (I2C_STAT) & I2C_STAT_NACK) {
143                         i2c_error = 1;
144                 }
145         } else {
146                 i2c_error = 1;
147         }
148
149         if (!i2c_error) {
150                 outw (I2C_CON_EN, I2C_CON);
151                 while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
152                         udelay (1000);
153                         /* have to read to clear intrrupt */
154                         inw (I2C_IV);
155                 }
156         }
157
158         return i2c_error;
159 }
160
161 int i2c_probe (uchar chip)
162 {
163         int res = 1;
164
165         if (chip == inw (I2C_OA)) {
166                 return res;
167         }
168
169         /* wait until bus not busy */
170         wait_for_bb ();
171
172         /* try to read one byte */
173         outw (1, I2C_CNT);
174         /* set slave address */
175         outw (chip, I2C_SA);
176         /* stop bit needed here */
177         outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
178         /* enough delay for the NACK bit set */
179         udelay (2000);
180         if (!(inw (I2C_STAT) & I2C_STAT_NACK)) {
181                 res = 0;
182         } else {
183                 outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON);
184                 udelay (20);
185                 wait_for_bb ();
186         }
187
188         return res;
189 }
190
191 int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
192 {
193         int i;
194
195         if (alen > 1) {
196                 printf ("I2C read: addr len %d not supported\n", alen);
197                 return 1;
198         }
199
200         if (addr + len > 256) {
201                 printf ("I2C read: address out of range\n");
202                 return 1;
203         }
204
205         for (i = 0; i < len; i++) {
206                 if (i2c_read_byte (chip, addr + i, &buffer[i])) {
207                         printf ("I2C read: I/O error\n");
208                         i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
209                         return 1;
210                 }
211         }
212
213         return 0;
214 }
215
216 int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
217 {
218         int i;
219
220         if (alen > 1) {
221                 printf ("I2C read: addr len %d not supported\n", alen);
222                 return 1;
223         }
224
225         if (addr + len > 256) {
226                 printf ("I2C read: address out of range\n");
227                 return 1;
228         }
229
230         for (i = 0; i < len; i++) {
231                 if (i2c_write_byte (chip, addr + i, buffer[i])) {
232                         printf ("I2C read: I/O error\n");
233                         i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
234                         return 1;
235                 }
236         }
237
238         return 0;
239 }
240
241 static void wait_for_bb (void)
242 {
243         int timeout = 10;
244
245         while ((inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
246                 inw (I2C_IV);
247                 udelay (1000);
248         }
249
250         if (timeout <= 0) {
251                 printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
252                         inw (I2C_STAT));
253         }
254 }
255
256 static u16 wait_for_pin (void)
257 {
258         u16 status, iv;
259         int timeout = 10;
260
261         do {
262                 udelay (1000);
263                 status = inw (I2C_STAT);
264                 iv = inw (I2C_IV);
265         } while (!iv &&
266                  !(status &
267                    (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
268                     I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
269                     I2C_STAT_AL)) && timeout--);
270
271         if (timeout <= 0) {
272                 printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
273                         inw (I2C_STAT));
274         }
275
276         return status;
277 }