summaryrefslogtreecommitdiff
path: root/drivers/input
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2014-04-16 11:50:13 +0530
committerSeema Khowala <seemaj@nvidia.com>2014-04-23 14:05:11 -0700
commit64a1197945c27bf35b36abab40ccebd0b29b5659 (patch)
treef876bd87852a602cfb0e4af1abaf0bb67faca66f /drivers/input
parentc24a1ec7773dc55c309b846589cbaff955780005 (diff)
input: gpio-keys: get button status through gpio for irq based key
The gpio keys supports the key functionality through irqs. The driver expect that key interrupt should be generated continuously till the key is pressed. When configuring with Palmas PMIC onkey, it is found that interrupt is getting generated only once when it is pressed. There is no interrupt if key is released. This way it is difficult to find that key pressed duration is short or long. Provide the mechanism to find out the key state through GPIO so that key press is detected through the interrupt and state will be determined by the gpio. This is based on http://git-master/r/375884 on bug 1392048 by Vineel Kumar Reddy Kovvuri <vineelkumarr@nvidia.com> Change-Id: I7ea9a98cc6e3d888143a41939a89daa34eae7f0a Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Vineel Kumar Reddy Kovvuri <vineelkumarr@nvidia.com> Reviewed-on: http://git-master/r/396850
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/keyboard/gpio_keys.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index edac00b51372..58adba9cc871 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -393,13 +393,22 @@ static void gpio_keys_irq_timer(unsigned long _data)
{
struct gpio_button_data *bdata = (struct gpio_button_data *)_data;
struct input_dev *input = bdata->input;
+ const struct gpio_keys_button *button = bdata->button;
unsigned long flags;
+ int state = 1;
spin_lock_irqsave(&bdata->lock, flags);
if (bdata->key_pressed) {
- input_event(input, EV_KEY, bdata->button->code, 0);
- input_sync(input);
- bdata->key_pressed = false;
+ if (button->gpio && gpio_is_valid(button->gpio))
+ state = gpio_get_value_cansleep(button->gpio);
+ if (state == 0) {
+ mod_timer(&bdata->timer, jiffies +
+ msecs_to_jiffies(bdata->timer_debounce));
+ } else {
+ input_event(input, EV_KEY, bdata->button->code, 0);
+ input_sync(input);
+ bdata->key_pressed = false;
+ }
}
spin_unlock_irqrestore(&bdata->lock, flags);
}
@@ -454,8 +463,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
bdata->button = button;
spin_lock_init(&bdata->lock);
- if (gpio_is_valid(button->gpio)) {
-
+ if (gpio_is_valid(button->gpio) && !button->irq) {
error = gpio_request_one(button->gpio, GPIOF_IN, desc);
if (error < 0) {
dev_err(dev, "Failed to request GPIO %d, error %d\n",
@@ -501,6 +509,15 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
return -EINVAL;
}
+ if (button->gpio && gpio_is_valid(button->gpio)) {
+ error = gpio_request_one(button->gpio, GPIOF_IN, desc);
+ if (error < 0) {
+ dev_err(dev, "Failed to request GPIO %d, error %d\n",
+ button->gpio, error);
+ return error;
+ }
+ }
+
bdata->timer_debounce = button->debounce_interval;
setup_timer(&bdata->timer,
gpio_keys_irq_timer, (unsigned long)bdata);