diff options
author | Grazvydas Ignotas <notasas@gmail.com> | 2010-06-28 13:59:32 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-06-28 14:01:10 -0400 |
commit | 28ed684fa3c0a75b59a00e209afef98aff7fa617 (patch) | |
tree | eaa3223d9556e1db6a11a05c981e5f7ddb9c8908 /drivers/input/keyboard | |
parent | df506f2c0023380ffa67a946fa36eee4150773a3 (diff) |
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>
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index b8213fd13c3..a9fd147f2ba 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -31,6 +31,7 @@ struct gpio_button_data { | |||
31 | struct input_dev *input; | 31 | struct input_dev *input; |
32 | struct timer_list timer; | 32 | struct timer_list timer; |
33 | struct work_struct work; | 33 | struct work_struct work; |
34 | int timer_debounce; /* in msecs */ | ||
34 | bool disabled; | 35 | bool disabled; |
35 | }; | 36 | }; |
36 | 37 | ||
@@ -109,7 +110,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata) | |||
109 | * Disable IRQ and possible debouncing timer. | 110 | * Disable IRQ and possible debouncing timer. |
110 | */ | 111 | */ |
111 | disable_irq(gpio_to_irq(bdata->button->gpio)); | 112 | disable_irq(gpio_to_irq(bdata->button->gpio)); |
112 | if (bdata->button->debounce_interval) | 113 | if (bdata->timer_debounce) |
113 | del_timer_sync(&bdata->timer); | 114 | del_timer_sync(&bdata->timer); |
114 | 115 | ||
115 | bdata->disabled = true; | 116 | bdata->disabled = true; |
@@ -347,9 +348,9 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | |||
347 | 348 | ||
348 | BUG_ON(irq != gpio_to_irq(button->gpio)); | 349 | BUG_ON(irq != gpio_to_irq(button->gpio)); |
349 | 350 | ||
350 | if (button->debounce_interval) | 351 | if (bdata->timer_debounce) |
351 | mod_timer(&bdata->timer, | 352 | mod_timer(&bdata->timer, |
352 | jiffies + msecs_to_jiffies(button->debounce_interval)); | 353 | jiffies + msecs_to_jiffies(bdata->timer_debounce)); |
353 | else | 354 | else |
354 | schedule_work(&bdata->work); | 355 | schedule_work(&bdata->work); |
355 | 356 | ||
@@ -383,6 +384,14 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, | |||
383 | goto fail3; | 384 | goto fail3; |
384 | } | 385 | } |
385 | 386 | ||
387 | if (button->debounce_interval) { | ||
388 | error = gpio_set_debounce(button->gpio, | ||
389 | button->debounce_interval * 1000); | ||
390 | /* use timer if gpiolib doesn't provide debounce */ | ||
391 | if (error < 0) | ||
392 | bdata->timer_debounce = button->debounce_interval; | ||
393 | } | ||
394 | |||
386 | irq = gpio_to_irq(button->gpio); | 395 | irq = gpio_to_irq(button->gpio); |
387 | if (irq < 0) { | 396 | if (irq < 0) { |
388 | error = irq; | 397 | error = irq; |
@@ -498,7 +507,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
498 | fail2: | 507 | fail2: |
499 | while (--i >= 0) { | 508 | while (--i >= 0) { |
500 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); | 509 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); |
501 | if (pdata->buttons[i].debounce_interval) | 510 | if (ddata->data[i].timer_debounce) |
502 | del_timer_sync(&ddata->data[i].timer); | 511 | del_timer_sync(&ddata->data[i].timer); |
503 | cancel_work_sync(&ddata->data[i].work); | 512 | cancel_work_sync(&ddata->data[i].work); |
504 | gpio_free(pdata->buttons[i].gpio); | 513 | gpio_free(pdata->buttons[i].gpio); |
@@ -526,7 +535,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
526 | for (i = 0; i < pdata->nbuttons; i++) { | 535 | for (i = 0; i < pdata->nbuttons; i++) { |
527 | int irq = gpio_to_irq(pdata->buttons[i].gpio); | 536 | int irq = gpio_to_irq(pdata->buttons[i].gpio); |
528 | free_irq(irq, &ddata->data[i]); | 537 | free_irq(irq, &ddata->data[i]); |
529 | if (pdata->buttons[i].debounce_interval) | 538 | if (ddata->data[i].timer_debounce) |
530 | del_timer_sync(&ddata->data[i].timer); | 539 | del_timer_sync(&ddata->data[i].timer); |
531 | cancel_work_sync(&ddata->data[i].work); | 540 | cancel_work_sync(&ddata->data[i].work); |
532 | gpio_free(pdata->buttons[i].gpio); | 541 | gpio_free(pdata->buttons[i].gpio); |