Skip to content

Commit

Permalink
Input: gpio-keys - add gpiolib debounce support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Grazvydas Ignotas authored and Dmitry Torokhov committed Jun 28, 2010
1 parent df506f2 commit 28ed684
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions drivers/input/keyboard/gpio_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct gpio_button_data {
struct input_dev *input;
struct timer_list timer;
struct work_struct work;
int timer_debounce; /* in msecs */
bool disabled;
};

Expand Down Expand Up @@ -109,7 +110,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
* 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;
Expand Down Expand Up @@ -347,9 +348,9 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id)

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);

Expand Down Expand Up @@ -383,6 +384,14 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev,
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;
Expand Down Expand Up @@ -498,7 +507,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
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);
Expand Down Expand Up @@ -526,7 +535,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
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);
Expand Down

0 comments on commit 28ed684

Please sign in to comment.