diff options
author | David Brownell <david-b@pacbell.net> | 2007-10-13 17:56:30 -0400 |
---|---|---|
committer | Jean Delvare <khali@hyperion.delvare> | 2007-10-13 17:56:30 -0400 |
commit | 8056c6cb2bb1632aa9221dce0e43a61db37b420f (patch) | |
tree | 4ca321bba9db87c80c77f841c9a52c456be63aa5 | |
parent | b5067f8ff37ed6cfa024170a9819bb09d55e9c1f (diff) |
i2c/tps65010: New-style driver updates, part 2
Switch the tps65010 driver into a "new-style" I2C driver, and convert all
of its in-tree users (board support for OSK, H2, H3) accordingly.
That accounts for most of the board-specific code in this driver; the
rest of that code is now moved into board-specific initcalls.
Also remove some of the many now-superfluous #includes.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r-- | arch/arm/mach-omap1/board-h2.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-h3.c | 39 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-osk.c | 64 | ||||
-rw-r--r-- | drivers/i2c/chips/tps65010.c | 184 |
4 files changed, 181 insertions, 151 deletions
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 48c8c9195dc3..2f8f6ecf111f 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c | |||
@@ -20,22 +20,23 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/init.h> | ||
24 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
25 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/i2c.h> | ||
26 | #include <linux/mtd/mtd.h> | 26 | #include <linux/mtd/mtd.h> |
27 | #include <linux/mtd/nand.h> | 27 | #include <linux/mtd/nand.h> |
28 | #include <linux/mtd/partitions.h> | 28 | #include <linux/mtd/partitions.h> |
29 | #include <linux/input.h> | 29 | #include <linux/input.h> |
30 | #include <linux/workqueue.h> | ||
31 | 30 | ||
32 | #include <asm/hardware.h> | 31 | #include <asm/hardware.h> |
32 | #include <asm/gpio.h> | ||
33 | |||
33 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
34 | #include <asm/mach/arch.h> | 35 | #include <asm/mach/arch.h> |
35 | #include <asm/mach/flash.h> | 36 | #include <asm/mach/flash.h> |
36 | #include <asm/mach/map.h> | 37 | #include <asm/mach/map.h> |
37 | 38 | ||
38 | #include <asm/arch/gpio.h> | 39 | #include <asm/arch/tps65010.h> |
39 | #include <asm/arch/mux.h> | 40 | #include <asm/arch/mux.h> |
40 | #include <asm/arch/tc.h> | 41 | #include <asm/arch/tc.h> |
41 | #include <asm/arch/irda.h> | 42 | #include <asm/arch/irda.h> |
@@ -277,6 +278,20 @@ static struct platform_device *h2_devices[] __initdata = { | |||
277 | &h2_mcbsp1_device, | 278 | &h2_mcbsp1_device, |
278 | }; | 279 | }; |
279 | 280 | ||
281 | static struct i2c_board_info __initdata h2_i2c_board_info[] = { | ||
282 | { | ||
283 | I2C_BOARD_INFO("tps65010", 0x48), | ||
284 | .type = "tps65010", | ||
285 | .irq = OMAP_GPIO_IRQ(58), | ||
286 | }, | ||
287 | /* TODO when driver support is ready: | ||
288 | * - isp1301 OTG transceiver | ||
289 | * - optional ov9640 camera sensor at 0x30 | ||
290 | * - pcf9754 for aGPS control | ||
291 | * - ... etc | ||
292 | */ | ||
293 | }; | ||
294 | |||
280 | static void __init h2_init_smc91x(void) | 295 | static void __init h2_init_smc91x(void) |
281 | { | 296 | { |
282 | if ((omap_request_gpio(0)) < 0) { | 297 | if ((omap_request_gpio(0)) < 0) { |
@@ -367,6 +382,14 @@ static void __init h2_init(void) | |||
367 | omap_board_config = h2_config; | 382 | omap_board_config = h2_config; |
368 | omap_board_config_size = ARRAY_SIZE(h2_config); | 383 | omap_board_config_size = ARRAY_SIZE(h2_config); |
369 | omap_serial_init(); | 384 | omap_serial_init(); |
385 | |||
386 | /* irq for tps65010 chip */ | ||
387 | omap_cfg_reg(W4_GPIO58); | ||
388 | if (gpio_request(58, "tps65010") == 0) | ||
389 | gpio_direction_input(58); | ||
390 | |||
391 | i2c_register_board_info(1, h2_i2c_board_info, | ||
392 | ARRAY_SIZE(h2_i2c_board_info)); | ||
370 | } | 393 | } |
371 | 394 | ||
372 | static void __init h2_map_io(void) | 395 | static void __init h2_map_io(void) |
@@ -374,6 +397,22 @@ static void __init h2_map_io(void) | |||
374 | omap1_map_common_io(); | 397 | omap1_map_common_io(); |
375 | } | 398 | } |
376 | 399 | ||
400 | #ifdef CONFIG_TPS65010 | ||
401 | static int __init h2_tps_init(void) | ||
402 | { | ||
403 | if (!machine_is_omap_h2()) | ||
404 | return 0; | ||
405 | |||
406 | /* gpio3 for SD, gpio4 for VDD_DSP */ | ||
407 | /* FIXME send power to DSP iff it's configured */ | ||
408 | |||
409 | /* Enable LOW_PWR */ | ||
410 | tps65010_set_low_pwr(ON); | ||
411 | return 0; | ||
412 | } | ||
413 | fs_initcall(h2_tps_init); | ||
414 | #endif | ||
415 | |||
377 | MACHINE_START(OMAP_H2, "TI-H2") | 416 | MACHINE_START(OMAP_H2, "TI-H2") |
378 | /* Maintainer: Imre Deak <imre.deak@nokia.com> */ | 417 | /* Maintainer: Imre Deak <imre.deak@nokia.com> */ |
379 | .phys_io = 0xfff00000, | 418 | .phys_io = 0xfff00000, |
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 79d4ef4c54d4..add2f703204f 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
24 | #include <linux/i2c.h> | ||
24 | #include <linux/mtd/mtd.h> | 25 | #include <linux/mtd/mtd.h> |
25 | #include <linux/mtd/nand.h> | 26 | #include <linux/mtd/nand.h> |
26 | #include <linux/mtd/partitions.h> | 27 | #include <linux/mtd/partitions.h> |
@@ -29,12 +30,14 @@ | |||
29 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
30 | #include <asm/page.h> | 31 | #include <asm/page.h> |
31 | #include <asm/hardware.h> | 32 | #include <asm/hardware.h> |
33 | #include <asm/gpio.h> | ||
34 | |||
32 | #include <asm/mach-types.h> | 35 | #include <asm/mach-types.h> |
33 | #include <asm/mach/arch.h> | 36 | #include <asm/mach/arch.h> |
34 | #include <asm/mach/flash.h> | 37 | #include <asm/mach/flash.h> |
35 | #include <asm/mach/map.h> | 38 | #include <asm/mach/map.h> |
36 | 39 | ||
37 | #include <asm/arch/gpio.h> | 40 | #include <asm/arch/tps65010.h> |
38 | #include <asm/arch/gpioexpander.h> | 41 | #include <asm/arch/gpioexpander.h> |
39 | #include <asm/arch/irqs.h> | 42 | #include <asm/arch/irqs.h> |
40 | #include <asm/arch/mux.h> | 43 | #include <asm/arch/mux.h> |
@@ -413,6 +416,19 @@ static struct omap_board_config_kernel h3_config[] = { | |||
413 | { OMAP_TAG_LCD, &h3_lcd_config }, | 416 | { OMAP_TAG_LCD, &h3_lcd_config }, |
414 | }; | 417 | }; |
415 | 418 | ||
419 | static struct i2c_board_info __initdata h3_i2c_board_info[] = { | ||
420 | { | ||
421 | I2C_BOARD_INFO("tps65010", 0x48), | ||
422 | .type = "tps65013", | ||
423 | /* .irq = OMAP_GPIO_IRQ(??), */ | ||
424 | }, | ||
425 | /* TODO when driver support is ready: | ||
426 | * - isp1301 OTG transceiver | ||
427 | * - optional ov9640 camera sensor at 0x30 | ||
428 | * - ... | ||
429 | */ | ||
430 | }; | ||
431 | |||
416 | #define H3_NAND_RB_GPIO_PIN 10 | 432 | #define H3_NAND_RB_GPIO_PIN 10 |
417 | 433 | ||
418 | static int nand_dev_ready(struct nand_platform_data *data) | 434 | static int nand_dev_ready(struct nand_platform_data *data) |
@@ -446,6 +462,10 @@ static void __init h3_init(void) | |||
446 | omap_board_config = h3_config; | 462 | omap_board_config = h3_config; |
447 | omap_board_config_size = ARRAY_SIZE(h3_config); | 463 | omap_board_config_size = ARRAY_SIZE(h3_config); |
448 | omap_serial_init(); | 464 | omap_serial_init(); |
465 | |||
466 | /* FIXME setup irq for tps65013 chip */ | ||
467 | i2c_register_board_info(1, h3_i2c_board_info, | ||
468 | ARRAY_SIZE(h3_i2c_board_info)); | ||
449 | } | 469 | } |
450 | 470 | ||
451 | static void __init h3_init_smc91x(void) | 471 | static void __init h3_init_smc91x(void) |
@@ -470,6 +490,23 @@ static void __init h3_map_io(void) | |||
470 | omap1_map_common_io(); | 490 | omap1_map_common_io(); |
471 | } | 491 | } |
472 | 492 | ||
493 | #ifdef CONFIG_TPS65010 | ||
494 | static int __init h3_tps_init(void) | ||
495 | { | ||
496 | if (!machine_is_omap_h3()) | ||
497 | return 0; | ||
498 | |||
499 | /* gpio4 for SD, gpio3 for VDD_DSP */ | ||
500 | /* FIXME send power to DSP iff it's configured */ | ||
501 | |||
502 | /* Enable LOW_PWR */ | ||
503 | tps65013_set_low_pwr(ON); | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | fs_initcall(h3_tps_init); | ||
508 | #endif | ||
509 | |||
473 | MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") | 510 | MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") |
474 | /* Maintainer: Texas Instruments, Inc. */ | 511 | /* Maintainer: Texas Instruments, Inc. */ |
475 | .phys_io = 0xfff00000, | 512 | .phys_io = 0xfff00000, |
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index e7130293a03f..a61bf455ee02 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c | |||
@@ -31,18 +31,21 @@ | |||
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/irq.h> | 32 | #include <linux/irq.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/i2c.h> | ||
34 | 35 | ||
35 | #include <linux/mtd/mtd.h> | 36 | #include <linux/mtd/mtd.h> |
36 | #include <linux/mtd/partitions.h> | 37 | #include <linux/mtd/partitions.h> |
37 | 38 | ||
38 | #include <asm/hardware.h> | 39 | #include <asm/hardware.h> |
40 | #include <asm/gpio.h> | ||
41 | |||
39 | #include <asm/mach-types.h> | 42 | #include <asm/mach-types.h> |
40 | #include <asm/mach/arch.h> | 43 | #include <asm/mach/arch.h> |
41 | #include <asm/mach/map.h> | 44 | #include <asm/mach/map.h> |
42 | #include <asm/mach/flash.h> | 45 | #include <asm/mach/flash.h> |
43 | 46 | ||
44 | #include <asm/arch/gpio.h> | ||
45 | #include <asm/arch/usb.h> | 47 | #include <asm/arch/usb.h> |
48 | #include <asm/arch/tps65010.h> | ||
46 | #include <asm/arch/mux.h> | 49 | #include <asm/arch/mux.h> |
47 | #include <asm/arch/tc.h> | 50 | #include <asm/arch/tc.h> |
48 | #include <asm/arch/common.h> | 51 | #include <asm/arch/common.h> |
@@ -179,6 +182,19 @@ static struct platform_device *osk5912_devices[] __initdata = { | |||
179 | &osk5912_mcbsp1_device, | 182 | &osk5912_mcbsp1_device, |
180 | }; | 183 | }; |
181 | 184 | ||
185 | static struct i2c_board_info __initdata osk_i2c_board_info[] = { | ||
186 | { | ||
187 | I2C_BOARD_INFO("tps65010", 0x48), | ||
188 | .type = "tps65010", | ||
189 | .irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)), | ||
190 | }, | ||
191 | /* TODO when driver support is ready: | ||
192 | * - aic23 audio chip at 0x1a | ||
193 | * - on Mistral, 24c04 eeprom at 0x50 | ||
194 | * - optionally on Mistral, ov9640 camera sensor at 0x30 | ||
195 | */ | ||
196 | }; | ||
197 | |||
182 | static void __init osk_init_smc91x(void) | 198 | static void __init osk_init_smc91x(void) |
183 | { | 199 | { |
184 | if ((omap_request_gpio(0)) < 0) { | 200 | if ((omap_request_gpio(0)) < 0) { |
@@ -397,6 +413,14 @@ static void __init osk_init(void) | |||
397 | omap_board_config_size = ARRAY_SIZE(osk_config); | 413 | omap_board_config_size = ARRAY_SIZE(osk_config); |
398 | USB_TRANSCEIVER_CTRL_REG |= (3 << 1); | 414 | USB_TRANSCEIVER_CTRL_REG |= (3 << 1); |
399 | 415 | ||
416 | /* irq for tps65010 chip */ | ||
417 | /* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */ | ||
418 | if (gpio_request(OMAP_MPUIO(1), "tps65010") == 0) | ||
419 | gpio_direction_input(OMAP_MPUIO(1)); | ||
420 | |||
421 | i2c_register_board_info(1, osk_i2c_board_info, | ||
422 | ARRAY_SIZE(osk_i2c_board_info)); | ||
423 | |||
400 | omap_serial_init(); | 424 | omap_serial_init(); |
401 | osk_mistral_init(); | 425 | osk_mistral_init(); |
402 | } | 426 | } |
@@ -406,6 +430,44 @@ static void __init osk_map_io(void) | |||
406 | omap1_map_common_io(); | 430 | omap1_map_common_io(); |
407 | } | 431 | } |
408 | 432 | ||
433 | #ifdef CONFIG_TPS65010 | ||
434 | static int __init osk_tps_init(void) | ||
435 | { | ||
436 | if (!machine_is_omap_osk()) | ||
437 | return 0; | ||
438 | |||
439 | /* Let LED1 (D9) blink */ | ||
440 | tps65010_set_led(LED1, BLINK); | ||
441 | |||
442 | /* Disable LED 2 (D2) */ | ||
443 | tps65010_set_led(LED2, OFF); | ||
444 | |||
445 | /* Set GPIO 1 HIGH to disable VBUS power supply; | ||
446 | * OHCI driver powers it up/down as needed. | ||
447 | */ | ||
448 | tps65010_set_gpio_out_value(GPIO1, HIGH); | ||
449 | |||
450 | /* Set GPIO 2 low to turn on LED D3 */ | ||
451 | tps65010_set_gpio_out_value(GPIO2, HIGH); | ||
452 | |||
453 | /* Set GPIO 3 low to take ethernet out of reset */ | ||
454 | tps65010_set_gpio_out_value(GPIO3, LOW); | ||
455 | |||
456 | /* gpio4 for VDD_DSP */ | ||
457 | /* FIXME send power to DSP iff it's configured */ | ||
458 | |||
459 | /* Enable LOW_PWR */ | ||
460 | tps65010_set_low_pwr(ON); | ||
461 | |||
462 | /* Switch VLDO2 to 3.0V for AIC23 */ | ||
463 | tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V | ||
464 | | TPS_LDO1_ENABLE); | ||
465 | |||
466 | return 0; | ||
467 | } | ||
468 | fs_initcall(osk_tps_init); | ||
469 | #endif | ||
470 | |||
409 | MACHINE_START(OMAP_OSK, "TI-OSK") | 471 | MACHINE_START(OMAP_OSK, "TI-OSK") |
410 | /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ | 472 | /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ |
411 | .phys_io = 0xfff00000, | 473 | .phys_io = 0xfff00000, |
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c index 402d911a9e7b..e320994b981c 100644 --- a/drivers/i2c/chips/tps65010.c +++ b/drivers/i2c/chips/tps65010.c | |||
@@ -24,20 +24,13 @@ | |||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/device.h> | ||
28 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
29 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
30 | #include <linux/workqueue.h> | 29 | #include <linux/workqueue.h> |
31 | #include <linux/suspend.h> | ||
32 | #include <linux/debugfs.h> | 30 | #include <linux/debugfs.h> |
33 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
34 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
35 | 33 | ||
36 | #include <asm/irq.h> | ||
37 | #include <asm/mach-types.h> | ||
38 | |||
39 | #include <asm/arch/gpio.h> | ||
40 | #include <asm/arch/mux.h> | ||
41 | #include <asm/arch/tps65010.h> | 34 | #include <asm/arch/tps65010.h> |
42 | 35 | ||
43 | /*-------------------------------------------------------------------------*/ | 36 | /*-------------------------------------------------------------------------*/ |
@@ -48,10 +41,6 @@ | |||
48 | MODULE_DESCRIPTION("TPS6501x Power Management Driver"); | 41 | MODULE_DESCRIPTION("TPS6501x Power Management Driver"); |
49 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
50 | 43 | ||
51 | static unsigned short normal_i2c[] = { 0x48, /* 0x49, */ I2C_CLIENT_END }; | ||
52 | |||
53 | I2C_CLIENT_INSMOD; | ||
54 | |||
55 | static struct i2c_driver tps65010_driver; | 44 | static struct i2c_driver tps65010_driver; |
56 | 45 | ||
57 | /*-------------------------------------------------------------------------*/ | 46 | /*-------------------------------------------------------------------------*/ |
@@ -79,10 +68,8 @@ enum tps_model { | |||
79 | }; | 68 | }; |
80 | 69 | ||
81 | struct tps65010 { | 70 | struct tps65010 { |
82 | struct i2c_client c; | ||
83 | struct i2c_client *client; | 71 | struct i2c_client *client; |
84 | struct mutex lock; | 72 | struct mutex lock; |
85 | int irq; | ||
86 | struct delayed_work work; | 73 | struct delayed_work work; |
87 | struct dentry *file; | 74 | struct dentry *file; |
88 | unsigned charging:1; | 75 | unsigned charging:1; |
@@ -445,7 +432,7 @@ static void tps65010_work(struct work_struct *work) | |||
445 | } | 432 | } |
446 | 433 | ||
447 | if (test_and_clear_bit(FLAG_IRQ_ENABLE, &tps->flags)) | 434 | if (test_and_clear_bit(FLAG_IRQ_ENABLE, &tps->flags)) |
448 | enable_irq(tps->irq); | 435 | enable_irq(tps->client->irq); |
449 | 436 | ||
450 | mutex_unlock(&tps->lock); | 437 | mutex_unlock(&tps->lock); |
451 | } | 438 | } |
@@ -464,116 +451,75 @@ static irqreturn_t tps65010_irq(int irq, void *_tps) | |||
464 | 451 | ||
465 | static struct tps65010 *the_tps; | 452 | static struct tps65010 *the_tps; |
466 | 453 | ||
467 | static int __exit tps65010_detach_client(struct i2c_client *client) | 454 | static int __exit tps65010_remove(struct i2c_client *client) |
468 | { | 455 | { |
469 | struct tps65010 *tps; | 456 | struct tps65010 *tps = i2c_get_clientdata(client); |
470 | 457 | ||
471 | tps = container_of(client, struct tps65010, c); | 458 | if (client->irq > 0) |
472 | free_irq(tps->irq, tps); | 459 | free_irq(client->irq, tps); |
473 | #ifdef CONFIG_ARM | ||
474 | if (machine_is_omap_h2()) | ||
475 | omap_free_gpio(58); | ||
476 | if (machine_is_omap_osk()) | ||
477 | omap_free_gpio(OMAP_MPUIO(1)); | ||
478 | #endif | ||
479 | cancel_delayed_work(&tps->work); | 460 | cancel_delayed_work(&tps->work); |
480 | flush_scheduled_work(); | 461 | flush_scheduled_work(); |
481 | debugfs_remove(tps->file); | 462 | debugfs_remove(tps->file); |
482 | if (i2c_detach_client(client) == 0) | 463 | kfree(tps); |
483 | kfree(tps); | ||
484 | the_tps = NULL; | 464 | the_tps = NULL; |
485 | return 0; | 465 | return 0; |
486 | } | 466 | } |
487 | 467 | ||
488 | static int tps65010_noscan(struct i2c_adapter *bus) | 468 | static int tps65010_probe(struct i2c_client *client) |
489 | { | ||
490 | /* pure paranoia, in case someone adds another i2c bus | ||
491 | * after our init section's gone... | ||
492 | */ | ||
493 | return -ENODEV; | ||
494 | } | ||
495 | |||
496 | /* no error returns, they'd just make bus scanning stop */ | ||
497 | static int __init | ||
498 | tps65010_probe(struct i2c_adapter *bus, int address, int kind) | ||
499 | { | 469 | { |
500 | struct tps65010 *tps; | 470 | struct tps65010 *tps; |
501 | int status; | 471 | int status; |
502 | unsigned long irqflags; | ||
503 | struct i2c_client *client; | ||
504 | 472 | ||
505 | if (the_tps) { | 473 | if (the_tps) { |
506 | dev_dbg(&bus->dev, "only one %s for now\n", DRIVER_NAME); | 474 | dev_dbg(&client->dev, "only one tps6501x chip allowed\n"); |
507 | return 0; | 475 | return -ENODEV; |
508 | } | 476 | } |
509 | 477 | ||
478 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
479 | return -EINVAL; | ||
480 | |||
510 | tps = kzalloc(sizeof *tps, GFP_KERNEL); | 481 | tps = kzalloc(sizeof *tps, GFP_KERNEL); |
511 | if (!tps) | 482 | if (!tps) |
512 | return 0; | 483 | return -ENOMEM; |
513 | 484 | ||
514 | mutex_init(&tps->lock); | 485 | mutex_init(&tps->lock); |
515 | INIT_DELAYED_WORK(&tps->work, tps65010_work); | 486 | INIT_DELAYED_WORK(&tps->work, tps65010_work); |
516 | tps->irq = -1; | 487 | tps->client = client; |
517 | tps->c.addr = address; | ||
518 | tps->c.adapter = bus; | ||
519 | tps->c.driver = &tps65010_driver; | ||
520 | strlcpy(tps->c.name, DRIVER_NAME, I2C_NAME_SIZE); | ||
521 | tps->client = client = &tps->c; | ||
522 | |||
523 | status = i2c_attach_client(client); | ||
524 | if (status < 0) { | ||
525 | dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n", | ||
526 | DRIVER_NAME, address, status); | ||
527 | goto fail1; | ||
528 | } | ||
529 | 488 | ||
530 | /* the IRQ is active low, but many gpio lines can't support that | 489 | if (strcmp(client->name, "tps65010") == 0) |
531 | * so this driver can use falling-edge triggers instead. | ||
532 | */ | ||
533 | irqflags = IRQF_SAMPLE_RANDOM; | ||
534 | #ifdef CONFIG_ARM | ||
535 | if (machine_is_omap_h2()) { | ||
536 | tps->model = TPS65010; | ||
537 | omap_cfg_reg(W4_GPIO58); | ||
538 | tps->irq = OMAP_GPIO_IRQ(58); | ||
539 | omap_request_gpio(58); | ||
540 | omap_set_gpio_direction(58, 1); | ||
541 | irqflags |= IRQF_TRIGGER_FALLING; | ||
542 | } | ||
543 | if (machine_is_omap_osk()) { | ||
544 | tps->model = TPS65010; | 490 | tps->model = TPS65010; |
545 | // omap_cfg_reg(U19_1610_MPUIO1); | 491 | else if (strcmp(client->name, "tps65011") == 0) |
546 | tps->irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)); | 492 | tps->model = TPS65011; |
547 | omap_request_gpio(OMAP_MPUIO(1)); | 493 | else if (strcmp(client->name, "tps65012") == 0) |
548 | omap_set_gpio_direction(OMAP_MPUIO(1), 1); | 494 | tps->model = TPS65012; |
549 | irqflags |= IRQF_TRIGGER_FALLING; | 495 | else if (strcmp(client->name, "tps65013") == 0) |
550 | } | ||
551 | if (machine_is_omap_h3()) { | ||
552 | tps->model = TPS65013; | 496 | tps->model = TPS65013; |
553 | 497 | else { | |
554 | // FIXME set up this board's IRQ ... | 498 | dev_warn(&client->dev, "unknown chip '%s'\n", client->name); |
499 | status = -ENODEV; | ||
500 | goto fail1; | ||
555 | } | 501 | } |
556 | #endif | ||
557 | 502 | ||
558 | if (tps->irq > 0) { | 503 | /* the IRQ is active low, but many gpio lines can't support that |
559 | status = request_irq(tps->irq, tps65010_irq, | 504 | * so this driver uses falling-edge triggers instead. |
560 | irqflags, DRIVER_NAME, tps); | 505 | */ |
506 | if (client->irq > 0) { | ||
507 | status = request_irq(client->irq, tps65010_irq, | ||
508 | IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING, | ||
509 | DRIVER_NAME, tps); | ||
561 | if (status < 0) { | 510 | if (status < 0) { |
562 | dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", | 511 | dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", |
563 | tps->irq, status); | 512 | client->irq, status); |
564 | i2c_detach_client(client); | ||
565 | goto fail1; | 513 | goto fail1; |
566 | } | 514 | } |
567 | #ifdef CONFIG_ARM | ||
568 | /* annoying race here, ideally we'd have an option | 515 | /* annoying race here, ideally we'd have an option |
569 | * to claim the irq now and enable it later. | 516 | * to claim the irq now and enable it later. |
517 | * FIXME genirq IRQF_NOAUTOEN now solves that ... | ||
570 | */ | 518 | */ |
571 | disable_irq(tps->irq); | 519 | disable_irq(client->irq); |
572 | set_bit(FLAG_IRQ_ENABLE, &tps->flags); | 520 | set_bit(FLAG_IRQ_ENABLE, &tps->flags); |
573 | #endif | ||
574 | } else | 521 | } else |
575 | printk(KERN_WARNING "%s: IRQ not configured!\n", | 522 | dev_warn(&client->dev, "IRQ not configured!\n"); |
576 | DRIVER_NAME); | ||
577 | 523 | ||
578 | 524 | ||
579 | switch (tps->model) { | 525 | switch (tps->model) { |
@@ -602,7 +548,6 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) | |||
602 | i2c_smbus_read_byte_data(client, TPS_DEFGPIO), | 548 | i2c_smbus_read_byte_data(client, TPS_DEFGPIO), |
603 | i2c_smbus_read_byte_data(client, TPS_MASK3)); | 549 | i2c_smbus_read_byte_data(client, TPS_MASK3)); |
604 | 550 | ||
605 | tps65010_driver.attach_adapter = tps65010_noscan; | ||
606 | the_tps = tps; | 551 | the_tps = tps; |
607 | 552 | ||
608 | #if defined(CONFIG_USB_GADGET) && !defined(CONFIG_USB_OTG) | 553 | #if defined(CONFIG_USB_GADGET) && !defined(CONFIG_USB_OTG) |
@@ -635,22 +580,15 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) | |||
635 | return 0; | 580 | return 0; |
636 | fail1: | 581 | fail1: |
637 | kfree(tps); | 582 | kfree(tps); |
638 | return 0; | 583 | return status; |
639 | } | ||
640 | |||
641 | static int __init tps65010_scan_bus(struct i2c_adapter *bus) | ||
642 | { | ||
643 | if (!i2c_check_functionality(bus, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
644 | return -EINVAL; | ||
645 | return i2c_probe(bus, &addr_data, tps65010_probe); | ||
646 | } | 584 | } |
647 | 585 | ||
648 | static struct i2c_driver tps65010_driver = { | 586 | static struct i2c_driver tps65010_driver = { |
649 | .driver = { | 587 | .driver = { |
650 | .name = "tps65010", | 588 | .name = "tps65010", |
651 | }, | 589 | }, |
652 | .attach_adapter = tps65010_scan_bus, | 590 | .probe = tps65010_probe, |
653 | .detach_client = __exit_p(tps65010_detach_client), | 591 | .remove = __exit_p(tps65010_remove), |
654 | }; | 592 | }; |
655 | 593 | ||
656 | /*-------------------------------------------------------------------------*/ | 594 | /*-------------------------------------------------------------------------*/ |
@@ -1014,52 +952,6 @@ static int __init tps_init(void) | |||
1014 | msleep(10); | 952 | msleep(10); |
1015 | } | 953 | } |
1016 | 954 | ||
1017 | #ifdef CONFIG_ARM | ||
1018 | if (machine_is_omap_osk()) { | ||
1019 | |||
1020 | // FIXME: More should be placed in the initialization code | ||
1021 | // of the submodules (DSP, ethernet, power management, | ||
1022 | // board-osk.c). Careful: I2C is initialized "late". | ||
1023 | |||
1024 | /* Let LED1 (D9) blink */ | ||
1025 | tps65010_set_led(LED1, BLINK); | ||
1026 | |||
1027 | /* Disable LED 2 (D2) */ | ||
1028 | tps65010_set_led(LED2, OFF); | ||
1029 | |||
1030 | /* Set GPIO 1 HIGH to disable VBUS power supply; | ||
1031 | * OHCI driver powers it up/down as needed. | ||
1032 | */ | ||
1033 | tps65010_set_gpio_out_value(GPIO1, HIGH); | ||
1034 | |||
1035 | /* Set GPIO 2 low to turn on LED D3 */ | ||
1036 | tps65010_set_gpio_out_value(GPIO2, HIGH); | ||
1037 | |||
1038 | /* Set GPIO 3 low to take ethernet out of reset */ | ||
1039 | tps65010_set_gpio_out_value(GPIO3, LOW); | ||
1040 | |||
1041 | /* gpio4 for VDD_DSP */ | ||
1042 | |||
1043 | /* Enable LOW_PWR */ | ||
1044 | tps65010_set_low_pwr(ON); | ||
1045 | |||
1046 | /* Switch VLDO2 to 3.0V for AIC23 */ | ||
1047 | tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V | TPS_LDO1_ENABLE); | ||
1048 | |||
1049 | } else if (machine_is_omap_h2()) { | ||
1050 | /* gpio3 for SD, gpio4 for VDD_DSP */ | ||
1051 | |||
1052 | /* Enable LOW_PWR */ | ||
1053 | tps65010_set_low_pwr(ON); | ||
1054 | } else if (machine_is_omap_h3()) { | ||
1055 | /* gpio4 for SD, gpio3 for VDD_DSP */ | ||
1056 | #ifdef CONFIG_PM | ||
1057 | /* Enable LOW_PWR */ | ||
1058 | tps65013_set_low_pwr(ON); | ||
1059 | #endif | ||
1060 | } | ||
1061 | #endif | ||
1062 | |||
1063 | return status; | 955 | return status; |
1064 | } | 956 | } |
1065 | /* NOTE: this MUST be initialized before the other parts of the system | 957 | /* NOTE: this MUST be initialized before the other parts of the system |