[ar71xx] add patches for 2.6.31
[openwrt.git] / target / linux / coldfire / patches / 055-m547x_8x_i2c.patch
1 From ce57fc22543d0ee0ca33157264815a52fc8cf9a3 Mon Sep 17 00:00:00 2001
2 From: Kurt Mahan <kmahan@freescale.com>
3 Date: Thu, 15 May 2008 13:23:27 -0600
4 Subject: [PATCH] Add I2C bus driver for MCF547x and MCF548x.
5
6 LTIBName: m547x-8x-i2c
7 Signed-off-by: Kurt Mahan <kmahan@freescale.com>
8 Signed-off-by: Shrek Wu <b16972@freescale.com>
9 ---
10  arch/m68k/coldfire/Makefile          |    1 +
11  arch/m68k/coldfire/mcf548x-devices.c |   94 ++++++
12  drivers/i2c/busses/Kconfig           |   12 +
13  drivers/i2c/busses/Makefile          |    1 +
14  drivers/i2c/busses/i2c-algo-mcf.h    |   23 ++
15  drivers/i2c/busses/i2c-mcf548x.c     |  573 ++++++++++++++++++++++++++++++++++
16  include/asm-m68k/m5485i2c.h          |   45 +++
17  7 files changed, 749 insertions(+), 0 deletions(-)
18  create mode 100644 arch/m68k/coldfire/mcf548x-devices.c
19  create mode 100644 drivers/i2c/busses/i2c-algo-mcf.h
20  create mode 100644 drivers/i2c/busses/i2c-mcf548x.c
21  create mode 100644 include/asm-m68k/m5485i2c.h
22
23 --- a/arch/m68k/coldfire/Makefile
24 +++ b/arch/m68k/coldfire/Makefile
25 @@ -11,4 +11,5 @@ endif
26  obj-$(CONFIG_PCI)      += pci.o mcf5445x-pci.o iomap.o
27  obj-$(CONFIG_M54455)   += mcf5445x-devices.o
28  obj-$(CONFIG_M547X_8X) += m547x_8x-devices.o
29 +obj-$(CONFIG_M547X_8X) += mcf548x-devices.o
30  obj-$(CONFIG_MCD_DMA)  += m547x_8x-dma.o
31 --- /dev/null
32 +++ b/arch/m68k/coldfire/mcf548x-devices.c
33 @@ -0,0 +1,94 @@
34 +/*
35 + * arch/m68k/coldfire/mcf5445x-devices.c
36 + *
37 + * Coldfire M5445x Platform Device Configuration
38 + *
39 + * Based on the Freescale MXC devices.c
40 + *
41 + * Copyright (c) 2007 Freescale Semiconductor, Inc.
42 + *     Kurt Mahan <kmahan@freescale.com>
43 + */
44 +#include <linux/module.h>
45 +#include <linux/kernel.h>
46 +#include <linux/init.h>
47 +#include <linux/mtd/physmap.h>
48 +#include <linux/platform_device.h>
49 +#include <linux/fsl_devices.h>
50 +
51 +#include <asm/coldfire.h>
52 +#include <asm/mcfsim.h>
53 +
54 +static struct resource coldfire_i2c_resources[] = {
55 +       [0] = {         /* I/O */
56 +               .start          = MCF_MBAR + 0x008F00,
57 +               .end            = MCF_MBAR + 0x008F20,
58 +               .flags          = IORESOURCE_MEM,
59 +       },
60 +       [2] = {         /* IRQ */
61 +               .start          = 40,
62 +               .end            = 40,
63 +               .flags          = IORESOURCE_IRQ,
64 +       },
65 +};
66 +
67 +static struct platform_device coldfire_i2c_device = {
68 +       .name                   = "MCF548X-i2c",
69 +       .id                     = -1,
70 +       .num_resources          = ARRAY_SIZE(coldfire_i2c_resources),
71 +       .resource               = coldfire_i2c_resources,
72 +};
73 +
74 +static struct resource coldfire_sec_resources[] = {
75 +       [0] = {         /* I/O */
76 +               .start          = MCF_MBAR + 0x00020000,
77 +               .end            = MCF_MBAR + 0x00033000,
78 +               .flags          = IORESOURCE_MEM,
79 +       },
80 +       [2] = {         /* IRQ */
81 +               .start          = ISC_SEC,
82 +               .end            = ISC_SEC,
83 +               .flags          = IORESOURCE_IRQ,
84 +       },
85 +};
86 +
87 +static struct platform_device coldfire_sec_device = {
88 +       .name                   = "fsl-sec1",
89 +       .id                     = -1,
90 +       .num_resources          = ARRAY_SIZE(coldfire_sec_resources),
91 +       .resource               = coldfire_sec_resources,
92 +};
93 +
94 +#if defined(CONFIG_MTD_PHYSMAP)
95 +static struct physmap_flash_data mcf5485_flash_data = {
96 +       .width          = 2,
97 +};
98 +
99 +static struct resource mcf5485_flash_resource = {
100 +       .start          = 0xf8000000,
101 +       .end            = 0xf80fffff,
102 +       .flags          = IORESOURCE_MEM,
103 +};
104 +
105 +static struct platform_device mcf5485_flash_device = {
106 +       .name           = "physmap-flash",
107 +       .id             = 0,
108 +       .dev            = {
109 +               .platform_data  = &mcf5485_flash_data,
110 +       },
111 +       .num_resources  = 1,
112 +       .resource       = &mcf5485_flash_resource,
113 +};
114 +#endif
115 +
116 +static int __init mcf5485_init_devices(void)
117 +{
118 +       printk(KERN_INFO "MCF5485x INIT_DEVICES\n");
119 +
120 +       platform_device_register(&coldfire_i2c_device);
121 +       platform_device_register(&coldfire_sec_device);
122 +/*#if defined(CONFIG_MTD_PHYSMAP)
123 +       platform_device_register(&mcf5485_flash_device);
124 +#endif*/
125 +       return 0;
126 +}
127 +arch_initcall(mcf5485_init_devices);
128 --- a/drivers/i2c/busses/Kconfig
129 +++ b/drivers/i2c/busses/Kconfig
130 @@ -4,6 +4,18 @@
131  
132  menu "I2C Hardware Bus support"
133  
134 +config I2C_MCF548x
135 +       tristate "I2C MCF547x/548x interfaces"
136 +       depends on I2C
137 +       help
138 +         This allows you to use the I2C adapters found on the Freescale
139 +         MCF547x/548x microcontrollers.
140 +         Say Y if you own an I2C adapter belonging to this class and then say
141 +         Y to the specific driver for you adapter below.
142 +
143 +         This support is also available as a module.  If so, the module
144 +         will be called i2c-algo-mcf.
145 +
146  config I2C_ALI1535
147         tristate "ALI 1535"
148         depends on PCI
149 --- a/drivers/i2c/busses/Makefile
150 +++ b/drivers/i2c/busses/Makefile
151 @@ -52,6 +52,7 @@ obj-$(CONFIG_I2C_VIAPRO)      += i2c-viapro.o
152  obj-$(CONFIG_I2C_VOODOO3)      += i2c-voodoo3.o
153  obj-$(CONFIG_SCx200_ACB)       += scx200_acb.o
154  obj-$(CONFIG_SCx200_I2C)       += scx200_i2c.o
155 +obj-$(CONFIG_I2C_MCF548x)       += i2c-mcf548x.o
156  
157  ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
158  EXTRA_CFLAGS += -DDEBUG
159 --- /dev/null
160 +++ b/drivers/i2c/busses/i2c-algo-mcf.h
161 @@ -0,0 +1,23 @@
162 +#ifndef I2C_ALGO_MCF_H
163 +#define I2C_ALGO_MCF_H 1
164 +
165 +/* --- Defines for pcf-adapters ---------------------------------------        */
166 +#include <linux/i2c.h>
167 +
168 +struct i2c_algo_mcf_data {
169 +       void *data;             /* private data for lolevel routines    */
170 +       void (*setmcf) (void *data, int ctl, int val);
171 +       int (*getmcf) (void *data, int ctl);
172 +       int (*getown) (void *data);
173 +       int (*getclock) (void *data);
174 +       void (*waitforpin) (void);
175 +       /* local settings */
176 +       int udelay;
177 +       int mdelay;
178 +       int timeout;
179 +};
180 +
181 +int i2c_mcf_add_bus(struct i2c_adapter *);
182 +int i2c_mcf_del_bus(struct i2c_adapter *);
183 +
184 +#endif /* I2C_ALGO_MCF_H */
185 --- /dev/null
186 +++ b/drivers/i2c/busses/i2c-mcf548x.c
187 @@ -0,0 +1,573 @@
188 +/*
189 + *     Performance and stability improvements: (C) Copyright 2008,
190 + *     Adrian Cox <adrian@humboldt.co.uk>
191 + *     ColdFire 547x/548x I2C master support
192 + *     Shrek Wu (b16972@freescale.com )moved the code driver/i2c/alg/mcf.c
193 + *      into driver/i2c/busses.And changed the driver to a platform driver.
194 + */
195 +#include <linux/i2c.h>
196 +#include "i2c-algo-mcf.h"
197 +
198 +#include <linux/init.h>
199 +#include <linux/kernel.h>
200 +#include <linux/module.h>
201 +#include <linux/delay.h>
202 +#include <linux/platform_device.h>
203 +#include <linux/sched.h>
204 +#include <linux/interrupt.h>
205 +#include <asm/io.h>
206 +
207 +#include <asm/coldfire.h>
208 +#include <asm/m5485sim.h>
209 +#include <asm/m5485i2c.h>
210 +
211 +#define get_clock(adap) (clock)
212 +#define get_own(adap)  (own)
213 +
214 +static int clock = 0x3b;  /*50000 / 1024 ~ 49 KHz*/
215 +module_param(clock, int, 0);
216 +MODULE_PARM_DESC(clock,
217 +       "Set I2C clock in kHz: 400=fast mode (default == 49khz)");
218 +
219 +static int own = 0x78;
220 +module_param(own, int, 0);
221 +MODULE_PARM_DESC(clock, "Set I2C Master controller address(0x78)");
222 +
223 +static struct i2c_algo_mcf_data i2c_mcf_board_data = {
224 +       .timeout =      10000,
225 +};
226 +
227 +static struct i2c_adapter i2c_mcf_board_adapter = {
228 +       .owner = THIS_MODULE,
229 +       .name = "MCF5485 adapter",
230 +       .id = I2C_HW_MPC107,
231 +       .algo_data = &i2c_mcf_board_data,
232 +       .class = I2C_CLASS_HWMON,
233 +       .timeout = 1,
234 +       .retries = 1
235 +};
236 +/*
237 + *  static void i2c_start()
238 + *
239 + *  Generates START signal
240 + */
241 +static void
242 +i2c_start(
243 +       struct i2c_algo_mcf_data *adap
244 +) {
245 +       MCF_I2CR |= MCF_I2CR_MSTA;
246 +}
247 +
248 +
249 +/*
250 + *  static void i2c_stop()
251 + *
252 + *  Generates STOP signal
253 + */
254 +static void
255 +i2c_stop(
256 +       struct i2c_algo_mcf_data *adap
257 +) {
258 +       MCF_I2CR &= ~MCF_I2CR_MSTA;
259 +}
260 +
261 +static int
262 +i2c_getack(
263 +       struct i2c_algo_mcf_data *adap
264 +) {
265 +       return !(MCF_I2SR & MCF_I2SR_RXAK);
266 +}
267 +
268 +/*
269 + *  static void i2c_repstart()
270 + *
271 + *  Generates repeated start signal (without STOP while mastering the bus)
272 + */
273 +static void
274 +i2c_repstart(
275 +       struct i2c_algo_mcf_data *adap
276 +) {
277 +       MCF_I2CR |= MCF_I2CR_RSTA;
278 +       MCF_I2CR |= MCF_I2CR_MTX;
279 +}
280 +
281 +
282 +/*
283 + *  static void wait_for_bb()
284 + *
285 + *  Wait for bus idle state
286 + */
287 +static int
288 +wait_for_bb(
289 +       struct i2c_algo_mcf_data *adap
290 +) {
291 +       int i;
292 +       for (i = 0; i < adap->timeout; i++) {
293 +               if (!(MCF_I2SR & MCF_I2SR_IBB))
294 +                       return 0;
295 +               udelay(10);
296 +       }
297 +       printk(KERN_ERR "%s: timeout", __FUNCTION__);
298 +       return -ETIMEDOUT;
299 +}
300 +
301 +/*
302 + *  static void wait_for_not_bb()
303 + *
304 + *  Wait for bus busy state
305 + */
306 +static int
307 +wait_for_not_bb(
308 +       struct i2c_algo_mcf_data *adap
309 +) {
310 +       int i;
311 +       for (i = 0; i < adap->timeout; i++) {
312 +               if (MCF_I2SR & MCF_I2SR_IBB)
313 +                       return 0;
314 +               udelay(10);
315 +       }
316 +       printk(KERN_ERR "%s: timeout", __FUNCTION__);
317 +       return -ETIMEDOUT;
318 +}
319 +
320 +/*
321 + *  static void wait_xfer_done()
322 + *
323 + *  Wait for transfer to complete
324 + */
325 +static int
326 +wait_xfer_done(
327 +       struct i2c_algo_mcf_data *adap
328 +) {
329 +       int i;
330 +
331 +       for (i = 0; i < adap->timeout; i++) {
332 +               if (MCF_I2SR & MCF_I2SR_IIF) {
333 +                       MCF_I2SR &= ~MCF_I2SR_IIF;
334 +                       return 0;
335 +               }
336 +               udelay(1);
337 +       }
338 +       printk(KERN_ERR "%s: timeout", __FUNCTION__);
339 +       return -ETIMEDOUT;
340 +}
341 +
342 +
343 +/*
344 + *  static void i2c_set_addr()
345 + *
346 + *  Sets slave address to communicate
347 + */
348 +static int
349 +i2c_set_addr(
350 +       struct i2c_algo_mcf_data *adap,
351 +       struct i2c_msg *msg,
352 +       int retries
353 +) {
354 +       unsigned short flags = msg->flags;
355 +       unsigned char addr;
356 +
357 +       if ((flags & I2C_M_TEN)) {
358 +               /* 10 bit address not supported yet */
359 +               return -EIO;
360 +       } else {
361 +               /* normal 7bit address */
362 +               addr = (msg->addr << 1);
363 +               if (flags & I2C_M_RD)
364 +                       addr |= 1;
365 +               if (flags & I2C_M_REV_DIR_ADDR)
366 +                       addr ^= 1;
367 +
368 +               MCF_I2DR = addr;
369 +       }
370 +       return 0;
371 +}
372 +
373 +
374 +/*
375 + *  static void mcf_i2c_init()
376 + *
377 + *  Perform ColdFire i2c initialization
378 + */
379 +static void
380 +mcf_i2c_init(struct i2c_algo_mcf_data *adap)
381 +{
382 +       u8 dummy;
383 +       /* Setup GPIO lines */
384 +       MCF_PAR_FECI2CIRQ |= MCF_PAR_SDA;
385 +       MCF_PAR_FECI2CIRQ |= MCF_PAR_SCL;
386 +
387 +       /*  Ensure slaves are in idle state */
388 +       if (MCF_I2SR & MCF_I2SR_IBB) {
389 +               MCF_I2ICR = 0x00;
390 +               MCF_I2CR  = 0x00;
391 +               MCF_I2CR  = 0x0A;
392 +               dummy = MCF_I2DR;
393 +               MCF_I2SR  = 0x00;
394 +               MCF_I2CR  = 0x00;
395 +               MCF_I2ICR = 0x01;
396 +       }
397 +
398 +       /* setup SCL clock */
399 +       MCF_I2FDR = get_clock(adap);
400 +
401 +       /* set slave address */
402 +       MCF_I2AR = get_own(adap);
403 +
404 +       /* enable I2C module */
405 +       MCF_I2CR = MCF_I2CR_IEN;
406 +}
407 +
408 +static int i2c_outb(
409 +       struct i2c_adapter *i2c_adap,
410 +       char c
411 +) {
412 +
413 +       struct i2c_algo_mcf_data *adap = i2c_adap->algo_data;
414 +       int timeout;
415 +       /* Put data to be sent */
416 +       MCF_I2DR = c;
417 +       /* Wait for xfer completed*/
418 +       timeout = wait_xfer_done(adap);
419 +       if (timeout) {
420 +               i2c_stop(adap);
421 +               wait_for_bb(adap);
422 +               printk(KERN_ERR "i2c-algo-mcf: %s i2c_write: "
423 +                       "error - timeout.\n", i2c_adap->name);
424 +               return -EREMOTEIO; /* got a better one ?? */
425 +       }
426 +
427 +       return 0;
428 +}
429 +
430 +
431 +/*
432 + *  static void mcf_sendbytes()
433 + *
434 + *  Perform tx data transfer
435 + */
436 +static int
437 +mcf_sendbytes(
438 +       struct i2c_adapter *i2c_adap,
439 +       const char *buf,
440 +       int count, int last
441 +) {
442 +       struct i2c_algo_mcf_data *adap = i2c_adap->algo_data;
443 +       int ret, i;
444 +
445 +       /* Set master TX mode */
446 +       MCF_I2CR |= MCF_I2CR_MTX;
447 +
448 +       for (i = 0; i < count; ++i) {
449 +               printk(KERN_DEBUG "i2c-algo-mcf: %s i2c_write: writing %2.2X\n",
450 +                     i2c_adap->name, buf[i]&0xff);
451 +               ret = i2c_outb(i2c_adap, buf[i]);
452 +               if (ret < 0)
453 +                       return ret;
454 +       }
455 +       if (last) {
456 +               i2c_stop(adap);
457 +               wait_for_bb(adap);
458 +       } else {
459 +               i2c_repstart(adap);
460 +       }
461 +
462 +       return (i);
463 +}
464 +
465 +
466 +/*
467 + *  static void mcf_readbytes()
468 + *
469 + *  Perform rx data transfer
470 + */
471 +static int
472 +mcf_readbytes(
473 +       struct i2c_adapter *i2c_adap,
474 +       char *buf,
475 +       int count, int last
476 +) {
477 +       int i;
478 +       struct i2c_algo_mcf_data *adap = i2c_adap->algo_data;
479 +       u8 dummy;
480 +
481 +       /* Set master RX mode */
482 +       MCF_I2CR &= ~MCF_I2CR_MTX;
483 +       MCF_I2CR &= ~MCF_I2CR_TXAK;
484 +       dummy = MCF_I2DR;
485 +
486 +       for (i = 0; i < count-1; i++) {
487 +               if (wait_xfer_done(adap)) {
488 +                       i2c_stop(adap);
489 +                       wait_for_bb(adap);
490 +                       printk(KERN_DEBUG
491 +                           "i2c-algo-mcf: mcf_readbytes timed out.\n");
492 +                       return (-1);
493 +               }
494 +
495 +               /* store next data byte */
496 +               buf[i] = MCF_I2DR;
497 +       }
498 +
499 +       if (wait_xfer_done(adap)) {
500 +               i2c_stop(adap);
501 +               wait_for_bb(adap);
502 +               printk(KERN_DEBUG "i2c-algo-mcf: mcf_readbytes timed out.\n");
503 +               return (-1);
504 +       }
505 +
506 +       /* Disable acknowlege (set I2CR.TXAK) */
507 +       MCF_I2CR |= MCF_I2CR_TXAK;
508 +       buf[i] = MCF_I2DR;
509 +       if (wait_xfer_done(adap)) {
510 +               i2c_stop(adap);
511 +               wait_for_bb(adap);
512 +               printk(KERN_DEBUG "i2c-algo-mcf: mcf_readbytes timed out.\n");
513 +               return (-1);
514 +       }
515 +
516 +       if (last) {
517 +               i2c_stop(adap);
518 +               wait_for_bb(adap);
519 +       } else {
520 +               i2c_repstart(adap);
521 +       }
522 +
523 +       return (i+1);
524 +}
525 +
526 +
527 +/*
528 + *  static void mcf_xfer()
529 + *
530 + *  Perform master data I/O transfer
531 + */
532 +static int
533 +mcf_xfer(
534 +       struct i2c_adapter *i2c_adap,
535 +       struct i2c_msg *msgs,
536 +       int num
537 +) {
538 +       struct i2c_algo_mcf_data *adap = i2c_adap->algo_data;
539 +       struct i2c_msg *pmsg;
540 +       int i;
541 +       int ret = 0, timeout;
542 +
543 +       /* Skip own address */
544 +       if (get_own(adap) == (msgs[0].addr << 1))
545 +               return -EIO;
546 +
547 +       /*  Ensure slaves are in idle state */
548 +       if (MCF_I2SR & MCF_I2SR_IBB) {
549 +               MCF_I2ICR = 0x00;
550 +               MCF_I2CR  = 0x00;
551 +               MCF_I2CR  = 0x0A;
552 +               timeout = MCF_I2DR;
553 +               MCF_I2SR  = 0x00;
554 +               MCF_I2CR  = 0x00;
555 +               MCF_I2ICR = 0x01;
556 +       }
557 +       /* setup SCL clock */
558 +       MCF_I2FDR = get_clock(adap);
559 +       /* set slave address */
560 +       MCF_I2AR = get_own(adap);
561 +       /* enable I2C module */
562 +       MCF_I2CR = MCF_I2CR_IEN;
563 +
564 +       MCF_I2CR |= MCF_I2CR_TXAK;
565 +
566 +       /* Check for bus busy */
567 +       wait_for_bb(adap);
568 +
569 +       for (i = 0; ret >= 0 && i < num; i++) {
570 +               pmsg = &msgs[i];
571 +
572 +               printk(KERN_DEBUG "i2c-algo-mcf: Doing %s %d bytes "
573 +                       "to 0x%02x - %d of %d messages\n",
574 +                       pmsg->flags & I2C_M_RD ? "read" : "write",
575 +                       pmsg->len, pmsg->addr, i + 1, num);
576 +
577 +               /* Send START */
578 +               if (i == 0)
579 +                       i2c_start(adap);
580 +
581 +               /* Wait for Bus Busy */
582 +               wait_for_not_bb(adap);
583 +
584 +               MCF_I2CR |= MCF_I2CR_MTX;
585 +
586 +               ret = i2c_set_addr(adap, pmsg, i2c_adap->retries);
587 +               if (ret < 0)
588 +                       return ret;
589 +
590 +               /* Wait for address transfer completion */
591 +               wait_xfer_done(adap);
592 +
593 +               /* Check for ACK */
594 +               if (!i2c_getack(adap)) {
595 +                       i2c_stop(adap);
596 +                       wait_for_bb(adap);
597 +                       printk(KERN_DEBUG "i2c-algo-mcf: No ack after "
598 +                                   "send address in mcf_xfer\n");
599 +                       return (-EREMOTEIO);
600 +               }
601 +
602 +               printk(KERN_DEBUG "i2c-algo-mcf: Msg %d, "
603 +                                 "addr = 0x%x, flags = 0x%x, len = %d\n",
604 +                               i, msgs[i].addr, msgs[i].flags, msgs[i].len);
605 +               /* Read */
606 +               if (pmsg->flags & I2C_M_RD) {
607 +                       /* read bytes into buffer*/
608 +                       ret = mcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
609 +                                               (i + 1 == num));
610 +
611 +                       if (ret != pmsg->len) {
612 +                               printk(KERN_DEBUG "i2c-algo-mcf: fail: "
613 +                                           "only read %d bytes.\n", ret);
614 +                       } else {
615 +                               printk(KERN_DEBUG "i2c-algo-mcf: "
616 +                                                 "read %d bytes.\n", ret);
617 +                       }
618 +               } else {
619 +                       /* write bytes into buffer*/
620 +                       ret = mcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
621 +                                               (i + 1 == num));
622 +                       if (ret != pmsg->len) {
623 +                               printk(KERN_DEBUG "i2c-algo-mcf: fail: "
624 +                                           "only wrote %d bytes.\n", ret);
625 +                       } else {
626 +                               printk(KERN_DEBUG "i2c-algo-mcf: wrote"
627 +                                       "%d bytes.\n", ret);
628 +                       }
629 +               }
630 +       }
631 +
632 +       /* Disable I2C module */
633 +       MCF_I2CR = 0;
634 +       return (i);
635 +}
636 +
637 +
638 +/*
639 + *  static void mcf_func()
640 + *
641 + *  Return algorithm funtionality
642 + */
643 +static u32
644 +mcf_func(
645 +       struct i2c_adapter *i2c_adap
646 +) {
647 +       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
648 +}
649 +
650 +/*
651 + *  ColdFire bus algorithm callbacks
652 + */
653 +static struct i2c_algorithm mcf_algo = {
654 +       .master_xfer    = mcf_xfer,
655 +       .functionality  = mcf_func,
656 +};
657 +
658 +/***********************************************************/
659 +struct coldfire_i2c {
660 +       void __iomem *base;
661 +       struct resource *irqarea;
662 +       struct resource *ioarea;
663 +       u32 irq;
664 +       struct i2c_adapter *adap;
665 +       u32 flags;
666 +};
667 +
668 +/*
669 + *  registering functions to load algorithms at runtime
670 + */
671 +int i2c_mcf_add_bus(struct i2c_adapter *adap)
672 +{
673 +       struct i2c_algo_mcf_data *mcf_adap = adap->algo_data;
674 +
675 +       /*adap->id |= mcf_algo.id;*/
676 +       adap->algo = &mcf_algo;
677 +       adap->timeout = 100;
678 +
679 +       mcf_i2c_init(mcf_adap);
680 +
681 +#ifdef MODULE
682 +       MOD_INC_USE_COUNT;
683 +#endif
684 +
685 +       i2c_add_adapter(adap);
686 +
687 +       return 0;
688 +}
689 +
690 +static int mcf548x_i2c_probe(struct platform_device *pdev)
691 +{
692 +       struct coldfire_i2c *i2c;
693 +       int rc = 0;
694 +
695 +       /************************************************************/
696 +       i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
697 +       if (!i2c) {
698 +               printk(KERN_ERR "%s kzalloc coldfire_i2c faile\n",
699 +                               __FUNCTION__);
700 +               return -ENOMEM;
701 +       }
702 +       /****************************************************************/
703 +       platform_set_drvdata(pdev, i2c);
704 +
705 +       i2c->adap = &i2c_mcf_board_adapter;
706 +       i2c->adap->dev.parent = &pdev->dev;
707 +       rc = i2c_mcf_add_bus(i2c->adap);
708 +       if (rc < 0) {
709 +               printk(KERN_ERR "%s - failed to add adapter\n", __FUNCTION__);
710 +               rc = -ENODEV;
711 +               goto fail_add;
712 +       }
713 +
714 +       printk(KERN_INFO "i2c-algo-mcf.o: I2C ColdFire algorithm"
715 +                       " module is loaded.\n");
716 +       return rc;
717 +
718 +fail_add:
719 +       kfree(i2c);
720 +       return rc;
721 +};
722 +
723 +static int mcf548x_i2c_remove(struct platform_device *pdev)
724 +{
725 +       struct coldfire_i2c *i2c = platform_get_drvdata(pdev);
726 +
727 +       i2c_del_adapter(i2c->adap);
728 +       platform_set_drvdata(pdev, NULL);
729 +       iounmap(i2c->base);
730 +       kfree(i2c);
731 +       return 0;
732 +};
733 +
734 +/* Structure for a device driver */
735 +static struct platform_driver mcf548x_i2c_driver = {
736 +       .probe  = mcf548x_i2c_probe,
737 +       .remove = mcf548x_i2c_remove,
738 +       .driver = {
739 +               .owner = THIS_MODULE,
740 +               .name = "MCF548X-i2c",
741 +       },
742 +};
743 +
744 +static int __init coldfire_i2c_init(void)
745 +{
746 +       return platform_driver_register(&mcf548x_i2c_driver);
747 +}
748 +
749 +static void __exit coldfire_i2c_exit(void)
750 +{
751 +       platform_driver_unregister(&mcf548x_i2c_driver);
752 +}
753 +
754 +module_init(coldfire_i2c_init);
755 +module_exit(coldfire_i2c_exit);
756 +
757 +MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
758 +MODULE_DESCRIPTION
759 +    ("I2C-Bus adapter for MCF547x and MCF548x processors");
760 +MODULE_LICENSE("GPL");
761 --- /dev/null
762 +++ b/include/asm-m68k/m5485i2c.h
763 @@ -0,0 +1,45 @@
764 +/*
765 + *     m5485i2c.h -- ColdFire 547x/548x i2c controller support.
766 + */
767 +#ifndef M548X_I2C_H
768 +#define M548X_I2C_H
769 +
770 +/* Register read/write macros */
771 +#define MCF_I2AR     MCF_REG08(0x008F00)       /* I2C Address           */
772 +#define MCF_I2FDR    MCF_REG08(0x008F04)       /* I2C Frequency Divider */
773 +#define MCF_I2CR     MCF_REG08(0x008F08)       /* I2C Control           */
774 +#define MCF_I2SR     MCF_REG08(0x008F0C)       /* I2C Status            */
775 +#define MCF_I2DR     MCF_REG08(0x008F10)       /* I2C Data I/O          */
776 +#define MCF_I2ICR    MCF_REG08(0x008F20)       /* I2C Interrupt Control */
777 +
778 +/* Bit definitions and macros for MCF_I2C_I2AR */
779 +#define MCF_I2AR_ADR(x)    (((x)&0x7F)<<1)
780 +
781 +/* Bit definitions and macros for MCF_I2C_I2FDR */
782 +#define MCF_I2FDR_IC(x)    (((x)&0x3F)<<0)
783 +
784 +/* Bit definitions and macros for MCF_I2C_I2CR */
785 +#define MCF_I2CR_RSTA      (0x04)
786 +#define MCF_I2CR_TXAK      (0x08)
787 +#define MCF_I2CR_MTX       (0x10)
788 +#define MCF_I2CR_MSTA      (0x20)
789 +#define MCF_I2CR_IIEN      (0x40)
790 +#define MCF_I2CR_IEN       (0x80)
791 +
792 +/* Bit definitions and macros for MCF_I2C_I2SR */
793 +#define MCF_I2SR_RXAK      (0x01)
794 +#define MCF_I2SR_IIF       (0x02)
795 +#define MCF_I2SR_SRW       (0x04)
796 +#define MCF_I2SR_IAL       (0x10)
797 +#define MCF_I2SR_IBB       (0x20)
798 +#define MCF_I2SR_IAAS      (0x40)
799 +#define MCF_I2SR_ICF       (0x80)
800 +
801 +/* Bit definitions and macros for MCF_I2C_I2ICR */
802 +#define MCF_I2ICR_IE       (0x01)
803 +#define MCF_I2ICR_RE       (0x02)
804 +#define MCF_I2ICR_TE       (0x04)
805 +#define MCF_I2ICR_BNBE     (0x08)
806 +
807 +/********************************************************************/
808 +#endif