switch to 2.6.38
[openwrt/staging/lynxis/omap.git] / target / linux / coldfire / patches / 025-Add-I2C-driver-for-MCF5445x-MCF547x-MCF548x.patch
1 From a7c7130d916c1f7e0d27ad9b338912496ad53089 Mon Sep 17 00:00:00 2001
2 From: Alison Wang <b18965@freescale.com>
3 Date: Thu, 4 Aug 2011 09:59:46 +0800
4 Subject: [PATCH 25/52] Add I2C driver for MCF5445x/MCF547x/MCF548x.
5
6 Add common I2C driver for MCF5445x/MCF547x/MCF548x and add I2C slave
7 mode support for MCF5445x.
8
9 Configure I2C adaptor as slave mode and Support I2C adaptor as a
10 "eeprom-like" slave device.
11
12 Signed-off-by: Alison Wang <b18965@freescale.com>
13 ---
14 arch/m68k/include/asm/mcfi2c.h | 57 +++
15 drivers/i2c/busses/Kconfig | 24 ++
16 drivers/i2c/busses/Makefile | 2 +
17 drivers/i2c/busses/i2c-algo-mcf.h | 23 ++
18 drivers/i2c/busses/i2c-mcf-slave.c | 358 ++++++++++++++++++
19 drivers/i2c/busses/i2c-mcf.c | 698 ++++++++++++++++++++++++++++++++++++
20 6 files changed, 1162 insertions(+), 0 deletions(-)
21 create mode 100644 arch/m68k/include/asm/mcfi2c.h
22 create mode 100644 drivers/i2c/busses/i2c-algo-mcf.h
23 create mode 100644 drivers/i2c/busses/i2c-mcf-slave.c
24 create mode 100644 drivers/i2c/busses/i2c-mcf.c
25
26 --- /dev/null
27 +++ b/arch/m68k/include/asm/mcfi2c.h
28 @@ -0,0 +1,57 @@
29 +/*
30 + * mcfi2c.h -- ColdFire mcfv4/mcfv4e i2c controller support.
31 + * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
32 + */
33 +#ifndef MCF_I2C_H
34 +#define MCF_I2C_H
35 +
36 +/* Register read/write macros */
37 +#if defined(CONFIG_M547X_8X)
38 +#define MCF_I2AR MCF_REG08(0x008F00) /* I2C Address */
39 +#define MCF_I2FDR MCF_REG08(0x008F04) /* I2C Frequency Divider */
40 +#define MCF_I2CR MCF_REG08(0x008F08) /* I2C Control */
41 +#define MCF_I2SR MCF_REG08(0x008F0C) /* I2C Status */
42 +#define MCF_I2DR MCF_REG08(0x008F10) /* I2C Data I/O */
43 +#define MCF_I2ICR MCF_REG08(0x008F20) /* I2C Interrupt Control */
44 +#elif defined(CONFIG_M5445X) || defined(CONFIG_M5441X)
45 +#define MCF_I2AR (*(volatile u8 *)(0xFC058000)) /* I2C Address */
46 +/* I2C Frequency Divider */
47 +#define MCF_I2FDR (*(volatile u8 *)(0xFC058004))
48 +#define MCF_I2CR (*(volatile u8 *)(0xFC058008)) /* I2C Control */
49 +#define MCF_I2SR (*(volatile u8 *)(0xFC05800C)) /* I2C Status */
50 +#define MCF_I2DR (*(volatile u8 *)(0xFC058010)) /* I2C Data I/O */
51 +#endif
52 +
53 +/* Bit definitions and macros for MCF_I2C_I2AR */
54 +#define MCF_I2AR_ADR(x) (((x)&0x7F)<<1)
55 +
56 +/* Bit definitions and macros for MCF_I2C_I2FDR */
57 +#define MCF_I2FDR_IC(x) (((x)&0x3F)<<0)
58 +
59 +/* Bit definitions and macros for MCF_I2C_I2CR */
60 +#define MCF_I2CR_RSTA (0x04)
61 +#define MCF_I2CR_TXAK (0x08)
62 +#define MCF_I2CR_MTX (0x10)
63 +#define MCF_I2CR_MSTA (0x20)
64 +#define MCF_I2CR_IIEN (0x40)
65 +#define MCF_I2CR_IEN (0x80)
66 +
67 +/* Bit definitions and macros for MCF_I2C_I2SR */
68 +#define MCF_I2SR_RXAK (0x01)
69 +#define MCF_I2SR_IIF (0x02)
70 +#define MCF_I2SR_SRW (0x04)
71 +#define MCF_I2SR_IAL (0x10)
72 +#define MCF_I2SR_IBB (0x20)
73 +#define MCF_I2SR_IAAS (0x40)
74 +#define MCF_I2SR_ICF (0x80)
75 +
76 +/* Bit definitions and macros for MCF_I2C_I2ICR */
77 +#if defined(CONFIG_M547X_8X)
78 +#define MCF_I2ICR_IE (0x01)
79 +#define MCF_I2ICR_RE (0x02)
80 +#define MCF_I2ICR_TE (0x04)
81 +#define MCF_I2ICR_BNBE (0x08)
82 +#endif
83 +
84 +/********************************************************************/
85 +#endif
86 --- a/drivers/i2c/busses/Kconfig
87 +++ b/drivers/i2c/busses/Kconfig
88 @@ -431,6 +431,30 @@ config I2C_IXP2000
89 This driver is deprecated and will be dropped soon. Use i2c-gpio
90 instead.
91
92 +config I2C_MCF
93 + tristate "MCF ColdFire I2C Interface"
94 + depends on I2C && COLDFIRE
95 + help
96 + If you say yes to this option, support will be included for the
97 + I2C on most ColdFire CPUs
98 +
99 + This driver can also be built as a module. If so, the module
100 + will be called i2c-mcf.
101 +
102 +config I2C_MCF_SLAVE
103 + tristate "MCF ColdFire I2C Slave Interface"
104 + depends on !(I2C_MCF)
105 + default n
106 + help
107 + mcf i2c adapter slave mode, only supported on mcf5445x platform.
108 +
109 +config I2C_SLAVE_TEST
110 + bool "I2C Slave Mode Test Configuration"
111 + depends on I2C_MCF_SLAVE
112 + default y
113 + help
114 + This configuration help to test I2C slave mode
115 +
116 config I2C_MPC
117 tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
118 depends on PPC32
119 --- a/drivers/i2c/busses/Makefile
120 +++ b/drivers/i2c/busses/Makefile
121 @@ -77,5 +77,7 @@ obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
122 obj-$(CONFIG_I2C_STUB) += i2c-stub.o
123 obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
124 obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
125 +obj-$(CONFIG_I2C_MCF) += i2c-mcf.o
126 +obj-$(CONFIG_I2C_MCF_SLAVE) += i2c-mcf-slave.o
127
128 ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
129 --- /dev/null
130 +++ b/drivers/i2c/busses/i2c-algo-mcf.h
131 @@ -0,0 +1,23 @@
132 +#ifndef I2C_ALGO_MCF_H
133 +#define I2C_ALGO_MCF_H 1
134 +
135 +/* --- Defines for pcf-adapters --------------------------------------- */
136 +#include <linux/i2c.h>
137 +
138 +struct i2c_algo_mcf_data {
139 + void *data; /* private data for lolevel routines */
140 + void (*setmcf) (void *data, int ctl, int val);
141 + int (*getmcf) (void *data, int ctl);
142 + int (*getown) (void *data);
143 + int (*getclock) (void *data);
144 + void (*waitforpin) (void);
145 + /* local settings */
146 + int udelay;
147 + int mdelay;
148 + int timeout;
149 +};
150 +
151 +int i2c_mcf_add_bus(struct i2c_adapter *);
152 +int i2c_mcf_del_bus(struct i2c_adapter *);
153 +
154 +#endif /* I2C_ALGO_MCF_H */
155 --- /dev/null
156 +++ b/drivers/i2c/busses/i2c-mcf-slave.c
157 @@ -0,0 +1,358 @@
158 +/*
159 + * i2c-mcf-slave.c - support adpater slave mode, now only support
160 + * mcf5445x platform
161 + *
162 + * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
163 + * Lanttor Guo <lanttor.guo@freescale.com>
164 + *
165 + * This program is free software; you can redistribute it and/or modify
166 + * it under the terms of the GNU General Public License as published by
167 + * the Free Software Foundation; either version 2 of the License, or
168 + * (at your option) any later version.
169 +*/
170 +
171 +#ifdef CONFIG_I2C_SLAVE_TEST
172 +#define DEBUG
173 +#endif
174 +
175 +#include <linux/init.h>
176 +#include <linux/module.h>
177 +#include <linux/kernel.h>
178 +#include <linux/errno.h>
179 +#include <linux/i2c.h>
180 +#include <linux/delay.h>
181 +#include <linux/string.h>
182 +#include <linux/platform_device.h>
183 +#include <linux/interrupt.h>
184 +#include <linux/proc_fs.h>
185 +#include <linux/types.h>
186 +#include <asm/coldfire.h>
187 +#include <asm/mcfsim.h>
188 +#include <asm/irq.h>
189 +#include <asm/mcfi2c.h>
190 +#if defined(CONFIG_M5445X)
191 +#include <asm/mcf5445x_intc.h>
192 +#endif
193 +
194 +#define IRQ (64+30)
195 +#define SLAVE_HANDLER_NAME "mcf-i2c slave handler"
196 +#define I2C_BUFFER_SIZE 50
197 +
198 +/* Structure for storing I2C transfer data */
199 +struct i2c_buffer {
200 + int tx_index; /* TX index */
201 + int rx_index; /* RX index */
202 + u16 length; /* Length of the buffer in bytes */
203 + u8 buf[I2C_BUFFER_SIZE]; /* Data buffer */
204 +};
205 +
206 +struct i2c_buffer i2c_tx_buffer;
207 +struct i2c_buffer i2c_rx_buffer;
208 +
209 +u8 *tx_string = "abcdefghijklmnopqrstuvwxyz0123456789)!@#$%^&*([].";
210 +
211 +/*
212 + * I2C slave mode interrupt handler
213 + *
214 + */
215 +static irqreturn_t i2c_slave_handler(int this_irq, void *dev_id)
216 +{
217 + u8 dummy_read;
218 + int tmp_index;
219 +
220 +#ifdef DEBUG
221 + printk(KERN_INFO "i2c adapter slave mode irq handler.\n");
222 +#endif
223 +
224 + /* Clear I2C interupt flag */
225 + MCF_I2SR = ~MCF_I2SR_IIF;
226 +
227 + /* Check if this device is in Master or Slave Mode. */
228 + if (MCF_I2CR & MCF_I2CR_MSTA) {
229 + /* Master mode, do nothing here */
230 + printk(KERN_INFO "i2c master mode at %s(), do nothing!\n",
231 + __func__);
232 + return IRQ_NONE;
233 + } else {
234 + /* Slave Mode - Check if Arbitration Lost. */
235 + if (MCF_I2SR & MCF_I2SR_IAL) {
236 +
237 + #ifdef DEBUG
238 + printk(KERN_INFO "Arbitration Lost.\n");
239 + #endif
240 +
241 + /* Clear IAL bit */
242 + MCF_I2SR &= ~MCF_I2SR_IAL;
243 +
244 + /* Arbitration Lost -
245 + * Check if this device is being addressed as slave.
246 + *(If not, nothing more needs to be done.)
247 + */
248 + if (MCF_I2SR & MCF_I2SR_IAAS) {
249 + /* Addressed as slave -
250 + * Check if master was reading from slave or
251 + * writing to slave.
252 + */
253 + if (MCF_I2SR & MCF_I2SR_SRW) {
254 + /* Set tx_index to 0 */
255 + if (i2c_tx_buffer.length == 0) {
256 + i2c_tx_buffer.length =
257 + I2C_BUFFER_SIZE;
258 + i2c_tx_buffer.tx_index = 0;
259 + }
260 +
261 + /* Master was reading from slave -
262 + * Set Transmit Mode.
263 + */
264 + MCF_I2CR |= MCF_I2CR_MTX;
265 +
266 + /* Write data to MBDR. */
267 + tmp_index = i2c_tx_buffer.tx_index++;
268 + MCF_I2DR = i2c_tx_buffer.buf[tmp_index];
269 + i2c_tx_buffer.length--;
270 +
271 + #ifdef DEBUG
272 + printk(KERN_INFO "Arbitration Lost: "
273 + "Addressed as slave - "
274 + "TX mode.\n");
275 + #endif
276 + } else {
277 + /* Set rx_index to 0 */
278 + i2c_rx_buffer.rx_index = 0;
279 +
280 + /* Master was writing to slave -
281 + Set Receive Mode. */
282 + MCF_I2CR &= ~MCF_I2CR_MTX;
283 +
284 + /* Dummy read from MBDR, to clear
285 + the ICF bit. */
286 + dummy_read = MCF_I2DR;
287 +
288 + #ifdef DEBUG
289 + printk(KERN_INFO "Arbitration Lost: "
290 + "Addressed as slave - "
291 + "RX mode.\n");
292 + #endif
293 + }
294 + }
295 +
296 + } else {
297 + /* Arbitration Not Lost - Check if data byte is this
298 + devices's Slave Address byte. */
299 + if (MCF_I2SR & MCF_I2SR_IAAS) {
300 + /* Data byte is Slave Address byte -
301 + Check Slave Read/Write bit. */
302 + if (MCF_I2SR & MCF_I2SR_SRW) {
303 + /* Set tx_index to 0 */
304 + if (i2c_tx_buffer.length == 0) {
305 + i2c_tx_buffer.length =
306 + I2C_BUFFER_SIZE;
307 + i2c_tx_buffer.tx_index = 0;
308 + }
309 +
310 + /* Master was reading from slave -
311 + Set Transmit Mode. */
312 + MCF_I2CR |= MCF_I2CR_MTX;
313 +
314 + /* Write data to MBDR. */
315 + tmp_index = i2c_tx_buffer.tx_index++;
316 + MCF_I2DR = i2c_tx_buffer.buf[tmp_index];
317 + i2c_tx_buffer.length--;
318 +
319 + #ifdef DEBUG
320 + tmp_index = i2c_tx_buffer.tx_index - 1;
321 + printk(KERN_INFO "Slave TX: First byte"
322 + " - 0x%02X\n",
323 + i2c_tx_buffer.buf[tmp_index]);
324 + #endif
325 + } else {
326 + /* Master has specified Slave Receive
327 + Mode. Set Receive Mode. (Writing to
328 + MBCR clears IAAS.) */
329 +
330 + /* Set rx_index to 0 */
331 + i2c_rx_buffer.rx_index = 0;
332 +
333 + MCF_I2CR &= ~MCF_I2CR_MTX;
334 +
335 + /* Dummy read from MBDR, to clear
336 + the ICF bit. */
337 + dummy_read = MCF_I2DR;
338 +
339 + #ifdef DEBUG
340 + printk(KERN_INFO "Slave RX: Receive "
341 + "address.\n");
342 + #endif
343 + }
344 + } else {
345 + /* Data byte received is not Slave Address byte
346 + Check if this device is in Transmit or
347 + Receive Mode. */
348 + if (MCF_I2CR & MCF_I2CR_MTX) {
349 + /* Last byte received? */
350 + if (MCF_I2SR & MCF_I2SR_RXAK) {
351 + MCF_I2CR &= ~MCF_I2CR_MTX;
352 + dummy_read = MCF_I2DR;
353 +
354 + #ifdef DEBUG
355 + printk(KERN_INFO "Slave TX: "
356 + "Last byte has been "
357 + "sent.\n");
358 + #endif
359 + } else {
360 + /* Write data to MBDR. */
361 + tmp_index =
362 + i2c_tx_buffer.tx_index++;
363 + MCF_I2DR =
364 + i2c_tx_buffer.buf[tmp_index];
365 + i2c_tx_buffer.length--;
366 +
367 + if (i2c_tx_buffer.length == 0) {
368 + i2c_tx_buffer.length =
369 + I2C_BUFFER_SIZE;
370 + i2c_tx_buffer.tx_index =
371 + 0;
372 + }
373 +
374 + }
375 + } else {
376 + /* Receive Mode - Read data from
377 + MBDR and store it. */
378 + tmp_index = i2c_rx_buffer.rx_index++;
379 + i2c_rx_buffer.buf[tmp_index] = MCF_I2DR;
380 + i2c_rx_buffer.length++;
381 + }
382 + }
383 + }
384 + return IRQ_HANDLED;
385 + }
386 +}
387 +
388 +#ifdef CONFIG_PROC_FS
389 +
390 +/*
391 + * Info exported via "/proc/driver/i2c".
392 + */
393 +
394 +static int gen_i2c_proc_output(char *buf)
395 +{
396 + char *p;
397 +
398 + p = buf;
399 + p += sprintf(p,
400 + "I2CR: 0x%x\n"
401 + "I2SR: 0x%x\n"
402 + "I2DR: 0x%x\n",
403 + MCF_I2CR, MCF_I2SR, MCF_I2DR);
404 +
405 + return p - buf;
406 +}
407 +
408 +static int gen_i2c_read_proc(char *page, char **start, off_t off,
409 + int count, int *eof, void *data)
410 +{
411 + int len = gen_i2c_proc_output(page);
412 + if (len <= off+count)
413 + *eof = 1;
414 + *start = page + off;
415 + len -= off;
416 + if (len > count)
417 + len = count;
418 + if (len < 0)
419 + len = 0;
420 + return len;
421 +}
422 +
423 +static int __init gen_i2c_proc_init(void)
424 +{
425 + struct proc_dir_entry *r;
426 +
427 + r = create_proc_read_entry("driver/i2c-adaptor-register", 0, NULL,
428 + gen_i2c_read_proc, NULL);
429 + if (!r)
430 + return -ENOMEM;
431 + return 0;
432 +}
433 +#else
434 +static inline int gen_i2c_proc_init(void) { return 0; }
435 +#endif /* CONFIG_PROC_FS */
436 +
437 +/*
438 + * Initalize I2C module
439 + */
440 +static int __init i2c_coldfire_init(void)
441 +{
442 + int retval;
443 + u8 dummy_read;
444 +
445 +#ifdef DEBUG
446 + printk(KERN_INFO "init i2c adaptor slave mode!\n");
447 +#endif
448 +
449 + /* Initialize the tx buffer */
450 + strcpy((char *)&i2c_tx_buffer.buf, (const char *)tx_string);
451 + i2c_tx_buffer.length = I2C_BUFFER_SIZE;
452 +
453 +#if defined(CONFIG_M5445X)
454 + /*
455 + * Initialize the GPIOs for I2C
456 + */
457 + MCF_GPIO_PAR_FECI2C |= (0
458 + | MCF_GPIO_PAR_FECI2C_PAR_SDA(3)
459 + | MCF_GPIO_PAR_FECI2C_PAR_SCL(3));
460 +#endif
461 +
462 + /* Set transmission frequency 0x19 = ~100kHz */
463 + MCF_I2FDR = 0x19;
464 +
465 + /* set the I2C slave address */
466 + MCF_I2AR = 0x6A;
467 +
468 + /* Enable I2C module and if IBB is set, do the special initialzation */
469 + /* procedures as are documented */
470 +
471 + if ((MCF_I2SR & MCF_I2SR_IBB) == 1) {
472 + printk(KERN_INFO "%s - do special I2C init procedures\n",
473 + __func__);
474 + MCF_I2CR = 0x00;
475 + MCF_I2CR = 0xA0;
476 + dummy_read = MCF_I2DR;
477 + MCF_I2SR = 0x00;
478 + MCF_I2CR = 0x00;
479 + }
480 +
481 + MCF_I2CR |= (MCF_I2CR_IEN | MCF_I2CR_IIEN);
482 +
483 + /* default I2C mode is - slave and receive */
484 + MCF_I2CR &= ~(MCF_I2CR_MSTA | MCF_I2CR_MTX);
485 +
486 + retval = request_irq(IRQ, i2c_slave_handler, IRQF_DISABLED,
487 + SLAVE_HANDLER_NAME, NULL);
488 + if (retval < 0)
489 + printk(KERN_INFO "request_irq for i2c slave mode failed!\n");
490 +
491 + retval = gen_i2c_proc_init();
492 +
493 + if (retval < 0)
494 + printk(KERN_INFO "gen /proc/i2c-adaptor-register for i2c slave mode failed!\n");
495 +
496 + return retval;
497 +};
498 +
499 +/*
500 + * I2C module exit function
501 + */
502 +
503 +static void __exit i2c_coldfire_exit(void)
504 +{
505 + /* disable I2C and Interrupt */
506 + MCF_I2CR &= ~(MCF_I2CR_IEN | MCF_I2CR_IIEN);
507 + free_irq(IRQ, NULL);
508 +
509 +};
510 +
511 +MODULE_DESCRIPTION("MCF5445x I2C adaptor slave mode support");
512 +MODULE_LICENSE("GPL");
513 +
514 +module_init(i2c_coldfire_init);
515 +module_exit(i2c_coldfire_exit);
516 --- /dev/null
517 +++ b/drivers/i2c/busses/i2c-mcf.c
518 @@ -0,0 +1,698 @@
519 +/*
520 + * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
521 + * Lanttor.Guo@freescale.com
522 + *
523 + * I2C bus driver on mcfv4/mcfv4e platform
524 + *
525 + * This program is free software; you can redistribute it and/or modify
526 + * it under the terms of the GNU General Public License as published by
527 + * the Free Software Foundation; either version 2 of the License, or
528 + * (at your option) any later version.
529 + */
530 +#include <linux/i2c.h>
531 +#include "i2c-algo-mcf.h"
532 +
533 +#include <linux/init.h>
534 +#include <linux/kernel.h>
535 +#include <linux/module.h>
536 +#include <linux/delay.h>
537 +#include <linux/platform_device.h>
538 +#include <linux/sched.h>
539 +#include <linux/interrupt.h>
540 +#include <linux/io.h>
541 +#include <linux/proc_fs.h>
542 +
543 +#include <asm/coldfire.h>
544 +#include <asm/mcfi2c.h>
545 +
546 +#if defined(CONFIG_M547X_8X)
547 +#include <asm/m5485sim.h>
548 +#elif defined(CONFIG_M5445X) || defined(CONFIG_M5441X)
549 +#include <asm/mcfsim.h>
550 +#endif
551 +
552 +#define get_clock(adap) (clock)
553 +#define get_own(adap) (own)
554 +
555 +#if defined(CONFIG_M547X_8X)
556 +static int clock = 0x3b;
557 +#elif defined(CONFIG_M5445X) || defined(CONFIG_M5441X)
558 +static int clock = 0x19;
559 +#endif
560 +module_param(clock, int, 0);
561 +MODULE_PARM_DESC(clock,
562 + "Set I2C clock in kHz: 400=fast mode (default == 100khz)");
563 +
564 +static int own = 0x78;
565 +module_param(own, int, 0);
566 +MODULE_PARM_DESC(clock, "Set I2C Master controller address");
567 +
568 +static struct i2c_algo_mcf_data i2c_mcf_board_data = {
569 + .timeout = 10000,
570 +};
571 +
572 +static struct i2c_adapter i2c_mcf_board_adapter = {
573 + .owner = THIS_MODULE,
574 + .name = "mcf i2c adapter",
575 + .algo_data = &i2c_mcf_board_data,
576 + .class = I2C_CLASS_HWMON,
577 + .timeout = 100,
578 + .retries = 2
579 +};
580 +/*
581 + * static void i2c_start()
582 + *
583 + * Generates START signal
584 + */
585 +static void
586 +i2c_start(
587 + struct i2c_algo_mcf_data *adap
588 +) {
589 + MCF_I2CR |= MCF_I2CR_MSTA;
590 +}
591 +
592 +
593 +/*
594 + * static void i2c_stop()
595 + *
596 + * Generates STOP signal
597 + */
598 +static void
599 +i2c_stop(
600 + struct i2c_algo_mcf_data *adap
601 +) {
602 + MCF_I2CR &= ~MCF_I2CR_MSTA;
603 +}
604 +
605 +static int
606 +i2c_getack(
607 + struct i2c_algo_mcf_data *adap
608 +) {
609 + return !(MCF_I2SR & MCF_I2SR_RXAK);
610 +}
611 +
612 +/*
613 + * static void wait_for_bb()
614 + *
615 + * Wait for bus idle state
616 + */
617 +static int
618 +wait_for_bb(
619 + struct i2c_algo_mcf_data *adap
620 +) {
621 + int i;
622 + for (i = 0; i < adap->timeout; i++) {
623 + if (!(MCF_I2SR & MCF_I2SR_IBB))
624 + return 0;
625 + udelay(100);
626 + }
627 + printk(KERN_ERR "%s: timeout", __func__);
628 + return -ETIMEDOUT;
629 +}
630 +
631 +/*
632 + * static void wait_for_not_bb()
633 + *
634 + * Wait for bus busy state
635 + */
636 +static int
637 +wait_for_not_bb(
638 + struct i2c_algo_mcf_data *adap
639 +) {
640 + int i;
641 + for (i = 0; i < adap->timeout; i++) {
642 + if (MCF_I2SR & MCF_I2SR_IBB)
643 + return 0;
644 + udelay(100);
645 + }
646 + printk(KERN_ERR "%s: timeout", __func__);
647 + return -ETIMEDOUT;
648 +}
649 +
650 +/*
651 + * static void wait_xfer_done()
652 + *
653 + * Wait for transfer to complete
654 + */
655 +static int
656 +wait_xfer_done(
657 + struct i2c_algo_mcf_data *adap
658 +) {
659 + int i;
660 +
661 + for (i = 0; i < adap->timeout; i++) {
662 + if (MCF_I2SR & MCF_I2SR_IIF) {
663 + MCF_I2SR &= ~MCF_I2SR_IIF;
664 + return 0;
665 + }
666 + udelay(10);
667 + }
668 + printk(KERN_ERR "%s: timeout", __func__);
669 + return -ETIMEDOUT;
670 +}
671 +
672 +
673 +/*
674 + * static void i2c_set_addr()
675 + *
676 + * Sets slave address to communicate
677 + */
678 +static int
679 +i2c_set_addr(
680 + struct i2c_algo_mcf_data *adap,
681 + struct i2c_msg *msg,
682 + int retries
683 +) {
684 + unsigned short flags = msg->flags;
685 + unsigned char addr;
686 + MCF_I2CR |= MCF_I2CR_MTX;
687 + if ((flags & I2C_M_TEN)) {
688 + /* 10 bit address not supported yet */
689 + return -EIO;
690 + } else {
691 + /* normal 7bit address */
692 + addr = (msg->addr << 1);
693 + if (flags & I2C_M_RD)
694 + addr |= 1;
695 + if (flags & I2C_M_REV_DIR_ADDR)
696 + addr ^= 1;
697 +
698 + MCF_I2DR = addr;
699 + }
700 + return 0;
701 +}
702 +
703 +
704 +/*
705 + * static void mcf_i2c_init()
706 + *
707 + * Perform ColdFire i2c initialization
708 + */
709 +static void
710 +mcf_i2c_init(struct i2c_algo_mcf_data *adap)
711 +{
712 + u8 dummy;
713 +
714 + /* Setup GPIO lines */
715 +#if defined(CONFIG_M547X_8X)
716 + MCF_PAR_FECI2CIRQ |= MCF_PAR_SDA;
717 + MCF_PAR_FECI2CIRQ |= MCF_PAR_SCL;
718 +#elif defined(CONFIG_M5445X)
719 + MCF_GPIO_PAR_FECI2C |= (0
720 + | MCF_GPIO_PAR_FECI2C_PAR_SDA(3)
721 + | MCF_GPIO_PAR_FECI2C_PAR_SCL(3));
722 +#elif defined(CONFIG_M5441X)
723 + MCF_GPIO_PAR_CANI2C =
724 + (MCF_GPIO_PAR_CANI2C & MCF_GPIO_PAR_CANI2C_I2C0SCL_MASK) |
725 + MCF_GPIO_PAR_CANI2C_I2C0SCL_I2C0SCL;
726 + MCF_GPIO_PAR_CANI2C =
727 + (MCF_GPIO_PAR_CANI2C & MCF_GPIO_PAR_CANI2C_I2C0SDA_MASK) |
728 + MCF_GPIO_PAR_CANI2C_I2C0SDA_I2C0SDA;
729 +#endif
730 +
731 + /* Ensure slaves are in idle state */
732 + if (MCF_I2SR & MCF_I2SR_IBB) {
733 +#if defined(CONFIG_M547X_8X)
734 + MCF_I2ICR = 0x00;
735 + MCF_I2CR = 0x00;
736 + MCF_I2CR = 0x0A;
737 + dummy = MCF_I2DR;
738 + MCF_I2SR = 0x00;
739 + MCF_I2CR = 0x00;
740 + MCF_I2ICR = 0x01;
741 +#elif defined(CONFIG_M5445X) || defined(CONFIG_M5441X)
742 + MCF_I2CR = 0x00;
743 + MCF_I2CR = 0xA0;
744 + dummy = MCF_I2DR;
745 + MCF_I2SR = 0x00;
746 + MCF_I2CR = 0x00;
747 + MCF_I2CR = 0x80;
748 +#endif
749 + }
750 +
751 + /* setup SCL clock */
752 + MCF_I2FDR = get_clock(adap);
753 +
754 + /* set slave address */
755 + MCF_I2AR = get_own(adap);
756 +
757 + /* enable I2C module */
758 +#if defined(CONFIG_M5441X)
759 + MCF_I2CR = (MCF_I2CR_IEN | MCF_I2CR_IIEN);
760 +#else
761 + MCF_I2CR = MCF_I2CR_IEN;
762 +#endif
763 +}
764 +
765 +static int i2c_outb(
766 + struct i2c_adapter *i2c_adap,
767 + char c
768 +) {
769 +
770 + struct i2c_algo_mcf_data *adap = i2c_adap->algo_data;
771 + int timeout;
772 + /* Put data to be sent */
773 + MCF_I2DR = c;
774 + /* Wait for xfer completed*/
775 + timeout = wait_xfer_done(adap);
776 + if (timeout) {
777 + i2c_stop(adap);
778 + wait_for_bb(adap);
779 + printk(KERN_ERR "i2c-algo-mcf: %s i2c_write: "
780 + "error - timeout.\n", i2c_adap->name);
781 + return -EREMOTEIO; /* got a better one ?? */
782 + }
783 +
784 + return 0;
785 +}
786 +
787 +
788 +/*
789 + * static void mcf_sendbytes()
790 + *
791 + * Perform tx data transfer
792 + */
793 +static int
794 +mcf_sendbytes(
795 + struct i2c_adapter *i2c_adap,
796 + const char *buf,
797 + int count, int last
798 +) {
799 + struct i2c_algo_mcf_data *adap = i2c_adap->algo_data;
800 + int ret, i;
801 +
802 + /* Set master TX mode */
803 + MCF_I2CR |= MCF_I2CR_MTX;
804 +
805 + for (i = 0; i < count; ++i) {
806 + printk(KERN_DEBUG "i2c-algo-mcf: %s i2c_write: writing %2.2X\n",
807 + i2c_adap->name, buf[i]&0xff);
808 + ret = i2c_outb(i2c_adap, buf[i]);
809 + if (ret < 0)
810 + return ret;
811 + }
812 + if (last) {
813 + i2c_stop(adap);
814 + wait_for_bb(adap);
815 + } else {
816 + /* i2c_repstart(adap);*/
817 + }
818 +
819 + return i;
820 +}
821 +
822 +
823 +/*
824 + * static void mcf_readbytes()
825 + *
826 + * Perform rx data transfer
827 + */
828 +static int
829 +mcf_readbytes(
830 + struct i2c_adapter *i2c_adap,
831 + char *buf,
832 + int count, int last
833 +) {
834 + int i;
835 + struct i2c_algo_mcf_data *adap = i2c_adap->algo_data;
836 + u8 dummy;
837 +
838 + /* Set master RX mode */
839 + MCF_I2CR &= ~MCF_I2CR_MTX;
840 + MCF_I2CR &= ~MCF_I2CR_TXAK;
841 + dummy = MCF_I2DR;
842 +
843 + for (i = 0; i < count-1; i++) {
844 + if (wait_xfer_done(adap)) {
845 + i2c_stop(adap);
846 + wait_for_bb(adap);
847 + printk(KERN_DEBUG
848 + "i2c-algo-mcf: mcf_readbytes timed out.\n");
849 + return -1;
850 + }
851 +
852 + /* store next data byte */
853 + buf[i] = MCF_I2DR;
854 + }
855 +
856 + if (wait_xfer_done(adap)) {
857 + i2c_stop(adap);
858 + wait_for_bb(adap);
859 + printk(KERN_DEBUG "i2c-algo-mcf: mcf_readbytes timed out.\n");
860 + return -1;
861 + }
862 +
863 + /* Disable acknowlege (set I2CR.TXAK) */
864 + MCF_I2CR |= MCF_I2CR_TXAK;
865 + buf[i] = MCF_I2DR;
866 + if (wait_xfer_done(adap)) {
867 + i2c_stop(adap);
868 + wait_for_bb(adap);
869 + printk(KERN_DEBUG "i2c-algo-mcf: mcf_readbytes timed out.\n");
870 + return -1;
871 + }
872 +
873 + if (last) {
874 + i2c_stop(adap);
875 + wait_for_bb(adap);
876 + } else {
877 + /* i2c_repstart(adap);*/
878 + }
879 +
880 + return i+1;
881 +}
882 +
883 +
884 +/*
885 + * static void mcf_xfer()
886 + *
887 + * Perform master data I/O transfer
888 + */
889 +static int
890 +mcf_xfer(
891 + struct i2c_adapter *i2c_adap,
892 + struct i2c_msg *msgs,
893 + int num)
894 +{
895 + struct i2c_algo_mcf_data *adap = i2c_adap->algo_data;
896 + struct i2c_msg *pmsg;
897 + int i;
898 + int ret = 0, timeout;
899 +
900 + /* Skip own address */
901 + if (get_own(adap) == (msgs[0].addr << 1))
902 + return -EIO;
903 +
904 + /* Ensure slaves are in idle state */
905 + if (MCF_I2SR & MCF_I2SR_IBB) {
906 +#if defined(CONFIG_M547X_8X)
907 + MCF_I2ICR = 0x00;
908 + MCF_I2CR = 0x00;
909 + MCF_I2CR = 0x0A;
910 + timeout = MCF_I2DR;
911 + MCF_I2SR = 0x00;
912 + MCF_I2CR = 0x00;
913 + MCF_I2ICR = 0x01;
914 +#elif defined(CONFIG_M5445X) || defined(CONFIG_M5441X)
915 + MCF_I2CR = 0x00;
916 + MCF_I2CR = 0xA0;
917 + timeout = MCF_I2DR;
918 + MCF_I2SR = 0x00;
919 + MCF_I2CR = 0x00;
920 + MCF_I2CR = 0x80;
921 +#endif
922 + }
923 +
924 + /* setup SCL clock */
925 + MCF_I2FDR = get_clock(adap);
926 + /* set slave address */
927 + MCF_I2AR = get_own(adap);
928 + /* enable I2C module */
929 +#if defined(CONFIG_M5441X)
930 + MCF_I2CR = (MCF_I2CR_IEN | MCF_I2CR_IIEN);
931 +#else
932 + MCF_I2CR = MCF_I2CR_IEN;
933 +#endif
934 + MCF_I2CR |= MCF_I2CR_TXAK;
935 +
936 + /* Check for bus busy */
937 + wait_for_bb(adap);
938 +
939 + for (i = 0; ret >= 0 && i < num; i++) {
940 + if (MCF_I2SR & MCF_I2SR_IBB) {
941 +#if defined(CONFIG_M547X_8X)
942 + MCF_I2ICR = 0x00;
943 + MCF_I2CR = 0x00;
944 + MCF_I2CR = 0x0A;
945 + timeout = MCF_I2DR;
946 + MCF_I2SR = 0x00;
947 + MCF_I2CR = 0x00;
948 + MCF_I2ICR = 0x01;
949 +#elif defined(CONFIG_M5445X) || defined(CONFIG_M5441X)
950 + MCF_I2CR = 0x00;
951 + MCF_I2CR = 0xA0;
952 + timeout = MCF_I2DR;
953 + MCF_I2SR = 0x00;
954 + MCF_I2CR = 0x00;
955 + MCF_I2CR = 0x80;
956 +#endif
957 + }
958 + /* setup SCL clock */
959 + MCF_I2FDR = get_clock(adap);
960 + /* set slave address */
961 + MCF_I2AR = get_own(adap);
962 + /* enable I2C module */
963 +#if defined(CONFIG_M5441X)
964 + MCF_I2CR = (MCF_I2CR_IEN | MCF_I2CR_IIEN);
965 +#else
966 + MCF_I2CR = MCF_I2CR_IEN;
967 +#endif
968 + MCF_I2CR |= MCF_I2CR_TXAK;
969 +
970 + /* Check for bus busy */
971 + wait_for_bb(adap);
972 +
973 + pmsg = &msgs[i];
974 +
975 + printk(KERN_DEBUG "i2c-algo-mcf: Doing %s %d bytes "
976 + "to 0x%02x - %d of %d messages\n",
977 + pmsg->flags & I2C_M_RD ? "read" : "write",
978 + pmsg->len, pmsg->addr, i + 1, num);
979 +
980 + /* Send START */
981 + /*if (i == 0)*/
982 + i2c_start(adap);
983 +
984 + /* Wait for Bus Busy */
985 + wait_for_not_bb(adap);
986 +
987 + MCF_I2CR |= MCF_I2CR_MTX;
988 +
989 + ret = i2c_set_addr(adap, pmsg, i2c_adap->retries);
990 + if (ret < 0)
991 + return ret;
992 +
993 + /* Wait for address transfer completion */
994 + wait_xfer_done(adap);
995 +
996 + /* Check for ACK */
997 + if (!i2c_getack(adap)) {
998 + i2c_stop(adap);
999 + wait_for_bb(adap);
1000 + printk(KERN_DEBUG "i2c-algo-mcf: No ack after "
1001 + "send address in mcf_xfer\n");
1002 + return -EREMOTEIO;
1003 + }
1004 +
1005 + printk(KERN_DEBUG "i2c-algo-mcf: Msg %d, "
1006 + "addr = 0x%x, flags = 0x%x, len = %d\n",
1007 + i, msgs[i].addr, msgs[i].flags, msgs[i].len);
1008 + /* Read */
1009 + if (pmsg->flags & I2C_M_RD) {
1010 + /* read bytes into buffer*/
1011 + ret = mcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
1012 + (i + 1 == num));
1013 +
1014 + if (ret != pmsg->len) {
1015 + printk(KERN_DEBUG "i2c-algo-mcf: fail: "
1016 + "only read %d bytes.\n", ret);
1017 + } else {
1018 + printk(KERN_DEBUG "i2c-algo-mcf: "
1019 + "read %d bytes.\n", ret);
1020 + }
1021 + } else {
1022 + /* write bytes into buffer*/
1023 + ret = mcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
1024 + (i + 1 == num));
1025 + if (ret != pmsg->len) {
1026 + printk(KERN_DEBUG "i2c-algo-mcf: fail: "
1027 + "only wrote %d bytes.\n", ret);
1028 + } else {
1029 + printk(KERN_DEBUG "i2c-algo-mcf: wrote"
1030 + "%d bytes.\n", ret);
1031 + }
1032 + }
1033 + MCF_I2CR = 0;
1034 + }
1035 +
1036 + /* Disable I2C module */
1037 + MCF_I2CR = 0;
1038 + return i;
1039 +}
1040 +
1041 +
1042 +/*
1043 + * static void mcf_func()
1044 + *
1045 + * Return algorithm funtionality
1046 + */
1047 +static u32
1048 +mcf_func(
1049 + struct i2c_adapter *i2c_adap
1050 +) {
1051 + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
1052 +}
1053 +
1054 +/*
1055 + * ColdFire bus algorithm callbacks
1056 + */
1057 +static struct i2c_algorithm mcf_algo = {
1058 + .master_xfer = mcf_xfer,
1059 + .functionality = mcf_func,
1060 +};
1061 +
1062 +/***********************************************************/
1063 +struct coldfire_i2c {
1064 + void __iomem *base;
1065 + struct resource *irqarea;
1066 + struct resource *ioarea;
1067 + u32 irq;
1068 + struct i2c_adapter *adap;
1069 + u32 flags;
1070 +};
1071 +
1072 +/*
1073 + * registering functions to load algorithms at runtime
1074 + */
1075 +int i2c_mcf_add_bus(struct i2c_adapter *adap)
1076 +{
1077 + struct i2c_algo_mcf_data *mcf_adap = adap->algo_data;
1078 +
1079 + /*adap->id |= mcf_algo.id;*/
1080 + adap->algo = &mcf_algo;
1081 + adap->timeout = 100;
1082 +
1083 + mcf_i2c_init(mcf_adap);
1084 +
1085 + i2c_add_numbered_adapter(adap);
1086 +
1087 + return 0;
1088 +}
1089 +
1090 +static int mcf_i2c_probe(struct platform_device *pdev)
1091 +{
1092 + struct coldfire_i2c *i2c;
1093 + int rc = 0;
1094 +
1095 + /************************************************************/
1096 + i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
1097 + if (!i2c) {
1098 + printk(KERN_ERR "%s kzalloc coldfire_i2c faile\n",
1099 + __func__);
1100 + return -ENOMEM;
1101 + }
1102 + /****************************************************************/
1103 + platform_set_drvdata(pdev, i2c);
1104 +
1105 + i2c->adap = &i2c_mcf_board_adapter;
1106 + i2c->adap->dev.parent = &pdev->dev;
1107 + i2c->adap->nr = pdev->id;
1108 + rc = i2c_mcf_add_bus(i2c->adap);
1109 + if (rc < 0) {
1110 + printk(KERN_ERR "%s - failed to add adapter\n", __func__);
1111 + rc = -ENODEV;
1112 + goto fail_add;
1113 + }
1114 +
1115 + printk(KERN_INFO "i2c-algo-mcf.o: I2C ColdFire algorithm"
1116 + " module is loaded.\n");
1117 + return rc;
1118 +
1119 +fail_add:
1120 + kfree(i2c);
1121 + return rc;
1122 +};
1123 +
1124 +static int mcf_i2c_remove(struct platform_device *pdev)
1125 +{
1126 + struct coldfire_i2c *i2c = platform_get_drvdata(pdev);
1127 +
1128 + i2c_del_adapter(i2c->adap);
1129 + platform_set_drvdata(pdev, NULL);
1130 + iounmap(i2c->base);
1131 + kfree(i2c);
1132 + return 0;
1133 +};
1134 +
1135 +/* Structure for a device driver */
1136 +static struct platform_driver mcf_i2c_driver = {
1137 + .probe = mcf_i2c_probe,
1138 + .remove = mcf_i2c_remove,
1139 + .driver = {
1140 + .owner = THIS_MODULE,
1141 + .name = "mcf-i2c",
1142 + },
1143 +};
1144 +
1145 +#ifdef CONFIG_PROC_FS
1146 +
1147 +/*
1148 + * Info exported via "/proc/driver/i2c".
1149 + */
1150 +
1151 +static int gen_i2c_proc_output(char *buf)
1152 +{
1153 + char *p;
1154 +
1155 + p = buf;
1156 + p += sprintf(p,
1157 + "I2CR: 0x%x\n"
1158 + "I2SR: 0x%x\n"
1159 + "I2DR: 0x%x\n",
1160 + MCF_I2CR, MCF_I2SR, MCF_I2DR);
1161 +
1162 + return p - buf;
1163 +}
1164 +
1165 +static int gen_i2c_read_proc(char *page, char **start, off_t off,
1166 + int count, int *eof, void *data)
1167 +{
1168 + int len = gen_i2c_proc_output(page);
1169 + if (len <= off+count)
1170 + *eof = 1;
1171 + *start = page + off;
1172 + len -= off;
1173 + if (len > count)
1174 + len = count;
1175 + if (len < 0)
1176 + len = 0;
1177 + return len;
1178 +}
1179 +
1180 +static int __init gen_i2c_proc_init(void)
1181 +{
1182 + struct proc_dir_entry *r;
1183 +
1184 + r = create_proc_read_entry("driver/i2c-adaptor-register", 0, NULL,
1185 + gen_i2c_read_proc, NULL);
1186 + if (!r)
1187 + return -ENOMEM;
1188 + return 0;
1189 +}
1190 +#else
1191 +static inline int gen_i2c_proc_init(void) { return 0; }
1192 +#endif /* CONFIG_PROC_FS */
1193 +
1194 +static int __init coldfire_i2c_init(void)
1195 +{
1196 + int retval;
1197 +
1198 + retval = gen_i2c_proc_init();
1199 + if (retval < 0)
1200 + printk(KERN_INFO "generate /proc/i2c-adaptor-register "
1201 + "for i2c master mode failed!\n");
1202 +
1203 + return platform_driver_register(&mcf_i2c_driver);
1204 +}
1205 +
1206 +static void __exit coldfire_i2c_exit(void)
1207 +{
1208 + platform_driver_unregister(&mcf_i2c_driver);
1209 +}
1210 +
1211 +module_init(coldfire_i2c_init);
1212 +module_exit(coldfire_i2c_exit);
1213 +
1214 +MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
1215 +MODULE_DESCRIPTION("I2C-Bus adapter for MCFV4/MCFV4E processors");
1216 +MODULE_LICENSE("GPL");