Skip to contentSkip to conversation

i2c: adds support for i2c bus on Frescale CPM1/CPM2 controllers

PATCH Superseded Jochen Friedrich 4 participants 6 messages Jan 2, 2008 – Jan 23, 2008

Subsystems (5)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Jochen Friedrich

author maintainer
#0 lore raw

PATCH v2 1/1 i2c: adds support for i2c bus on Frescale CPM1/CPM2 controllers

Using the port of 2.4 code from Vitaly Bordug <[email protected]> and the actual algorithm used by the i2c driver of the DBox code on cvs.tuxboc.org from Tmbinc, Gillem ([email protected]). Renamed i2c-rpx.c and i2c-algo-8xx.c to i2c-cpm.c and converted the driver to an of_platform_driver.

---

arch/powerpc/boot/dts/mpc8272ads.dts         |   10 +
arch/powerpc/boot/dts/mpc866ads.dts          |   10 +
arch/powerpc/boot/dts/mpc885ads.dts          |   10 +
arch/powerpc/platforms/8xx/mpc885ads_setup.c |    5 +
drivers/i2c/busses/Kconfig                   |   10 +
drivers/i2c/busses/Makefile                  |    1 +
drivers/i2c/busses/i2c-cpm.c                 |  786 ++++++++++++++++++++++++++
7 files changed, 832 insertions(+), 0 deletions(-)

create mode 100644 drivers/i2c/busses/i2c-cpm.c

arch/powerpc/boot/dts/mpc8272ads.dts +0 -0
index 7285ca1..7273996 100644
@@ -215,6 +215,16 @@
				linux,network-index = <1>;
				fsl,cpm-command = <16200300>;
			};

+
+ i2c@11860 {
+ compatible = "fsl,mpc8248-i2c",
+ "fsl,cpm2-i2c",
+ "fsl,cpm-i2c";
+ reg = <11860 20 8afc 2>;
+ interrupts = <1 8>;
+ interrupt-parent = <&PIC>;
+ fsl,cpm-command = <29600000>;

+			};
		};

		PIC: interrupt-controller@10c00 {
arch/powerpc/boot/dts/mpc866ads.dts +0 -0
index daf9433..80c08bf 100644
@@ -169,6 +169,16 @@
				fsl,cpm-command = <0000>;
				linux,network-index = <1>;
			};

+
+ i2c@860 {
+ compatible = "fsl,mpc866-i2c",
+ "fsl,cpm1-i2c",
+ "fsl,cpm-i2c";
+ reg = <860 20 3c80 30>;
+ interrupts = <10 3>;
+ interrupt-parent = <&Cpm_pic>;
+ fsl,cpm-command = <0010>;

+			};
		};
	};
arch/powerpc/boot/dts/mpc885ads.dts +0 -0
index 8848e63..fd9c9d7 100644
@@ -213,6 +213,16 @@
				fsl,cpm-command = <0080>;
				linux,network-index = <2>;
			};

+
+ i2c@860 {
+ compatible = "fsl,mpc885-i2c",
+ "fsl,cpm1-i2c",
+ "fsl,cpm-i2c";
+ reg = <860 20 3c80 30>;
+ interrupts = <10>;
+ interrupt-parent = <&CPM_PIC>;
+ fsl,cpm-command = <0010>;

+			};
		};
	};
