|
@@ -41,6 +41,8 @@ struct adp5588_gpio {
|
|
|
uint8_t int_en[3];
|
|
|
uint8_t irq_mask[3];
|
|
|
uint8_t irq_stat[3];
|
|
|
+ uint8_t int_input_en[3];
|
|
|
+ uint8_t int_lvl_cached[3];
|
|
|
};
|
|
|
|
|
|
static int adp5588_gpio_read(struct i2c_client *client, u8 reg)
|
|
@@ -173,12 +175,28 @@ static void adp5588_irq_bus_sync_unlock(struct irq_data *d)
|
|
|
struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d);
|
|
|
int i;
|
|
|
|
|
|
- for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++)
|
|
|
+ for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
|
|
|
+ if (dev->int_input_en[i]) {
|
|
|
+ mutex_lock(&dev->lock);
|
|
|
+ dev->dir[i] &= ~dev->int_input_en[i];
|
|
|
+ dev->int_input_en[i] = 0;
|
|
|
+ adp5588_gpio_write(dev->client, GPIO_DIR1 + i,
|
|
|
+ dev->dir[i]);
|
|
|
+ mutex_unlock(&dev->lock);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (dev->int_lvl_cached[i] != dev->int_lvl[i]) {
|
|
|
+ dev->int_lvl_cached[i] = dev->int_lvl[i];
|
|
|
+ adp5588_gpio_write(dev->client, GPIO_INT_LVL1 + i,
|
|
|
+ dev->int_lvl[i]);
|
|
|
+ }
|
|
|
+
|
|
|
if (dev->int_en[i] ^ dev->irq_mask[i]) {
|
|
|
dev->int_en[i] = dev->irq_mask[i];
|
|
|
adp5588_gpio_write(dev->client, GPIO_INT_EN1 + i,
|
|
|
dev->int_en[i]);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
mutex_unlock(&dev->irq_lock);
|
|
|
}
|
|
@@ -221,9 +239,7 @@ static int adp5588_irq_set_type(struct irq_data *d, unsigned int type)
|
|
|
else
|
|
|
return -EINVAL;
|
|
|
|
|
|
- adp5588_gpio_direction_input(&dev->gpio_chip, gpio);
|
|
|
- adp5588_gpio_write(dev->client, GPIO_INT_LVL1 + bank,
|
|
|
- dev->int_lvl[bank]);
|
|
|
+ dev->int_input_en[bank] |= bit;
|
|
|
|
|
|
return 0;
|
|
|
}
|