From: Gabor Juhos Date: Wed, 13 Jan 2010 10:18:24 +0000 (+0000) Subject: kernel: change debounce logic in the gpio-buttons driver X-Git-Tag: reboot~21446 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=21742847bd842fd7a2e7ba60854b38e09a287260;p=openwrt%2Fstaging%2Flynxis.git kernel: change debounce logic in the gpio-buttons driver * thanks to Nuno Gonçalves SVN-Revision: 19115 --- 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 83a8178340..e4e0e339d7 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; diff --git a/target/linux/generic-2.6/files/include/linux/gpio_buttons.h b/target/linux/generic-2.6/files/include/linux/gpio_buttons.h index f5e6297258..f85b993ed2 100644 --- a/target/linux/generic-2.6/files/include/linux/gpio_buttons.h +++ b/target/linux/generic-2.6/files/include/linux/gpio_buttons.h @@ -1,7 +1,7 @@ /* * Definitions for the GPIO buttons interface driver * - * Copyright (C) 2007,2008 Gabor Juhos + * Copyright (C) 2007-2010 Gabor Juhos * * This file was based on: /include/linux/gpio_keys.h * The original gpio_keys.h seems not to have a license. @@ -21,7 +21,6 @@ struct gpio_button { char *desc; /* button description */ int type; /* input event type (EV_KEY, EV_SW) */ int code; /* input event code (KEY_*, SW_*) */ - int count; int threshold; /* count threshold */ }; @@ -32,4 +31,3 @@ struct gpio_buttons_platform_data { }; #endif /* _GPIO_BUTTONS_H_ */ -