diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 17 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-ibm_iic.c | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-tiny-usb.c | 12 | ||||
-rw-r--r-- | drivers/i2c/chips/Kconfig | 1 | ||||
-rw-r--r-- | drivers/i2c/chips/tps65010.c | 101 |
5 files changed, 116 insertions, 17 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index cce5a614758d..fde26345a379 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -382,9 +382,8 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) | |||
382 | break; | 382 | break; |
383 | 383 | ||
384 | case DAVINCI_I2C_IVR_ARDY: | 384 | case DAVINCI_I2C_IVR_ARDY: |
385 | w = davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG); | 385 | davinci_i2c_write_reg(dev, |
386 | MOD_REG_BIT(w, DAVINCI_I2C_STR_ARDY, 1); | 386 | DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY); |
387 | davinci_i2c_write_reg(dev, DAVINCI_I2C_STR_REG, w); | ||
388 | complete(&dev->cmd_complete); | 387 | complete(&dev->cmd_complete); |
389 | break; | 388 | break; |
390 | 389 | ||
@@ -397,12 +396,9 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) | |||
397 | if (dev->buf_len) | 396 | if (dev->buf_len) |
398 | continue; | 397 | continue; |
399 | 398 | ||
400 | w = davinci_i2c_read_reg(dev, | ||
401 | DAVINCI_I2C_STR_REG); | ||
402 | MOD_REG_BIT(w, DAVINCI_I2C_IMR_RRDY, 0); | ||
403 | davinci_i2c_write_reg(dev, | 399 | davinci_i2c_write_reg(dev, |
404 | DAVINCI_I2C_STR_REG, | 400 | DAVINCI_I2C_STR_REG, |
405 | w); | 401 | DAVINCI_I2C_IMR_RRDY); |
406 | } else | 402 | } else |
407 | dev_err(dev->dev, "RDR IRQ while no " | 403 | dev_err(dev->dev, "RDR IRQ while no " |
408 | "data requested\n"); | 404 | "data requested\n"); |
@@ -428,9 +424,8 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) | |||
428 | break; | 424 | break; |
429 | 425 | ||
430 | case DAVINCI_I2C_IVR_SCD: | 426 | case DAVINCI_I2C_IVR_SCD: |
431 | w = davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG); | 427 | davinci_i2c_write_reg(dev, |
432 | MOD_REG_BIT(w, DAVINCI_I2C_STR_SCD, 1); | 428 | DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_SCD); |
433 | davinci_i2c_write_reg(dev, DAVINCI_I2C_STR_REG, w); | ||
434 | complete(&dev->cmd_complete); | 429 | complete(&dev->cmd_complete); |
435 | break; | 430 | break; |
436 | 431 | ||
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 7c7eb0cfeceb..22bb247d0e60 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c | |||
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(iic_force_poll, "Force polling mode"); | |||
55 | 55 | ||
56 | static int iic_force_fast; | 56 | static int iic_force_fast; |
57 | module_param(iic_force_fast, bool, 0); | 57 | module_param(iic_force_fast, bool, 0); |
58 | MODULE_PARM_DESC(iic_fast_poll, "Force fast mode (400 kHz)"); | 58 | MODULE_PARM_DESC(iic_force_fast, "Force fast mode (400 kHz)"); |
59 | 59 | ||
60 | #define DBG_LEVEL 0 | 60 | #define DBG_LEVEL 0 |
61 | 61 | ||
diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index cb9abe7565a7..b1c050ff311d 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c | |||
@@ -131,11 +131,15 @@ static const struct i2c_algorithm usb_algorithm = { | |||
131 | 131 | ||
132 | /* ----- begin of usb layer ---------------------------------------------- */ | 132 | /* ----- begin of usb layer ---------------------------------------------- */ |
133 | 133 | ||
134 | /* The usb i2c interface uses a vid/pid pair donated by */ | 134 | /* |
135 | /* Future Technology Devices International Ltd. */ | 135 | * Initially the usb i2c interface uses a vid/pid pair donated by |
136 | * Future Technology Devices International Ltd., later a pair was | ||
137 | * bought from EZPrototypes | ||
138 | */ | ||
136 | static struct usb_device_id i2c_tiny_usb_table [] = { | 139 | static struct usb_device_id i2c_tiny_usb_table [] = { |
137 | { USB_DEVICE(0x0403, 0xc631) }, | 140 | { USB_DEVICE(0x0403, 0xc631) }, /* FTDI */ |
138 | { } /* Terminating entry */ | 141 | { USB_DEVICE(0x1c40, 0x0534) }, /* EZPrototypes */ |
142 | { } /* Terminating entry */ | ||
139 | }; | 143 | }; |
140 | 144 | ||
141 | MODULE_DEVICE_TABLE(usb, i2c_tiny_usb_table); | 145 | MODULE_DEVICE_TABLE(usb, i2c_tiny_usb_table); |
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index b21593f93586..2da2edfa68ec 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig | |||
@@ -93,6 +93,7 @@ config ISP1301_OMAP | |||
93 | 93 | ||
94 | config TPS65010 | 94 | config TPS65010 |
95 | tristate "TPS6501x Power Management chips" | 95 | tristate "TPS6501x Power Management chips" |
96 | depends on HAVE_GPIO_LIB | ||
96 | default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK | 97 | default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK |
97 | help | 98 | help |
98 | If you say yes here you get support for the TPS6501x series of | 99 | If you say yes here you get support for the TPS6501x series of |
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c index 4154a9108859..b67f69c2e7f3 100644 --- a/drivers/i2c/chips/tps65010.c +++ b/drivers/i2c/chips/tps65010.c | |||
@@ -30,9 +30,13 @@ | |||
30 | #include <linux/debugfs.h> | 30 | #include <linux/debugfs.h> |
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
33 | #include <linux/platform_device.h> | ||
33 | 34 | ||
34 | #include <linux/i2c/tps65010.h> | 35 | #include <linux/i2c/tps65010.h> |
35 | 36 | ||
37 | #include <asm/gpio.h> | ||
38 | |||
39 | |||
36 | /*-------------------------------------------------------------------------*/ | 40 | /*-------------------------------------------------------------------------*/ |
37 | 41 | ||
38 | #define DRIVER_VERSION "2 May 2005" | 42 | #define DRIVER_VERSION "2 May 2005" |
@@ -84,7 +88,9 @@ struct tps65010 { | |||
84 | u8 chgstatus, regstatus, chgconf; | 88 | u8 chgstatus, regstatus, chgconf; |
85 | u8 nmask1, nmask2; | 89 | u8 nmask1, nmask2; |
86 | 90 | ||
87 | /* not currently tracking GPIO state */ | 91 | u8 outmask; |
92 | struct gpio_chip chip; | ||
93 | struct platform_device *leds; | ||
88 | }; | 94 | }; |
89 | 95 | ||
90 | #define POWER_POLL_DELAY msecs_to_jiffies(5000) | 96 | #define POWER_POLL_DELAY msecs_to_jiffies(5000) |
@@ -449,12 +455,72 @@ static irqreturn_t tps65010_irq(int irq, void *_tps) | |||
449 | 455 | ||
450 | /*-------------------------------------------------------------------------*/ | 456 | /*-------------------------------------------------------------------------*/ |
451 | 457 | ||
458 | /* offsets 0..3 == GPIO1..GPIO4 | ||
459 | * offsets 4..5 == LED1/nPG, LED2 (we set one of the non-BLINK modes) | ||
460 | */ | ||
461 | static void | ||
462 | tps65010_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
463 | { | ||
464 | if (offset < 4) | ||
465 | tps65010_set_gpio_out_value(offset + 1, value); | ||
466 | else | ||
467 | tps65010_set_led(offset - 3, value ? ON : OFF); | ||
468 | } | ||
469 | |||
470 | static int | ||
471 | tps65010_output(struct gpio_chip *chip, unsigned offset, int value) | ||
472 | { | ||
473 | /* GPIOs may be input-only */ | ||
474 | if (offset < 4) { | ||
475 | struct tps65010 *tps; | ||
476 | |||
477 | tps = container_of(chip, struct tps65010, chip); | ||
478 | if (!(tps->outmask & (1 << offset))) | ||
479 | return -EINVAL; | ||
480 | tps65010_set_gpio_out_value(offset + 1, value); | ||
481 | } else | ||
482 | tps65010_set_led(offset - 3, value ? ON : OFF); | ||
483 | |||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static int tps65010_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
488 | { | ||
489 | int value; | ||
490 | struct tps65010 *tps; | ||
491 | |||
492 | tps = container_of(chip, struct tps65010, chip); | ||
493 | |||
494 | if (offset < 4) { | ||
495 | value = i2c_smbus_read_byte_data(tps->client, TPS_DEFGPIO); | ||
496 | if (value < 0) | ||
497 | return 0; | ||
498 | if (value & (1 << (offset + 4))) /* output */ | ||
499 | return !(value & (1 << offset)); | ||
500 | else /* input */ | ||
501 | return (value & (1 << offset)); | ||
502 | } | ||
503 | |||
504 | /* REVISIT we *could* report LED1/nPG and LED2 state ... */ | ||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | |||
509 | /*-------------------------------------------------------------------------*/ | ||
510 | |||
452 | static struct tps65010 *the_tps; | 511 | static struct tps65010 *the_tps; |
453 | 512 | ||
454 | static int __exit tps65010_remove(struct i2c_client *client) | 513 | static int __exit tps65010_remove(struct i2c_client *client) |
455 | { | 514 | { |
456 | struct tps65010 *tps = i2c_get_clientdata(client); | 515 | struct tps65010 *tps = i2c_get_clientdata(client); |
516 | struct tps65010_board *board = client->dev.platform_data; | ||
457 | 517 | ||
518 | if (board && board->teardown) { | ||
519 | int status = board->teardown(client, board->context); | ||
520 | if (status < 0) | ||
521 | dev_dbg(&client->dev, "board %s %s err %d\n", | ||
522 | "teardown", client->name, status); | ||
523 | } | ||
458 | if (client->irq > 0) | 524 | if (client->irq > 0) |
459 | free_irq(client->irq, tps); | 525 | free_irq(client->irq, tps); |
460 | cancel_delayed_work(&tps->work); | 526 | cancel_delayed_work(&tps->work); |
@@ -469,6 +535,7 @@ static int tps65010_probe(struct i2c_client *client) | |||
469 | { | 535 | { |
470 | struct tps65010 *tps; | 536 | struct tps65010 *tps; |
471 | int status; | 537 | int status; |
538 | struct tps65010_board *board = client->dev.platform_data; | ||
472 | 539 | ||
473 | if (the_tps) { | 540 | if (the_tps) { |
474 | dev_dbg(&client->dev, "only one tps6501x chip allowed\n"); | 541 | dev_dbg(&client->dev, "only one tps6501x chip allowed\n"); |
@@ -577,6 +644,38 @@ static int tps65010_probe(struct i2c_client *client) | |||
577 | 644 | ||
578 | tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL, | 645 | tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL, |
579 | tps, DEBUG_FOPS); | 646 | tps, DEBUG_FOPS); |
647 | |||
648 | /* optionally register GPIOs */ | ||
649 | if (board && board->base > 0) { | ||
650 | tps->outmask = board->outmask; | ||
651 | |||
652 | tps->chip.label = client->name; | ||
653 | |||
654 | tps->chip.set = tps65010_gpio_set; | ||
655 | tps->chip.direction_output = tps65010_output; | ||
656 | |||
657 | /* NOTE: only partial support for inputs; nyet IRQs */ | ||
658 | tps->chip.get = tps65010_gpio_get; | ||
659 | |||
660 | tps->chip.base = board->base; | ||
661 | tps->chip.ngpio = 6; | ||
662 | tps->chip.can_sleep = 1; | ||
663 | |||
664 | status = gpiochip_add(&tps->chip); | ||
665 | if (status < 0) | ||
666 | dev_err(&client->dev, "can't add gpiochip, err %d\n", | ||
667 | status); | ||
668 | else if (board->setup) { | ||
669 | status = board->setup(client, board->context); | ||
670 | if (status < 0) { | ||
671 | dev_dbg(&client->dev, | ||
672 | "board %s %s err %d\n", | ||
673 | "setup", client->name, status); | ||
674 | status = 0; | ||
675 | } | ||
676 | } | ||
677 | } | ||
678 | |||
580 | return 0; | 679 | return 0; |
581 | fail1: | 680 | fail1: |
582 | kfree(tps); | 681 | kfree(tps); |