bcm47xx: Add basic 2.6.32 support.
[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
This page took 0.074091 seconds and 5 git commands to generate.