]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/evb64260/i2c.c
board/evb64260/i2c.c: Coding Style cleanup
[karo-tx-uboot.git] / board / evb64260 / i2c.c
1 #include <common.h>
2 #include <mpc8xx.h>
3 #include <malloc.h>
4 #include <galileo/gt64260R.h>
5 #include <galileo/core.h>
6
7 #define MAX_I2C_RETRYS      10
8 #define I2C_DELAY           1000  /* Should be at least the # of MHz of Tclk */
9 #undef  DEBUG_I2C
10
11 #ifdef DEBUG_I2C
12 #define DP(x) x
13 #else
14 #define DP(x)
15 #endif
16
17 /* Assuming that there is only one master on the bus (us) */
18
19 static void
20 i2c_init(int speed, int slaveaddr)
21 {
22         unsigned int n, m, freq, margin, power;
23         unsigned int actualFreq, actualN = 0, actualM = 0;
24         unsigned int control, status;
25         unsigned int minMargin = 0xffffffff;
26         unsigned int tclk = 125000000;
27
28         DP(puts("i2c_init\n"));
29
30         for (n = 0 ; n < 8 ; n++) {
31                 for (m = 0 ; m < 16 ; m++) {
32                         power = 2<<n; /* power = 2^(n+1) */
33                         freq = tclk/(10*(m+1)*power);
34                         if (speed > freq)
35                                 margin = speed - freq;
36                         else
37                                 margin = freq - speed;
38                         if (margin < minMargin) {
39                                 minMargin   = margin;
40                                 actualFreq  = freq;
41                                 actualN     = n;
42                                 actualM     = m;
43                         }
44                 }
45         }
46
47         DP(puts("setup i2c bus\n"));
48
49         /* Setup bus */
50
51         GT_REG_WRITE(I2C_SOFT_RESET, 0);
52
53         DP(puts("udelay...\n"));
54
55         udelay(I2C_DELAY);
56
57         DP(puts("set baudrate\n"));
58
59         GT_REG_WRITE(I2C_STATUS_BAUDE_RATE, (actualM << 3) | actualN);
60         GT_REG_WRITE(I2C_CONTROL, (0x1 << 2) | (0x1 << 6));
61
62         udelay(I2C_DELAY * 10);
63
64         DP(puts("read control, baudrate\n"));
65
66         GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
67         GT_REG_READ(I2C_CONTROL, &control);
68 }
69
70 static uchar
71 i2c_start(void)
72 {
73         unsigned int control, status;
74         int count = 0;
75
76         DP(puts("i2c_start\n"));
77
78         /* Set the start bit */
79
80         GT_REG_READ(I2C_CONTROL, &control);
81         control |= (0x1 << 5);
82         GT_REG_WRITE(I2C_CONTROL, control);
83
84         GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
85
86         count = 0;
87         while ((status & 0xff) != 0x08) {
88                 udelay(I2C_DELAY);
89                 if (count > 20) {
90                         GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /*stop*/
91                         return status;
92                 }
93                 GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
94                 count++;
95         }
96
97         return 0;
98 }
99
100 static uchar
101 i2c_select_device(uchar dev_addr, uchar read, int ten_bit)
102 {
103         unsigned int status, data, bits = 7;
104         int count = 0;
105
106         DP(puts("i2c_select_device\n"));
107
108         /* Output slave address */
109
110         if (ten_bit)
111                 bits = 10;
112
113         data = (dev_addr << 1);
114         /* set the read bit */
115         data |= read;
116         GT_REG_WRITE(I2C_DATA, data);
117         /* assert the address */
118         RESET_REG_BITS(I2C_CONTROL, BIT3);
119
120         udelay(I2C_DELAY);
121
122         GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
123         count = 0;
124         while (((status & 0xff) != 0x40) && ((status & 0xff) != 0x18)) {
125                 udelay(I2C_DELAY);
126                 if (count > 20) {
127                         GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /*stop*/
128                         return status;
129                 }
130                 GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
131                 count++;
132         }
133
134         if (bits == 10) {
135                 printf("10 bit I2C addressing not yet implemented\n");
136                 return 0xff;
137         }
138
139         return 0;
140 }
141
142 static uchar
143 i2c_get_data(uchar *return_data, int len) {
144
145         unsigned int data, status = 0;
146         int count = 0;
147
148         DP(puts("i2c_get_data\n"));
149
150         while (len) {
151
152                 /* Get and return the data */
153
154                 RESET_REG_BITS(I2C_CONTROL, (0x1 << 3));
155
156                 udelay(I2C_DELAY * 5);
157
158                 GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
159                 count++;
160                 while ((status & 0xff) != 0x50) {
161                         udelay(I2C_DELAY);
162                         if (count > 2) {
163                                 GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /*stop*/
164                                 return 0;
165                         }
166                         GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
167                         count++;
168                 }
169                 GT_REG_READ(I2C_DATA, &data);
170                 len--;
171                 *return_data = (uchar)data;
172                 return_data++;
173         }
174         RESET_REG_BITS(I2C_CONTROL, BIT2|BIT3);
175         while ((status & 0xff) != 0x58) {
176                 udelay(I2C_DELAY);
177                 if (count > 200) {
178                         GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /*stop*/
179                         return status;
180                 }
181                 GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
182                 count++;
183         }
184         GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /* stop */
185
186         return 0;
187 }
188
189 static uchar
190 i2c_write_data(unsigned int data, int len)
191 {
192         unsigned int status;
193         int count = 0;
194
195         DP(puts("i2c_write_data\n"));
196
197         if (len > 4)
198                 return -1;
199
200         while (len) {
201                 /* Set and assert the data */
202
203                 GT_REG_WRITE(I2C_DATA, (unsigned int)data);
204                 RESET_REG_BITS(I2C_CONTROL, (0x1 << 3));
205
206                 udelay(I2C_DELAY);
207
208                 GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
209                 count++;
210                 while ((status & 0xff) != 0x28) {
211                         udelay(I2C_DELAY);
212                         if (count > 20) {
213                                 GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /*stop*/
214                                 return status;
215                         }
216                         GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
217                         count++;
218                 }
219                 len--;
220         }
221         GT_REG_WRITE(I2C_CONTROL, (0x1 << 3) | (0x1 << 4));
222         GT_REG_WRITE(I2C_CONTROL, (0x1 << 4));
223
224         udelay(I2C_DELAY * 10);
225
226         return 0;
227 }
228
229 static uchar
230 i2c_set_dev_offset(uchar dev_addr, unsigned int offset, int ten_bit)
231 {
232         uchar status;
233
234         DP(puts("i2c_set_dev_offset\n"));
235
236         status = i2c_select_device(dev_addr, 0, ten_bit);
237         if (status) {
238 #ifdef DEBUG_I2C
239                 printf("Failed to select device setting offset: 0x%02x\n",
240                        status);
241 #endif
242                 return status;
243         }
244
245         status = i2c_write_data(offset, 1);
246         if (status) {
247 #ifdef DEBUG_I2C
248                 printf("Failed to write data: 0x%02x\n", status);
249 #endif
250                 return status;
251         }
252
253         return 0;
254 }
255
256 uchar
257 i2c_read(uchar dev_addr, unsigned int offset, int len, uchar *data,
258          int ten_bit)
259 {
260         uchar status = 0;
261         unsigned int i2cFreq = 400000;
262
263         DP(puts("i2c_read\n"));
264
265         i2c_init(i2cFreq, 0);
266
267         status = i2c_start();
268
269         if (status) {
270 #ifdef DEBUG_I2C
271                 printf("Transaction start failed: 0x%02x\n", status);
272 #endif
273                 return status;
274         }
275
276         status = i2c_set_dev_offset(dev_addr, 0, 0);
277         if (status) {
278 #ifdef DEBUG_I2C
279                 printf("Failed to set offset: 0x%02x\n", status);
280 #endif
281                 return status;
282         }
283
284         i2c_init(i2cFreq, 0);
285
286         status = i2c_start();
287         if (status) {
288 #ifdef DEBUG_I2C
289                 printf("Transaction restart failed: 0x%02x\n", status);
290 #endif
291                 return status;
292         }
293
294         status = i2c_select_device(dev_addr, 1, ten_bit);
295         if (status) {
296 #ifdef DEBUG_I2C
297                 printf("Address not acknowledged: 0x%02x\n", status);
298 #endif
299                 return status;
300         }
301
302         status = i2c_get_data(data, len);
303         if (status) {
304 #ifdef DEBUG_I2C
305                 printf("Data not received: 0x%02x\n", status);
306 #endif
307                 return status;
308         }
309
310         return 0;
311 }