diff options
Diffstat (limited to 'drivers/gpio/gpio-pca953x.c')
-rw-r--r-- | drivers/gpio/gpio-pca953x.c | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 1c313c710be3..9c693ae17956 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
@@ -78,10 +78,10 @@ struct pca953x_chip { | |||
78 | 78 | ||
79 | #ifdef CONFIG_GPIO_PCA953X_IRQ | 79 | #ifdef CONFIG_GPIO_PCA953X_IRQ |
80 | struct mutex irq_lock; | 80 | struct mutex irq_lock; |
81 | uint16_t irq_mask; | 81 | u32 irq_mask; |
82 | uint16_t irq_stat; | 82 | u32 irq_stat; |
83 | uint16_t irq_trig_raise; | 83 | u32 irq_trig_raise; |
84 | uint16_t irq_trig_fall; | 84 | u32 irq_trig_fall; |
85 | int irq_base; | 85 | int irq_base; |
86 | #endif | 86 | #endif |
87 | 87 | ||
@@ -98,12 +98,11 @@ static int pca953x_write_reg(struct pca953x_chip *chip, int reg, u32 val) | |||
98 | if (chip->gpio_chip.ngpio <= 8) | 98 | if (chip->gpio_chip.ngpio <= 8) |
99 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); | 99 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); |
100 | else if (chip->gpio_chip.ngpio == 24) { | 100 | else if (chip->gpio_chip.ngpio == 24) { |
101 | ret = i2c_smbus_write_word_data(chip->client, | 101 | cpu_to_le32s(&val); |
102 | ret = i2c_smbus_write_i2c_block_data(chip->client, | ||
102 | (reg << 2) | REG_ADDR_AI, | 103 | (reg << 2) | REG_ADDR_AI, |
103 | val & 0xffff); | 104 | 3, |
104 | ret = i2c_smbus_write_byte_data(chip->client, | 105 | (u8 *) &val); |
105 | (reg << 2) + 2, | ||
106 | (val & 0xff0000) >> 16); | ||
107 | } | 106 | } |
108 | else { | 107 | else { |
109 | switch (chip->chip_type) { | 108 | switch (chip->chip_type) { |
@@ -135,22 +134,27 @@ static int pca953x_read_reg(struct pca953x_chip *chip, int reg, u32 *val) | |||
135 | { | 134 | { |
136 | int ret; | 135 | int ret; |
137 | 136 | ||
138 | if (chip->gpio_chip.ngpio <= 8) | 137 | if (chip->gpio_chip.ngpio <= 8) { |
139 | ret = i2c_smbus_read_byte_data(chip->client, reg); | 138 | ret = i2c_smbus_read_byte_data(chip->client, reg); |
140 | else if (chip->gpio_chip.ngpio == 24) { | 139 | *val = ret; |
141 | ret = i2c_smbus_read_word_data(chip->client, reg << 2); | ||
142 | ret |= (i2c_smbus_read_byte_data(chip->client, | ||
143 | (reg << 2) + 2)<<16); | ||
144 | } | 140 | } |
145 | else | 141 | else if (chip->gpio_chip.ngpio == 24) { |
142 | *val = 0; | ||
143 | ret = i2c_smbus_read_i2c_block_data(chip->client, | ||
144 | (reg << 2) | REG_ADDR_AI, | ||
145 | 3, | ||
146 | (u8 *) val); | ||
147 | le32_to_cpus(val); | ||
148 | } else { | ||
146 | ret = i2c_smbus_read_word_data(chip->client, reg << 1); | 149 | ret = i2c_smbus_read_word_data(chip->client, reg << 1); |
150 | *val = ret; | ||
151 | } | ||
147 | 152 | ||
148 | if (ret < 0) { | 153 | if (ret < 0) { |
149 | dev_err(&chip->client->dev, "failed reading register\n"); | 154 | dev_err(&chip->client->dev, "failed reading register\n"); |
150 | return ret; | 155 | return ret; |
151 | } | 156 | } |
152 | 157 | ||
153 | *val = (u32)ret; | ||
154 | return 0; | 158 | return 0; |
155 | } | 159 | } |
156 | 160 | ||
@@ -349,8 +353,8 @@ static void pca953x_irq_bus_lock(struct irq_data *d) | |||
349 | static void pca953x_irq_bus_sync_unlock(struct irq_data *d) | 353 | static void pca953x_irq_bus_sync_unlock(struct irq_data *d) |
350 | { | 354 | { |
351 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 355 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
352 | uint16_t new_irqs; | 356 | u32 new_irqs; |
353 | uint16_t level; | 357 | u32 level; |
354 | 358 | ||
355 | /* Look for any newly setup interrupt */ | 359 | /* Look for any newly setup interrupt */ |
356 | new_irqs = chip->irq_trig_fall | chip->irq_trig_raise; | 360 | new_irqs = chip->irq_trig_fall | chip->irq_trig_raise; |
@@ -368,8 +372,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) | |||
368 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) | 372 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) |
369 | { | 373 | { |
370 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 374 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
371 | uint16_t level = d->irq - chip->irq_base; | 375 | u32 level = d->irq - chip->irq_base; |
372 | uint16_t mask = 1 << level; | 376 | u32 mask = 1 << level; |
373 | 377 | ||
374 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { | 378 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
375 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", | 379 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", |
@@ -399,12 +403,12 @@ static struct irq_chip pca953x_irq_chip = { | |||
399 | .irq_set_type = pca953x_irq_set_type, | 403 | .irq_set_type = pca953x_irq_set_type, |
400 | }; | 404 | }; |
401 | 405 | ||
402 | static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | 406 | static u32 pca953x_irq_pending(struct pca953x_chip *chip) |
403 | { | 407 | { |
404 | u32 cur_stat; | 408 | u32 cur_stat; |
405 | uint16_t old_stat; | 409 | u32 old_stat; |
406 | uint16_t pending; | 410 | u32 pending; |
407 | uint16_t trigger; | 411 | u32 trigger; |
408 | int ret, offset = 0; | 412 | int ret, offset = 0; |
409 | 413 | ||
410 | switch (chip->chip_type) { | 414 | switch (chip->chip_type) { |
@@ -440,8 +444,8 @@ static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | |||
440 | static irqreturn_t pca953x_irq_handler(int irq, void *devid) | 444 | static irqreturn_t pca953x_irq_handler(int irq, void *devid) |
441 | { | 445 | { |
442 | struct pca953x_chip *chip = devid; | 446 | struct pca953x_chip *chip = devid; |
443 | uint16_t pending; | 447 | u32 pending; |
444 | uint16_t level; | 448 | u32 level; |
445 | 449 | ||
446 | pending = pca953x_irq_pending(chip); | 450 | pending = pca953x_irq_pending(chip); |
447 | 451 | ||
@@ -564,7 +568,7 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip) | |||
564 | * WARNING: This is DEPRECATED and will be removed eventually! | 568 | * WARNING: This is DEPRECATED and will be removed eventually! |
565 | */ | 569 | */ |
566 | static void | 570 | static void |
567 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | 571 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) |
568 | { | 572 | { |
569 | struct device_node *node; | 573 | struct device_node *node; |
570 | const __be32 *val; | 574 | const __be32 *val; |
@@ -592,13 +596,13 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | |||
592 | } | 596 | } |
593 | #else | 597 | #else |
594 | static void | 598 | static void |
595 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | 599 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert) |
596 | { | 600 | { |
597 | *gpio_base = -1; | 601 | *gpio_base = -1; |
598 | } | 602 | } |
599 | #endif | 603 | #endif |
600 | 604 | ||
601 | static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert) | 605 | static int __devinit device_pca953x_init(struct pca953x_chip *chip, u32 invert) |
602 | { | 606 | { |
603 | int ret; | 607 | int ret; |
604 | 608 | ||
@@ -617,7 +621,7 @@ out: | |||
617 | return ret; | 621 | return ret; |
618 | } | 622 | } |
619 | 623 | ||
620 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert) | 624 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, u32 invert) |
621 | { | 625 | { |
622 | int ret; | 626 | int ret; |
623 | u32 val = 0; | 627 | u32 val = 0; |
@@ -653,8 +657,9 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
653 | { | 657 | { |
654 | struct pca953x_platform_data *pdata; | 658 | struct pca953x_platform_data *pdata; |
655 | struct pca953x_chip *chip; | 659 | struct pca953x_chip *chip; |
656 | int irq_base=0, invert=0; | 660 | int irq_base = 0; |
657 | int ret; | 661 | int ret; |
662 | u32 invert = 0; | ||
658 | 663 | ||
659 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); | 664 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); |
660 | if (chip == NULL) | 665 | if (chip == NULL) |