From 1fc2b717c59f1ce91c385c443705aad5e77c08df Mon Sep 17 00:00:00 2001 From: juhosg Date: Wed, 13 Jan 2010 10:18:24 +0000 Subject: kernel: change debounce logic in the gpio-buttons driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * thanks to Nuno Gonçalves git-svn-id: svn://svn.openwrt.org/openwrt/trunk@19115 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../files/drivers/input/misc/gpio_buttons.c | 42 ++++++++++++---------- 1 file changed, 24 insertions(+), 18 deletions(-) (limited to 'target/linux/generic-2.6/files/drivers/input') diff --git a/target/linux/generic-2.6/files/drivers/input/misc/gpio_buttons.c b/target/linux/generic-2.6/files/drivers/input/misc/gpio_buttons.c index 83a817834..e4e0e339d 100644 --- a/target/linux/generic-2.6/files/drivers/input/misc/gpio_buttons.c +++ b/target/linux/generic-2.6/files/drivers/input/misc/gpio_buttons.c @@ -1,7 +1,8 @@ /* * Driver for buttons on GPIO lines not capable of generating interrupts * - * Copyright (C) 2007,2008 Gabor Juhos + * Copyright (C) 2007-2010 Gabor Juhos + * Copyright (C) 2010 Nuno Goncalves * * This file was based on: /drivers/input/misc/cobalt_btns.c * Copyright (C) 2007 Yoichi Yuasa @@ -29,12 +30,18 @@ #include #define DRV_NAME "gpio-buttons" -#define DRV_VERSION "0.1.1" +#define DRV_VERSION "0.1.2" #define PFX DRV_NAME ": " +struct gpio_button_data { + int last_state; + int count; +}; + struct gpio_buttons_dev { struct input_polled_dev *poll_dev; struct gpio_buttons_platform_data *pdata; + struct gpio_button_data *data; }; static void gpio_buttons_poll(struct input_polled_dev *dev) @@ -49,22 +56,18 @@ static void gpio_buttons_poll(struct input_polled_dev *dev) unsigned int type = button->type ?: EV_KEY; int state; - state = gpio_get_value(button->gpio) ? 1 : 0; - state ^= button->active_low; - - if (state) { - button->count++; - } else { - if (button->count >= button->threshold) { - input_event(input, type, button->code, 1); - input_sync(input); - } - button->count = 0; + if (bdev->data[i].count < button->threshold) { + bdev->data[i].count++; + continue; } - if (button->count == button->threshold) { - input_event(input, type, button->code, 0); + state = gpio_get_value(button->gpio) ? 1 : 0; + if (state != bdev->data[i].last_state) { + input_event(input, type, button->code, + !!(state ^ button->active_low)); input_sync(input); + bdev->data[i].count = 0; + bdev->data[i].last_state = state; } } } @@ -77,16 +80,19 @@ static int __devinit gpio_buttons_probe(struct platform_device *pdev) struct input_dev *input; int error, i; - if (!pdata) return -ENXIO; - bdev = kzalloc(sizeof(*bdev), GFP_KERNEL); + bdev = kzalloc(sizeof(struct gpio_buttons_dev) + + sizeof(struct gpio_button_data) * pdata->nbuttons, + GFP_KERNEL); if (!bdev) { printk(KERN_ERR DRV_NAME "no memory for device\n"); return -ENOMEM; } + bdev->data = (struct gpio_button_data *) &bdev[1]; + poll_dev = input_allocate_polled_device(); if (!poll_dev) { printk(KERN_ERR DRV_NAME "no memory for polled device\n"); @@ -131,7 +137,7 @@ static int __devinit gpio_buttons_probe(struct platform_device *pdev) } input_set_capability(input, type, button->code); - button->count = 0; + bdev->data[i].last_state = gpio_get_value(button->gpio) ? 1 : 0; } bdev->poll_dev = poll_dev; -- cgit v1.2.3