All of lore.kernel.org
 help / color / mirror / Atom feed
* I2C on mpc8248 / device tree
@ 2007-11-13 23:39 Alan Bennett
  2007-11-13 23:56 ` Jon Smirl
  2007-11-14  7:17 ` Kumar Gala
  0 siblings, 2 replies; 9+ messages in thread
From: Alan Bennett @ 2007-11-13 23:39 UTC (permalink / raw)
  To: Scott Wood, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1093 bytes --]

I've got four devices on i2c that I need to read.  Simple thermal and
voltage monitors.  I2c works fine in uboot, and now I'm trying to get things
to work in linux.

In the kernel .config I enable
  I2C
and
  I2C_MPC

During the platform boot code:
I init the IO ports for i2c, (same as ep8248e code)
    {3, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
    {3, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY},

__Do I need to configure a brg for the i2c along with the other devices ?
i.e. cpm2_clk_setup ?


Next, I'm sure my device tree needs work, but my first stab adds i2c onto
the SOC @ 11860  (immr+11860= I2c mode register) and interrupt 1.
       soc@e0000000 {
               ...
               cpm@119c0 {
               ...
               i2c@11860 {
                   device_type = "i2c";
                   compatible = "fsl-i2c";
                   reg = <11860 18>;
                   interrupts = <1 3>;
                   interrupt-parent = <&PIC>;
               };

After Cleaning up these routines and descriptions, would I be expected to
continue using the /dev/i2c- entries?

-Alan

[-- Attachment #2: Type: text/html, Size: 2054 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: I2C on mpc8248 / device tree
  2007-11-13 23:39 I2C on mpc8248 / device tree Alan Bennett
@ 2007-11-13 23:56 ` Jon Smirl
  2007-11-14 15:31   ` Alan Bennett
  2007-11-14  7:17 ` Kumar Gala
  1 sibling, 1 reply; 9+ messages in thread
From: Jon Smirl @ 2007-11-13 23:56 UTC (permalink / raw)
  To: Alan Bennett; +Cc: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 397 bytes --]

I am working on a patch for i2c and device tree. I attached the current version.

DTC entry looks like this.

		i2c@3d40 {
			compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c";
			reg = <3d40 40>;
			interrupts = <2 10 0>;
			interrupt-parent = <&mpc5200_pic>;
			fsl5200-clocking;

			rtc@51f {
				compatible = "epson,rtc8564";
				reg = <51>;
			};
		};
		


-- 
Jon Smirl
jonsmirl@gmail.com

[-- Attachment #2: jds-i2c-list --]
[-- Type: application/octet-stream, Size: 9036 bytes --]

Extend i2c-core to support lists of device tree compatible names when matching drivers

From: Jon Smirl <jonsmirl@gmail.com>

Patch creates a new field, aliases, in the i2c_driver structure. i2c chip device drivers can use this field to add alias names. For example in Open Firmware format: "ricoh,rs5c372a". Three drivers implement alias names as an example. fsl_soc.c is adjusted to remove private mapping mechanism and use this more general form.
---

 arch/powerpc/sysdev/fsl_soc.c |   46 ++++++-----------------------------------
 drivers/i2c/i2c-core.c        |   16 +++++++++++++-
 drivers/rtc/rtc-ds1307.c      |   14 ++++++++++++
 drivers/rtc/rtc-ds1374.c      |    1 +
 drivers/rtc/rtc-pcf8563.c     |    1 +
 drivers/rtc/rtc-rs5c372.c     |   18 +++++++++++++---
 include/linux/i2c.h           |   13 +++++++++---
 7 files changed, 63 insertions(+), 46 deletions(-)


diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 3ace747..cb95a72 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -320,48 +320,12 @@ arch_initcall(gfar_of_init);
 
 #ifdef CONFIG_I2C_BOARDINFO
 #include <linux/i2c.h>
-struct i2c_driver_device {
-	char	*of_device;
-	char	*i2c_driver;
-	char	*i2c_type;
-};
-
-static struct i2c_driver_device i2c_devices[] __initdata = {
-	{"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",},
-	{"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",},
-	{"ricoh,rv5c386",  "rtc-rs5c372", "rv5c386",},
-	{"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",},
-	{"dallas,ds1307",  "rtc-ds1307",  "ds1307",},
-	{"dallas,ds1337",  "rtc-ds1307",  "ds1337",},
-	{"dallas,ds1338",  "rtc-ds1307",  "ds1338",},
-	{"dallas,ds1339",  "rtc-ds1307",  "ds1339",},
-	{"dallas,ds1340",  "rtc-ds1307",  "ds1340",},
-	{"stm,m41t00",     "rtc-ds1307",  "m41t00"},
-	{"dallas,ds1374",  "rtc-ds1374",  "rtc-ds1374",},
-};
-
-static int __init of_find_i2c_driver(struct device_node *node,
-				     struct i2c_board_info *info)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
-		if (!of_device_is_compatible(node, i2c_devices[i].of_device))
-			continue;
-		if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver,
-			    KOBJ_NAME_LEN) >= KOBJ_NAME_LEN ||
-		    strlcpy(info->type, i2c_devices[i].i2c_type,
-			    I2C_NAME_SIZE) >= I2C_NAME_SIZE)
-			return -ENOMEM;
-		return 0;
-	}
-	return -ENODEV;
-}
 
 static void __init of_register_i2c_devices(struct device_node *adap_node,
 					   int bus_num)
 {
 	struct device_node *node = NULL;
+	const char *compatible;
 
 	while ((node = of_get_next_child(adap_node, node))) {
 		struct i2c_board_info info = {};
@@ -378,9 +342,13 @@ static void __init of_register_i2c_devices(struct device_node *adap_node,
 		if (info.irq == NO_IRQ)
 			info.irq = -1;
 
-		if (of_find_i2c_driver(node, &info) < 0)
+		compatible = of_get_property(node, "compatible", &len);
+		if (!compatible) {
+			printk(KERN_WARNING "i2c-mpc.c: invalid entry, missing compatible attribute\n");
 			continue;
-
+		}
+		strncpy(info.name, compatible, sizeof(info.name));
+		
 		info.addr = *addr;
 
 		i2c_register_board_info(bus_num, &info, 1);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 1a4e8dc..8b49860 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -51,6 +51,7 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
 {
 	struct i2c_client	*client = to_i2c_client(dev);
 	struct i2c_driver	*driver = to_i2c_driver(drv);
+	char const **alias;
 
 	/* make legacy i2c drivers bypass driver model probing entirely;
 	 * such drivers scan each i2c adapter/bus themselves.
@@ -61,7 +62,20 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
 	/* new style drivers use the same kind of driver matching policy
 	 * as platform devices or SPI:  compare device and driver IDs.
 	 */
-	return strcmp(client->driver_name, drv->name) == 0;
+	if (strcmp(client->driver_name, drv->name) == 0)
+		return true;
+	
+	/* Match against arrary of alias device tree names. When a match 
+	 * is found change the reference to point at the copy inside the
+	 * chip driver allowing the caller's string to be freed.
+ 	 */
+	alias = driver->aliases;
+	while (alias && *alias) {
+		if (strnicmp(client->driver_name, *alias, sizeof client->driver_name) == 0)
+			return true;
+		alias++;
+	}
+	return 0;	
 }
 
 #ifdef	CONFIG_HOTPLUG
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index db6f3f0..456b7ca 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -135,6 +135,11 @@ static inline const struct chip_desc *find_chip(const char *s)
 	for (i = 0; i < ARRAY_SIZE(chips); i++)
 		if (strnicmp(s, chips[i].name, sizeof chips[i].name) == 0)
 			return &chips[i];
+	/* check the alias names */
+	for (i = ds_1307; i <= m41t00; i++)
+		if (strnicmp(client->driver_name, ds1307_driver.aliases[i], sizeof client->driver_name) == 0)
+			return &chips[i];
+	
 	return NULL;
 }
 
@@ -442,6 +447,15 @@ static struct i2c_driver ds1307_driver = {
 		.name	= "rtc-ds1307",
 		.owner	= THIS_MODULE,
 	},
+	.aliases = (char const *[]){
+		[ds_1307] = "dallas,ds1307", 
+		[ds_1337] = "dallas,ds1337",
+		[ds_1338] = "dallas,ds1338",
+		[ds_1339] = "dallas,ds1339",
+		[ds_1340] = "dallas,ds1340",
+		[m41t00] = "stm,m41t00",
+		0
+	},
 	.probe		= ds1307_probe,
 	.remove		= __devexit_p(ds1307_remove),
 };
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 45bda18..df8eca4 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -427,6 +427,7 @@ static struct i2c_driver ds1374_driver = {
 		.name = "rtc-ds1374",
 		.owner = THIS_MODULE,
 	},
+	.aliases = (char const *[]){"dallas,ds1374", 0},
 	.probe = ds1374_probe,
 	.remove = __devexit_p(ds1374_remove),
 };
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 0242d80..fa04dc5 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -266,6 +266,7 @@ static struct i2c_driver pcf8563_driver = {
 	.driver		= {
 		.name	= "pcf8563",
 	},
+	.aliases = (char const *[]){"philips,pcf8563", "epson,rtc8564", 0},
 	.id		= I2C_DRIVERID_PCF8563,
 	.attach_adapter = &pcf8563_attach,
 	.detach_client	= &pcf8563_detach,
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 6b67b50..b458f5f 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -62,7 +62,6 @@
 
 
 enum rtc_type {
-	rtc_undef = 0,
 	rtc_rs5c372a,
 	rtc_rs5c372b,
 	rtc_rv5c386,
@@ -531,8 +530,14 @@ static int rs5c372_probe(struct i2c_client *client)
 	else if (strcmp(client->name, "rv5c387a") == 0)
 		rs5c372->type = rtc_rv5c387a;
 	else {
-		rs5c372->type = rtc_rs5c372b;
-		dev_warn(&client->dev, "assuming rs5c372b\n");
+		/* check the alias names */
+		for (rs5c372->type = rtc_rs5c372a; rs5c372->type <= rtc_rv5c387a; rs5c372->type++)
+			if (strnicmp(client->driver_name, rs5c372_driver.aliases[rs5c372->type], sizeof client->driver_name) == 0)
+				break;
+		if (rs5c372->type > rtc_rv5c387a) {
+			rs5c372->type = rtc_rs5c372b;
+			dev_warn(&client->dev, "assuming rs5c372b\n");
+		}
 	}
 
 	/* clock may be set for am/pm or 24 hr time */
@@ -649,6 +654,13 @@ static struct i2c_driver rs5c372_driver = {
 	.driver		= {
 		.name	= "rtc-rs5c372",
 	},
+	.aliases	= (char const *[]){
+		[rtc_rs5c372a] = "ricoh,rs5c372a", 
+		[rtc_rs5c372b] = "ricoh,rs5c372b", 
+		[rtc_rv5c386] = "ricoh,rv5c386", 
+		[rtc_rv5c387a] = "ricoh,rv5c387a", 
+		0
+	},
 	.probe		= rs5c372_probe,
 	.remove		= rs5c372_remove,
 };
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 8033e6b..b952c8a 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -105,6 +105,13 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
 struct i2c_driver {
 	int id;
 	unsigned int class;
+	
+	/* Alias names for the driver. Used to support device trees on
+	 * the PowerPC architecture. Device tree names take the form of
+	 * vendor,chip. For example "epson,rtc8564". Alias is a list of
+	 * strings terminated by a zero entry.
+	 */
+	char const **aliases;	
 
 	/* Notifies the driver that a new bus has appeared. This routine
 	 * can be used by the driver to test if the bus meets its conditions
@@ -144,7 +151,7 @@ struct i2c_driver {
 };
 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
 
-#define I2C_NAME_SIZE	20
+#define I2C_NAME_SIZE	40
 
 /**
  * struct i2c_client - represent an I2C slave device
@@ -179,7 +186,7 @@ struct i2c_client {
 					/* to the client		*/
 	struct device dev;		/* the device structure		*/
 	int irq;			/* irq issued by device (or -1) */
-	char driver_name[KOBJ_NAME_LEN];
+	char driver_name[I2C_NAME_SIZE];
 	struct list_head list;
 	struct completion released;
 };
@@ -223,7 +230,7 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
  * with the adapter already known.
  */
 struct i2c_board_info {
-	char		driver_name[KOBJ_NAME_LEN];
+	char		driver_name[I2C_NAME_SIZE];
 	char		type[I2C_NAME_SIZE];
 	unsigned short	flags;
 	unsigned short	addr;

[-- Attachment #3: jds-mpc-i2c --]
[-- Type: application/octet-stream, Size: 10663 bytes --]

Convert PowerPC MPC i2c to of_platform_driver from platform_driver

From: Jon Smirl <jonsmirl@gmail.com>

Convert MPC i2c driver from being a platform_driver to an open firmware version. Error returns were improved. Routine names were changed from fsl_ to mpc_ to make them match the file name.
---

 arch/powerpc/sysdev/fsl_soc.c |   96 -----------------------
 drivers/i2c/busses/i2c-mpc.c  |  169 +++++++++++++++++++++++++++--------------
 2 files changed, 113 insertions(+), 152 deletions(-)


diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index cb95a72..d6ef264 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -318,102 +318,6 @@ err:
 
 arch_initcall(gfar_of_init);
 
-#ifdef CONFIG_I2C_BOARDINFO
-#include <linux/i2c.h>
-
-static void __init of_register_i2c_devices(struct device_node *adap_node,
-					   int bus_num)
-{
-	struct device_node *node = NULL;
-	const char *compatible;
-
-	while ((node = of_get_next_child(adap_node, node))) {
-		struct i2c_board_info info = {};
-		const u32 *addr;
-		int len;
-
-		addr = of_get_property(node, "reg", &len);
-		if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
-			printk(KERN_WARNING "fsl_soc.c: invalid i2c device entry\n");
-			continue;
-		}
-
-		info.irq = irq_of_parse_and_map(node, 0);
-		if (info.irq == NO_IRQ)
-			info.irq = -1;
-
-		compatible = of_get_property(node, "compatible", &len);
-		if (!compatible) {
-			printk(KERN_WARNING "i2c-mpc.c: invalid entry, missing compatible attribute\n");
-			continue;
-		}
-		strncpy(info.name, compatible, sizeof(info.name));
-		
-		info.addr = *addr;
-
-		i2c_register_board_info(bus_num, &info, 1);
-	}
-}
-
-static int __init fsl_i2c_of_init(void)
-{
-	struct device_node *np;
-	unsigned int i;
-	struct platform_device *i2c_dev;
-	int ret;
-
-	for (np = NULL, i = 0;
-	     (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
-	     i++) {
-		struct resource r[2];
-		struct fsl_i2c_platform_data i2c_data;
-		const unsigned char *flags = NULL;
-
-		memset(&r, 0, sizeof(r));
-		memset(&i2c_data, 0, sizeof(i2c_data));
-
-		ret = of_address_to_resource(np, 0, &r[0]);
-		if (ret)
-			goto err;
-
-		of_irq_to_resource(np, 0, &r[1]);
-
-		i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
-		if (IS_ERR(i2c_dev)) {
-			ret = PTR_ERR(i2c_dev);
-			goto err;
-		}
-
-		i2c_data.device_flags = 0;
-		flags = of_get_property(np, "dfsrr", NULL);
-		if (flags)
-			i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
-
-		flags = of_get_property(np, "fsl5200-clocking", NULL);
-		if (flags)
-			i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
-
-		ret =
-		    platform_device_add_data(i2c_dev, &i2c_data,
-					     sizeof(struct
-						    fsl_i2c_platform_data));
-		if (ret)
-			goto unreg;
-
-		of_register_i2c_devices(np, i);
-	}
-
-	return 0;
-
-unreg:
-	platform_device_unregister(i2c_dev);
-err:
-	return ret;
-}
-
-arch_initcall(fsl_i2c_of_init);
-#endif
-
 #ifdef CONFIG_PPC_83xx
 static int __init mpc83xx_wdt_init(void)
 {
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index d8de4ac..d20669b 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -17,7 +17,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/init.h>
-#include <linux/platform_device.h>
+#include <linux/of_platform.h>
 
 #include <asm/io.h>
 #include <linux/fsl_devices.h>
@@ -25,13 +25,13 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 
-#define MPC_I2C_ADDR  0x00
+#define DRV_NAME "mpc-i2c"
+
 #define MPC_I2C_FDR 	0x04
 #define MPC_I2C_CR	0x08
 #define MPC_I2C_SR	0x0c
 #define MPC_I2C_DR	0x10
 #define MPC_I2C_DFSRR 0x14
-#define MPC_I2C_REGION 0x20
 
 #define CCR_MEN  0x80
 #define CCR_MIEN 0x40
@@ -180,7 +180,7 @@ static void mpc_i2c_stop(struct mpc_i2c *i2c)
 static int mpc_write(struct mpc_i2c *i2c, int target,
 		     const u8 * data, int length, int restart)
 {
-	int i;
+	int i, result;
 	unsigned timeout = i2c->adap.timeout;
 	u32 flags = restart ? CCR_RSTA : 0;
 
@@ -192,15 +192,15 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
 	/* Write target byte */
 	writeb((target << 1), i2c->base + MPC_I2C_DR);
 
-	if (i2c_wait(i2c, timeout, 1) < 0)
-		return -1;
+	if ((result = i2c_wait(i2c, timeout, 1)) < 0)
+		return result;
 
 	for (i = 0; i < length; i++) {
 		/* Write data byte */
 		writeb(data[i], i2c->base + MPC_I2C_DR);
 
-		if (i2c_wait(i2c, timeout, 1) < 0)
-			return -1;
+		if ((result = i2c_wait(i2c, timeout, 1)) < 0)
+			return result;
 	}
 
 	return 0;
@@ -210,7 +210,7 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
 		    u8 * data, int length, int restart)
 {
 	unsigned timeout = i2c->adap.timeout;
-	int i;
+	int i, result;
 	u32 flags = restart ? CCR_RSTA : 0;
 
 	/* Start with MEN */
@@ -221,8 +221,8 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
 	/* Write target address byte - this time with the read flag set */
 	writeb((target << 1) | 1, i2c->base + MPC_I2C_DR);
 
-	if (i2c_wait(i2c, timeout, 1) < 0)
-		return -1;
+	if ((result = i2c_wait(i2c, timeout, 1)) < 0)
+		return result;
 
 	if (length) {
 		if (length == 1)
@@ -234,8 +234,8 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
 	}
 
 	for (i = 0; i < length; i++) {
-		if (i2c_wait(i2c, timeout, 0) < 0)
-			return -1;
+		if ((result = i2c_wait(i2c, timeout, 0)) < 0)
+			return result;
 
 		/* Generate txack on next to last byte */
 		if (i == length - 2)
@@ -312,74 +312,115 @@ static struct i2c_adapter mpc_ops = {
 	.retries = 1
 };
 
-static int fsl_i2c_probe(struct platform_device *pdev)
+struct i2c_driver_device {
+	char	*of_device;
+	char	*i2c_driver;
+	char	*i2c_type;
+};
+
+static void of_register_i2c_devices(struct i2c_adapter *adap, struct device_node *adap_node)
+{
+	struct device_node *node = NULL;
+
+	while ((node = of_get_next_child(adap_node, node))) {
+		struct i2c_board_info info;
+		const u32 *addr;
+		const char *compatible;
+		int len;
+
+		addr = of_get_property(node, "reg", &len);
+		if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
+			printk(KERN_WARNING "i2c-mpc.c: invalid entry, missing reg attribute\n");
+			continue;
+		}
+
+		info.irq = irq_of_parse_and_map(node, 0);
+		if (info.irq == NO_IRQ)
+			info.irq = -1;
+
+		compatible = of_get_property(node, "compatible", &len);
+		if (!compatible) {
+			printk(KERN_WARNING "i2c-mpc.c: invalid entry, missing compatible attribute\n");
+			continue;
+		}
+		strncpy(info.driver_name, compatible, sizeof(info.driver_name));
+		info.type[0] = '\0';
+
+		info.platform_data = NULL;
+		info.addr = *addr;
+		
+		i2c_new_device(adap, &info);
+	}
+}
+
+static int mpc_i2c_probe(struct of_device *op, const struct of_device_id *match)
 {
 	int result = 0;
 	struct mpc_i2c *i2c;
-	struct fsl_i2c_platform_data *pdata;
-	struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
 
 	if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) {
 		return -ENOMEM;
 	}
 
-	i2c->irq = platform_get_irq(pdev, 0);
-	if (i2c->irq < 0) {
-		result = -ENXIO;
-		goto fail_get_irq;
-	}
-	i2c->flags = pdata->device_flags;
-	init_waitqueue_head(&i2c->queue);
+	if (of_get_property(op->node, "dfsrr", NULL))
+		i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
 
-	i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION);
+	if (of_device_is_compatible(op->node, "mpc5200-i2c"))
+		i2c->flags |= FSL_I2C_DEV_CLOCK_5200;
 
+	init_waitqueue_head(&i2c->queue);
+
+	i2c->base = of_iomap(op->node, 0);
 	if (!i2c->base) {
 		printk(KERN_ERR "i2c-mpc - failed to map controller\n");
 		result = -ENOMEM;
 		goto fail_map;
 	}
 
-	if (i2c->irq != 0)
-		if ((result = request_irq(i2c->irq, mpc_i2c_isr,
-					  IRQF_SHARED, "i2c-mpc", i2c)) < 0) {
-			printk(KERN_ERR
-			       "i2c-mpc - failed to attach interrupt\n");
-			goto fail_irq;
-		}
+	i2c->irq = irq_of_parse_and_map(op->node, 0);
+	if (i2c->irq == NO_IRQ) {
+		result = -ENXIO;
+		goto fail_irq;
+	}
+	
+	if ((result = request_irq(i2c->irq, mpc_i2c_isr,
+				  	IRQF_SHARED, "i2c-mpc", i2c)) < 0) {
+		printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n");
+		goto fail_irq;
+	}
 
 	mpc_i2c_setclock(i2c);
-	platform_set_drvdata(pdev, i2c);
+	
+	dev_set_drvdata(&op->dev, i2c);
 
 	i2c->adap = mpc_ops;
-	i2c->adap.nr = pdev->id;
 	i2c_set_adapdata(&i2c->adap, i2c);
-	i2c->adap.dev.parent = &pdev->dev;
-	if ((result = i2c_add_numbered_adapter(&i2c->adap)) < 0) {
+	i2c->adap.dev.parent = &op->dev;
+	if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
 		printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
 		goto fail_add;
 	}
+	
+	of_register_i2c_devices(&i2c->adap, op->node);
 
 	return result;
 
-      fail_add:
+fail_add:
 	if (i2c->irq != 0)
 		free_irq(i2c->irq, i2c);
-      fail_irq:
+fail_irq:
 	iounmap(i2c->base);
-      fail_map:
-      fail_get_irq:
+fail_map:
 	kfree(i2c);
 	return result;
 };
 
-static int fsl_i2c_remove(struct platform_device *pdev)
+static int mpc_i2c_remove(struct of_device *op)
 {
-	struct mpc_i2c *i2c = platform_get_drvdata(pdev);
+	struct mpc_i2c *i2c = dev_get_drvdata(&op->dev);
 
 	i2c_del_adapter(&i2c->adap);
-	platform_set_drvdata(pdev, NULL);
+	dev_set_drvdata(&op->dev, NULL);
 
 	if (i2c->irq != 0)
 		free_irq(i2c->irq, i2c);
@@ -389,28 +430,44 @@ static int fsl_i2c_remove(struct platform_device *pdev)
 	return 0;
 };
 
+static struct of_device_id mpc_i2c_of_match[] = {
+	{
+		.compatible	= "fsl-i2c",
+	},
+};
+MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
+
+
 /* Structure for a device driver */
-static struct platform_driver fsl_i2c_driver = {
-	.probe = fsl_i2c_probe,
-	.remove = fsl_i2c_remove,
-	.driver	= {
-		.owner = THIS_MODULE,
-		.name = "fsl-i2c",
+static struct of_platform_driver mpc_i2c_driver = {
+	.match_table	= mpc_i2c_of_match,
+	.probe		= mpc_i2c_probe,
+	.remove		= __devexit_p(mpc_i2c_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= DRV_NAME,
 	},
 };
 
-static int __init fsl_i2c_init(void)
+static int __init mpc_i2c_init(void)
 {
-	return platform_driver_register(&fsl_i2c_driver);
+	int rv;
+
+	rv = of_register_platform_driver(&mpc_i2c_driver);
+	if (rv) {
+		printk(KERN_ERR DRV_NAME " of_register_platform_driver failed (%i)\n", rv);
+		return rv;
+	}
+	return 0;
 }
 
-static void __exit fsl_i2c_exit(void)
+static void __exit mpc_i2c_exit(void)
 {
-	platform_driver_unregister(&fsl_i2c_driver);
+	of_unregister_platform_driver(&mpc_i2c_driver);
 }
 
-module_init(fsl_i2c_init);
-module_exit(fsl_i2c_exit);
+module_init(mpc_i2c_init);
+module_exit(mpc_i2c_exit);
 
 MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
 MODULE_DESCRIPTION

[-- Attachment #4: jds-pfc-rtc --]
[-- Type: application/octet-stream, Size: 3762 bytes --]

Convert pfc8563 i2c driver from old style to new style

From: Jon Smirl <jonsmirl@gmail.com>


---

 drivers/rtc/rtc-pcf8563.c |  103 +++++++++------------------------------------
 1 files changed, 21 insertions(+), 82 deletions(-)


diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index fa04dc5..bebe139 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -25,10 +25,6 @@
  * located at 0x51 will pass the validation routine due to
  * the way the registers are implemented.
  */
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Module parameters */
-I2C_CLIENT_INSMOD;
 
 #define PCF8563_REG_ST1		0x00 /* status */
 #define PCF8563_REG_ST2		0x01
@@ -72,9 +68,6 @@ struct pcf8563 {
 	int c_polarity;	/* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
 };
 
-static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
-static int pcf8563_detach(struct i2c_client *client);
-
 /*
  * In the routines that deal directly with the pcf8563 hardware, we use
  * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@@ -257,99 +250,45 @@ static const struct rtc_class_ops pcf8563_rtc_ops = {
 	.set_time	= pcf8563_rtc_set_time,
 };
 
-static int pcf8563_attach(struct i2c_adapter *adapter)
+static int pcf8563_remove(struct i2c_client *client)
 {
-	return i2c_probe(adapter, &addr_data, pcf8563_probe);
+	struct rtc_device *rtc = i2c_get_clientdata(client);
+
+	if (rtc)
+		rtc_device_unregister(rtc);
+	
+	return 0;
 }
 
+static int pcf8563_probe(struct i2c_client *client);
+
 static struct i2c_driver pcf8563_driver = {
 	.driver		= {
-		.name	= "pcf8563",
+		.name	= "rtc-pcf8563",
 	},
 	.aliases = (char const *[]){"philips,pcf8563", "epson,rtc8564", 0},
 	.id		= I2C_DRIVERID_PCF8563,
-	.attach_adapter = &pcf8563_attach,
-	.detach_client	= &pcf8563_detach,
+	.probe = &pcf8563_probe,
+	.remove = &pcf8563_remove,
 };
 
-static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
+static int pcf8563_probe(struct i2c_client *client)
 {
-	struct pcf8563 *pcf8563;
-	struct i2c_client *client;
+	int result;
 	struct rtc_device *rtc;
-
-	int err = 0;
-
-	dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
-		err = -ENODEV;
-		goto exit;
-	}
-
-	if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-
-	client = &pcf8563->client;
-	client->addr = address;
-	client->driver = &pcf8563_driver;
-	client->adapter	= adapter;
-
-	strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE);
-
-	/* Verify the chip is really an PCF8563 */
-	if (kind < 0) {
-		if (pcf8563_validate_client(client) < 0) {
-			err = -ENODEV;
-			goto exit_kfree;
-		}
-	}
-
-	/* Inform the i2c layer */
-	if ((err = i2c_attach_client(client)))
-		goto exit_kfree;
-
-	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-
+	
+	result = pcf8563_validate_client(client);
+	if (result)
+		return result;
+	
 	rtc = rtc_device_register(pcf8563_driver.driver.name, &client->dev,
 				&pcf8563_rtc_ops, THIS_MODULE);
-
-	if (IS_ERR(rtc)) {
-		err = PTR_ERR(rtc);
-		goto exit_detach;
-	}
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
 
 	i2c_set_clientdata(client, rtc);
 
 	return 0;
-
-exit_detach:
-	i2c_detach_client(client);
-
-exit_kfree:
-	kfree(pcf8563);
-
-exit:
-	return err;
-}
-
-static int pcf8563_detach(struct i2c_client *client)
-{
-	struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
-	int err;
-	struct rtc_device *rtc = i2c_get_clientdata(client);
-
-	if (rtc)
-		rtc_device_unregister(rtc);
-
-	if ((err = i2c_detach_client(client)))
-		return err;
-
-	kfree(pcf8563);
-
-	return 0;
 }
 
 static int __init pcf8563_init(void)

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: I2C on mpc8248 / device tree
  2007-11-13 23:39 I2C on mpc8248 / device tree Alan Bennett
  2007-11-13 23:56 ` Jon Smirl
@ 2007-11-14  7:17 ` Kumar Gala
  1 sibling, 0 replies; 9+ messages in thread
From: Kumar Gala @ 2007-11-14  7:17 UTC (permalink / raw)
  To: Alan Bennett; +Cc: linuxppc-dev


On Nov 13, 2007, at 5:39 PM, Alan Bennett wrote:

> I've got four devices on i2c that I need to read.  Simple thermal  
> and voltage monitors.  I2c works fine in uboot, and now I'm trying  
> to get things to work in linux.
>
> In the kernel .config I enable
>   I2C
> and
>   I2C_MPC

This driver isn't for the I2C on 8248.  You need a cpm2 i2c driver  
for that controller.

- k

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: I2C on mpc8248 / device tree
  2007-11-13 23:56 ` Jon Smirl
@ 2007-11-14 15:31   ` Alan Bennett
  2007-11-14 16:20     ` Kumar Gala
  0 siblings, 1 reply; 9+ messages in thread
From: Alan Bennett @ 2007-11-14 15:31 UTC (permalink / raw)
  To: Jon Smirl; +Cc: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 837 bytes --]

Does this patch support the cpm2 as well?

I get conflicting thoughts looking over the latest postings.

-Alan


On 11/13/07, Jon Smirl <jonsmirl@gmail.com> wrote:
>
> I am working on a patch for i2c and device tree. I attached the current
> version.
>
> DTC entry looks like this.
>
>                 i2c@3d40 {
>                         compatible =
> "mpc5200b-i2c","mpc5200-i2c","fsl-i2c";
>                         reg = <3d40 40>;
>                         interrupts = <2 10 0>;
>                         interrupt-parent = <&mpc5200_pic>;
>                         fsl5200-clocking;
>
>                         rtc@51f {
>                                 compatible = "epson,rtc8564";
>                                 reg = <51>;
>                         };
>                 };
>
>
>
> --
> Jon Smirl
> jonsmirl@gmail.com
>
>

[-- Attachment #2: Type: text/html, Size: 2581 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: I2C on mpc8248 / device tree
  2007-11-14 15:31   ` Alan Bennett
@ 2007-11-14 16:20     ` Kumar Gala
  2007-11-14 17:49       ` Alan Bennett
  0 siblings, 1 reply; 9+ messages in thread
From: Kumar Gala @ 2007-11-14 16:20 UTC (permalink / raw)
  To: Alan Bennett; +Cc: linuxppc-dev

The patch is orthogonal to your issue.

There is NOT a driver in the kernel tree for the i2c on CPM2 based  
parts like the 8248 (from what I can tell).

- k

On Nov 14, 2007, at 9:31 AM, Alan Bennett wrote:

> Does this patch support the cpm2 as well?
>
> I get conflicting thoughts looking over the latest postings.
>
> -Alan
>
>
> On 11/13/07, Jon Smirl < jonsmirl@gmail.com> wrote:I am working on  
> a patch for i2c and device tree. I attached the current version.
>
> DTC entry looks like this.
>
>                 i2c@3d40 {
>                         compatible = "mpc5200b-i2c","mpc5200- 
> i2c","fsl-i2c";
>                         reg = <3d40 40>;
>                         interrupts = <2 10 0>;
>                         interrupt-parent = <&mpc5200_pic>;
>                         fsl5200-clocking;
>
>                         rtc@51f {
>                                 compatible = "epson,rtc8564";
>                                 reg = <51>;
>                         };
>                 };
>
>
>
> --
> Jon Smirl
> jonsmirl@gmail.com
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: I2C on mpc8248 / device tree
  2007-11-14 16:20     ` Kumar Gala
@ 2007-11-14 17:49       ` Alan Bennett
  2007-11-14 17:56         ` Scott Wood
  0 siblings, 1 reply; 9+ messages in thread
From: Alan Bennett @ 2007-11-14 17:49 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 2185 bytes --]

ERk.
  So if I needed to read values from four i2c devices (raw access would be
fine) and I need to get this working in a few days, how would you suggest I
proceed?  Kernel = 2.6.23+.

  Do I need to start from scratch?

  Start by using Jon's patch  (or are the 5200 i2c and the cpm2 i2c
completely incompatible?)

  What about other cpm2/i2c threads - Did they ever complete?
     1) On Wednesday, November 23, 2005 8:01 AM Kumar Gala wrote: >* Can we
rename the driver from mpc8260 -> cpm2. The driver should work* >* on any
device that has a "CPM2" which includes a number of MPC82xx* >* and MPC85xx
processors <http://osdir.com/ml/ports.ppc.devel/2005-11/msg00153.html#>. So
calling it and its config options, etc* >* MPC8260 is going to be confusing
to users.* [PATCH] I2C: Add I2C Bus support for MPC with CPM2.





On 11/14/07, Kumar Gala <galak@kernel.crashing.org> wrote:
>
> The patch is orthogonal to your issue.
>
> There is NOT a driver in the kernel tree for the i2c on CPM2 based
> parts like the 8248 (from what I can tell).
>
> - k
>
> On Nov 14, 2007, at 9:31 AM, Alan Bennett wrote:
>
> > Does this patch support the cpm2 as well?
> >
> > I get conflicting thoughts looking over the latest postings.
> >
> > -Alan
> >
> >
> > On 11/13/07, Jon Smirl < jonsmirl@gmail.com> wrote:I am working on
> > a patch for i2c and device tree. I attached the current version.
> >
> > DTC entry looks like this.
> >
> >                 i2c@3d40 {
> >                         compatible = "mpc5200b-i2c","mpc5200-
> > i2c","fsl-i2c";
> >                         reg = <3d40 40>;
> >                         interrupts = <2 10 0>;
> >                         interrupt-parent = <&mpc5200_pic>;
> >                         fsl5200-clocking;
> >
> >                         rtc@51f {
> >                                 compatible = "epson,rtc8564";
> >                                 reg = <51>;
> >                         };
> >                 };
> >
> >
> >
> > --
> > Jon Smirl
> > jonsmirl@gmail.com
> >
> >
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@ozlabs.org
> > https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
>

[-- Attachment #2: Type: text/html, Size: 4974 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: I2C on mpc8248 / device tree
  2007-11-14 17:49       ` Alan Bennett
@ 2007-11-14 17:56         ` Scott Wood
  2007-11-14 19:26           ` Jon Smirl
  0 siblings, 1 reply; 9+ messages in thread
From: Scott Wood @ 2007-11-14 17:56 UTC (permalink / raw)
  To: Alan Bennett; +Cc: linuxppc-dev

On Wed, Nov 14, 2007 at 10:49:13AM -0700, Alan Bennett wrote:
> ERk.
>   So if I needed to read values from four i2c devices (raw access would be
> fine) and I need to get this working in a few days, how would you suggest I
> proceed?  Kernel = 2.6.23+.
> 
>   Do I need to start from scratch?
> 
>   Start by using Jon's patch  (or are the 5200 i2c and the cpm2 i2c
> completely incompatible?)

Start with the cpm i2c driver that Jochen Friedrich posted to
linuxppc-embedded.

-Scott

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: I2C on mpc8248 / device tree
  2007-11-14 17:56         ` Scott Wood
@ 2007-11-14 19:26           ` Jon Smirl
  2007-11-14 20:21             ` Kumar Gala
  0 siblings, 1 reply; 9+ messages in thread
From: Jon Smirl @ 2007-11-14 19:26 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, Alan Bennett

On 11/14/07, Scott Wood <scottwood@freescale.com> wrote:
> On Wed, Nov 14, 2007 at 10:49:13AM -0700, Alan Bennett wrote:
> > ERk.
> >   So if I needed to read values from four i2c devices (raw access would be
> > fine) and I need to get this working in a few days, how would you suggest I
> > proceed?  Kernel = 2.6.23+.
> >
> >   Do I need to start from scratch?
> >
> >   Start by using Jon's patch  (or are the 5200 i2c and the cpm2 i2c
> > completely incompatible?)
>
> Start with the cpm i2c driver that Jochen Friedrich posted to
> linuxppc-embedded.

Sorry about the confusion I thought the mpc82xx chips had the same i2c
core as the mpc52xx but I was not correct.


>
> -Scott
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>


-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: I2C on mpc8248 / device tree
  2007-11-14 19:26           ` Jon Smirl
@ 2007-11-14 20:21             ` Kumar Gala
  0 siblings, 0 replies; 9+ messages in thread
From: Kumar Gala @ 2007-11-14 20:21 UTC (permalink / raw)
  To: Jon Smirl; +Cc: linuxppc-dev, Alan Bennett


On Nov 14, 2007, at 1:26 PM, Jon Smirl wrote:

> On 11/14/07, Scott Wood <scottwood@freescale.com> wrote:
>> On Wed, Nov 14, 2007 at 10:49:13AM -0700, Alan Bennett wrote:
>>> ERk.
>>>   So if I needed to read values from four i2c devices (raw access  
>>> would be
>>> fine) and I need to get this working in a few days, how would you  
>>> suggest I
>>> proceed?  Kernel = 2.6.23+.
>>>
>>>   Do I need to start from scratch?
>>>
>>>   Start by using Jon's patch  (or are the 5200 i2c and the cpm2 i2c
>>> completely incompatible?)
>>
>> Start with the cpm i2c driver that Jochen Friedrich posted to
>> linuxppc-embedded.
>
> Sorry about the confusion I thought the mpc82xx chips had the same i2c
> core as the mpc52xx but I was not correct.

the 8241 and 8245 have it, but they are the only ones.

- k

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2007-11-14 20:21 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-13 23:39 I2C on mpc8248 / device tree Alan Bennett
2007-11-13 23:56 ` Jon Smirl
2007-11-14 15:31   ` Alan Bennett
2007-11-14 16:20     ` Kumar Gala
2007-11-14 17:49       ` Alan Bennett
2007-11-14 17:56         ` Scott Wood
2007-11-14 19:26           ` Jon Smirl
2007-11-14 20:21             ` Kumar Gala
2007-11-14  7:17 ` Kumar Gala

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.