]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/Marvell/common/i2c.c
imported Freescale specific U-Boot additions for i.MX28,... release L2.6.31_10.08.01
[karo-tx-uboot.git] / board / Marvell / common / i2c.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  *
23  * Hacked for the DB64360 board by Ingo.Assmus@keymile.com
24  * extra improvments by Brain Waite
25  */
26 #include <common.h>
27 #include <mpc8xx.h>
28 #include <malloc.h>
29 #include <i2c.h>
30 #include "../include/mv_gen_reg.h"
31 #include "../include/core.h"
32
33 #define MAX_I2C_RETRYS      10
34 #define I2C_DELAY           1000        /* Should be at least the # of MHz of Tclk */
35 #undef  DEBUG_I2C
36 /*#define DEBUG_I2C*/
37
38 #ifdef DEBUG_I2C
39 #define DP(x) x
40 #else
41 #define DP(x)
42 #endif
43
44 /* Assuming that there is only one master on the bus (us) */
45
46 void i2c_init (int speed, int slaveaddr)
47 {
48         unsigned int n, m, freq, margin, power;
49         unsigned int actualN = 0, actualM = 0;
50         unsigned int control, status;
51         unsigned int minMargin = 0xffffffff;
52         unsigned int tclk = CONFIG_SYS_TCLK;
53         unsigned int i2cFreq = speed;   /* 100000 max. Fast mode not supported */
54
55         DP (puts ("i2c_init\n"));
56 /* gtI2cMasterInit */
57         for (n = 0; n < 8; n++) {
58                 for (m = 0; m < 16; m++) {
59                         power = 2 << n; /* power = 2^(n+1) */
60                         freq = tclk / (10 * (m + 1) * power);
61                         if (i2cFreq > freq)
62                                 margin = i2cFreq - freq;
63                         else
64                                 margin = freq - i2cFreq;
65                         if (margin < minMargin) {
66                                 minMargin = margin;
67                                 actualN = n;
68                                 actualM = m;
69                         }
70                 }
71         }
72
73         DP (puts ("setup i2c bus\n"));
74
75         /* Setup bus */
76 /* gtI2cReset */
77         GT_REG_WRITE (I2C_SOFT_RESET, 0);
78
79         DP (puts ("udelay...\n"));
80
81         udelay (I2C_DELAY);
82
83         DP (puts ("set baudrate\n"));
84
85         GT_REG_WRITE (I2C_STATUS_BAUDE_RATE, (actualM << 3) | actualN);
86         GT_REG_WRITE (I2C_CONTROL, (0x1 << 2) | (0x1 << 6));
87
88         udelay (I2C_DELAY * 10);
89
90         DP (puts ("read control, baudrate\n"));
91
92         GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
93         GT_REG_READ (I2C_CONTROL, &control);
94 }
95
96 static uchar i2c_start (void)
97 {                               /* DB64360 checked -> ok */
98         unsigned int control, status;
99         int count = 0;
100
101         DP (puts ("i2c_start\n"));
102
103         /* Set the start bit */
104
105 /* gtI2cGenerateStartBit() */
106
107         GT_REG_READ (I2C_CONTROL, &control);
108         control |= (0x1 << 5);  /* generate the I2C_START_BIT */
109         GT_REG_WRITE (I2C_CONTROL, control);
110
111         GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
112
113         count = 0;
114         while ((status & 0xff) != 0x08) {
115                 udelay (I2C_DELAY);
116                 if (count > 20) {
117                         GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
118                         return (status);
119                 }
120                 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
121                 count++;
122         }
123
124         return (0);
125 }
126
127 static uchar i2c_select_device (uchar dev_addr, uchar read, int ten_bit)
128 {
129         unsigned int status, data, bits = 7;
130         int count = 0;
131
132         DP (puts ("i2c_select_device\n"));
133
134         /* Output slave address */
135
136         if (ten_bit) {
137                 bits = 10;
138         }
139
140         data = (dev_addr << 1);
141         /* set the read bit */
142         data |= read;
143         GT_REG_WRITE (I2C_DATA, data);
144         /* assert the address */
145         RESET_REG_BITS (I2C_CONTROL, BIT3);
146
147         udelay (I2C_DELAY);
148
149         GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
150         count = 0;
151         while (((status & 0xff) != 0x40) && ((status & 0xff) != 0x18)) {
152                 udelay (I2C_DELAY);
153                 if (count > 20) {
154                         GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
155                         return (status);
156                 }
157                 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
158                 count++;
159         }
160
161         if (bits == 10) {
162                 printf ("10 bit I2C addressing not yet implemented\n");
163                 return (0xff);
164         }
165
166         return (0);
167 }
168
169 static uchar i2c_get_data (uchar * return_data, int len)
170 {
171
172         unsigned int data, status = 0;
173         int count = 0;
174
175         DP (puts ("i2c_get_data\n"));
176
177         while (len) {
178
179                 /* Get and return the data */
180
181                 RESET_REG_BITS (I2C_CONTROL, (0x1 << 3));
182
183                 udelay (I2C_DELAY * 5);
184
185                 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
186                 count++;
187                 while ((status & 0xff) != 0x50) {
188                         udelay (I2C_DELAY);
189                         if (count > 2) {
190                                 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
191                                 return 0;
192                         }
193                         GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
194                         count++;
195                 }
196                 GT_REG_READ (I2C_DATA, &data);
197                 len--;
198                 *return_data = (uchar) data;
199                 return_data++;
200         }
201         RESET_REG_BITS (I2C_CONTROL, BIT2 | BIT3);
202         while ((status & 0xff) != 0x58) {
203                 udelay (I2C_DELAY);
204                 if (count > 200) {
205                         GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
206                         return (status);
207                 }
208                 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
209                 count++;
210         }
211         GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /* stop */
212
213         return (0);
214 }
215
216 static uchar i2c_write_data (unsigned int *data, int len)
217 {
218         unsigned int status;
219         int count = 0;
220         unsigned int temp;
221         unsigned int *temp_ptr = data;
222
223         DP (puts ("i2c_write_data\n"));
224
225         while (len) {
226                 temp = (unsigned int) (*temp_ptr);
227                 GT_REG_WRITE (I2C_DATA, temp);
228                 RESET_REG_BITS (I2C_CONTROL, (0x1 << 3));
229
230                 udelay (I2C_DELAY);
231
232                 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
233                 count++;
234                 while ((status & 0xff) != 0x28) {
235                         udelay (I2C_DELAY);
236                         if (count > 20) {
237                                 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
238                                 return (status);
239                         }
240                         GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
241                         count++;
242                 }
243                 len--;
244                 temp_ptr++;
245         }
246 /* 11-14-2002 Paul Marchese */
247 /* Can't have the write issuing a stop command */
248 /* it's wrong to have a stop bit in read stream or write stream */
249 /* since we don't know if it's really the end of the command */
250 /* or whether we have just send the device address + offset */
251 /* we will push issuing the stop command off to the original */
252 /* calling function */
253         /* set the interrupt bit in the control register */
254         GT_REG_WRITE (I2C_CONTROL, (0x1 << 3));
255         udelay (I2C_DELAY * 10);
256         return (0);
257 }
258
259 /* 11-14-2002 Paul Marchese */
260 /* created this function to get the i2c_write() */
261 /* function working properly. */
262 /* function to write bytes out on the i2c bus */
263 /* this is identical to the function i2c_write_data() */
264 /* except that it requires a buffer that is an */
265 /* unsigned character array.  You can't use */
266 /* i2c_write_data() to send an array of unsigned characters */
267 /* since the byte of interest ends up on the wrong end of the bus */
268 /* aah, the joys of big endian versus little endian! */
269 /* */
270 /* returns 0 = success */
271 /*         anything other than zero is failure */
272 static uchar i2c_write_byte (unsigned char *data, int len)
273 {
274         unsigned int status;
275         int count = 0;
276         unsigned int temp;
277         unsigned char *temp_ptr = data;
278
279         DP (puts ("i2c_write_byte\n"));
280
281         while (len) {
282                 /* Set and assert the data */
283                 temp = *temp_ptr;
284                 GT_REG_WRITE (I2C_DATA, temp);
285                 RESET_REG_BITS (I2C_CONTROL, (0x1 << 3));
286
287                 udelay (I2C_DELAY);
288
289                 GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
290                 count++;
291                 while ((status & 0xff) != 0x28) {
292                         udelay (I2C_DELAY);
293                         if (count > 20) {
294                                 GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
295                                 return (status);
296                         }
297                         GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
298                         count++;
299                 }
300                 len--;
301                 temp_ptr++;
302         }
303 /* Can't have the write issuing a stop command */
304 /* it's wrong to have a stop bit in read stream or write stream */
305 /* since we don't know if it's really the end of the command */
306 /* or whether we have just send the device address + offset */
307 /* we will push issuing the stop command off to the original */
308 /* calling function */
309 /*      GT_REG_WRITE(I2C_CONTROL, (0x1 << 3) | (0x1 << 4));
310         GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); */
311         /* set the interrupt bit in the control register */
312         GT_REG_WRITE (I2C_CONTROL, (0x1 << 3));
313         udelay (I2C_DELAY * 10);
314
315         return (0);
316 }
317
318 static uchar
319 i2c_set_dev_offset (uchar dev_addr, unsigned int offset, int ten_bit,
320                     int alen)
321 {
322         uchar status;
323         unsigned int table[2];
324
325 /* initialize the table of address offset bytes */
326 /* utilized for 2 byte address offsets */
327 /* NOTE: the order is high byte first! */
328         table[1] = offset & 0xff;       /* low byte */
329         table[0] = offset / 0x100;      /* high byte */
330
331         DP (puts ("i2c_set_dev_offset\n"));
332
333         status = i2c_select_device (dev_addr, 0, ten_bit);
334         if (status) {
335 #ifdef DEBUG_I2C
336                 printf ("Failed to select device setting offset: 0x%02x\n",
337                         status);
338 #endif
339                 return status;
340         }
341 /* check the address offset length */
342         if (alen == 0)
343                 /* no address offset */
344                 return (0);
345         else if (alen == 1) {
346                 /* 1 byte address offset */
347                 status = i2c_write_data (&offset, 1);
348                 if (status) {
349 #ifdef DEBUG_I2C
350                         printf ("Failed to write data: 0x%02x\n", status);
351 #endif
352                         return status;
353                 }
354         } else if (alen == 2) {
355                 /* 2 bytes address offset */
356                 status = i2c_write_data (table, 2);
357                 if (status) {
358 #ifdef DEBUG_I2C
359                         printf ("Failed to write data: 0x%02x\n", status);
360 #endif
361                         return status;
362                 }
363         } else {
364                 /* address offset unknown or not supported */
365                 printf ("Address length offset %d is not supported\n", alen);
366                 return 1;
367         }
368         return 0;               /* sucessful completion */
369 }
370
371 int
372 i2c_read (uchar dev_addr, unsigned int offset, int alen, uchar * data,
373           int len)
374 {
375         uchar status = 0;
376         unsigned int i2cFreq = CONFIG_SYS_I2C_SPEED;
377
378         DP (puts ("i2c_read\n"));
379
380         /* set the i2c frequency */
381         i2c_init (i2cFreq, CONFIG_SYS_I2C_SLAVE);
382
383         status = i2c_start ();
384
385         if (status) {
386 #ifdef DEBUG_I2C
387                 printf ("Transaction start failed: 0x%02x\n", status);
388 #endif
389                 return status;
390         }
391
392         status = i2c_set_dev_offset (dev_addr, offset, 0, alen);        /* send the slave address + offset */
393         if (status) {
394 #ifdef DEBUG_I2C
395                 printf ("Failed to set slave address & offset: 0x%02x\n",
396                         status);
397 #endif
398                 return status;
399         }
400
401         /* set the i2c frequency again */
402         i2c_init (i2cFreq, CONFIG_SYS_I2C_SLAVE);
403
404         status = i2c_start ();
405         if (status) {
406 #ifdef DEBUG_I2C
407                 printf ("Transaction restart failed: 0x%02x\n", status);
408 #endif
409                 return status;
410         }
411
412         status = i2c_select_device (dev_addr, 1, 0);    /* send the slave address */
413         if (status) {
414 #ifdef DEBUG_I2C
415                 printf ("Address not acknowledged: 0x%02x\n", status);
416 #endif
417                 return status;
418         }
419
420         status = i2c_get_data (data, len);
421         if (status) {
422 #ifdef DEBUG_I2C
423                 printf ("Data not recieved: 0x%02x\n", status);
424 #endif
425                 return status;
426         }
427
428         return 0;
429 }
430
431 /* 11-14-2002 Paul Marchese */
432 /* Function to set the I2C stop bit */
433 void i2c_stop (void)
434 {
435         GT_REG_WRITE (I2C_CONTROL, (0x1 << 4));
436 }
437
438 /* 11-14-2002 Paul Marchese */
439 /* I2C write function */
440 /* dev_addr = device address */
441 /* offset = address offset */
442 /* alen = length in bytes of the address offset */
443 /* data = pointer to buffer to read data into */
444 /* len = # of bytes to read */
445 /* */
446 /* returns 0 = succesful */
447 /*         anything but zero is failure */
448 int
449 i2c_write (uchar dev_addr, unsigned int offset, int alen, uchar * data,
450            int len)
451 {
452         uchar status = 0;
453         unsigned int i2cFreq = CONFIG_SYS_I2C_SPEED;
454
455         DP (puts ("i2c_write\n"));
456
457         /* set the i2c frequency */
458         i2c_init (i2cFreq, CONFIG_SYS_I2C_SLAVE);
459
460         status = i2c_start ();  /* send a start bit */
461
462         if (status) {
463 #ifdef DEBUG_I2C
464                 printf ("Transaction start failed: 0x%02x\n", status);
465 #endif
466                 return status;
467         }
468
469         status = i2c_set_dev_offset (dev_addr, offset, 0, alen);        /* send the slave address + offset */
470         if (status) {
471 #ifdef DEBUG_I2C
472                 printf ("Failed to set slave address & offset: 0x%02x\n",
473                         status);
474 #endif
475                 return status;
476         }
477
478
479         status = i2c_write_byte (data, len);    /* write the data */
480         if (status) {
481 #ifdef DEBUG_I2C
482                 printf ("Data not written: 0x%02x\n", status);
483 #endif
484                 return status;
485         }
486         /* issue a stop bit */
487         i2c_stop ();
488         return 0;
489 }
490
491 /* 11-14-2002 Paul Marchese */
492 /* function to determine if an I2C device is present */
493 /* chip = device address of chip to check for */
494 /* */
495 /* returns 0 = sucessful, the device exists */
496 /*         anything other than zero is failure, no device */
497 int i2c_probe (uchar chip)
498 {
499
500         /* We are just looking for an <ACK> back. */
501         /* To see if the device/chip is there */
502
503 #ifdef DEBUG_I2C
504         unsigned int i2c_status;
505 #endif
506         uchar status = 0;
507         unsigned int i2cFreq = CONFIG_SYS_I2C_SPEED;
508
509         DP (puts ("i2c_probe\n"));
510
511         /* set the i2c frequency */
512         i2c_init (i2cFreq, CONFIG_SYS_I2C_SLAVE);
513
514         status = i2c_start ();  /* send a start bit */
515
516         if (status) {
517 #ifdef DEBUG_I2C
518                 printf ("Transaction start failed: 0x%02x\n", status);
519 #endif
520                 return (int) status;
521         }
522
523         status = i2c_set_dev_offset (chip, 0, 0, 0);    /* send the slave address + no offset */
524         if (status) {
525 #ifdef DEBUG_I2C
526                 printf ("Failed to set slave address: 0x%02x\n", status);
527 #endif
528                 return (int) status;
529         }
530 #ifdef DEBUG_I2C
531         GT_REG_READ (I2C_STATUS_BAUDE_RATE, &i2c_status);
532         printf ("address %#x returned %#x\n", chip, i2c_status);
533 #endif
534         /* issue a stop bit */
535         i2c_stop ();
536         return 0;               /* successful completion */
537 }