]> git.ipfire.org Git - people/ms/u-boot.git/blob - cpu/mpc8220/i2c.c
62f7c0f5d330df815284ca99031017880c66273c
[people/ms/u-boot.git] / cpu / mpc8220 / i2c.c
1 /*
2 * (C) Copyright 2004, Freescale, Inc
3 * TsiChung Liew, Tsi-Chung.Liew@freescale.com.
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
24 #include <common.h>
25
26 #ifdef CONFIG_HARD_I2C
27
28 #include <mpc8220.h>
29 #include <i2c.h>
30
31 typedef struct mpc8220_i2c {
32 volatile u32 adr; /* I2Cn + 0x00 */
33 volatile u32 fdr; /* I2Cn + 0x04 */
34 volatile u32 cr; /* I2Cn + 0x08 */
35 volatile u32 sr; /* I2Cn + 0x0C */
36 volatile u32 dr; /* I2Cn + 0x10 */
37 } i2c_t;
38
39 /* I2Cn control register bits */
40 #define I2C_EN 0x80
41 #define I2C_IEN 0x40
42 #define I2C_STA 0x20
43 #define I2C_TX 0x10
44 #define I2C_TXAK 0x08
45 #define I2C_RSTA 0x04
46 #define I2C_INIT_MASK (I2C_EN | I2C_STA | I2C_TX | I2C_RSTA)
47
48 /* I2Cn status register bits */
49 #define I2C_CF 0x80
50 #define I2C_AAS 0x40
51 #define I2C_BB 0x20
52 #define I2C_AL 0x10
53 #define I2C_SRW 0x04
54 #define I2C_IF 0x02
55 #define I2C_RXAK 0x01
56
57 #define I2C_TIMEOUT 100
58 #define I2C_RETRIES 1
59
60 struct mpc8220_i2c_tap {
61 int scl2tap;
62 int tap2tap;
63 };
64
65 static int mpc_reg_in (volatile u32 * reg);
66 static void mpc_reg_out (volatile u32 * reg, int val, int mask);
67 static int wait_for_bb (void);
68 static int wait_for_pin (int *status);
69 static int do_address (uchar chip, char rdwr_flag);
70 static int send_bytes (uchar chip, char *buf, int len);
71 static int receive_bytes (uchar chip, char *buf, int len);
72 static int mpc_get_fdr (int);
73
74 static int mpc_reg_in (volatile u32 * reg)
75 {
76 int ret;
77 ret = *reg >> 24;
78 __asm__ __volatile__ ("eieio");
79 return ret;
80 }
81
82 static void mpc_reg_out (volatile u32 * reg, int val, int mask)
83 {
84 int tmp;
85
86 if (!mask) {
87 *reg = val << 24;
88 } else {
89 tmp = mpc_reg_in (reg);
90 *reg = ((tmp & ~mask) | (val & mask)) << 24;
91 }
92 __asm__ __volatile__ ("eieio");
93
94 return;
95 }
96
97 static int wait_for_bb (void)
98 {
99 i2c_t *regs = (i2c_t *) MMAP_I2C;
100 int timeout = I2C_TIMEOUT;
101 int status;
102
103 status = mpc_reg_in (&regs->sr);
104
105 while (timeout-- && (status & I2C_BB)) {
106 #if 1
107 volatile int temp;
108
109 mpc_reg_out (&regs->cr, I2C_STA, I2C_STA);
110 temp = mpc_reg_in (&regs->dr);
111 mpc_reg_out (&regs->cr, 0, I2C_STA);
112 mpc_reg_out (&regs->cr, 0, 0);
113 mpc_reg_out (&regs->cr, I2C_EN, 0);
114 #endif
115 udelay (1000);
116 status = mpc_reg_in (&regs->sr);
117 }
118
119 return (status & I2C_BB);
120 }
121
122 static int wait_for_pin (int *status)
123 {
124 i2c_t *regs = (i2c_t *) MMAP_I2C;
125 int timeout = I2C_TIMEOUT;
126
127 *status = mpc_reg_in (&regs->sr);
128
129 while (timeout-- && !(*status & I2C_IF)) {
130 udelay (1000);
131 *status = mpc_reg_in (&regs->sr);
132 }
133
134 if (!(*status & I2C_IF)) {
135 return -1;
136 }
137
138 mpc_reg_out (&regs->sr, 0, I2C_IF);
139 return 0;
140 }
141
142 static int do_address (uchar chip, char rdwr_flag)
143 {
144 i2c_t *regs = (i2c_t *) MMAP_I2C;
145 int status;
146
147 chip <<= 1;
148
149 if (rdwr_flag)
150 chip |= 1;
151
152 mpc_reg_out (&regs->cr, I2C_TX, I2C_TX);
153 mpc_reg_out (&regs->dr, chip, 0);
154
155 if (wait_for_pin (&status))
156 return -2;
157 if (status & I2C_RXAK)
158 return -3;
159 return 0;
160 }
161
162 static int send_bytes (uchar chip, char *buf, int len)
163 {
164 i2c_t *regs = (i2c_t *) MMAP_I2C;
165 int wrcount;
166 int status;
167
168 for (wrcount = 0; wrcount < len; ++wrcount) {
169
170 mpc_reg_out (&regs->dr, buf[wrcount], 0);
171
172 if (wait_for_pin (&status))
173 break;
174
175 if (status & I2C_RXAK)
176 break;
177
178 }
179
180 return !(wrcount == len);
181 return 0;
182 }
183
184 static int receive_bytes (uchar chip, char *buf, int len)
185 {
186 i2c_t *regs = (i2c_t *) MMAP_I2C;
187 int dummy = 1;
188 int rdcount = 0;
189 int status;
190 int i;
191
192 mpc_reg_out (&regs->cr, 0, I2C_TX);
193
194 for (i = 0; i < len; ++i) {
195 buf[rdcount] = mpc_reg_in (&regs->dr);
196
197 if (dummy)
198 dummy = 0;
199 else
200 rdcount++;
201
202 if (wait_for_pin (&status))
203 return -4;
204 }
205
206 mpc_reg_out (&regs->cr, I2C_TXAK, I2C_TXAK);
207 buf[rdcount++] = mpc_reg_in (&regs->dr);
208
209 if (wait_for_pin (&status))
210 return -5;
211
212 mpc_reg_out (&regs->cr, 0, I2C_TXAK);
213 return 0;
214 }
215
216 /**************** I2C API ****************/
217
218 void i2c_init (int speed, int saddr)
219 {
220 i2c_t *regs = (i2c_t *) MMAP_I2C;
221
222 mpc_reg_out (&regs->cr, 0, 0);
223 mpc_reg_out (&regs->adr, saddr << 1, 0);
224
225 /* Set clock
226 */
227 mpc_reg_out (&regs->fdr, mpc_get_fdr (speed), 0);
228
229 /* Enable module
230 */
231 mpc_reg_out (&regs->cr, I2C_EN, I2C_INIT_MASK);
232 mpc_reg_out (&regs->sr, 0, I2C_IF);
233 return;
234 }
235
236 static int mpc_get_fdr (int speed)
237 {
238 DECLARE_GLOBAL_DATA_PTR;
239 static int fdr = -1;
240
241 if (fdr == -1) {
242 ulong best_speed = 0;
243 ulong divider;
244 ulong ipb, scl;
245 ulong bestmatch = 0xffffffffUL;
246 int best_i = 0, best_j = 0, i, j;
247 int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8 };
248 struct mpc8220_i2c_tap scltap[] = {
249 {4, 1},
250 {4, 2},
251 {6, 4},
252 {6, 8},
253 {14, 16},
254 {30, 32},
255 {62, 64},
256 {126, 128}
257 };
258
259 ipb = gd->bus_clk;
260 for (i = 7; i >= 0; i--) {
261 for (j = 7; j >= 0; j--) {
262 scl = 2 * (scltap[j].scl2tap +
263 (SCL_Tap[i] -
264 1) * scltap[j].tap2tap + 2);
265 if (ipb <= speed * scl) {
266 if ((speed * scl - ipb) < bestmatch) {
267 bestmatch = speed * scl - ipb;
268 best_i = i;
269 best_j = j;
270 best_speed = ipb / scl;
271 }
272 }
273 }
274 }
275 divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2);
276 if (gd->flags & GD_FLG_RELOC) {
277 fdr = divider;
278 } else {
279 printf ("%ld kHz, ", best_speed / 1000);
280 return divider;
281 }
282 }
283
284 return fdr;
285 }
286
287 int i2c_probe (uchar chip)
288 {
289 i2c_t *regs = (i2c_t *) MMAP_I2C;
290 int i;
291
292 for (i = 0; i < I2C_RETRIES; i++) {
293 mpc_reg_out (&regs->cr, I2C_STA, I2C_STA);
294
295 if (!do_address (chip, 0)) {
296 mpc_reg_out (&regs->cr, 0, I2C_STA);
297 break;
298 }
299
300 mpc_reg_out (&regs->cr, 0, I2C_STA);
301 udelay (50);
302 }
303
304 return (i == I2C_RETRIES);
305 }
306
307 int i2c_read (uchar chip, uint addr, int alen, uchar * buf, int len)
308 {
309 uchar xaddr[4];
310 i2c_t *regs = (i2c_t *) MMAP_I2C;
311 int ret = -1;
312
313 xaddr[0] = (addr >> 24) & 0xFF;
314 xaddr[1] = (addr >> 16) & 0xFF;
315 xaddr[2] = (addr >> 8) & 0xFF;
316 xaddr[3] = addr & 0xFF;
317
318 if (wait_for_bb ()) {
319 printf ("i2c_read: bus is busy\n");
320 goto Done;
321 }
322
323 mpc_reg_out (&regs->cr, I2C_STA, I2C_STA);
324 if (do_address (chip, 0)) {
325 printf ("i2c_read: failed to address chip\n");
326 goto Done;
327 }
328
329 if (send_bytes (chip, (char *)&xaddr[4 - alen], alen)) {
330 printf ("i2c_read: send_bytes failed\n");
331 goto Done;
332 }
333
334 mpc_reg_out (&regs->cr, I2C_RSTA, I2C_RSTA);
335 if (do_address (chip, 1)) {
336 printf ("i2c_read: failed to address chip\n");
337 goto Done;
338 }
339
340 if (receive_bytes (chip, (char *)buf, len)) {
341 printf ("i2c_read: receive_bytes failed\n");
342 goto Done;
343 }
344
345 ret = 0;
346 Done:
347 mpc_reg_out (&regs->cr, 0, I2C_STA);
348 return ret;
349 }
350
351 int i2c_write (uchar chip, uint addr, int alen, uchar * buf, int len)
352 {
353 uchar xaddr[4];
354 i2c_t *regs = (i2c_t *) MMAP_I2C;
355 int ret = -1;
356
357 xaddr[0] = (addr >> 24) & 0xFF;
358 xaddr[1] = (addr >> 16) & 0xFF;
359 xaddr[2] = (addr >> 8) & 0xFF;
360 xaddr[3] = addr & 0xFF;
361
362 if (wait_for_bb ()) {
363 printf ("i2c_write: bus is busy\n");
364 goto Done;
365 }
366
367 mpc_reg_out (&regs->cr, I2C_STA, I2C_STA);
368 if (do_address (chip, 0)) {
369 printf ("i2c_write: failed to address chip\n");
370 goto Done;
371 }
372
373 if (send_bytes (chip, (char *)&xaddr[4 - alen], alen)) {
374 printf ("i2c_write: send_bytes failed\n");
375 goto Done;
376 }
377
378 if (send_bytes (chip, (char *)buf, len)) {
379 printf ("i2c_write: send_bytes failed\n");
380 goto Done;
381 }
382
383 ret = 0;
384 Done:
385 mpc_reg_out (&regs->cr, 0, I2C_STA);
386 return ret;
387 }
388
389 uchar i2c_reg_read (uchar chip, uchar reg)
390 {
391 uchar buf;
392
393 i2c_read (chip, reg, 1, &buf, 1);
394
395 return buf;
396 }
397
398 void i2c_reg_write (uchar chip, uchar reg, uchar val)
399 {
400 i2c_write (chip, reg, 1, &val, 1);
401
402 return;
403 }
404
405 #endif /* CONFIG_HARD_I2C */