]> git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/i2c/kirkwood_i2c.c
PXA: PXAMMC: Add Monahans support
[people/ms/u-boot.git] / drivers / i2c / kirkwood_i2c.c
1 /*
2 * Driver for the i2c controller on the Marvell line of host bridges
3 * (e.g, gt642[46]0, mv643[46]0, mv644[46]0, Orion SoC family),
4 * and Kirkwood family.
5 *
6 * Based on:
7 * Author: Mark A. Greer <mgreer@mvista.com>
8 * 2005 (c) MontaVista, Software, Inc.
9 *
10 * See file CREDITS for list of people who contributed to this
11 * project.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of
16 * the License, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 * MA 02110-1301 USA
27 *
28 * ported from Linux to u-boot
29 * (C) Copyright 2009
30 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
31 */
32 #include <common.h>
33 #include <i2c.h>
34 #include <asm/arch/kirkwood.h>
35 #include <asm/errno.h>
36 #include <asm/io.h>
37
38 DECLARE_GLOBAL_DATA_PTR;
39
40 static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = 0;
41 #if defined(CONFIG_I2C_MUX)
42 static unsigned int i2c_bus_num_mux __attribute__ ((section ("data"))) = 0;
43 #endif
44
45 /* Register defines */
46 #define KW_I2C_REG_SLAVE_ADDR 0x00
47 #define KW_I2C_REG_DATA 0x04
48 #define KW_I2C_REG_CONTROL 0x08
49 #define KW_I2C_REG_STATUS 0x0c
50 #define KW_I2C_REG_BAUD 0x0c
51 #define KW_I2C_REG_EXT_SLAVE_ADDR 0x10
52 #define KW_I2C_REG_SOFT_RESET 0x1c
53
54 #define KW_I2C_REG_CONTROL_ACK 0x00000004
55 #define KW_I2C_REG_CONTROL_IFLG 0x00000008
56 #define KW_I2C_REG_CONTROL_STOP 0x00000010
57 #define KW_I2C_REG_CONTROL_START 0x00000020
58 #define KW_I2C_REG_CONTROL_TWSIEN 0x00000040
59 #define KW_I2C_REG_CONTROL_INTEN 0x00000080
60
61 /* Ctlr status values */
62 #define KW_I2C_STATUS_BUS_ERR 0x00
63 #define KW_I2C_STATUS_MAST_START 0x08
64 #define KW_I2C_STATUS_MAST_REPEAT_START 0x10
65 #define KW_I2C_STATUS_MAST_WR_ADDR_ACK 0x18
66 #define KW_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20
67 #define KW_I2C_STATUS_MAST_WR_ACK 0x28
68 #define KW_I2C_STATUS_MAST_WR_NO_ACK 0x30
69 #define KW_I2C_STATUS_MAST_LOST_ARB 0x38
70 #define KW_I2C_STATUS_MAST_RD_ADDR_ACK 0x40
71 #define KW_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48
72 #define KW_I2C_STATUS_MAST_RD_DATA_ACK 0x50
73 #define KW_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58
74 #define KW_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0
75 #define KW_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8
76 #define KW_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0
77 #define KW_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8
78 #define KW_I2C_STATUS_NO_STATUS 0xf8
79
80 /* Driver states */
81 enum {
82 KW_I2C_STATE_INVALID,
83 KW_I2C_STATE_IDLE,
84 KW_I2C_STATE_WAITING_FOR_START_COND,
85 KW_I2C_STATE_WAITING_FOR_ADDR_1_ACK,
86 KW_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
87 KW_I2C_STATE_WAITING_FOR_SLAVE_ACK,
88 KW_I2C_STATE_WAITING_FOR_SLAVE_DATA,
89 };
90
91 /* Driver actions */
92 enum {
93 KW_I2C_ACTION_INVALID,
94 KW_I2C_ACTION_CONTINUE,
95 KW_I2C_ACTION_SEND_START,
96 KW_I2C_ACTION_SEND_ADDR_1,
97 KW_I2C_ACTION_SEND_ADDR_2,
98 KW_I2C_ACTION_SEND_DATA,
99 KW_I2C_ACTION_RCV_DATA,
100 KW_I2C_ACTION_RCV_DATA_STOP,
101 KW_I2C_ACTION_SEND_STOP,
102 };
103
104 /* defines to get compatible with Linux driver */
105 #define IRQ_NONE 0x0
106 #define IRQ_HANDLED 0x01
107
108 #define I2C_M_TEN 0x01
109 #define I2C_M_RD 0x02
110 #define I2C_M_REV_DIR_ADDR 0x04;
111
112 struct i2c_msg {
113 u32 addr;
114 u32 flags;
115 u8 *buf;
116 u32 len;
117 };
118
119 struct kirkwood_i2c_data {
120 int irq;
121 u32 state;
122 u32 action;
123 u32 aborting;
124 u32 cntl_bits;
125 void *reg_base;
126 u32 reg_base_p;
127 u32 reg_size;
128 u32 addr1;
129 u32 addr2;
130 u32 bytes_left;
131 u32 byte_posn;
132 u32 block;
133 int rc;
134 u32 freq_m;
135 u32 freq_n;
136 struct i2c_msg *msg;
137 };
138
139 static struct kirkwood_i2c_data __drv_data __attribute__ ((section (".data")));
140 static struct kirkwood_i2c_data *drv_data = &__drv_data;
141 static struct i2c_msg __i2c_msg __attribute__ ((section (".data")));
142 static struct i2c_msg *kirkwood_i2c_msg = &__i2c_msg;
143
144 /*
145 *****************************************************************************
146 *
147 * Finite State Machine & Interrupt Routines
148 *
149 *****************************************************************************
150 */
151
152 static inline int abs(int n)
153 {
154 if(n >= 0)
155 return n;
156 else
157 return n * -1;
158 }
159
160 static void kirkwood_calculate_speed(int speed)
161 {
162 int calcspeed;
163 int diff;
164 int best_diff = CONFIG_SYS_TCLK;
165 int best_speed = 0;
166 int m, n;
167 int tmp[8] = {2, 4, 8, 16, 32, 64, 128, 256};
168
169 for (n = 0; n < 8; n++) {
170 for (m = 0; m < 16; m++) {
171 calcspeed = CONFIG_SYS_TCLK / (10 * (m + 1) * tmp[n]);
172 diff = abs((speed - calcspeed));
173 if ( diff < best_diff) {
174 best_diff = diff;
175 best_speed = calcspeed;
176 drv_data->freq_m = m;
177 drv_data->freq_n = n;
178 }
179 }
180 }
181 }
182
183 /* Reset hardware and initialize FSM */
184 static void
185 kirkwood_i2c_hw_init(int speed, int slaveadd)
186 {
187 drv_data->state = KW_I2C_STATE_IDLE;
188
189 kirkwood_calculate_speed(speed);
190 writel(0, CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_SOFT_RESET);
191 writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)),
192 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_BAUD);
193 writel(slaveadd, CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_SLAVE_ADDR);
194 writel(0, CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_EXT_SLAVE_ADDR);
195 writel(KW_I2C_REG_CONTROL_TWSIEN | KW_I2C_REG_CONTROL_STOP,
196 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
197 }
198
199 static void
200 kirkwood_i2c_fsm(u32 status)
201 {
202 /*
203 * If state is idle, then this is likely the remnants of an old
204 * operation that driver has given up on or the user has killed.
205 * If so, issue the stop condition and go to idle.
206 */
207 if (drv_data->state == KW_I2C_STATE_IDLE) {
208 drv_data->action = KW_I2C_ACTION_SEND_STOP;
209 return;
210 }
211
212 /* The status from the ctlr [mostly] tells us what to do next */
213 switch (status) {
214 /* Start condition interrupt */
215 case KW_I2C_STATUS_MAST_START: /* 0x08 */
216 case KW_I2C_STATUS_MAST_REPEAT_START: /* 0x10 */
217 drv_data->action = KW_I2C_ACTION_SEND_ADDR_1;
218 drv_data->state = KW_I2C_STATE_WAITING_FOR_ADDR_1_ACK;
219 break;
220
221 /* Performing a write */
222 case KW_I2C_STATUS_MAST_WR_ADDR_ACK: /* 0x18 */
223 if (drv_data->msg->flags & I2C_M_TEN) {
224 drv_data->action = KW_I2C_ACTION_SEND_ADDR_2;
225 drv_data->state =
226 KW_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
227 break;
228 }
229 /* FALLTHRU */
230 case KW_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */
231 case KW_I2C_STATUS_MAST_WR_ACK: /* 0x28 */
232 if ((drv_data->bytes_left == 0)
233 || (drv_data->aborting
234 && (drv_data->byte_posn != 0))) {
235 drv_data->action = KW_I2C_ACTION_SEND_STOP;
236 drv_data->state = KW_I2C_STATE_IDLE;
237 } else {
238 drv_data->action = KW_I2C_ACTION_SEND_DATA;
239 drv_data->state =
240 KW_I2C_STATE_WAITING_FOR_SLAVE_ACK;
241 drv_data->bytes_left--;
242 }
243 break;
244
245 /* Performing a read */
246 case KW_I2C_STATUS_MAST_RD_ADDR_ACK: /* 40 */
247 if (drv_data->msg->flags & I2C_M_TEN) {
248 drv_data->action = KW_I2C_ACTION_SEND_ADDR_2;
249 drv_data->state =
250 KW_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
251 break;
252 }
253 /* FALLTHRU */
254 case KW_I2C_STATUS_MAST_RD_ADDR_2_ACK: /* 0xe0 */
255 if (drv_data->bytes_left == 0) {
256 drv_data->action = KW_I2C_ACTION_SEND_STOP;
257 drv_data->state = KW_I2C_STATE_IDLE;
258 break;
259 }
260 /* FALLTHRU */
261 case KW_I2C_STATUS_MAST_RD_DATA_ACK: /* 0x50 */
262 if (status != KW_I2C_STATUS_MAST_RD_DATA_ACK)
263 drv_data->action = KW_I2C_ACTION_CONTINUE;
264 else {
265 drv_data->action = KW_I2C_ACTION_RCV_DATA;
266 drv_data->bytes_left--;
267 }
268 drv_data->state = KW_I2C_STATE_WAITING_FOR_SLAVE_DATA;
269
270 if ((drv_data->bytes_left == 1) || drv_data->aborting)
271 drv_data->cntl_bits &= ~KW_I2C_REG_CONTROL_ACK;
272 break;
273
274 case KW_I2C_STATUS_MAST_RD_DATA_NO_ACK: /* 0x58 */
275 drv_data->action = KW_I2C_ACTION_RCV_DATA_STOP;
276 drv_data->state = KW_I2C_STATE_IDLE;
277 break;
278
279 case KW_I2C_STATUS_MAST_WR_ADDR_NO_ACK: /* 0x20 */
280 case KW_I2C_STATUS_MAST_WR_NO_ACK: /* 30 */
281 case KW_I2C_STATUS_MAST_RD_ADDR_NO_ACK: /* 48 */
282 /* Doesn't seem to be a device at other end */
283 drv_data->action = KW_I2C_ACTION_SEND_STOP;
284 drv_data->state = KW_I2C_STATE_IDLE;
285 drv_data->rc = -ENODEV;
286 break;
287
288 default:
289 printf("kirkwood_i2c_fsm: Ctlr Error -- state: 0x%x, "
290 "status: 0x%x, addr: 0x%x, flags: 0x%x\n",
291 drv_data->state, status, drv_data->msg->addr,
292 drv_data->msg->flags);
293 drv_data->action = KW_I2C_ACTION_SEND_STOP;
294 kirkwood_i2c_hw_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
295 drv_data->rc = -EIO;
296 }
297 }
298
299 static void
300 kirkwood_i2c_do_action(void)
301 {
302 switch(drv_data->action) {
303 case KW_I2C_ACTION_CONTINUE:
304 writel(drv_data->cntl_bits,
305 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
306 break;
307
308 case KW_I2C_ACTION_SEND_START:
309 writel(drv_data->cntl_bits | KW_I2C_REG_CONTROL_START,
310 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
311 break;
312
313 case KW_I2C_ACTION_SEND_ADDR_1:
314 writel(drv_data->addr1,
315 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
316 writel(drv_data->cntl_bits,
317 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
318 break;
319
320 case KW_I2C_ACTION_SEND_ADDR_2:
321 writel(drv_data->addr2,
322 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
323 writel(drv_data->cntl_bits,
324 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
325 break;
326
327 case KW_I2C_ACTION_SEND_DATA:
328 writel(drv_data->msg->buf[drv_data->byte_posn++],
329 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
330 writel(drv_data->cntl_bits,
331 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
332 break;
333
334 case KW_I2C_ACTION_RCV_DATA:
335 drv_data->msg->buf[drv_data->byte_posn++] =
336 readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
337 writel(drv_data->cntl_bits,
338 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
339 break;
340
341 case KW_I2C_ACTION_RCV_DATA_STOP:
342 drv_data->msg->buf[drv_data->byte_posn++] =
343 readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
344 drv_data->cntl_bits &= ~KW_I2C_REG_CONTROL_INTEN;
345 writel(drv_data->cntl_bits | KW_I2C_REG_CONTROL_STOP,
346 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
347 drv_data->block = 0;
348 break;
349
350 case KW_I2C_ACTION_INVALID:
351 default:
352 printf("kirkwood_i2c_do_action: Invalid action: %d\n",
353 drv_data->action);
354 drv_data->rc = -EIO;
355 /* FALLTHRU */
356 case KW_I2C_ACTION_SEND_STOP:
357 drv_data->cntl_bits &= ~KW_I2C_REG_CONTROL_INTEN;
358 writel(drv_data->cntl_bits | KW_I2C_REG_CONTROL_STOP,
359 CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
360 drv_data->block = 0;
361 break;
362 }
363 }
364
365 static int
366 kirkwood_i2c_intr(void)
367 {
368 u32 status;
369 u32 ctrl;
370 int rc = IRQ_NONE;
371
372 ctrl = readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
373 while ((ctrl & KW_I2C_REG_CONTROL_IFLG) &&
374 (drv_data->rc == 0)) {
375 status = readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_STATUS);
376 kirkwood_i2c_fsm(status);
377 kirkwood_i2c_do_action();
378 rc = IRQ_HANDLED;
379 ctrl = readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
380 udelay(1000);
381 }
382 return rc;
383 }
384
385 static void
386 kirkwood_i2c_doio(struct i2c_msg *msg)
387 {
388 int ret;
389
390 while ((drv_data->rc == 0) && (drv_data->state != KW_I2C_STATE_IDLE)) {
391 /* poll Status register */
392 ret = kirkwood_i2c_intr();
393 if (ret == IRQ_NONE)
394 udelay(10);
395 }
396 }
397
398 static void
399 kirkwood_i2c_prepare_for_io(struct i2c_msg *msg)
400 {
401 u32 dir = 0;
402
403 drv_data->msg = msg;
404 drv_data->byte_posn = 0;
405 drv_data->bytes_left = msg->len;
406 drv_data->aborting = 0;
407 drv_data->rc = 0;
408 /* in u-boot we use no IRQs */
409 drv_data->cntl_bits = KW_I2C_REG_CONTROL_ACK | KW_I2C_REG_CONTROL_TWSIEN;
410
411 if (msg->flags & I2C_M_RD)
412 dir = 1;
413 if (msg->flags & I2C_M_TEN) {
414 drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
415 drv_data->addr2 = (u32)msg->addr & 0xff;
416 } else {
417 drv_data->addr1 = ((u32)msg->addr & 0x7f) << 1 | dir;
418 drv_data->addr2 = 0;
419 }
420 /* OK, no start it (from kirkwood_i2c_execute_msg())*/
421 drv_data->action = KW_I2C_ACTION_SEND_START;
422 drv_data->state = KW_I2C_STATE_WAITING_FOR_START_COND;
423 drv_data->block = 1;
424 kirkwood_i2c_do_action();
425 }
426
427 void
428 i2c_init(int speed, int slaveadd)
429 {
430 kirkwood_i2c_hw_init(speed, slaveadd);
431 }
432
433 int
434 i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
435 {
436 kirkwood_i2c_msg->buf = data;
437 kirkwood_i2c_msg->len = length;
438 kirkwood_i2c_msg->addr = dev;
439 kirkwood_i2c_msg->flags = I2C_M_RD;
440
441 kirkwood_i2c_prepare_for_io(kirkwood_i2c_msg);
442 kirkwood_i2c_doio(kirkwood_i2c_msg);
443 return drv_data->rc;
444 }
445
446 int
447 i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
448 {
449 kirkwood_i2c_msg->buf = data;
450 kirkwood_i2c_msg->len = length;
451 kirkwood_i2c_msg->addr = dev;
452 kirkwood_i2c_msg->flags = 0;
453
454 kirkwood_i2c_prepare_for_io(kirkwood_i2c_msg);
455 kirkwood_i2c_doio(kirkwood_i2c_msg);
456 return drv_data->rc;
457 }
458
459 int
460 i2c_probe(uchar chip)
461 {
462 return i2c_read(chip, 0, 0, NULL, 0);
463 }
464
465 int i2c_set_bus_num(unsigned int bus)
466 {
467 #if defined(CONFIG_I2C_MUX)
468 if (bus < CONFIG_SYS_MAX_I2C_BUS) {
469 i2c_bus_num = bus;
470 } else {
471 int ret;
472
473 ret = i2x_mux_select_mux(bus);
474 if (ret)
475 return ret;
476 i2c_bus_num = 0;
477 }
478 i2c_bus_num_mux = bus;
479 #else
480 if (bus > 0) {
481 return -1;
482 }
483
484 i2c_bus_num = bus;
485 #endif
486 return 0;
487 }
488
489 unsigned int i2c_get_bus_num(void)
490 {
491 #if defined(CONFIG_I2C_MUX)
492 return i2c_bus_num_mux;
493 #else
494 return i2c_bus_num;
495 #endif
496 }