]> git.sur5r.net Git - u-boot/blob - drivers/fsl_i2c.c
mpc83xx: make 8360 default environment fdt be 8360 (not 8349)
[u-boot] / drivers / fsl_i2c.c
1 /*
2  * Copyright 2006 Freescale Semiconductor, Inc.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * Version 2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
16  * MA 02111-1307 USA
17  */
18
19 #include <common.h>
20
21 #ifdef CONFIG_FSL_I2C
22 #ifdef CONFIG_HARD_I2C
23
24 #include <command.h>
25 #include <i2c.h>                /* Functional interface */
26
27 #include <asm/io.h>
28 #include <asm/fsl_i2c.h>        /* HW definitions */
29
30 #define I2C_TIMEOUT     (CFG_HZ / 4)
31
32 #define I2C_READ_BIT  1
33 #define I2C_WRITE_BIT 0
34
35 /* Initialize the bus pointer to whatever one the SPD EEPROM is on.
36  * Default is bus 0.  This is necessary because the DDR initialization
37  * runs from ROM, and we can't switch buses because we can't modify
38  * the global variables.
39  */
40 #ifdef CFG_SPD_BUS_NUM
41 static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CFG_SPD_BUS_NUM;
42 #else
43 static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0;
44 #endif
45
46 static volatile struct fsl_i2c *i2c_dev[2] = {
47         (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET),
48 #ifdef CFG_I2C2_OFFSET
49         (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET)
50 #endif
51 };
52
53 void
54 i2c_init(int speed, int slaveadd)
55 {
56         volatile struct fsl_i2c *dev;
57
58         dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET);
59
60         writeb(0, &dev->cr);                    /* stop I2C controller */
61         writeb(0x3F, &dev->fdr);                /* set bus speed */
62         writeb(0x3F, &dev->dfsrr);              /* set default filter */
63         writeb(slaveadd << 1, &dev->adr);       /* write slave address */
64         writeb(0x0, &dev->sr);                  /* clear status register */
65         writeb(I2C_CR_MEN, &dev->cr);           /* start I2C controller */
66
67 #ifdef  CFG_I2C2_OFFSET
68         dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET);
69
70         writeb(0, &dev->cr);                    /* stop I2C controller */
71         writeb(0x3F, &dev->fdr);                /* set bus speed */
72         writeb(0x3F, &dev->dfsrr);              /* set default filter */
73         writeb(slaveadd, &dev->adr);            /* write slave address */
74         writeb(0x0, &dev->sr);                  /* clear status register */
75         writeb(I2C_CR_MEN, &dev->cr);           /* start I2C controller */
76 #endif  /* CFG_I2C2_OFFSET */
77 }
78
79 static __inline__ int
80 i2c_wait4bus(void)
81 {
82         ulong timeval = get_timer(0);
83
84         while (readb(&i2c_dev[i2c_bus_num]->sr) & I2C_SR_MBB) {
85                 if (get_timer(timeval) > I2C_TIMEOUT) {
86                         return -1;
87                 }
88         }
89
90         return 0;
91 }
92
93 static __inline__ int
94 i2c_wait(int write)
95 {
96         u32 csr;
97         ulong timeval = get_timer(0);
98
99         do {
100                 csr = readb(&i2c_dev[i2c_bus_num]->sr);
101                 if (!(csr & I2C_SR_MIF))
102                         continue;
103
104                 writeb(0x0, &i2c_dev[i2c_bus_num]->sr);
105
106                 if (csr & I2C_SR_MAL) {
107                         debug("i2c_wait: MAL\n");
108                         return -1;
109                 }
110
111                 if (!(csr & I2C_SR_MCF))        {
112                         debug("i2c_wait: unfinished\n");
113                         return -1;
114                 }
115
116                 if (write == I2C_WRITE_BIT && (csr & I2C_SR_RXAK)) {
117                         debug("i2c_wait: No RXACK\n");
118                         return -1;
119                 }
120
121                 return 0;
122         } while (get_timer (timeval) < I2C_TIMEOUT);
123
124         debug("i2c_wait: timed out\n");
125         return -1;
126 }
127
128 static __inline__ int
129 i2c_write_addr (u8 dev, u8 dir, int rsta)
130 {
131         writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
132                | (rsta ? I2C_CR_RSTA : 0),
133                &i2c_dev[i2c_bus_num]->cr);
134
135         writeb((dev << 1) | dir, &i2c_dev[i2c_bus_num]->dr);
136
137         if (i2c_wait(I2C_WRITE_BIT) < 0)
138                 return 0;
139
140         return 1;
141 }
142
143 static __inline__ int
144 __i2c_write(u8 *data, int length)
145 {
146         int i;
147
148         writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
149                &i2c_dev[i2c_bus_num]->cr);
150
151         for (i = 0; i < length; i++) {
152                 writeb(data[i], &i2c_dev[i2c_bus_num]->dr);
153
154                 if (i2c_wait(I2C_WRITE_BIT) < 0)
155                         break;
156         }
157
158         return i;
159 }
160
161 static __inline__ int
162 __i2c_read(u8 *data, int length)
163 {
164         int i;
165
166         writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
167                &i2c_dev[i2c_bus_num]->cr);
168
169         /* dummy read */
170         readb(&i2c_dev[i2c_bus_num]->dr);
171
172         for (i = 0; i < length; i++) {
173                 if (i2c_wait(I2C_READ_BIT) < 0)
174                         break;
175
176                 /* Generate ack on last next to last byte */
177                 if (i == length - 2)
178                         writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
179                                &i2c_dev[i2c_bus_num]->cr);
180
181                 /* Generate stop on last byte */
182                 if (i == length - 1)
183                         writeb(I2C_CR_MEN | I2C_CR_TXAK, &i2c_dev[i2c_bus_num]->cr);
184
185                 data[i] = readb(&i2c_dev[i2c_bus_num]->dr);
186         }
187
188         return i;
189 }
190
191 int
192 i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
193 {
194         int i = 0;
195         u8 *a = (u8*)&addr;
196
197         if (i2c_wait4bus() >= 0
198             && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
199             && __i2c_write(&a[4 - alen], alen) == alen
200             && i2c_write_addr(dev, I2C_READ_BIT, 1) != 0) {
201                 i = __i2c_read(data, length);
202         }
203
204         writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
205
206         if (i == length)
207             return 0;
208
209         return -1;
210 }
211
212 int
213 i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
214 {
215         int i = 0;
216         u8 *a = (u8*)&addr;
217
218         if (i2c_wait4bus() >= 0
219             && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
220             && __i2c_write(&a[4 - alen], alen) == alen) {
221                 i = __i2c_write(data, length);
222         }
223
224         writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
225
226         if (i == length)
227             return 0;
228
229         return -1;
230 }
231
232 int
233 i2c_probe(uchar chip)
234 {
235         int tmp;
236
237         /*
238          * Try to read the first location of the chip.  The underlying
239          * driver doesn't appear to support sending just the chip address
240          * and looking for an <ACK> back.
241          */
242         udelay(10000);
243
244         return i2c_read(chip, 0, 1, (uchar *)&tmp, 1);
245 }
246
247 uchar
248 i2c_reg_read(uchar i2c_addr, uchar reg)
249 {
250         uchar buf[1];
251
252         i2c_read(i2c_addr, reg, 1, buf, 1);
253
254         return buf[0];
255 }
256
257 void
258 i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
259 {
260         i2c_write(i2c_addr, reg, 1, &val, 1);
261 }
262
263 int i2c_set_bus_num(unsigned int bus)
264 {
265 #ifdef CFG_I2C2_OFFSET
266         if (bus > 1) {
267 #else
268         if (bus > 0) {
269 #endif
270                 return -1;
271         }
272
273         i2c_bus_num = bus;
274
275         return 0;
276 }
277
278 int i2c_set_bus_speed(unsigned int speed)
279 {
280         return -1;
281 }
282
283 unsigned int i2c_get_bus_num(void)
284 {
285         return i2c_bus_num;
286 }
287
288 unsigned int i2c_get_bus_speed(void)
289 {
290         return 0;
291 }
292 #endif /* CONFIG_HARD_I2C */
293 #endif /* CONFIG_FSL_I2C */