Add support for the Siemens SMN42 board.
[platform/kernel/u-boot.git] / 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         udelay(5);                              /* let it shutdown in peace */
62         writeb(0x3F, &dev->fdr);                /* set bus speed */
63         writeb(0x3F, &dev->dfsrr);              /* set default filter */
64         writeb(slaveadd << 1, &dev->adr);       /* write slave address */
65         writeb(0x0, &dev->sr);                  /* clear status register */
66         writeb(I2C_CR_MEN, &dev->cr);           /* start I2C controller */
67
68 #ifdef  CFG_I2C2_OFFSET
69         dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET);
70
71         writeb(0, &dev->cr);                    /* stop I2C controller */
72         writeb(0x3F, &dev->fdr);                /* set bus speed */
73         writeb(0x3F, &dev->dfsrr);              /* set default filter */
74         writeb(slaveadd, &dev->adr);            /* write slave address */
75         writeb(0x0, &dev->sr);                  /* clear status register */
76         writeb(I2C_CR_MEN, &dev->cr);           /* start I2C controller */
77 #endif  /* CFG_I2C2_OFFSET */
78 }
79
80 static __inline__ int
81 i2c_wait4bus(void)
82 {
83         ulong timeval = get_timer(0);
84
85         while (readb(&i2c_dev[i2c_bus_num]->sr) & I2C_SR_MBB) {
86                 if (get_timer(timeval) > I2C_TIMEOUT) {
87                         return -1;
88                 }
89         }
90
91         return 0;
92 }
93
94 static __inline__ int
95 i2c_wait(int write)
96 {
97         u32 csr;
98         ulong timeval = get_timer(0);
99
100         do {
101                 csr = readb(&i2c_dev[i2c_bus_num]->sr);
102                 if (!(csr & I2C_SR_MIF))
103                         continue;
104
105                 writeb(0x0, &i2c_dev[i2c_bus_num]->sr);
106
107                 if (csr & I2C_SR_MAL) {
108                         debug("i2c_wait: MAL\n");
109                         return -1;
110                 }
111
112                 if (!(csr & I2C_SR_MCF))        {
113                         debug("i2c_wait: unfinished\n");
114                         return -1;
115                 }
116
117                 if (write == I2C_WRITE_BIT && (csr & I2C_SR_RXAK)) {
118                         debug("i2c_wait: No RXACK\n");
119                         return -1;
120                 }
121
122                 return 0;
123         } while (get_timer (timeval) < I2C_TIMEOUT);
124
125         debug("i2c_wait: timed out\n");
126         return -1;
127 }
128
129 static __inline__ int
130 i2c_write_addr (u8 dev, u8 dir, int rsta)
131 {
132         writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
133                | (rsta ? I2C_CR_RSTA : 0),
134                &i2c_dev[i2c_bus_num]->cr);
135
136         writeb((dev << 1) | dir, &i2c_dev[i2c_bus_num]->dr);
137
138         if (i2c_wait(I2C_WRITE_BIT) < 0)
139                 return 0;
140
141         return 1;
142 }
143
144 static __inline__ int
145 __i2c_write(u8 *data, int length)
146 {
147         int i;
148
149         writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
150                &i2c_dev[i2c_bus_num]->cr);
151
152         for (i = 0; i < length; i++) {
153                 writeb(data[i], &i2c_dev[i2c_bus_num]->dr);
154
155                 if (i2c_wait(I2C_WRITE_BIT) < 0)
156                         break;
157         }
158
159         return i;
160 }
161
162 static __inline__ int
163 __i2c_read(u8 *data, int length)
164 {
165         int i;
166
167         writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
168                &i2c_dev[i2c_bus_num]->cr);
169
170         /* dummy read */
171         readb(&i2c_dev[i2c_bus_num]->dr);
172
173         for (i = 0; i < length; i++) {
174                 if (i2c_wait(I2C_READ_BIT) < 0)
175                         break;
176
177                 /* Generate ack on last next to last byte */
178                 if (i == length - 2)
179                         writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
180                                &i2c_dev[i2c_bus_num]->cr);
181
182                 /* Generate stop on last byte */
183                 if (i == length - 1)
184                         writeb(I2C_CR_MEN | I2C_CR_TXAK, &i2c_dev[i2c_bus_num]->cr);
185
186                 data[i] = readb(&i2c_dev[i2c_bus_num]->dr);
187         }
188
189         return i;
190 }
191
192 int
193 i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
194 {
195         int i = -1; /* signal error */
196         u8 *a = (u8*)&addr;
197
198         if (i2c_wait4bus() >= 0
199             && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
200             && __i2c_write(&a[4 - alen], alen) == alen)
201                 i = 0; /* No error so far */
202
203         if (length
204             && i2c_write_addr(dev, I2C_READ_BIT, 1) != 0)
205                 i = __i2c_read(data, length);
206
207         writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
208
209         if (i == length)
210             return 0;
211
212         return -1;
213 }
214
215 int
216 i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
217 {
218         int i = -1; /* signal error */
219         u8 *a = (u8*)&addr;
220
221         if (i2c_wait4bus() >= 0
222             && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
223             && __i2c_write(&a[4 - alen], alen) == alen) {
224                 i = __i2c_write(data, length);
225         }
226
227         writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
228
229         if (i == length)
230             return 0;
231
232         return -1;
233 }
234
235 int
236 i2c_probe(uchar chip)
237 {
238         /* For unknow reason the controller will ACK when
239          * probing for a slave with the same address, so skip
240          * it.
241          */
242         if (chip == (readb(&i2c_dev[i2c_bus_num]->adr) >> 1))
243                 return -1;
244
245         return i2c_read(chip, 0, 0, NULL, 0);
246 }
247
248 uchar
249 i2c_reg_read(uchar i2c_addr, uchar reg)
250 {
251         uchar buf[1];
252
253         i2c_read(i2c_addr, reg, 1, buf, 1);
254
255         return buf[0];
256 }
257
258 void
259 i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
260 {
261         i2c_write(i2c_addr, reg, 1, &val, 1);
262 }
263
264 int i2c_set_bus_num(unsigned int bus)
265 {
266 #ifdef CFG_I2C2_OFFSET
267         if (bus > 1) {
268 #else
269         if (bus > 0) {
270 #endif
271                 return -1;
272         }
273
274         i2c_bus_num = bus;
275
276         return 0;
277 }
278
279 int i2c_set_bus_speed(unsigned int speed)
280 {
281         return -1;
282 }
283
284 unsigned int i2c_get_bus_num(void)
285 {
286         return i2c_bus_num;
287 }
288
289 unsigned int i2c_get_bus_speed(void)
290 {
291         return 0;
292 }
293 #endif /* CONFIG_HARD_I2C */
294 #endif /* CONFIG_FSL_I2C */