arch/powerpc/platforms/8xx/mpc885ads_setup.c +0 -0
index 2cf1b6a..4377521 100644
@@ -157,6 +157,11 @@ static struct cpm_pin mpc885ads_pins[] = {
	{CPM_PORTE, 28, CPM_PIN_OUTPUT},
	{CPM_PORTE, 29, CPM_PIN_OUTPUT},

#endif
+ /* I2C */
+#ifdef CONFIG_I2C_8XX
+ {CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+ {CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+#endif
};

static void __init init_ioports(void)

drivers/i2c/busses/Kconfig +0 -0
index c466c6c..5950172 100644
@@ -114,6 +114,16 @@ config I2C_BLACKFIN_TWI_CLK_KHZ

help
The unit of the TWI clock is kHz.

+config I2C_CPM
+ tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
+ depends on (CPM1 || CPM2) && I2C && PPC_OF
+ help
+ This supports the use of the I2C interface on Freescale
+ processors with CPM1 or CPM2.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-cpm.
+
config I2C_DAVINCI
tristate "DaVinci I2C driver"
depends on ARCH_DAVINCI

drivers/i2c/busses/Makefile +0 -0
index 81d43c2..a395555 100644
@@ -11,6 +11,7 @@ obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o

obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
+obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o

drivers/i2c/busses/i2c-cpm.c new file +786 -0

786 lines not on this page · raw message

Signature · 1 line
1.5.3.7
#1 lore raw

Hi Jochen,

Just a few trivial things.

drivers/i2c/busses/i2c-cpm.c line 137

Quoted 11 lines · On Wed, 02 Jan 2008 20:52:00 +0100 Jochen Friedrich <[email protected]> wrote:

+++ b/drivers/i2c/busses/i2c-cpm.c

drivers/i2c/busses/i2c-cpm.c new file +9 -0
+
+static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
+{
+	struct i2c_adapter *adap;
+	struct cpm_i2c *cpm;
+	struct i2c_reg __iomem *i2c_reg;
+	int i;
+
+	adap = (struct i2c_adapter *) dev_id;

This cast is unnecessary. In fact, you could just pass dev_id to the following call to i2c_get_adapdata() and eliminate adap completely.

Review

Quoted 2 lines
(quoted diff) +2 -0
+	/* Get 'me going again.
+	 */

For short comments, just make them one line. Similarly later as well.

drivers/i2c/busses/i2c-cpm.c line 210

Quoted 3 lines
drivers/i2c/busses/i2c-cpm.c new file +3 -0
+	/* This chip can't do zero length writes. However, the i2c core uses
+	   them to scan for devices. The best we can do is to convert them
+	   into 1 byte reads */

For multiline comments, we normally do
/*
* blah ...
* more blah
*/

Quoted 18 lines
drivers/i2c/busses/i2c-cpm.c new file +18 -0
+static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+
+	while (tptr < num) {
+		/* Check for outstanding messages */
+		dev_dbg(&adap->dev, "test ready.\n");
+		if (!(tbdf[tptr].cbd_sc & BD_SC_READY)) {
+			dev_dbg(&adap->dev, "ready.\n");
+			rmsg = &msgs[tptr];
+			ret = cpm_i2c_check_message(adap, rmsg, tptr, rptr);
+			tptr++;
+			if (rmsg->flags & I2C_M_RD)
+				rptr++;
+			if (ret) {
+				cpm_i2c_force_close(adap);
+				mutex_unlock(&cpm->i2c_mutex);
+				return ret;
+			}

drivers/i2c/busses/i2c-cpm.c line 420

Quoted 10 lines
drivers/i2c/busses/i2c-cpm.c new file +10 -0
+		} else {
+			dev_dbg(&adap->dev, "not ready.\n");
+			ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+				!(tbdf[tptr].cbd_sc & BD_SC_READY), 1 * HZ);
+			if (ret == 0) {
+				cpm_i2c_force_close(adap);
+				dev_dbg(&adap->dev, "I2C read: timeout!\n");
+				mutex_unlock(&cpm->i2c_mutex);
+				return -EREMOTEIO;
+			}

You might want to consolidate the two error paths above using gotos to an error return section below.

drivers/i2c/busses/i2c-cpm.c line 647

Quoted 6 lines
drivers/i2c/busses/i2c-cpm.c new file +6 -0
+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))) {

Use

	for_each_child_of_node(adap_node, node) {

instead and you don't need to initialise "node" above.

Quoted 1 line

+static struct of_device_id cpm_i2c_match[] = {

const?

Signature · 3 lines
Cheers,
Stephen Rothwell                    [email protected]
http://www.canb.auug.org.au/~sfr/
#2 lore raw

Hi Jochen,

Sorry for the late answer.

Quoted 75 lines · Stephen Rothwell

Hi Jochen,

Just a few trivial things.

drivers/i2c/busses/i2c-cpm.c line 137

Quoted 11 lines · On Wed, 02 Jan 2008 20:52:00 +0100 Jochen Friedrich <[email protected]> wrote:

+++ b/drivers/i2c/busses/i2c-cpm.c

drivers/i2c/busses/i2c-cpm.c new file +9 -0
+
+static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
+{
+	struct i2c_adapter *adap;
+	struct cpm_i2c *cpm;
+	struct i2c_reg __iomem *i2c_reg;
+	int i;
+
+	adap = (struct i2c_adapter *) dev_id;

This cast is unnecessary. In fact, you could just pass dev_id to the following call to i2c_get_adapdata() and eliminate adap completely.

Review

Quoted 2 lines
(quoted diff) +2 -0
+	/* Get 'me going again.
+	 */

For short comments, just make them one line. Similarly later as well.

drivers/i2c/busses/i2c-cpm.c line 210

Quoted 3 lines
drivers/i2c/busses/i2c-cpm.c new file +3 -0
+	/* This chip can't do zero length writes. However, the i2c core uses
+	   them to scan for devices. The best we can do is to convert them
+	   into 1 byte reads */

For multiline comments, we normally do
/*
* blah ...
* more blah
*/

Quoted 18 lines
drivers/i2c/busses/i2c-cpm.c new file +18 -0
+static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+
+	while (tptr < num) {
+		/* Check for outstanding messages */
+		dev_dbg(&adap->dev, "test ready.\n");
+		if (!(tbdf[tptr].cbd_sc & BD_SC_READY)) {
+			dev_dbg(&adap->dev, "ready.\n");
+			rmsg = &msgs[tptr];
+			ret = cpm_i2c_check_message(adap, rmsg, tptr, rptr);
+			tptr++;
+			if (rmsg->flags & I2C_M_RD)
+				rptr++;
+			if (ret) {
+				cpm_i2c_force_close(adap);
+				mutex_unlock(&cpm->i2c_mutex);
+				return ret;
+			}

drivers/i2c/busses/i2c-cpm.c line 420

Quoted 10 lines
drivers/i2c/busses/i2c-cpm.c new file +10 -0
+		} else {
+			dev_dbg(&adap->dev, "not ready.\n");
+			ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+				!(tbdf[tptr].cbd_sc & BD_SC_READY), 1 * HZ);
+			if (ret == 0) {
+				cpm_i2c_force_close(adap);
+				dev_dbg(&adap->dev, "I2C read: timeout!\n");
+				mutex_unlock(&cpm->i2c_mutex);
+				return -EREMOTEIO;
+			}

You might want to consolidate the two error paths above using gotos to an error return section below.

drivers/i2c/busses/i2c-cpm.c line 647

Quoted 6 lines
drivers/i2c/busses/i2c-cpm.c new file +6 -0
+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))) {

Use

Quoted 6 lines
	for_each_child_of_node(adap_node, node) {

instead and you don't need to initialise "node" above.

Quoted 1 line

+static struct of_device_id cpm_i2c_match[] = {

const?

Do you have an updated patch addressing Stephen's comment?

Note: you'd rather send updates of this patch to the i2c list rather than LKML.

Thanks,

Signature · 1 line
Jean Delvare
author maintainer
#3 lore raw

Hi Jean,

Quoted 4 lines

Do you have an updated patch addressing Stephen's comment?

Note: you'd rather send updates of this patch to the i2c list rather than LKML.

I'm currently looking at that last patches from Jon and try to make this driver fit in there (+ the class override stuff).

Note: will do. I just subscribed to this list.

Thanks,
Jochen

#4 lore raw

Hallo Jochen,

Quoted 9 lines · Jochen Friedrich

Hi Jean,

Quoted 4 lines

Do you have an updated patch addressing Stephen's comment?

Note: you'd rather send updates of this patch to the i2c list rather than LKML.

I'm currently looking at that last patches from Jon and try to make this driver fit in there (+ the class override stuff).

I'm not sure what patches exactly you're talking about, but the aliasing stuff Jon and myself have been working on are still under debate. Your patch shouldn't assume that any of these patches will go upstream immediately, so your patch adding the i2c-cpm driver can ignore them. I'll update the patches before merging them as needed, do not worry too much about that.

Quoted 1 line

Note: will do. I just subscribed to this list.

Note hat you do not need to be subscribed to post to the i2c list (but of course, if you have some interest in Linux i2c development, subscribing was a good idea anyway.)

Signature · 1 line
Jean Delvare
#5 lore raw
Quoted 13 lines · Jean Delvare

Hallo Jochen,

Quoted 9 lines · Jochen Friedrich

Hi Jean,

Quoted 4 lines

Do you have an updated patch addressing Stephen's comment?

Note: you'd rather send updates of this patch to the i2c list rather than LKML.

I'm currently looking at that last patches from Jon and try to make this driver fit in there (+ the class override stuff).

Quoted 6 lines

I'm not sure what patches exactly you're talking about, but the aliasing stuff Jon and myself have been working on are still under debate. Your patch shouldn't assume that any of these patches will go upstream immediately, so your patch adding the i2c-cpm driver can ignore them. I'll update the patches before merging them as needed, do not worry too much about that.

He wants the module name translation support I split out into powerpc-common.c.

Quoted 10 lines
Quoted 2 lines

Note: will do. I just subscribed to this list.

Note hat you do not need to be subscribed to post to the i2c list (but of course, if you have some interest in Linux i2c development, subscribing was a good idea anyway.)

--
Jean Delvare

Signature · 2 lines
Jon Smirl
[email protected]