diff options
-rw-r--r-- | drivers/gpio/gpio-tc3589x.c | 18 | ||||
-rw-r--r-- | include/linux/mfd/tc3589x.h | 6 |
2 files changed, 22 insertions, 2 deletions
diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 58b0da9eb76f..79d285b845dc 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -19,9 +19,9 @@ * These registers are modified under the irq bus lock and cached to avoid * unnecessary writes in bus_sync_unlock. */ -enum { REG_IBE, REG_IEV, REG_IS, REG_IE }; +enum { REG_IBE, REG_IEV, REG_IS, REG_IE, REG_DIRECT }; -#define CACHE_NR_REGS 4 +#define CACHE_NR_REGS 5 #define CACHE_NR_BANKS 3 struct tc3589x_gpio { @@ -200,6 +200,7 @@ static void tc3589x_gpio_irq_sync_unlock(struct irq_data *d) [REG_IEV] = TC3589x_GPIOIEV0, [REG_IS] = TC3589x_GPIOIS0, [REG_IE] = TC3589x_GPIOIE0, + [REG_DIRECT] = TC3589x_DIRECT0, }; int i, j; @@ -228,6 +229,7 @@ static void tc3589x_gpio_irq_mask(struct irq_data *d) int mask = BIT(offset % 8); tc3589x_gpio->regs[REG_IE][regoffset] &= ~mask; + tc3589x_gpio->regs[REG_DIRECT][regoffset] |= mask; } static void tc3589x_gpio_irq_unmask(struct irq_data *d) @@ -239,6 +241,7 @@ static void tc3589x_gpio_irq_unmask(struct irq_data *d) int mask = BIT(offset % 8); tc3589x_gpio->regs[REG_IE][regoffset] |= mask; + tc3589x_gpio->regs[REG_DIRECT][regoffset] &= ~mask; } static struct irq_chip tc3589x_gpio_irq_chip = { @@ -334,6 +337,17 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) if (ret < 0) return ret; + /* For tc35894, have to disable Direct KBD interrupts, + * else IRQST will always be 0x20, IRQN low level, can't + * clear the irq status. + * TODO: need more test on other tc3589x chip. + * + */ + ret = tc3589x_reg_write(tc3589x, TC3589x_DKBDMSK, + TC3589x_DKBDMSK_ELINT | TC3589x_DKBDMSK_EINT); + if (ret < 0) + return ret; + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, tc3589x_gpio_irq, IRQF_ONESHOT, "tc3589x-gpio", diff --git a/include/linux/mfd/tc3589x.h b/include/linux/mfd/tc3589x.h index bb2b19599761..b84955410e03 100644 --- a/include/linux/mfd/tc3589x.h +++ b/include/linux/mfd/tc3589x.h @@ -19,6 +19,9 @@ enum tx3589x_block { #define TC3589x_RSTCTRL_KBDRST (1 << 1) #define TC3589x_RSTCTRL_GPIRST (1 << 0) +#define TC3589x_DKBDMSK_ELINT (1 << 1) +#define TC3589x_DKBDMSK_EINT (1 << 0) + /* Keyboard Configuration Registers */ #define TC3589x_KBDSETTLE_REG 0x01 #define TC3589x_KBDBOUNCE 0x02 @@ -101,6 +104,9 @@ enum tx3589x_block { #define TC3589x_GPIOODM2 0xE4 #define TC3589x_GPIOODE2 0xE5 +#define TC3589x_DIRECT0 0xEC +#define TC3589x_DKBDMSK 0xF3 + #define TC3589x_INT_GPIIRQ 0 #define TC3589x_INT_TI0IRQ 1 #define TC3589x_INT_TI1IRQ 2 |