From 9d15b9298807283813e0495ccf04c1175d12719f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 9 Dec 2015 08:27:52 +0100 Subject: input: gpio-keys: implement debouncing The gpio-keys driver often generates multiple events on a single buttong press. Implement debouncing. The default debouncing time is 20ms and can be configured with the "debounce-interval" device tree property. Signed-off-by: Sascha Hauer --- drivers/input/gpio_keys.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers/input') diff --git a/drivers/input/gpio_keys.c b/drivers/input/gpio_keys.c index d017594662..5b03fd76cb 100644 --- a/drivers/input/gpio_keys.c +++ b/drivers/input/gpio_keys.c @@ -21,6 +21,9 @@ struct gpio_key { int active_low; int previous_state; + + int debounce_interval; + u64 debounce_start; }; struct gpio_keys { @@ -60,11 +63,17 @@ static void gpio_key_poller(struct poller_struct *poller) gb = &gk->buttons[i]; val = gpio_get_value(gb->gpio); - if (val != gb->previous_state && val != gb->active_low) { - kfifo_put(gk->recv_fifo, (u_char*)&gb->code, sizeof(int)); - debug("pressed gpio(%d) as %d\n", gb->gpio, gb->code); + if (!is_timeout(gb->debounce_start, gb->debounce_interval * MSECOND)) + continue; + + if (val != gb->previous_state) { + gb->debounce_start = get_time_ns(); + if (val != gb->active_low) { + kfifo_put(gk->recv_fifo, (u_char*)&gb->code, sizeof(int)); + debug("pressed gpio(%d) as %d\n", gb->gpio, gb->code); + } + gb->previous_state = val; } - gb->previous_state = val; } } @@ -111,6 +120,7 @@ static int gpio_keys_probe_pdata(struct gpio_keys *gk, struct device_d *dev) gk->buttons[i].gpio = pdata->buttons[i].gpio; gk->buttons[i].code = pdata->buttons[i].code; gk->buttons[i].active_low = pdata->buttons[i].active_low; + gk->buttons[i].debounce_interval = 20; } return 0; @@ -142,6 +152,11 @@ static int gpio_keys_probe_dt(struct gpio_keys *gk, struct device_d *dev) if (ret) return ret; + gk->buttons[i].debounce_interval = 20; + + of_property_read_u32(npkey, "debounce-interval", + &gk->buttons[i].debounce_interval); + gk->buttons[i].code = keycode; i++; -- cgit v1.2.3