[i2c] [PATCH] Is review of AT91 patch pending?

David Brownell david-b at pacbell.net
Sun Oct 21 20:25:26 CEST 2007


> > 2.6.24, yes.  I think what's needed is to push this through
> > the ARM patch system, along with the at91sam926x update and
> > defconfig updates.  I CC'd Russell so he'll know that's coming.
> > Acks from you and from Andrew would probably be useful.
>
> I'd personally prefer if we don't override the existing CONFIG_I2C_AT91
> support in the _devices.c file with the GPIO-I2C support, but rather add
> a new GPIO-I2C platform device and allow the boards / user to select
> which they'd like to use.

Here's an updated patch.  Evidently one of the AT91 patches you
sent to Russell (but which hasn't yet merged to kernel.org) has
changed I2C init, so this needs some tweaking that I can't sort
yet ... Russell suggested you handle the next steps here.

- Dave

===========	CUT HERE
Make AT91 chips use bitbanged GPIO for I2C, preventing regressions
caused by marking the i2c-at91 driver as BROKEN (hardware issues).
The GPIO driver is slower, but it works correctly.

This updates platform setup logic (setting up an i2c-gpio device
using the same pins as the i2c-at91 device, unless only the BROKEN
driver is enabled), and the i2c sections of defconfigs for AT91
platforms which currently try to enable the broken driver.

Run-tested on at91rm9200.  Build-tested for others.

Signed-off-by: David Brownell <dbrownell at users.sourceforge.net>
---
 arch/arm/configs/at91rm9200dk_defconfig  |    4 +--
 arch/arm/configs/at91rm9200ek_defconfig  |    4 +--
 arch/arm/configs/at91sam9261ek_defconfig |    4 +--
 arch/arm/configs/at91sam9263ek_defconfig |    4 +--
 arch/arm/configs/ateb9200_defconfig      |    2 -
 arch/arm/configs/csb337_defconfig        |    4 +--
 arch/arm/configs/csb637_defconfig        |    4 +--
 arch/arm/configs/kafa_defconfig          |    4 +--
 arch/arm/configs/picotux200_defconfig    |    4 +--
 arch/arm/mach-at91/at91rm9200_devices.c  |   38 +++++++++++++++++++++++++++++--
 arch/arm/mach-at91/at91sam9260_devices.c |   38 +++++++++++++++++++++++++++++--
 arch/arm/mach-at91/at91sam9261_devices.c |   38 +++++++++++++++++++++++++++++--
 arch/arm/mach-at91/at91sam9263_devices.c |   38 +++++++++++++++++++++++++++++--
 arch/arm/mach-at91/at91sam9rl_devices.c  |   38 +++++++++++++++++++++++++++++--
 14 files changed, 197 insertions(+), 27 deletions(-)

--- at91.orig/arch/arm/mach-at91/at91rm9200_devices.c	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/mach-at91/at91rm9200_devices.c	2007-10-21 10:54:07.000000000 -0700
@@ -14,6 +14,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
 
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
@@ -432,10 +433,43 @@ void __init at91_add_device_nand(struct 
 
 
 /* --------------------------------------------------------------------
- *  TWI (i2c)
+ *  TWI (i2c) ... prefer the GPIO code since this TWI controller isn't
+ *  robust (gets overruns and underruns under load) and can only issue
+ *  repeated STARTs in one scenario (the driver doesn't yet handle them).
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PA25,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PA26,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91rm9200_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(void)
+{
+	/* pins used for TWI interface -- set as GPIO */
+
+	/* TWD/SDA */
+	at91_set_GPIO_periph(AT91_PIN_PA25, 1);
+	at91_set_multi_drive(AT91_PIN_PA25, 1);
+
+	/* TWCK/SCL */
+	at91_set_GPIO_periph(AT91_PIN_PA26, 1);
+	at91_set_multi_drive(AT91_PIN_PA26, 1);
+
+	platform_device_register(&at91rm9200_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
 
 static struct resource twi_resources[] = {
 	[0] = {
--- at91.orig/arch/arm/mach-at91/at91sam9260_devices.c	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/mach-at91/at91sam9260_devices.c	2007-10-21 10:54:14.000000000 -0700
@@ -13,6 +13,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
 
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
@@ -349,10 +350,43 @@ void __init at91_add_device_nand(struct 
 
 
 /* --------------------------------------------------------------------
- *  TWI (i2c)
+ *  TWI (i2c) ... prefer the GPIO code since this TWI controller isn't
+ *  robust (gets overruns and underruns under load) and can only issue
+ *  repeated STARTs in one scenario (the driver doesn't yet handle them).
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PA23,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PA24,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91sam9260_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(void)
+{
+	/* pins used for TWI interface -- set as GPIO */
+
+	/* TWD/SDA */
+	at91_set_GPIO_periph(AT91_PIN_PA23, 1);
+	at91_set_multi_drive(AT91_PIN_PA23, 1);
+
+	/* TWCK/SCL */
+	at91_set_GPIO_periph(AT91_PIN_PA24, 1);
+	at91_set_multi_drive(AT91_PIN_PA24, 1);
+
+	platform_device_register(&at91sam9260_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
 
 static struct resource twi_resources[] = {
 	[0] = {
--- at91.orig/arch/arm/mach-at91/at91sam9261_devices.c	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/mach-at91/at91sam9261_devices.c	2007-10-21 10:54:28.000000000 -0700
@@ -14,6 +14,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
 
 #include <video/atmel_lcdc.h>
 
@@ -272,10 +273,43 @@ void __init at91_add_device_nand(struct 
 
 
 /* --------------------------------------------------------------------
- *  TWI (i2c)
+ *  TWI (i2c) ... prefer the GPIO code since this TWI controller isn't
+ *  robust (gets overruns and underruns under load) and can only issue
+ *  repeated STARTs in one scenario (the driver doesn't yet handle them).
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PA7,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PA8,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91sam9261_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(void)
+{
+	/* pins used for TWI interface -- set as GPIO */
+
+	/* TWD/SDA */
+	at91_set_GPIO_periph(AT91_PIN_PA7, 1);
+	at91_set_multi_drive(AT91_PIN_PA7, 1);
+
+	/* TWCK/SCL */
+	at91_set_GPIO_periph(AT91_PIN_PA8, 1);
+	at91_set_multi_drive(AT91_PIN_PA8, 1);
+
+	platform_device_register(&at91sam9261_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
 
 static struct resource twi_resources[] = {
 	[0] = {
--- at91.orig/arch/arm/mach-at91/at91sam9263_devices.c	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/mach-at91/at91sam9263_devices.c	2007-10-21 10:54:43.000000000 -0700
@@ -13,6 +13,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
 
 #include <video/atmel_lcdc.h>
 
@@ -418,10 +419,43 @@ void __init at91_add_device_nand(struct 
 
 
 /* --------------------------------------------------------------------
- *  TWI (i2c)
+ *  TWI (i2c) ... prefer the GPIO code since this TWI controller isn't
+ *  robust (gets overruns and underruns under load) and can only issue
+ *  repeated STARTs in one scenario (the driver doesn't yet handle them).
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PB4,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PB5,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91sam9263_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(void)
+{
+	/* pins used for TWI interface -- set as GPIO */
+
+	/* TWD: at91_set_A_periph(AT91_PIN_PB4, 0); */
+	at91_set_GPIO_periph(AT91_PIN_PB4, 1);
+	at91_set_multi_drive(AT91_PIN_PB4, 1);
+
+	/* TWCK: at91_set_A_periph(AT91_PIN_PB5, 0); */
+	at91_set_GPIO_periph(AT91_PIN_PB5, 1);
+	at91_set_multi_drive(AT91_PIN_PB5, 1);
+
+	platform_device_register(&at91sam9263_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
 
 static struct resource twi_resources[] = {
 	[0] = {
--- at91.orig/arch/arm/mach-at91/at91sam9rl_devices.c	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/mach-at91/at91sam9rl_devices.c	2007-10-21 10:54:53.000000000 -0700
@@ -10,6 +10,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
 #include <linux/fb.h>
 
 #include <video/atmel_lcdc.h>
@@ -166,10 +167,43 @@ void __init at91_add_device_nand(struct 
 
 
 /* --------------------------------------------------------------------
- *  TWI (i2c)
+ *  TWI (i2c) ... prefer the GPIO code since this TWI controller isn't
+ *  robust (gets overruns and underruns under load) and can only issue
+ *  repeated STARTs in one scenario (the driver doesn't yet handle them).
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PA23,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PA24,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91sam9rl_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(void)
+{
+	/* pins used for TWI interface -- set as GPIO */
+
+	/* TWD/SDA */
+	at91_set_GPIO_periph(AT91_PIN_PA23, 1);
+	at91_set_multi_drive(AT91_PIN_PA23, 1);
+
+	/* TWCK/SCL */
+	at91_set_GPIO_periph(AT91_PIN_PA24, 1);
+	at91_set_multi_drive(AT91_PIN_PA24, 1);
+
+	platform_device_register(&at91sam9rl_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
 
 static struct resource twi_resources[] = {
 	[0] = {
--- at91.orig/arch/arm/configs/at91rm9200dk_defconfig	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/configs/at91rm9200dk_defconfig	2007-10-21 10:38:07.000000000 -0700
@@ -620,14 +620,14 @@ CONFIG_I2C_CHARDEV=y
 #
 # I2C Algorithms
 #
-# CONFIG_I2C_ALGOBIT is not set
+CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_ALGOPCF is not set
 # CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
 #
-CONFIG_I2C_AT91=y
+CONFIG_I2C_GPIO=y
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
 # CONFIG_I2C_PCA_ISA is not set
--- at91.orig/arch/arm/configs/at91rm9200ek_defconfig	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/configs/at91rm9200ek_defconfig	2007-10-21 10:38:07.000000000 -0700
@@ -594,14 +594,14 @@ CONFIG_I2C_CHARDEV=y
 #
 # I2C Algorithms
 #
-# CONFIG_I2C_ALGOBIT is not set
+CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_ALGOPCF is not set
 # CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
 #
-CONFIG_I2C_AT91=y
+CONFIG_I2C_GPIO=y
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
 # CONFIG_I2C_PCA_ISA is not set
--- at91.orig/arch/arm/configs/at91sam9261ek_defconfig	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/configs/at91sam9261ek_defconfig	2007-10-21 10:38:07.000000000 -0700
@@ -654,14 +654,14 @@ CONFIG_I2C_CHARDEV=y
 #
 # I2C Algorithms
 #
-# CONFIG_I2C_ALGOBIT is not set
+CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_ALGOPCF is not set
 # CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
 #
-CONFIG_I2C_AT91=y
+CONFIG_I2C_GPIO=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
--- at91.orig/arch/arm/configs/at91sam9263ek_defconfig	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/configs/at91sam9263ek_defconfig	2007-10-21 10:38:07.000000000 -0700
@@ -677,14 +677,14 @@ CONFIG_I2C_CHARDEV=y
 #
 # I2C Algorithms
 #
-# CONFIG_I2C_ALGOBIT is not set
+CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_ALGOPCF is not set
 # CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
 #
-CONFIG_I2C_AT91=y
+CONFIG_I2C_GPIO=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
--- at91.orig/arch/arm/configs/ateb9200_defconfig	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/configs/ateb9200_defconfig	2007-10-21 10:38:07.000000000 -0700
@@ -714,7 +714,7 @@ CONFIG_I2C_ALGOPCA=m
 #
 # I2C Hardware Bus support
 #
-CONFIG_I2C_AT91=m
+CONFIG_I2C_GPIO=m
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
 # CONFIG_I2C_PCA_ISA is not set
--- at91.orig/arch/arm/configs/csb337_defconfig	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/configs/csb337_defconfig	2007-10-21 10:38:07.000000000 -0700
@@ -657,14 +657,14 @@ CONFIG_I2C_CHARDEV=y
 #
 # I2C Algorithms
 #
-# CONFIG_I2C_ALGOBIT is not set
+CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_ALGOPCF is not set
 # CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
 #
-CONFIG_I2C_AT91=y
+CONFIG_I2C_GPIO=y
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
 # CONFIG_I2C_PCA_ISA is not set
--- at91.orig/arch/arm/configs/csb637_defconfig	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/configs/csb637_defconfig	2007-10-21 10:38:07.000000000 -0700
@@ -658,14 +658,14 @@ CONFIG_I2C_CHARDEV=y
 #
 # I2C Algorithms
 #
-# CONFIG_I2C_ALGOBIT is not set
+CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_ALGOPCF is not set
 # CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
 #
-CONFIG_I2C_AT91=y
+CONFIG_I2C_GPIO=y
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
 # CONFIG_I2C_PCA_ISA is not set
--- at91.orig/arch/arm/configs/kafa_defconfig	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/configs/kafa_defconfig	2007-10-21 10:38:07.000000000 -0700
@@ -587,14 +587,14 @@ CONFIG_I2C_CHARDEV=y
 #
 # I2C Algorithms
 #
-# CONFIG_I2C_ALGOBIT is not set
+CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_ALGOPCF is not set
 # CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
 #
-CONFIG_I2C_AT91=y
+CONFIG_I2C_GPIO=y
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set
 # CONFIG_I2C_PCA_ISA is not set
--- at91.orig/arch/arm/configs/picotux200_defconfig	2007-10-21 10:37:18.000000000 -0700
+++ at91/arch/arm/configs/picotux200_defconfig	2007-10-21 10:38:07.000000000 -0700
@@ -727,14 +727,14 @@ CONFIG_I2C_CHARDEV=m
 #
 # I2C Algorithms
 #
-# CONFIG_I2C_ALGOBIT is not set
+CONFIG_I2C_ALGOBIT=m
 # CONFIG_I2C_ALGOPCF is not set
 # CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
 #
-CONFIG_I2C_AT91=m
+CONFIG_I2C_GPIO=m
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_STUB is not set



More information about the i2c mailing list