xburst: remove support for old kernels
[openwrt.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");