blob: 0ea12806b92c718648d8677bd9b5f61a12e13d10 [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
Rafal Jaworowski8993e542007-07-27 14:43:59 +020033#include <i2c.h>
34
Rafal Jaworowski8993e542007-07-27 14:43:59 +020035/* by default set I2C bus 0 active */
Stefan Roesec60dc852009-06-08 09:38:07 +020036static unsigned int bus_num __attribute__ ((section (".data"))) = 0;
Rafal Jaworowski8993e542007-07-27 14:43:59 +020037
38#define I2C_TIMEOUT 100
39#define I2C_RETRIES 3
40
41struct mpc512x_i2c_tap {
42 int scl2tap;
43 int tap2tap;
44};
45
46static int mpc_reg_in(volatile u32 *reg);
47static void mpc_reg_out(volatile u32 *reg, int val, int mask);
48static int wait_for_bb(void);
49static int wait_for_pin(int *status);
50static int do_address(uchar chip, char rdwr_flag);
51static int send_bytes(uchar chip, char *buf, int len);
52static int receive_bytes(uchar chip, char *buf, int len);
53static int mpc_get_fdr(int);
54
55static int mpc_reg_in (volatile u32 *reg)
56{
Wolfgang Denk843efb12009-05-16 10:47:43 +020057 int ret = in_be32(reg) >> 24;
58
Rafal Jaworowski8993e542007-07-27 14:43:59 +020059 return ret;
60}
61
62static void mpc_reg_out (volatile u32 *reg, int val, int mask)
63{
Rafal Jaworowski8993e542007-07-27 14:43:59 +020064 if (!mask) {
Wolfgang Denk843efb12009-05-16 10:47:43 +020065 out_be32(reg, val << 24);
Rafal Jaworowski8993e542007-07-27 14:43:59 +020066 } else {
Wolfgang Denk843efb12009-05-16 10:47:43 +020067 clrsetbits_be32(reg, mask << 24, (val & mask) << 24);
Rafal Jaworowski8993e542007-07-27 14:43:59 +020068 }
Rafal Jaworowski8993e542007-07-27 14:43:59 +020069}
70
71static int wait_for_bb (void)
72{
Wolfgang Denk843efb12009-05-16 10:47:43 +020073 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
74 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +020075 int timeout = I2C_TIMEOUT;
76 int status;
77
78 status = mpc_reg_in (&regs->msr);
79
80 while (timeout-- && (status & I2C_BB)) {
Rafal Jaworowski8993e542007-07-27 14:43:59 +020081 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
Anatolij Gustschind14a94b2011-11-10 12:21:44 +000082 (void)mpc_reg_in(&regs->mdr);
Rafal Jaworowski8993e542007-07-27 14:43:59 +020083 mpc_reg_out (&regs->mcr, 0, I2C_STA);
84 mpc_reg_out (&regs->mcr, 0, 0);
85 mpc_reg_out (&regs->mcr, I2C_EN, 0);
86
87 udelay (1000);
88 status = mpc_reg_in (&regs->msr);
89 }
90
91 return (status & I2C_BB);
92}
93
94static int wait_for_pin (int *status)
95{
Wolfgang Denk843efb12009-05-16 10:47:43 +020096 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
97 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +020098 int timeout = I2C_TIMEOUT;
99
100 *status = mpc_reg_in (&regs->msr);
101
102 while (timeout-- && !(*status & I2C_IF)) {
103 udelay (1000);
104 *status = mpc_reg_in (&regs->msr);
105 }
106
107 if (!(*status & I2C_IF)) {
108 return -1;
109 }
110
111 mpc_reg_out (&regs->msr, 0, I2C_IF);
112
113 return 0;
114}
115
116static int do_address (uchar chip, char rdwr_flag)
117{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200118 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
119 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200120 int status;
121
122 chip <<= 1;
123
124 if (rdwr_flag) {
125 chip |= 1;
126 }
127
128 mpc_reg_out (&regs->mcr, I2C_TX, I2C_TX);
129 mpc_reg_out (&regs->mdr, chip, 0);
130
131 if (wait_for_pin (&status)) {
132 return -2;
133 }
134
135 if (status & I2C_RXAK) {
136 return -3;
137 }
138
139 return 0;
140}
141
142static int send_bytes (uchar chip, char *buf, int len)
143{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200144 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
145 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200146 int wrcount;
147 int status;
148
149 for (wrcount = 0; wrcount < len; ++wrcount) {
150
151 mpc_reg_out (&regs->mdr, buf[wrcount], 0);
152
153 if (wait_for_pin (&status)) {
154 break;
155 }
156
157 if (status & I2C_RXAK) {
158 break;
159 }
160
161 }
162
163 return !(wrcount == len);
164}
165
166static int receive_bytes (uchar chip, char *buf, int len)
167{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200168 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
169 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200170 int dummy = 1;
171 int rdcount = 0;
172 int status;
173 int i;
174
175 mpc_reg_out (&regs->mcr, 0, I2C_TX);
176
177 for (i = 0; i < len; ++i) {
178 buf[rdcount] = mpc_reg_in (&regs->mdr);
179
180 if (dummy) {
181 dummy = 0;
182 } else {
183 rdcount++;
184 }
185
186 if (wait_for_pin (&status)) {
187 return -4;
188 }
189 }
190
191 mpc_reg_out (&regs->mcr, I2C_TXAK, I2C_TXAK);
192 buf[rdcount++] = mpc_reg_in (&regs->mdr);
193
194 if (wait_for_pin (&status)) {
195 return -5;
196 }
197
198 mpc_reg_out (&regs->mcr, 0, I2C_TXAK);
199
200 return 0;
201}
202
203/**************** I2C API ****************/
204
205void i2c_init (int speed, int saddr)
206{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200207 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200208 int i;
Wolfgang Denk843efb12009-05-16 10:47:43 +0200209
210 for (i = 0; i < I2C_BUS_CNT; i++){
211 volatile i2c512x_dev_t *regs = &im->i2c.dev[i];
212
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200213 mpc_reg_out (&regs->mcr, 0, 0);
214
215 /* Set clock */
216 mpc_reg_out (&regs->mfdr, mpc_get_fdr (speed), 0);
217 mpc_reg_out (&regs->madr, saddr << 1, 0);
218
219 /* Enable module */
220 mpc_reg_out (&regs->mcr, I2C_EN, I2C_INIT_MASK);
221 mpc_reg_out (&regs->msr, 0, I2C_IF);
222 }
223
224 /* Disable interrupts */
Wolfgang Denk843efb12009-05-16 10:47:43 +0200225 out_be32(&im->i2c.icr, 0);
226
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200227 /* Turn off filters */
Wolfgang Denk843efb12009-05-16 10:47:43 +0200228 out_be32(&im->i2c.mifr, 0);
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200229}
230
231static int mpc_get_fdr (int speed)
232{
233 static int fdr = -1;
234
235 if (fdr == -1) {
236 ulong best_speed = 0;
237 ulong divider;
Grzegorz Bernacki5d49e0e2008-01-11 12:03:43 +0100238 ulong ips, scl;
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200239 ulong bestmatch = 0xffffffffUL;
240 int best_i = 0, best_j = 0, i, j;
241 int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8};
242 struct mpc512x_i2c_tap scltap[] = {
243 {4, 1},
244 {4, 2},
245 {6, 4},
246 {6, 8},
247 {14, 16},
248 {30, 32},
249 {62, 64},
250 {126, 128}
251 };
252
Grzegorz Bernacki5d49e0e2008-01-11 12:03:43 +0100253 ips = gd->ips_clk;
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200254 for (i = 7; i >= 0; i--) {
255 for (j = 7; j >= 0; j--) {
256 scl = 2 * (scltap[j].scl2tap +
257 (SCL_Tap[i] - 1) * scltap[j].tap2tap
258 + 2);
Grzegorz Bernacki5d49e0e2008-01-11 12:03:43 +0100259 if (ips <= speed*scl) {
260 if ((speed*scl - ips) < bestmatch) {
261 bestmatch = speed*scl - ips;
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200262 best_i = i;
263 best_j = j;
Grzegorz Bernacki5d49e0e2008-01-11 12:03:43 +0100264 best_speed = ips/scl;
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200265 }
266 }
267 }
268 }
269 divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2);
270 if (gd->flags & GD_FLG_RELOC) {
271 fdr = divider;
272 } else {
273 debug("%ld kHz, \n", best_speed / 1000);
274 return divider;
275 }
276 }
277
278 return fdr;
279}
280
281int i2c_probe (uchar chip)
282{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200283 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
284 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200285 int i;
286
287 for (i = 0; i < I2C_RETRIES; i++) {
288 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
289
290 if (! do_address (chip, 0)) {
291 mpc_reg_out (&regs->mcr, 0, I2C_STA);
292 udelay (500);
293 break;
294 }
295
296 mpc_reg_out (&regs->mcr, 0, I2C_STA);
297 udelay (500);
298 }
299
300 return (i == I2C_RETRIES);
301}
302
303int i2c_read (uchar chip, uint addr, int alen, uchar *buf, int len)
304{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200305 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
306 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200307 char xaddr[4];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200308 int ret = -1;
309
310 xaddr[0] = (addr >> 24) & 0xFF;
311 xaddr[1] = (addr >> 16) & 0xFF;
312 xaddr[2] = (addr >> 8) & 0xFF;
313 xaddr[3] = addr & 0xFF;
314
315 if (wait_for_bb ()) {
316 printf ("i2c_read: bus is busy\n");
317 goto Done;
318 }
319
320 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
321 if (do_address (chip, 0)) {
322 printf ("i2c_read: failed to address chip\n");
323 goto Done;
324 }
325
326 if (send_bytes (chip, &xaddr[4-alen], alen)) {
327 printf ("i2c_read: send_bytes failed\n");
328 goto Done;
329 }
330
331 mpc_reg_out (&regs->mcr, I2C_RSTA, I2C_RSTA);
332 if (do_address (chip, 1)) {
333 printf ("i2c_read: failed to address chip\n");
334 goto Done;
335 }
336
337 if (receive_bytes (chip, (char *)buf, len)) {
338 printf ("i2c_read: receive_bytes failed\n");
339 goto Done;
340 }
341
342 ret = 0;
343Done:
344 mpc_reg_out (&regs->mcr, 0, I2C_STA);
345 return ret;
346}
347
348int i2c_write (uchar chip, uint addr, int alen, uchar *buf, int len)
349{
Wolfgang Denk843efb12009-05-16 10:47:43 +0200350 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
351 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200352 char xaddr[4];
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200353 int ret = -1;
354
355 xaddr[0] = (addr >> 24) & 0xFF;
356 xaddr[1] = (addr >> 16) & 0xFF;
357 xaddr[2] = (addr >> 8) & 0xFF;
358 xaddr[3] = addr & 0xFF;
359
360 if (wait_for_bb ()) {
361 printf ("i2c_write: bus is busy\n");
362 goto Done;
363 }
364
365 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
366 if (do_address (chip, 0)) {
367 printf ("i2c_write: failed to address chip\n");
368 goto Done;
369 }
370
371 if (send_bytes (chip, &xaddr[4-alen], alen)) {
372 printf ("i2c_write: send_bytes failed\n");
373 goto Done;
374 }
375
376 if (send_bytes (chip, (char *)buf, len)) {
377 printf ("i2c_write: send_bytes failed\n");
378 goto Done;
379 }
380
381 ret = 0;
382Done:
383 mpc_reg_out (&regs->mcr, 0, I2C_STA);
384 return ret;
385}
386
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200387int i2c_set_bus_num (unsigned int bus)
388{
389 if (bus >= I2C_BUS_CNT) {
390 return -1;
391 }
392 bus_num = bus;
393
394 return 0;
395}
396
397unsigned int i2c_get_bus_num (void)
398{
399 return bus_num;
400}
401
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200402#endif /* CONFIG_HARD_I2C */