]>
git.ipfire.org Git - people/ms/u-boot.git/blob - cpu/mpc8220/i2c.c
2 * (C) Copyright 2004, Freescale, Inc
3 * TsiChung Liew, Tsi-Chung.Liew@freescale.com.
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
26 DECLARE_GLOBAL_DATA_PTR
;
28 #ifdef CONFIG_HARD_I2C
33 typedef struct mpc8220_i2c
{
34 volatile u32 adr
; /* I2Cn + 0x00 */
35 volatile u32 fdr
; /* I2Cn + 0x04 */
36 volatile u32 cr
; /* I2Cn + 0x08 */
37 volatile u32 sr
; /* I2Cn + 0x0C */
38 volatile u32 dr
; /* I2Cn + 0x10 */
41 /* I2Cn control register bits */
48 #define I2C_INIT_MASK (I2C_EN | I2C_STA | I2C_TX | I2C_RSTA)
50 /* I2Cn status register bits */
59 #define I2C_TIMEOUT 100
62 struct mpc8220_i2c_tap
{
67 static int mpc_reg_in (volatile u32
* reg
);
68 static void mpc_reg_out (volatile u32
* reg
, int val
, int mask
);
69 static int wait_for_bb (void);
70 static int wait_for_pin (int *status
);
71 static int do_address (uchar chip
, char rdwr_flag
);
72 static int send_bytes (uchar chip
, char *buf
, int len
);
73 static int receive_bytes (uchar chip
, char *buf
, int len
);
74 static int mpc_get_fdr (int);
76 static int mpc_reg_in (volatile u32
* reg
)
80 __asm__
__volatile__ ("eieio");
84 static void mpc_reg_out (volatile u32
* reg
, int val
, int mask
)
91 tmp
= mpc_reg_in (reg
);
92 *reg
= ((tmp
& ~mask
) | (val
& mask
)) << 24;
94 __asm__
__volatile__ ("eieio");
99 static int wait_for_bb (void)
101 i2c_t
*regs
= (i2c_t
*) MMAP_I2C
;
102 int timeout
= I2C_TIMEOUT
;
105 status
= mpc_reg_in (®s
->sr
);
107 while (timeout
-- && (status
& I2C_BB
)) {
111 mpc_reg_out (®s
->cr
, I2C_STA
, I2C_STA
);
112 temp
= mpc_reg_in (®s
->dr
);
113 mpc_reg_out (®s
->cr
, 0, I2C_STA
);
114 mpc_reg_out (®s
->cr
, 0, 0);
115 mpc_reg_out (®s
->cr
, I2C_EN
, 0);
118 status
= mpc_reg_in (®s
->sr
);
121 return (status
& I2C_BB
);
124 static int wait_for_pin (int *status
)
126 i2c_t
*regs
= (i2c_t
*) MMAP_I2C
;
127 int timeout
= I2C_TIMEOUT
;
129 *status
= mpc_reg_in (®s
->sr
);
131 while (timeout
-- && !(*status
& I2C_IF
)) {
133 *status
= mpc_reg_in (®s
->sr
);
136 if (!(*status
& I2C_IF
)) {
140 mpc_reg_out (®s
->sr
, 0, I2C_IF
);
144 static int do_address (uchar chip
, char rdwr_flag
)
146 i2c_t
*regs
= (i2c_t
*) MMAP_I2C
;
154 mpc_reg_out (®s
->cr
, I2C_TX
, I2C_TX
);
155 mpc_reg_out (®s
->dr
, chip
, 0);
157 if (wait_for_pin (&status
))
159 if (status
& I2C_RXAK
)
164 static int send_bytes (uchar chip
, char *buf
, int len
)
166 i2c_t
*regs
= (i2c_t
*) MMAP_I2C
;
170 for (wrcount
= 0; wrcount
< len
; ++wrcount
) {
172 mpc_reg_out (®s
->dr
, buf
[wrcount
], 0);
174 if (wait_for_pin (&status
))
177 if (status
& I2C_RXAK
)
182 return !(wrcount
== len
);
186 static int receive_bytes (uchar chip
, char *buf
, int len
)
188 i2c_t
*regs
= (i2c_t
*) MMAP_I2C
;
194 mpc_reg_out (®s
->cr
, 0, I2C_TX
);
196 for (i
= 0; i
< len
; ++i
) {
197 buf
[rdcount
] = mpc_reg_in (®s
->dr
);
204 if (wait_for_pin (&status
))
208 mpc_reg_out (®s
->cr
, I2C_TXAK
, I2C_TXAK
);
209 buf
[rdcount
++] = mpc_reg_in (®s
->dr
);
211 if (wait_for_pin (&status
))
214 mpc_reg_out (®s
->cr
, 0, I2C_TXAK
);
218 /**************** I2C API ****************/
220 void i2c_init (int speed
, int saddr
)
222 i2c_t
*regs
= (i2c_t
*) MMAP_I2C
;
224 mpc_reg_out (®s
->cr
, 0, 0);
225 mpc_reg_out (®s
->adr
, saddr
<< 1, 0);
229 mpc_reg_out (®s
->fdr
, mpc_get_fdr (speed
), 0);
233 mpc_reg_out (®s
->cr
, I2C_EN
, I2C_INIT_MASK
);
234 mpc_reg_out (®s
->sr
, 0, I2C_IF
);
238 static int mpc_get_fdr (int speed
)
243 ulong best_speed
= 0;
246 ulong bestmatch
= 0xffffffffUL
;
247 int best_i
= 0, best_j
= 0, i
, j
;
248 int SCL_Tap
[] = { 9, 10, 12, 15, 5, 6, 7, 8 };
249 struct mpc8220_i2c_tap scltap
[] = {
261 for (i
= 7; i
>= 0; i
--) {
262 for (j
= 7; j
>= 0; j
--) {
263 scl
= 2 * (scltap
[j
].scl2tap
+
265 1) * scltap
[j
].tap2tap
+ 2);
266 if (ipb
<= speed
* scl
) {
267 if ((speed
* scl
- ipb
) < bestmatch
) {
268 bestmatch
= speed
* scl
- ipb
;
271 best_speed
= ipb
/ scl
;
276 divider
= (best_i
& 3) | ((best_i
& 4) << 3) | (best_j
<< 2);
277 if (gd
->flags
& GD_FLG_RELOC
) {
280 printf ("%ld kHz, ", best_speed
/ 1000);
288 int i2c_probe (uchar chip
)
290 i2c_t
*regs
= (i2c_t
*) MMAP_I2C
;
293 for (i
= 0; i
< I2C_RETRIES
; i
++) {
294 mpc_reg_out (®s
->cr
, I2C_STA
, I2C_STA
);
296 if (!do_address (chip
, 0)) {
297 mpc_reg_out (®s
->cr
, 0, I2C_STA
);
301 mpc_reg_out (®s
->cr
, 0, I2C_STA
);
305 return (i
== I2C_RETRIES
);
308 int i2c_read (uchar chip
, uint addr
, int alen
, uchar
* buf
, int len
)
311 i2c_t
*regs
= (i2c_t
*) MMAP_I2C
;
314 xaddr
[0] = (addr
>> 24) & 0xFF;
315 xaddr
[1] = (addr
>> 16) & 0xFF;
316 xaddr
[2] = (addr
>> 8) & 0xFF;
317 xaddr
[3] = addr
& 0xFF;
319 if (wait_for_bb ()) {
320 printf ("i2c_read: bus is busy\n");
324 mpc_reg_out (®s
->cr
, I2C_STA
, I2C_STA
);
325 if (do_address (chip
, 0)) {
326 printf ("i2c_read: failed to address chip\n");
330 if (send_bytes (chip
, (char *)&xaddr
[4 - alen
], alen
)) {
331 printf ("i2c_read: send_bytes failed\n");
335 mpc_reg_out (®s
->cr
, I2C_RSTA
, I2C_RSTA
);
336 if (do_address (chip
, 1)) {
337 printf ("i2c_read: failed to address chip\n");
341 if (receive_bytes (chip
, (char *)buf
, len
)) {
342 printf ("i2c_read: receive_bytes failed\n");
348 mpc_reg_out (®s
->cr
, 0, I2C_STA
);
352 int i2c_write (uchar chip
, uint addr
, int alen
, uchar
* buf
, int len
)
355 i2c_t
*regs
= (i2c_t
*) MMAP_I2C
;
358 xaddr
[0] = (addr
>> 24) & 0xFF;
359 xaddr
[1] = (addr
>> 16) & 0xFF;
360 xaddr
[2] = (addr
>> 8) & 0xFF;
361 xaddr
[3] = addr
& 0xFF;
363 if (wait_for_bb ()) {
364 printf ("i2c_write: bus is busy\n");
368 mpc_reg_out (®s
->cr
, I2C_STA
, I2C_STA
);
369 if (do_address (chip
, 0)) {
370 printf ("i2c_write: failed to address chip\n");
374 if (send_bytes (chip
, (char *)&xaddr
[4 - alen
], alen
)) {
375 printf ("i2c_write: send_bytes failed\n");
379 if (send_bytes (chip
, (char *)buf
, len
)) {
380 printf ("i2c_write: send_bytes failed\n");
386 mpc_reg_out (®s
->cr
, 0, I2C_STA
);
390 #endif /* CONFIG_HARD_I2C */