diff options
author | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-11-22 13:31:46 +0000 |
---|---|---|
committer | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-11-22 13:31:46 +0000 |
commit | 02028358c7be16b3a798973bd88432ca68cfdfdf (patch) | |
tree | a5e99f7798071ae6ca4b0fbd43d490c0987393db /target/linux/coldfire/patches/055-m547x_8x_i2c.patch | |
parent | 12a0868f9234d1b7cbf7141959276c809169819b (diff) |
[coldfire]: remove 2.6.25 support
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@24088 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/coldfire/patches/055-m547x_8x_i2c.patch')
-rw-r--r-- | target/linux/coldfire/patches/055-m547x_8x_i2c.patch | 808 |
1 files changed, 0 insertions, 808 deletions
diff --git a/target/linux/coldfire/patches/055-m547x_8x_i2c.patch b/target/linux/coldfire/patches/055-m547x_8x_i2c.patch deleted file mode 100644 index 0a2a277d3..000000000 --- a/target/linux/coldfire/patches/055-m547x_8x_i2c.patch +++ /dev/null @@ -1,808 +0,0 @@ -From ce57fc22543d0ee0ca33157264815a52fc8cf9a3 Mon Sep 17 00:00:00 2001 -From: Kurt Mahan <kmahan@freescale.com> -Date: Thu, 15 May 2008 13:23:27 -0600 -Subject: [PATCH] Add I2C bus driver for MCF547x and MCF548x. - -LTIBName: m547x-8x-i2c -Signed-off-by: Kurt Mahan <kmahan@freescale.com> -Signed-off-by: Shrek Wu <b16972@freescale.com> ---- - arch/m68k/coldfire/Makefile | 1 + - arch/m68k/coldfire/mcf548x-devices.c | 94 ++++++ - drivers/i2c/busses/Kconfig | 12 + - drivers/i2c/busses/Makefile | 1 + - drivers/i2c/busses/i2c-algo-mcf.h | 23 ++ - drivers/i2c/busses/i2c-mcf548x.c | 573 ++++++++++++++++++++++++++++++++++ - include/asm-m68k/m5485i2c.h | 45 +++ - 7 files changed, 749 insertions(+), 0 deletions(-) - create mode 100644 arch/m68k/coldfire/mcf548x-devices.c - create mode 100644 drivers/i2c/busses/i2c-algo-mcf.h - create mode 100644 drivers/i2c/busses/i2c-mcf548x.c - create mode 100644 include/asm-m68k/m5485i2c.h - ---- a/arch/m68k/coldfire/Makefile -+++ b/arch/m68k/coldfire/Makefile -@@ -11,4 +11,5 @@ endif - obj-$(CONFIG_PCI) += pci.o mcf5445x-pci.o iomap.o - obj-$(CONFIG_M54455) += mcf5445x-devices.o - obj-$(CONFIG_M547X_8X) += m547x_8x-devices.o -+obj-$(CONFIG_M547X_8X) += mcf548x-devices.o - obj-$(CONFIG_MCD_DMA) += m547x_8x-dma.o ---- /dev/null -+++ b/arch/m68k/coldfire/mcf548x-devices.c -@@ -0,0 +1,94 @@ -+/* -+ * arch/m68k/coldfire/mcf5445x-devices.c -+ * -+ * Coldfire M5445x Platform Device Configuration -+ * -+ * Based on the Freescale MXC devices.c -+ * -+ * Copyright (c) 2007 Freescale Semiconductor, Inc. -+ * Kurt Mahan <kmahan@freescale.com> -+ */ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/mtd/physmap.h> -+#include <linux/platform_device.h> -+#include <linux/fsl_devices.h> -+ -+#include <asm/coldfire.h> -+#include <asm/mcfsim.h> -+ -+static struct resource coldfire_i2c_resources[] = { -+ [0] = { /* I/O */ -+ .start = MCF_MBAR + 0x008F00, -+ .end = MCF_MBAR + 0x008F20, -+ .flags = IORESOURCE_MEM, -+ }, -+ [2] = { /* IRQ */ -+ .start = 40, -+ .end = 40, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct platform_device coldfire_i2c_device = { -+ .name = "MCF548X-i2c", -+ .id = -1, -+ .num_resources = ARRAY_SIZE(coldfire_i2c_resources), -+ .resource = coldfire_i2c_resources, -+}; -+ -+static struct resource coldfire_sec_resources[] = { -+ [0] = { /* I/O */ -+ .start = MCF_MBAR + 0x00020000, -+ .end = MCF_MBAR + 0x00033000, -+ .flags = IORESOURCE_MEM, -+ }, -+ [2] = { /* IRQ */ -+ .start = ISC_SEC, -+ .end = ISC_SEC, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct platform_device coldfire_sec_device = { -+ .name = "fsl-sec1", -+ .id = -1, -+ .num_resources = ARRAY_SIZE(coldfire_sec_resources), -+ .resource = coldfire_sec_resources, -+}; -+ -+#if defined(CONFIG_MTD_PHYSMAP) -+static struct physmap_flash_data mcf5485_flash_data = { -+ .width = 2, -+}; -+ -+static struct resource mcf5485_flash_resource = { -+ .start = 0xf8000000, -+ .end = 0xf80fffff, -+ .flags = IORESOURCE_MEM, -+}; -+ -+static struct platform_device mcf5485_flash_device = { -+ .name = "physmap-flash", -+ .id = 0, -+ .dev = { -+ .platform_data = &mcf5485_flash_data, -+ }, -+ .num_resources = 1, -+ .resource = &mcf5485_flash_resource, -+}; -+#endif -+ -+static int __init mcf5485_init_devices(void) -+{ -+ printk(KERN_INFO "MCF5485x INIT_DEVICES\n"); -+ -+ platform_device_register(&coldfire_i2c_device); -+ platform_device_register(&coldfire_sec_device); -+/*#if defined(CONFIG_MTD_PHYSMAP) -+ platform_device_register(&mcf5485_flash_device); -+#endif*/ -+ return 0; -+} -+arch_initcall(mcf5485_init_devices); ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -4,6 +4,18 @@ - - menu "I2C Hardware Bus support" - -+config I2C_MCF548x -+ tristate "I2C MCF547x/548x interfaces" -+ depends on I2C -+ help -+ This allows you to use the I2C adapters found on the Freescale -+ MCF547x/548x microcontrollers. -+ Say Y if you own an I2C adapter belonging to this class and then say -+ Y to the specific driver for you adapter below. -+ -+ This support is also available as a module. If so, the module -+ will be called i2c-algo-mcf. -+ - config I2C_ALI1535 - tristate "ALI 1535" - depends on PCI ---- a/drivers/i2c/busses/Makefile -+++ b/drivers/i2c/busses/Makefile -@@ -52,6 +52,7 @@ obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o - obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o - obj-$(CONFIG_SCx200_ACB) += scx200_acb.o - obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o -+obj-$(CONFIG_I2C_MCF548x) += i2c-mcf548x.o - - ifeq ($(CONFIG_I2C_DEBUG_BUS),y) - EXTRA_CFLAGS += -DDEBUG ---- /dev/null -+++ b/drivers/i2c/busses/i2c-algo-mcf.h -@@ -0,0 +1,23 @@ -+#ifndef I2C_ALGO_MCF_H -+#define I2C_ALGO_MCF_H 1 -+ -+/* --- Defines for pcf-adapters --------------------------------------- */ -+#include <linux/i2c.h> -+ -+struct i2c_algo_mcf_data { -+ void *data; /* private data for lolevel routines */ -+ void (*setmcf) (void *data, int ctl, int val); -+ int (*getmcf) (void *data, int ctl); -+ int (*getown) (void *data); -+ int (*getclock) (void *data); -+ void (*waitforpin) (void); -+ /* local settings */ -+ int udelay; -+ int mdelay; -+ int timeout; -+}; -+ -+int i2c_mcf_add_bus(struct i2c_adapter *); -+int i2c_mcf_del_bus(struct i2c_adapter *); -+ -+#endif /* I2C_ALGO_MCF_H */ ---- /dev/null -+++ b/drivers/i2c/busses/i2c-mcf548x.c -@@ -0,0 +1,573 @@ -+/* -+ * Performance and stability improvements: (C) Copyright 2008, -+ * Adrian Cox <adrian@humboldt.co.uk> -+ * ColdFire 547x/548x I2C master support -+ * Shrek Wu (b16972@freescale.com )moved the code driver/i2c/alg/mcf.c -+ * into driver/i2c/busses.And changed the driver to a platform driver. -+ */ -+#include <linux/i2c.h> -+#include "i2c-algo-mcf.h" -+ -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/delay.h> -+#include <linux/platform_device.h> -+#include <linux/sched.h> -+#include <linux/interrupt.h> -+#include <asm/io.h> -+ -+#include <asm/coldfire.h> -+#include <asm/m5485sim.h> -+#include <asm/m5485i2c.h> -+ -+#define get_clock(adap) (clock) -+#define get_own(adap) (own) -+ -+static int clock = 0x3b; /*50000 / 1024 ~ 49 KHz*/ -+module_param(clock, int, 0); -+MODULE_PARM_DESC(clock, -+ "Set I2C clock in kHz: 400=fast mode (default == 49khz)"); -+ -+static int own = 0x78; -+module_param(own, int, 0); -+MODULE_PARM_DESC(clock, "Set I2C Master controller address(0x78)"); -+ -+static struct i2c_algo_mcf_data i2c_mcf_board_data = { -+ .timeout = 10000, -+}; -+ -+static struct i2c_adapter i2c_mcf_board_adapter = { -+ .owner = THIS_MODULE, -+ .name = "MCF5485 adapter", -+ .id = I2C_HW_MPC107, -+ .algo_data = &i2c_mcf_board_data, -+ .class = I2C_CLASS_HWMON, -+ .timeout = 1, -+ .retries = 1 -+}; -+/* -+ * static void i2c_start() -+ * -+ * Generates START signal -+ */ -+static void -+i2c_start( -+ struct i2c_algo_mcf_data *adap -+) { -+ MCF_I2CR |= MCF_I2CR_MSTA; -+} -+ -+ -+/* -+ * static void i2c_stop() -+ * -+ * Generates STOP signal -+ */ -+static void -+i2c_stop( -+ struct i2c_algo_mcf_data *adap -+) { -+ MCF_I2CR &= ~MCF_I2CR_MSTA; -+} -+ -+static int -+i2c_getack( -+ struct i2c_algo_mcf_data *adap -+) { -+ return !(MCF_I2SR & MCF_I2SR_RXAK); -+} -+ -+/* -+ * static void i2c_repstart() -+ * -+ * Generates repeated start signal (without STOP while mastering the bus) -+ */ -+static void -+i2c_repstart( -+ struct i2c_algo_mcf_data *adap -+) { -+ MCF_I2CR |= MCF_I2CR_RSTA; -+ MCF_I2CR |= MCF_I2CR_MTX; -+} -+ -+ -+/* -+ * static void wait_for_bb() -+ * -+ * Wait for bus idle state -+ */ -+static int -+wait_for_bb( -+ struct i2c_algo_mcf_data *adap -+) { -+ int i; -+ for (i = 0; i < adap->timeout; i++) { -+ if (!(MCF_I2SR & MCF_I2SR_IBB)) -+ return 0; -+ udelay(10); -+ } -+ printk(KERN_ERR "%s: timeout", __FUNCTION__); -+ return -ETIMEDOUT; -+} -+ -+/* -+ * static void wait_for_not_bb() -+ * -+ * Wait for bus busy state -+ */ -+static int -+wait_for_not_bb( -+ struct i2c_algo_mcf_data *adap -+) { -+ int i; -+ for (i = 0; i < adap->timeout; i++) { -+ if (MCF_I2SR & MCF_I2SR_IBB) -+ return 0; -+ udelay(10); -+ } -+ printk(KERN_ERR "%s: timeout", __FUNCTION__); -+ return -ETIMEDOUT; -+} -+ -+/* -+ * static void wait_xfer_done() -+ * -+ * Wait for transfer to complete -+ */ -+static int -+wait_xfer_done( -+ struct i2c_algo_mcf_data *adap -+) { -+ int i; -+ -+ for (i = 0; i < adap->timeout; i++) { -+ if (MCF_I2SR & MCF_I2SR_IIF) { -+ MCF_I2SR &= ~MCF_I2SR_IIF; -+ return 0; -+ } -+ udelay(1); -+ } -+ printk(KERN_ERR "%s: timeout", __FUNCTION__); -+ return -ETIMEDOUT; -+} -+ -+ -+/* -+ * static void i2c_set_addr() -+ * -+ * Sets slave address to communicate -+ */ -+static int -+i2c_set_addr( -+ struct i2c_algo_mcf_data *adap, -+ struct i2c_msg *msg, -+ int retries -+) { -+ unsigned short flags = msg->flags; -+ unsigned char addr; -+ -+ if ((flags & I2C_M_TEN)) { -+ /* 10 bit address not supported yet */ -+ return -EIO; -+ } else { -+ /* normal 7bit address */ -+ addr = (msg->addr << 1); -+ if (flags & I2C_M_RD) -+ addr |= 1; -+ if (flags & I2C_M_REV_DIR_ADDR) -+ addr ^= 1; -+ -+ MCF_I2DR = addr; -+ } -+ return 0; -+} -+ -+ -+/* -+ * static void mcf_i2c_init() -+ * -+ * Perform ColdFire i2c initialization -+ */ -+static void -+mcf_i2c_init(struct i2c_algo_mcf_data *adap) -+{ -+ u8 dummy; -+ /* Setup GPIO lines */ -+ MCF_PAR_FECI2CIRQ |= MCF_PAR_SDA; -+ MCF_PAR_FECI2CIRQ |= MCF_PAR_SCL; -+ -+ /* Ensure slaves are in idle state */ -+ if (MCF_I2SR & MCF_I2SR_IBB) { -+ MCF_I2ICR = 0x00; -+ MCF_I2CR = 0x00; -+ MCF_I2CR = 0x0A; -+ dummy = MCF_I2DR; -+ MCF_I2SR = 0x00; -+ MCF_I2CR = 0x00; -+ MCF_I2ICR = 0x01; -+ } -+ -+ /* setup SCL clock */ -+ MCF_I2FDR = get_clock(adap); -+ -+ /* set slave address */ -+ MCF_I2AR = get_own(adap); -+ -+ /* enable I2C module */ -+ MCF_I2CR = MCF_I2CR_IEN; -+} -+ -+static int i2c_outb( -+ struct i2c_adapter *i2c_adap, -+ char c -+) { -+ -+ struct i2c_algo_mcf_data *adap = i2c_adap->algo_data; -+ int timeout; -+ /* Put data to be sent */ -+ MCF_I2DR = c; -+ /* Wait for xfer completed*/ -+ timeout = wait_xfer_done(adap); -+ if (timeout) { -+ i2c_stop(adap); -+ wait_for_bb(adap); -+ printk(KERN_ERR "i2c-algo-mcf: %s i2c_write: " -+ "error - timeout.\n", i2c_adap->name); -+ return -EREMOTEIO; /* got a better one ?? */ -+ } -+ -+ return 0; -+} -+ -+ -+/* -+ * static void mcf_sendbytes() -+ * -+ * Perform tx data transfer -+ */ -+static int -+mcf_sendbytes( -+ struct i2c_adapter *i2c_adap, -+ const char *buf, -+ int count, int last -+) { -+ struct i2c_algo_mcf_data *adap = i2c_adap->algo_data; -+ int ret, i; -+ -+ /* Set master TX mode */ -+ MCF_I2CR |= MCF_I2CR_MTX; -+ -+ for (i = 0; i < count; ++i) { -+ printk(KERN_DEBUG "i2c-algo-mcf: %s i2c_write: writing %2.2X\n", -+ i2c_adap->name, buf[i]&0xff); -+ ret = i2c_outb(i2c_adap, buf[i]); -+ if (ret < 0) -+ return ret; -+ } -+ if (last) { -+ i2c_stop(adap); -+ wait_for_bb(adap); -+ } else { -+ i2c_repstart(adap); -+ } -+ -+ return (i); -+} -+ -+ -+/* -+ * static void mcf_readbytes() -+ * -+ * Perform rx data transfer -+ */ -+static int -+mcf_readbytes( -+ struct i2c_adapter *i2c_adap, -+ char *buf, -+ int count, int last -+) { -+ int i; -+ struct i2c_algo_mcf_data *adap = i2c_adap->algo_data; -+ u8 dummy; -+ -+ /* Set master RX mode */ -+ MCF_I2CR &= ~MCF_I2CR_MTX; -+ MCF_I2CR &= ~MCF_I2CR_TXAK; -+ dummy = MCF_I2DR; -+ -+ for (i = 0; i < count-1; i++) { -+ if (wait_xfer_done(adap)) { -+ i2c_stop(adap); -+ wait_for_bb(adap); -+ printk(KERN_DEBUG -+ "i2c-algo-mcf: mcf_readbytes timed out.\n"); -+ return (-1); -+ } -+ -+ /* store next data byte */ -+ buf[i] = MCF_I2DR; -+ } -+ -+ if (wait_xfer_done(adap)) { -+ i2c_stop(adap); -+ wait_for_bb(adap); -+ printk(KERN_DEBUG "i2c-algo-mcf: mcf_readbytes timed out.\n"); -+ return (-1); -+ } -+ -+ /* Disable acknowlege (set I2CR.TXAK) */ -+ MCF_I2CR |= MCF_I2CR_TXAK; -+ buf[i] = MCF_I2DR; -+ if (wait_xfer_done(adap)) { -+ i2c_stop(adap); -+ wait_for_bb(adap); -+ printk(KERN_DEBUG "i2c-algo-mcf: mcf_readbytes timed out.\n"); -+ return (-1); -+ } -+ -+ if (last) { -+ i2c_stop(adap); -+ wait_for_bb(adap); -+ } else { -+ i2c_repstart(adap); -+ } -+ -+ return (i+1); -+} -+ -+ -+/* -+ * static void mcf_xfer() -+ * -+ * Perform master data I/O transfer -+ */ -+static int -+mcf_xfer( -+ struct i2c_adapter *i2c_adap, -+ struct i2c_msg *msgs, -+ int num -+) { -+ struct i2c_algo_mcf_data *adap = i2c_adap->algo_data; -+ struct i2c_msg *pmsg; -+ int i; -+ int ret = 0, timeout; -+ -+ /* Skip own address */ -+ if (get_own(adap) == (msgs[0].addr << 1)) -+ return -EIO; -+ -+ /* Ensure slaves are in idle state */ -+ if (MCF_I2SR & MCF_I2SR_IBB) { -+ MCF_I2ICR = 0x00; -+ MCF_I2CR = 0x00; -+ MCF_I2CR = 0x0A; -+ timeout = MCF_I2DR; -+ MCF_I2SR = 0x00; -+ MCF_I2CR = 0x00; -+ MCF_I2ICR = 0x01; -+ } -+ /* setup SCL clock */ -+ MCF_I2FDR = get_clock(adap); -+ /* set slave address */ -+ MCF_I2AR = get_own(adap); -+ /* enable I2C module */ -+ MCF_I2CR = MCF_I2CR_IEN; -+ -+ MCF_I2CR |= MCF_I2CR_TXAK; -+ -+ /* Check for bus busy */ -+ wait_for_bb(adap); -+ -+ for (i = 0; ret >= 0 && i < num; i++) { -+ pmsg = &msgs[i]; -+ -+ printk(KERN_DEBUG "i2c-algo-mcf: Doing %s %d bytes " -+ "to 0x%02x - %d of %d messages\n", -+ pmsg->flags & I2C_M_RD ? "read" : "write", -+ pmsg->len, pmsg->addr, i + 1, num); -+ -+ /* Send START */ -+ if (i == 0) -+ i2c_start(adap); -+ -+ /* Wait for Bus Busy */ -+ wait_for_not_bb(adap); -+ -+ MCF_I2CR |= MCF_I2CR_MTX; -+ -+ ret = i2c_set_addr(adap, pmsg, i2c_adap->retries); -+ if (ret < 0) -+ return ret; -+ -+ /* Wait for address transfer completion */ -+ wait_xfer_done(adap); -+ -+ /* Check for ACK */ -+ if (!i2c_getack(adap)) { -+ i2c_stop(adap); -+ wait_for_bb(adap); -+ printk(KERN_DEBUG "i2c-algo-mcf: No ack after " -+ "send address in mcf_xfer\n"); -+ return (-EREMOTEIO); -+ } -+ -+ printk(KERN_DEBUG "i2c-algo-mcf: Msg %d, " -+ "addr = 0x%x, flags = 0x%x, len = %d\n", -+ i, msgs[i].addr, msgs[i].flags, msgs[i].len); -+ /* Read */ -+ if (pmsg->flags & I2C_M_RD) { -+ /* read bytes into buffer*/ -+ ret = mcf_readbytes(i2c_adap, pmsg->buf, pmsg->len, -+ (i + 1 == num)); -+ -+ if (ret != pmsg->len) { -+ printk(KERN_DEBUG "i2c-algo-mcf: fail: " -+ "only read %d bytes.\n", ret); -+ } else { -+ printk(KERN_DEBUG "i2c-algo-mcf: " -+ "read %d bytes.\n", ret); -+ } -+ } else { -+ /* write bytes into buffer*/ -+ ret = mcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len, -+ (i + 1 == num)); -+ if (ret != pmsg->len) { -+ printk(KERN_DEBUG "i2c-algo-mcf: fail: " -+ "only wrote %d bytes.\n", ret); -+ } else { -+ printk(KERN_DEBUG "i2c-algo-mcf: wrote" -+ "%d bytes.\n", ret); -+ } -+ } -+ } -+ -+ /* Disable I2C module */ -+ MCF_I2CR = 0; -+ return (i); -+} -+ -+ -+/* -+ * static void mcf_func() -+ * -+ * Return algorithm funtionality -+ */ -+static u32 -+mcf_func( -+ struct i2c_adapter *i2c_adap -+) { -+ return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; -+} -+ -+/* -+ * ColdFire bus algorithm callbacks -+ */ -+static struct i2c_algorithm mcf_algo = { -+ .master_xfer = mcf_xfer, -+ .functionality = mcf_func, -+}; -+ -+/***********************************************************/ -+struct coldfire_i2c { -+ void __iomem *base; -+ struct resource *irqarea; -+ struct resource *ioarea; -+ u32 irq; -+ struct i2c_adapter *adap; -+ u32 flags; -+}; -+ -+/* -+ * registering functions to load algorithms at runtime -+ */ -+int i2c_mcf_add_bus(struct i2c_adapter *adap) -+{ -+ struct i2c_algo_mcf_data *mcf_adap = adap->algo_data; -+ -+ /*adap->id |= mcf_algo.id;*/ -+ adap->algo = &mcf_algo; -+ adap->timeout = 100; -+ -+ mcf_i2c_init(mcf_adap); -+ -+#ifdef MODULE -+ MOD_INC_USE_COUNT; -+#endif -+ -+ i2c_add_adapter(adap); -+ -+ return 0; -+} -+ -+static int mcf548x_i2c_probe(struct platform_device *pdev) -+{ -+ struct coldfire_i2c *i2c; -+ int rc = 0; -+ -+ /************************************************************/ -+ i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); -+ if (!i2c) { -+ printk(KERN_ERR "%s kzalloc coldfire_i2c faile\n", -+ __FUNCTION__); -+ return -ENOMEM; -+ } -+ /****************************************************************/ -+ platform_set_drvdata(pdev, i2c); -+ -+ i2c->adap = &i2c_mcf_board_adapter; -+ i2c->adap->dev.parent = &pdev->dev; -+ rc = i2c_mcf_add_bus(i2c->adap); -+ if (rc < 0) { -+ printk(KERN_ERR "%s - failed to add adapter\n", __FUNCTION__); -+ rc = -ENODEV; -+ goto fail_add; -+ } -+ -+ printk(KERN_INFO "i2c-algo-mcf.o: I2C ColdFire algorithm" -+ " module is loaded.\n"); -+ return rc; -+ -+fail_add: -+ kfree(i2c); -+ return rc; -+}; -+ -+static int mcf548x_i2c_remove(struct platform_device *pdev) -+{ -+ struct coldfire_i2c *i2c = platform_get_drvdata(pdev); -+ -+ i2c_del_adapter(i2c->adap); -+ platform_set_drvdata(pdev, NULL); -+ iounmap(i2c->base); -+ kfree(i2c); -+ return 0; -+}; -+ -+/* Structure for a device driver */ -+static struct platform_driver mcf548x_i2c_driver = { -+ .probe = mcf548x_i2c_probe, -+ .remove = mcf548x_i2c_remove, -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "MCF548X-i2c", -+ }, -+}; -+ -+static int __init coldfire_i2c_init(void) -+{ -+ return platform_driver_register(&mcf548x_i2c_driver); -+} -+ -+static void __exit coldfire_i2c_exit(void) -+{ -+ platform_driver_unregister(&mcf548x_i2c_driver); -+} -+ -+module_init(coldfire_i2c_init); -+module_exit(coldfire_i2c_exit); -+ -+MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>"); -+MODULE_DESCRIPTION -+ ("I2C-Bus adapter for MCF547x and MCF548x processors"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/include/asm-m68k/m5485i2c.h -@@ -0,0 +1,45 @@ -+/* -+ * m5485i2c.h -- ColdFire 547x/548x i2c controller support. -+ */ -+#ifndef M548X_I2C_H -+#define M548X_I2C_H -+ -+/* Register read/write macros */ -+#define MCF_I2AR MCF_REG08(0x008F00) /* I2C Address */ -+#define MCF_I2FDR MCF_REG08(0x008F04) /* I2C Frequency Divider */ -+#define MCF_I2CR MCF_REG08(0x008F08) /* I2C Control */ -+#define MCF_I2SR MCF_REG08(0x008F0C) /* I2C Status */ -+#define MCF_I2DR MCF_REG08(0x008F10) /* I2C Data I/O */ -+#define MCF_I2ICR MCF_REG08(0x008F20) /* I2C Interrupt Control */ -+ -+/* Bit definitions and macros for MCF_I2C_I2AR */ -+#define MCF_I2AR_ADR(x) (((x)&0x7F)<<1) -+ -+/* Bit definitions and macros for MCF_I2C_I2FDR */ -+#define MCF_I2FDR_IC(x) (((x)&0x3F)<<0) -+ -+/* Bit definitions and macros for MCF_I2C_I2CR */ -+#define MCF_I2CR_RSTA (0x04) -+#define MCF_I2CR_TXAK (0x08) -+#define MCF_I2CR_MTX (0x10) -+#define MCF_I2CR_MSTA (0x20) -+#define MCF_I2CR_IIEN (0x40) -+#define MCF_I2CR_IEN (0x80) -+ -+/* Bit definitions and macros for MCF_I2C_I2SR */ -+#define MCF_I2SR_RXAK (0x01) -+#define MCF_I2SR_IIF (0x02) -+#define MCF_I2SR_SRW (0x04) -+#define MCF_I2SR_IAL (0x10) -+#define MCF_I2SR_IBB (0x20) -+#define MCF_I2SR_IAAS (0x40) -+#define MCF_I2SR_ICF (0x80) -+ -+/* Bit definitions and macros for MCF_I2C_I2ICR */ -+#define MCF_I2ICR_IE (0x01) -+#define MCF_I2ICR_RE (0x02) -+#define MCF_I2ICR_TE (0x04) -+#define MCF_I2ICR_BNBE (0x08) -+ -+/********************************************************************/ -+#endif |