diff options
author | Nikolaus Voss <n.voss@weinmann.de> | 2011-11-08 05:49:46 -0500 |
---|---|---|
committer | Wolfram Sang <w.sang@pengutronix.de> | 2012-09-12 08:49:13 -0400 |
commit | fac368a040484293006bb488e67972aafcf88ec7 (patch) | |
tree | 9c132f85cd1a0df4cb1dedcd48d90d2bbb15e6b8 /arch/arm | |
parent | a879e9c34b93ee43f5caa7f94eb17e7af4f6ef50 (diff) |
i2c: at91: add new driver
This driver has the following properties compared to the old driver:
1. Support for multiple interfaces.
2. Interrupt driven I/O as opposed to polling/busy waiting.
3. Support for _one_ repeated start (Sr) condition, which is enough
for most real-world applications including all SMBus transfer types.
(The hardware does not support issuing arbitrary Sr conditions on the
bus.)
testing: SoC: at91sam9g45
- BQ20Z80 battery SMBus client.
- on a 2.6.38 kernel with several i2c clients (temp-sensor,
audio-codec, touchscreen-controller, w1-bridge, io-expanders)
Signed-off-by: Nikolaus Voss <n.voss@weinmann.de>
Reviewed-by: Felipe Balbi <balbi@ti.com>
Tested-by: Hubert Feurstein <h.feurstein@gmail.com>
Tested-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Reviewed-by: Nicolas Ferre <nicolas.ferre@atmel.com>
[wsa: squashed with the following patches from Ludovic to have some flaws
fixed:
i2c: at91: use managed resources
i2c: at91: add warning about transmission issues for some devices
i2c: at91: use an id table for SoC dependent parameters
]
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-at91/at91rm9200.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91rm9200_devices.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9260.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9260_devices.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9261.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9261_devices.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9263.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9263_devices.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9g45.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9g45_devices.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9rl.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9rl_devices.c | 2 |
12 files changed, 29 insertions, 15 deletions
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index f2112f9c1800..b4f0565aff63 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c | |||
@@ -187,7 +187,7 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
187 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | 187 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), |
188 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 188 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), |
189 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), | 189 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), |
190 | CLKDEV_CON_DEV_ID(NULL, "at91_i2c", &twi_clk), | 190 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200", &twi_clk), |
191 | /* fake hclk clock */ | 191 | /* fake hclk clock */ |
192 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), | 192 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), |
193 | CLKDEV_CON_ID("pioA", &pioA_clk), | 193 | CLKDEV_CON_ID("pioA", &pioA_clk), |
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 01fb7325fecc..0b972f2e57eb 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c | |||
@@ -495,7 +495,7 @@ static struct resource twi_resources[] = { | |||
495 | }; | 495 | }; |
496 | 496 | ||
497 | static struct platform_device at91rm9200_twi_device = { | 497 | static struct platform_device at91rm9200_twi_device = { |
498 | .name = "at91_i2c", | 498 | .name = "i2c-at91rm9200", |
499 | .id = -1, | 499 | .id = -1, |
500 | .resource = twi_resources, | 500 | .resource = twi_resources, |
501 | .num_resources = ARRAY_SIZE(twi_resources), | 501 | .num_resources = ARRAY_SIZE(twi_resources), |
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 57c79eed5fd0..5bd19a442365 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c | |||
@@ -211,7 +211,8 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
211 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), | 211 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), |
212 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), | 212 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), |
213 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), | 213 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), |
214 | CLKDEV_CON_DEV_ID(NULL, "at91_i2c", &twi_clk), | 214 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk), |
215 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20", &twi_clk), | ||
215 | /* more usart lookup table for DT entries */ | 216 | /* more usart lookup table for DT entries */ |
216 | CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), | 217 | CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), |
217 | CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk), | 218 | CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk), |
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index bce572a530ef..95fc23aab432 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c | |||
@@ -503,7 +503,6 @@ static struct resource twi_resources[] = { | |||
503 | }; | 503 | }; |
504 | 504 | ||
505 | static struct platform_device at91sam9260_twi_device = { | 505 | static struct platform_device at91sam9260_twi_device = { |
506 | .name = "at91_i2c", | ||
507 | .id = -1, | 506 | .id = -1, |
508 | .resource = twi_resources, | 507 | .resource = twi_resources, |
509 | .num_resources = ARRAY_SIZE(twi_resources), | 508 | .num_resources = ARRAY_SIZE(twi_resources), |
@@ -511,6 +510,13 @@ static struct platform_device at91sam9260_twi_device = { | |||
511 | 510 | ||
512 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | 511 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) |
513 | { | 512 | { |
513 | /* IP version is not the same on 9260 and g20 */ | ||
514 | if (cpu_is_at91sam9g20()) { | ||
515 | at91sam9260_twi_device.name = "i2c-at91sam9g20"; | ||
516 | } else { | ||
517 | at91sam9260_twi_device.name = "i2c-at91sam9260"; | ||
518 | } | ||
519 | |||
514 | /* pins used for TWI interface */ | 520 | /* pins used for TWI interface */ |
515 | at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ | 521 | at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ |
516 | at91_set_multi_drive(AT91_PIN_PA23, 1); | 522 | at91_set_multi_drive(AT91_PIN_PA23, 1); |
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 71ca1e06a16f..8d999eb1a137 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c | |||
@@ -178,7 +178,8 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
178 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 178 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), |
179 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), | 179 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), |
180 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), | 180 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), |
181 | CLKDEV_CON_DEV_ID(NULL, "at91_i2c", &twi_clk), | 181 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261", &twi_clk), |
182 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10", &twi_clk), | ||
182 | CLKDEV_CON_ID("pioA", &pioA_clk), | 183 | CLKDEV_CON_ID("pioA", &pioA_clk), |
183 | CLKDEV_CON_ID("pioB", &pioB_clk), | 184 | CLKDEV_CON_ID("pioB", &pioB_clk), |
184 | CLKDEV_CON_ID("pioC", &pioC_clk), | 185 | CLKDEV_CON_ID("pioC", &pioC_clk), |
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index bc2590d712d0..29188ef7422b 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c | |||
@@ -317,7 +317,6 @@ static struct resource twi_resources[] = { | |||
317 | }; | 317 | }; |
318 | 318 | ||
319 | static struct platform_device at91sam9261_twi_device = { | 319 | static struct platform_device at91sam9261_twi_device = { |
320 | .name = "at91_i2c", | ||
321 | .id = -1, | 320 | .id = -1, |
322 | .resource = twi_resources, | 321 | .resource = twi_resources, |
323 | .num_resources = ARRAY_SIZE(twi_resources), | 322 | .num_resources = ARRAY_SIZE(twi_resources), |
@@ -325,6 +324,13 @@ static struct platform_device at91sam9261_twi_device = { | |||
325 | 324 | ||
326 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) | 325 | void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) |
327 | { | 326 | { |
327 | /* IP version is not the same on 9261 and g10 */ | ||
328 | if (cpu_is_at91sam9g10()) { | ||
329 | at91sam9261_twi_device.name = "i2c-at91sam9g10"; | ||
330 | } else { | ||
331 | at91sam9261_twi_device.name = "i2c-at91sam9261"; | ||
332 | } | ||
333 | |||
328 | /* pins used for TWI interface */ | 334 | /* pins used for TWI interface */ |
329 | at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */ | 335 | at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */ |
330 | at91_set_multi_drive(AT91_PIN_PA7, 1); | 336 | at91_set_multi_drive(AT91_PIN_PA7, 1); |
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 2a08305b6571..e6b595658e75 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c | |||
@@ -193,7 +193,7 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
193 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), | 193 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), |
194 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), | 194 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), |
195 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), | 195 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), |
196 | CLKDEV_CON_DEV_ID(NULL, "at91_i2c", &twi_clk), | 196 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk), |
197 | /* fake hclk clock */ | 197 | /* fake hclk clock */ |
198 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), | 198 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), |
199 | CLKDEV_CON_ID("pioA", &pioA_clk), | 199 | CLKDEV_CON_ID("pioA", &pioA_clk), |
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 9b6ca734f1a9..3f5288ea64b9 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c | |||
@@ -574,7 +574,7 @@ static struct resource twi_resources[] = { | |||
574 | }; | 574 | }; |
575 | 575 | ||
576 | static struct platform_device at91sam9263_twi_device = { | 576 | static struct platform_device at91sam9263_twi_device = { |
577 | .name = "at91_i2c", | 577 | .name = "i2c-at91sam9260", |
578 | .id = -1, | 578 | .id = -1, |
579 | .resource = twi_resources, | 579 | .resource = twi_resources, |
580 | .num_resources = ARRAY_SIZE(twi_resources), | 580 | .num_resources = ARRAY_SIZE(twi_resources), |
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index ddf3d3707c54..858f032e5102 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c | |||
@@ -237,8 +237,8 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
237 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), | 237 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), |
238 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk), | 238 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk), |
239 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk), | 239 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk), |
240 | CLKDEV_CON_DEV_ID(NULL, "at91_i2c.0", &twi0_clk), | 240 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi0_clk), |
241 | CLKDEV_CON_DEV_ID(NULL, "at91_i2c.1", &twi1_clk), | 241 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.1", &twi1_clk), |
242 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | 242 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), |
243 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 243 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), |
244 | CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk), | 244 | CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk), |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 1b47319ca00b..ac1b0f8c3b31 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -653,7 +653,7 @@ static struct resource twi0_resources[] = { | |||
653 | }; | 653 | }; |
654 | 654 | ||
655 | static struct platform_device at91sam9g45_twi0_device = { | 655 | static struct platform_device at91sam9g45_twi0_device = { |
656 | .name = "at91_i2c", | 656 | .name = "i2c-at91sam9g10", |
657 | .id = 0, | 657 | .id = 0, |
658 | .resource = twi0_resources, | 658 | .resource = twi0_resources, |
659 | .num_resources = ARRAY_SIZE(twi0_resources), | 659 | .num_resources = ARRAY_SIZE(twi0_resources), |
@@ -673,7 +673,7 @@ static struct resource twi1_resources[] = { | |||
673 | }; | 673 | }; |
674 | 674 | ||
675 | static struct platform_device at91sam9g45_twi1_device = { | 675 | static struct platform_device at91sam9g45_twi1_device = { |
676 | .name = "at91_i2c", | 676 | .name = "i2c-at91sam9g10", |
677 | .id = 1, | 677 | .id = 1, |
678 | .resource = twi1_resources, | 678 | .resource = twi1_resources, |
679 | .num_resources = ARRAY_SIZE(twi1_resources), | 679 | .num_resources = ARRAY_SIZE(twi1_resources), |
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index bf79c1fd5939..72e908412222 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c | |||
@@ -186,8 +186,8 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
186 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), | 186 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), |
187 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), | 187 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), |
188 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), | 188 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), |
189 | CLKDEV_CON_DEV_ID(NULL, "at91_i2c.0", &twi0_clk), | 189 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk), |
190 | CLKDEV_CON_DEV_ID(NULL, "at91_i2c.1", &twi1_clk), | 190 | CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk), |
191 | CLKDEV_CON_ID("pioA", &pioA_clk), | 191 | CLKDEV_CON_ID("pioA", &pioA_clk), |
192 | CLKDEV_CON_ID("pioB", &pioB_clk), | 192 | CLKDEV_CON_ID("pioB", &pioB_clk), |
193 | CLKDEV_CON_ID("pioC", &pioC_clk), | 193 | CLKDEV_CON_ID("pioC", &pioC_clk), |
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index b3d365dadef5..0794954953e5 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c | |||
@@ -346,7 +346,7 @@ static struct resource twi_resources[] = { | |||
346 | }; | 346 | }; |
347 | 347 | ||
348 | static struct platform_device at91sam9rl_twi_device = { | 348 | static struct platform_device at91sam9rl_twi_device = { |
349 | .name = "at91_i2c", | 349 | .name = "i2c-at91sam9g20", |
350 | .id = -1, | 350 | .id = -1, |
351 | .resource = twi_resources, | 351 | .resource = twi_resources, |
352 | .num_resources = ARRAY_SIZE(twi_resources), | 352 | .num_resources = ARRAY_SIZE(twi_resources), |