blob: 62f7c0f5d330df815284ca99031017880c66273c [file] [log] [blame]
wdenk337f5652004-10-28 00:09:35 +00001/*
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
31typedef 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
60struct mpc8220_i2c_tap {
61 int scl2tap;
62 int tap2tap;
63};
64
65static int mpc_reg_in (volatile u32 * reg);
66static void mpc_reg_out (volatile u32 * reg, int val, int mask);
67static int wait_for_bb (void);
68static int wait_for_pin (int *status);
69static int do_address (uchar chip, char rdwr_flag);
70static int send_bytes (uchar chip, char *buf, int len);
71static int receive_bytes (uchar chip, char *buf, int len);
72static int mpc_get_fdr (int);
73
74static int mpc_reg_in (volatile u32 * reg)
75{
Wolfgang Denk7fb52662005-10-13 16:45:02 +020076 int ret;
77 ret = *reg >> 24;
wdenk337f5652004-10-28 00:09:35 +000078 __asm__ __volatile__ ("eieio");
Wolfgang Denk7fb52662005-10-13 16:45:02 +020079 return ret;
wdenk337f5652004-10-28 00:09:35 +000080}
81
82static 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
97static 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
122static 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
142static 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
162static 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
184static 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
218void 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
236static 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
287int 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
307int 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
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200329 if (send_bytes (chip, (char *)&xaddr[4 - alen], alen)) {
wdenk337f5652004-10-28 00:09:35 +0000330 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
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200340 if (receive_bytes (chip, (char *)buf, len)) {
wdenk337f5652004-10-28 00:09:35 +0000341 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
351int 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
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200373 if (send_bytes (chip, (char *)&xaddr[4 - alen], alen)) {
wdenk337f5652004-10-28 00:09:35 +0000374 printf ("i2c_write: send_bytes failed\n");
375 goto Done;
376 }
377
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200378 if (send_bytes (chip, (char *)buf, len)) {
wdenk337f5652004-10-28 00:09:35 +0000379 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
389uchar i2c_reg_read (uchar chip, uchar reg)
390{
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200391 uchar buf;
wdenk337f5652004-10-28 00:09:35 +0000392
393 i2c_read (chip, reg, 1, &buf, 1);
394
395 return buf;
396}
397
398void 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 */