blob: 4a3f9a0873bfcdf181ae02b3394b4ddf9bebfbc2 [file] [log] [blame]
Rafal Jaworowski8993e542007-07-27 14:43:59 +02001/*
Wolfgang Denk843efb12009-05-16 10:47:43 +02002 * (C) Copyright 2003 - 2009
Rafal Jaworowski8993e542007-07-27 14:43:59 +02003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
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 * Based on the MPC5xxx code.
24 */
25
26#include <common.h>
Wolfgang Denk843efb12009-05-16 10:47:43 +020027#include <asm/io.h>
Rafal Jaworowski8993e542007-07-27 14:43:59 +020028
29DECLARE_GLOBAL_DATA_PTR;
30
31#ifdef CONFIG_HARD_I2C
32
33#include <mpc512x.h>
34#include <i2c.h>
35
Rafal Jaworowski8993e542007-07-27 14:43:59 +020036/* by default set I2C bus 0 active */
37static unsigned int bus_num = 0;
38
39#define I2C_TIMEOUT 100
40#define I2C_RETRIES 3
41
42struct mpc512x_i2c_tap {
43 int scl2tap;
44 int tap2tap;
45};
46
47static int mpc_reg_in(volatile u32 *reg);
48static void mpc_reg_out(volatile u32 *reg, int val, int mask);
49static int wait_for_bb(void);
50static int wait_for_pin(int *status);
51static int do_address(uchar chip, char rdwr_flag);
52static int send_bytes(uchar chip, char *buf, int len);
53static int receive_bytes(uchar chip, char *buf, int len);
54static int mpc_get_fdr(int);
55
56static int mpc_reg_in (volatile u32 *reg)
57{
Wolfgang Denk843efb12009-05-16 10:47:43 +020058 int ret = in_be32(reg) >> 24;
59
Rafal Jaworowski8993e542007-07-27 14:43:59 +020060 return ret;
61}
62
63static void mpc_reg_out (volatile u32 *reg, int val, int mask)
64{
Rafal Jaworowski8993e542007-07-27 14:43:59 +020065 if (!mask) {
Wolfgang Denk843efb12009-05-16 10:47:43 +020066 out_be32(reg, val << 24);
Rafal Jaworowski8993e542007-07-27 14:43:59 +020067 } else {
Wolfgang Denk843efb12009-05-16 10:47:43 +020068 clrsetbits_be32(reg, mask << 24, (val & mask) << 24);
Rafal Jaworowski8993e542007-07-27 14:43:59 +020069 }
Rafal Jaworowski8993e542007-07-27 14:43:59 +020070}
71
72static int wait_for_bb (void)
73{
Wolfgang Denk843efb12009-05-16 10:47:43 +020074 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
75 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +020076 int timeout = I2C_TIMEOUT;
77 int status;
78
79 status = mpc_reg_in (&regs->msr);
80
81 while (timeout-- && (status & I2C_BB)) {
82 volatile int temp;
83 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
84 temp = mpc_reg_in (&regs->mdr);
85 mpc_reg_out (&regs->mcr, 0, I2C_STA);
86 mpc_reg_out (&regs->mcr, 0, 0);
87 mpc_reg_out (&regs->mcr, I2C_EN, 0);
88
89 udelay (1000);
90 status = mpc_reg_in (&regs->msr);
91 }
92
93 return (status & I2C_BB);
94}
95
96static int wait_for_pin (int *status)
97{
Wolfgang Denk843efb12009-05-16 10:47:43 +020098 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
99 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200100 int timeout = I2C_TIMEOUT;
101
102 *status = mpc_reg_in (&regs->msr);
103
104 while (timeout-- && !(*status & I2C_IF)) {
105 udelay (1000);
106 *status = mpc_reg_in (&regs->msr);
107 }
108
109 if (!(*status & I2C_IF)) {
110 return -1;
111 }
112
113 mpc_reg_out (&regs->msr, 0, I2C_IF);
114
115 return 0;
116}
117
118static int do_address (uchar chip, char rdwr_flag)
119{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200120 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
121 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200122 int status;
123
124 chip <<= 1;
125
126 if (rdwr_flag) {
127 chip |= 1;
128 }
129
130 mpc_reg_out (&regs->mcr, I2C_TX, I2C_TX);
131 mpc_reg_out (&regs->mdr, chip, 0);
132
133 if (wait_for_pin (&status)) {
134 return -2;
135 }
136
137 if (status & I2C_RXAK) {
138 return -3;
139 }
140
141 return 0;
142}
143
144static int send_bytes (uchar chip, char *buf, int len)
145{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200146 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
147 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200148 int wrcount;
149 int status;
150
151 for (wrcount = 0; wrcount < len; ++wrcount) {
152
153 mpc_reg_out (&regs->mdr, buf[wrcount], 0);
154
155 if (wait_for_pin (&status)) {
156 break;
157 }
158
159 if (status & I2C_RXAK) {
160 break;
161 }
162
163 }
164
165 return !(wrcount == len);
166}
167
168static int receive_bytes (uchar chip, char *buf, int len)
169{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200170 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
171 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200172 int dummy = 1;
173 int rdcount = 0;
174 int status;
175 int i;
176
177 mpc_reg_out (&regs->mcr, 0, I2C_TX);
178
179 for (i = 0; i < len; ++i) {
180 buf[rdcount] = mpc_reg_in (&regs->mdr);
181
182 if (dummy) {
183 dummy = 0;
184 } else {
185 rdcount++;
186 }
187
188 if (wait_for_pin (&status)) {
189 return -4;
190 }
191 }
192
193 mpc_reg_out (&regs->mcr, I2C_TXAK, I2C_TXAK);
194 buf[rdcount++] = mpc_reg_in (&regs->mdr);
195
196 if (wait_for_pin (&status)) {
197 return -5;
198 }
199
200 mpc_reg_out (&regs->mcr, 0, I2C_TXAK);
201
202 return 0;
203}
204
205/**************** I2C API ****************/
206
207void i2c_init (int speed, int saddr)
208{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200209 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200210 int i;
Wolfgang Denk843efb12009-05-16 10:47:43 +0200211
212 for (i = 0; i < I2C_BUS_CNT; i++){
213 volatile i2c512x_dev_t *regs = &im->i2c.dev[i];
214
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200215 mpc_reg_out (&regs->mcr, 0, 0);
216
217 /* Set clock */
218 mpc_reg_out (&regs->mfdr, mpc_get_fdr (speed), 0);
219 mpc_reg_out (&regs->madr, saddr << 1, 0);
220
221 /* Enable module */
222 mpc_reg_out (&regs->mcr, I2C_EN, I2C_INIT_MASK);
223 mpc_reg_out (&regs->msr, 0, I2C_IF);
224 }
225
226 /* Disable interrupts */
Wolfgang Denk843efb12009-05-16 10:47:43 +0200227 out_be32(&im->i2c.icr, 0);
228
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200229 /* Turn off filters */
Wolfgang Denk843efb12009-05-16 10:47:43 +0200230 out_be32(&im->i2c.mifr, 0);
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200231}
232
233static int mpc_get_fdr (int speed)
234{
235 static int fdr = -1;
236
237 if (fdr == -1) {
238 ulong best_speed = 0;
239 ulong divider;
Grzegorz Bernacki5d49e0e2008-01-11 12:03:43 +0100240 ulong ips, scl;
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200241 ulong bestmatch = 0xffffffffUL;
242 int best_i = 0, best_j = 0, i, j;
243 int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8};
244 struct mpc512x_i2c_tap scltap[] = {
245 {4, 1},
246 {4, 2},
247 {6, 4},
248 {6, 8},
249 {14, 16},
250 {30, 32},
251 {62, 64},
252 {126, 128}
253 };
254
Grzegorz Bernacki5d49e0e2008-01-11 12:03:43 +0100255 ips = gd->ips_clk;
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200256 for (i = 7; i >= 0; i--) {
257 for (j = 7; j >= 0; j--) {
258 scl = 2 * (scltap[j].scl2tap +
259 (SCL_Tap[i] - 1) * scltap[j].tap2tap
260 + 2);
Grzegorz Bernacki5d49e0e2008-01-11 12:03:43 +0100261 if (ips <= speed*scl) {
262 if ((speed*scl - ips) < bestmatch) {
263 bestmatch = speed*scl - ips;
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200264 best_i = i;
265 best_j = j;
Grzegorz Bernacki5d49e0e2008-01-11 12:03:43 +0100266 best_speed = ips/scl;
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200267 }
268 }
269 }
270 }
271 divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2);
272 if (gd->flags & GD_FLG_RELOC) {
273 fdr = divider;
274 } else {
275 debug("%ld kHz, \n", best_speed / 1000);
276 return divider;
277 }
278 }
279
280 return fdr;
281}
282
283int i2c_probe (uchar chip)
284{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200285 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
286 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200287 int i;
288
289 for (i = 0; i < I2C_RETRIES; i++) {
290 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
291
292 if (! do_address (chip, 0)) {
293 mpc_reg_out (&regs->mcr, 0, I2C_STA);
294 udelay (500);
295 break;
296 }
297
298 mpc_reg_out (&regs->mcr, 0, I2C_STA);
299 udelay (500);
300 }
301
302 return (i == I2C_RETRIES);
303}
304
305int i2c_read (uchar chip, uint addr, int alen, uchar *buf, int len)
306{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200307 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
308 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200309 char xaddr[4];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200310 int ret = -1;
311
312 xaddr[0] = (addr >> 24) & 0xFF;
313 xaddr[1] = (addr >> 16) & 0xFF;
314 xaddr[2] = (addr >> 8) & 0xFF;
315 xaddr[3] = addr & 0xFF;
316
317 if (wait_for_bb ()) {
318 printf ("i2c_read: bus is busy\n");
319 goto Done;
320 }
321
322 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
323 if (do_address (chip, 0)) {
324 printf ("i2c_read: failed to address chip\n");
325 goto Done;
326 }
327
328 if (send_bytes (chip, &xaddr[4-alen], alen)) {
329 printf ("i2c_read: send_bytes failed\n");
330 goto Done;
331 }
332
333 mpc_reg_out (&regs->mcr, I2C_RSTA, I2C_RSTA);
334 if (do_address (chip, 1)) {
335 printf ("i2c_read: failed to address chip\n");
336 goto Done;
337 }
338
339 if (receive_bytes (chip, (char *)buf, len)) {
340 printf ("i2c_read: receive_bytes failed\n");
341 goto Done;
342 }
343
344 ret = 0;
345Done:
346 mpc_reg_out (&regs->mcr, 0, I2C_STA);
347 return ret;
348}
349
350int i2c_write (uchar chip, uint addr, int alen, uchar *buf, int len)
351{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200352 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
353 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200354 char xaddr[4];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200355 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->mcr, 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, &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;
384Done:
385 mpc_reg_out (&regs->mcr, 0, I2C_STA);
386 return ret;
387}
388
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200389int i2c_set_bus_num (unsigned int bus)
390{
391 if (bus >= I2C_BUS_CNT) {
392 return -1;
393 }
394 bus_num = bus;
395
396 return 0;
397}
398
399unsigned int i2c_get_bus_num (void)
400{
401 return bus_num;
402}
403
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200404#endif /* CONFIG_HARD_I2C */