Input: gpio-keys - add gpiolib debounce support
gpiolib now has debounce support added in .35, so let's make use of it.
This allows to use hardware GPIO debouncing on some platforms like OMAP.
In case gpiolib debounce setup fails for some GPIO, the driver will fall
back to timer based debouncing, which is what it used before.
Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index b8213fd..a9fd147 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -31,6 +31,7 @@
struct input_dev *input;
struct timer_list timer;
struct work_struct work;
+ int timer_debounce; /* in msecs */
bool disabled;
};
@@ -109,7 +110,7 @@
* Disable IRQ and possible debouncing timer.
*/
disable_irq(gpio_to_irq(bdata->button->gpio));
- if (bdata->button->debounce_interval)
+ if (bdata->timer_debounce)
del_timer_sync(&bdata->timer);
bdata->disabled = true;
@@ -347,9 +348,9 @@
BUG_ON(irq != gpio_to_irq(button->gpio));
- if (button->debounce_interval)
+ if (bdata->timer_debounce)
mod_timer(&bdata->timer,
- jiffies + msecs_to_jiffies(button->debounce_interval));
+ jiffies + msecs_to_jiffies(bdata->timer_debounce));
else
schedule_work(&bdata->work);
@@ -383,6 +384,14 @@
goto fail3;
}
+ if (button->debounce_interval) {
+ error = gpio_set_debounce(button->gpio,
+ button->debounce_interval * 1000);
+ /* use timer if gpiolib doesn't provide debounce */
+ if (error < 0)
+ bdata->timer_debounce = button->debounce_interval;
+ }
+
irq = gpio_to_irq(button->gpio);
if (irq < 0) {
error = irq;
@@ -498,7 +507,7 @@
fail2:
while (--i >= 0) {
free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
- if (pdata->buttons[i].debounce_interval)
+ if (ddata->data[i].timer_debounce)
del_timer_sync(&ddata->data[i].timer);
cancel_work_sync(&ddata->data[i].work);
gpio_free(pdata->buttons[i].gpio);
@@ -526,7 +535,7 @@
for (i = 0; i < pdata->nbuttons; i++) {
int irq = gpio_to_irq(pdata->buttons[i].gpio);
free_irq(irq, &ddata->data[i]);
- if (pdata->buttons[i].debounce_interval)
+ if (ddata->data[i].timer_debounce)
del_timer_sync(&ddata->data[i].timer);
cancel_work_sync(&ddata->data[i].work);
gpio_free(pdata->buttons[i].gpio);