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