From 7554eedf9ae9e6de0ce29061e83916a5bb89edde Mon Sep 17 00:00:00 2001 From: Brennan Ashton Date: Thu, 17 Sep 2020 18:31:00 -0700 Subject: [PATCH] input: STMPE811 GPIO interrupt bug fixes This patch resolves to bugs in the GPIO interrupt logic: 1. Any pins did not have STMPE811_GPIO_RISING in their pincfg would clear the rising edge interrupt enable flag for all pins due to a masking bug. 2. Pins would never trigger a second interrupt. There is an undocumented requirement that you have to clear both the GPIO interrupt status register __and__ also the edge detection status register. Failure to clear either of these will result in no further interrupts being triggered. This requirement exists both for edge and level modes of operation. Signed-off-by: Brennan Ashton --- drivers/input/stmpe811_base.c | 1 - drivers/input/stmpe811_gpio.c | 15 ++++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/input/stmpe811_base.c b/drivers/input/stmpe811_base.c index 28f0eb5df7a..bd20a14a3b7 100644 --- a/drivers/input/stmpe811_base.c +++ b/drivers/input/stmpe811_base.c @@ -93,7 +93,6 @@ static void stmpe811_worker(FAR void *arg) /* Get the global interrupt status */ - regval = stmpe811_getreg8(priv, STMPE811_INT_EN); regval = stmpe811_getreg8(priv, STMPE811_INT_STA); /* Check for a touchscreen interrupt */ diff --git a/drivers/input/stmpe811_gpio.c b/drivers/input/stmpe811_gpio.c index 14ea471228c..8dccac0213b 100644 --- a/drivers/input/stmpe811_gpio.c +++ b/drivers/input/stmpe811_gpio.c @@ -194,7 +194,7 @@ int stmpe811_gpioconfig(STMPE811_HANDLE handle, uint8_t pinconfig) } else { - regval &= pinmask; + regval &= ~pinmask; } stmpe811_putreg8(priv, STMPE811_GPIO_FE, regval); @@ -202,13 +202,13 @@ int stmpe811_gpioconfig(STMPE811_HANDLE handle, uint8_t pinconfig) /* Set up the rising edge detection */ regval = stmpe811_getreg8(priv, STMPE811_GPIO_RE); - if ((pinconfig & STMPE811_GPIO_FALLING) != 0) + if ((pinconfig & STMPE811_GPIO_RISING) != 0) { regval |= pinmask; } else { - regval &= pinmask; + regval &= ~pinmask; } stmpe811_putreg8(priv, STMPE811_GPIO_RE, regval); @@ -443,6 +443,15 @@ void stmpe811_gpioworker(FAR struct stmpe811_dev_s *priv) */ stmpe811_putreg8(priv, STMPE811_GPIO_INTSTA, pinmask); + + /* Must also clear the edge detection status bit + * this is _not documented_ as being required but is used in + * the SDK and without it a second interrupt will never trigger. + * Yep you have to "clear" _both_ the edge detection status and + * GPIO interrupt status register even in level mode. + */ + + stmpe811_putreg8(priv, STMPE811_GPIO_ED, pinmask); } } }