diff options
author | Andrew Victor <andrew@sanpeople.com> | 2007-11-19 07:47:20 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-11-26 14:40:47 -0500 |
commit | f230d3f53d72d05bcb5666ab7e2eccd49c8b3a15 (patch) | |
tree | 0d06454868ca879f06a268de71beb0b1ba6a08d7 /arch/arm/mach-at91/at91sam9rl_devices.c | |
parent | a95c729b7484d2bbb9ab6beef4865641e73deb99 (diff) |
[ARM] 4650/1: AT91: New-style init of I2C, support for i2c-gpio
The AT91 I2C driver is currently marked as "broken" due to hardware
issues. This patch enables AT91-based platforms to also use the
bitbanged GPIO for I2C.
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).
Also make use of the new-style initialization of I2C devices using
i2c_register_board_info().
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-at91/at91sam9rl_devices.c')
-rw-r--r-- | arch/arm/mach-at91/at91sam9rl_devices.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index cd7532bcd4e5..2bd60a3dc623 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c | |||
@@ -10,8 +10,9 @@ | |||
10 | #include <asm/mach/map.h> | 10 | #include <asm/mach/map.h> |
11 | 11 | ||
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/fb.h> | 13 | #include <linux/i2c-gpio.h> |
14 | 14 | ||
15 | #include <linux/fb.h> | ||
15 | #include <video/atmel_lcdc.h> | 16 | #include <video/atmel_lcdc.h> |
16 | 17 | ||
17 | #include <asm/arch/board.h> | 18 | #include <asm/arch/board.h> |
@@ -169,7 +170,40 @@ void __init at91_add_device_nand(struct at91_nand_data *data) {} | |||
169 | * TWI (i2c) | 170 | * TWI (i2c) |
170 | * -------------------------------------------------------------------- */ | 171 | * -------------------------------------------------------------------- */ |
171 | 172 | ||
172 | #if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | 173 | /* |
174 | * Prefer the GPIO code since the TWI controller isn't robust | ||
175 | * (gets overruns and underruns under load) and can only issue | ||
176 | * repeated STARTs in one scenario (the driver doesn't yet handle them). | ||
177 | */ | ||
178 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) | ||
179 | |||
180 | static struct i2c_gpio_platform_data pdata = { | ||
181 | .sda_pin = AT91_PIN_PA23, | ||
182 | .sda_is_open_drain = 1, | ||
183 | .scl_pin = AT91_PIN_PA24, | ||
184 | .scl_is_open_drain = 1, | ||
185 | .udelay = 2, /* ~100 kHz */ | ||
186 | }; | ||
187 | |||
188 | static struct platform_device at91sam9rl_twi_device = { | ||
189 | .name = "i2c-gpio", | ||
190 | .id = -1, | ||
191 | .dev.platform_data = &pdata, | ||
192 | }; | ||
193 | |||
194 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | ||
195 | { | ||
196 | at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */ | ||
197 | at91_set_multi_drive(AT91_PIN_PA23, 1); | ||
198 | |||
199 | at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */ | ||
200 | at91_set_multi_drive(AT91_PIN_PA24, 1); | ||
201 | |||
202 | i2c_register_board_info(0, devices, nr_devices); | ||
203 | platform_device_register(&at91sam9rl_twi_device); | ||
204 | } | ||
205 | |||
206 | #elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | ||
173 | 207 | ||
174 | static struct resource twi_resources[] = { | 208 | static struct resource twi_resources[] = { |
175 | [0] = { | 209 | [0] = { |
@@ -191,7 +225,7 @@ static struct platform_device at91sam9rl_twi_device = { | |||
191 | .num_resources = ARRAY_SIZE(twi_resources), | 225 | .num_resources = ARRAY_SIZE(twi_resources), |
192 | }; | 226 | }; |
193 | 227 | ||
194 | void __init at91_add_device_i2c(void) | 228 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) |
195 | { | 229 | { |
196 | /* pins used for TWI interface */ | 230 | /* pins used for TWI interface */ |
197 | at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ | 231 | at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ |
@@ -200,10 +234,11 @@ void __init at91_add_device_i2c(void) | |||
200 | at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */ | 234 | at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */ |
201 | at91_set_multi_drive(AT91_PIN_PA24, 1); | 235 | at91_set_multi_drive(AT91_PIN_PA24, 1); |
202 | 236 | ||
237 | i2c_register_board_info(0, devices, nr_devices); | ||
203 | platform_device_register(&at91sam9rl_twi_device); | 238 | platform_device_register(&at91sam9rl_twi_device); |
204 | } | 239 | } |
205 | #else | 240 | #else |
206 | void __init at91_add_device_i2c(void) {} | 241 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} |
207 | #endif | 242 | #endif |
208 | 243 | ||
209 | 244 | ||