aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-03-19 20:54:31 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-03-19 20:56:18 -0400
commitd8ee4a1c90529ed06e1aa43d034986649f7b670b (patch)
tree5a9aec5fe8a9b146799842a2dd284495051621e1 /drivers/input
parenta16ca23935afc0d72215b139720bd07df3162a9f (diff)
Input: gpio_keys - add support for interrupt only keys
Some of buttons, like power-on key or onkey, may only generate interrupts when pressed and not actually be mapped as gpio in the system. Allow setting gpio to invalid value and specify IRQ instead to support such keys. The debounce timer is used not to debounce but to ignore new IRQs coming while button is kept pressed. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/keyboard/gpio_keys.c214
1 files changed, 148 insertions, 66 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 8f44f7b8c94..62bfce468f9 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -28,14 +28,18 @@
28#include <linux/gpio.h> 28#include <linux/gpio.h>
29#include <linux/of_platform.h> 29#include <linux/of_platform.h>
30#include <linux/of_gpio.h> 30#include <linux/of_gpio.h>
31#include <linux/spinlock.h>
31 32
32struct gpio_button_data { 33struct gpio_button_data {
33 const struct gpio_keys_button *button; 34 const struct gpio_keys_button *button;
34 struct input_dev *input; 35 struct input_dev *input;
35 struct timer_list timer; 36 struct timer_list timer;
36 struct work_struct work; 37 struct work_struct work;
37 int timer_debounce; /* in msecs */ 38 unsigned int timer_debounce; /* in msecs */
39 unsigned int irq;
40 spinlock_t lock;
38 bool disabled; 41 bool disabled;
42 bool key_pressed;
39}; 43};
40 44
41struct gpio_keys_drvdata { 45struct gpio_keys_drvdata {
@@ -114,7 +118,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
114 /* 118 /*
115 * Disable IRQ and possible debouncing timer. 119 * Disable IRQ and possible debouncing timer.
116 */ 120 */
117 disable_irq(gpio_to_irq(bdata->button->gpio)); 121 disable_irq(bdata->irq);
118 if (bdata->timer_debounce) 122 if (bdata->timer_debounce)
119 del_timer_sync(&bdata->timer); 123 del_timer_sync(&bdata->timer);
120 124
@@ -135,7 +139,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
135static void gpio_keys_enable_button(struct gpio_button_data *bdata) 139static void gpio_keys_enable_button(struct gpio_button_data *bdata)
136{ 140{
137 if (bdata->disabled) { 141 if (bdata->disabled) {
138 enable_irq(gpio_to_irq(bdata->button->gpio)); 142 enable_irq(bdata->irq);
139 bdata->disabled = false; 143 bdata->disabled = false;
140 } 144 }
141} 145}
@@ -320,7 +324,7 @@ static struct attribute_group gpio_keys_attr_group = {
320 .attrs = gpio_keys_attrs, 324 .attrs = gpio_keys_attrs,
321}; 325};
322 326
323static void gpio_keys_report_event(struct gpio_button_data *bdata) 327static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
324{ 328{
325 const struct gpio_keys_button *button = bdata->button; 329 const struct gpio_keys_button *button = bdata->button;
326 struct input_dev *input = bdata->input; 330 struct input_dev *input = bdata->input;
@@ -336,27 +340,26 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata)
336 input_sync(input); 340 input_sync(input);
337} 341}
338 342
339static void gpio_keys_work_func(struct work_struct *work) 343static void gpio_keys_gpio_work_func(struct work_struct *work)
340{ 344{
341 struct gpio_button_data *bdata = 345 struct gpio_button_data *bdata =
342 container_of(work, struct gpio_button_data, work); 346 container_of(work, struct gpio_button_data, work);
343 347
344 gpio_keys_report_event(bdata); 348 gpio_keys_gpio_report_event(bdata);
345} 349}
346 350
347static void gpio_keys_timer(unsigned long _data) 351static void gpio_keys_gpio_timer(unsigned long _data)
348{ 352{
349 struct gpio_button_data *data = (struct gpio_button_data *)_data; 353 struct gpio_button_data *bdata = (struct gpio_button_data *)_data;
350 354
351 schedule_work(&data->work); 355 schedule_work(&bdata->work);
352} 356}
353 357
354static irqreturn_t gpio_keys_isr(int irq, void *dev_id) 358static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
355{ 359{
356 struct gpio_button_data *bdata = dev_id; 360 struct gpio_button_data *bdata = dev_id;
357 const struct gpio_keys_button *button = bdata->button;
358 361
359 BUG_ON(irq != gpio_to_irq(button->gpio)); 362 BUG_ON(irq != bdata->irq);
360 363
361 if (bdata->timer_debounce) 364 if (bdata->timer_debounce)
362 mod_timer(&bdata->timer, 365 mod_timer(&bdata->timer,
@@ -367,6 +370,53 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
367 return IRQ_HANDLED; 370 return IRQ_HANDLED;
368} 371}
369 372
373static void gpio_keys_irq_timer(unsigned long _data)
374{
375 struct gpio_button_data *bdata = (struct gpio_button_data *)_data;
376 struct input_dev *input = bdata->input;
377 unsigned long flags;
378
379 spin_lock_irqsave(&bdata->lock, flags);
380 if (bdata->key_pressed) {
381 input_event(input, EV_KEY, bdata->button->code, 0);
382 input_sync(input);
383 bdata->key_pressed = false;
384 }
385 spin_unlock_irqrestore(&bdata->lock, flags);
386}
387
388static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
389{
390 struct gpio_button_data *bdata = dev_id;
391 const struct gpio_keys_button *button = bdata->button;
392 struct input_dev *input = bdata->input;
393 unsigned long flags;
394
395 BUG_ON(irq != bdata->irq);
396
397 spin_lock_irqsave(&bdata->lock, flags);
398
399 if (!bdata->key_pressed) {
400 input_event(input, EV_KEY, button->code, 1);
401 input_sync(input);
402
403 if (!bdata->timer_debounce) {
404 input_event(input, EV_KEY, button->code, 0);
405 input_sync(input);
406 goto out;
407 }
408
409 bdata->key_pressed = true;
410 }
411
412 if (bdata->timer_debounce)
413 mod_timer(&bdata->timer,
414 jiffies + msecs_to_jiffies(bdata->timer_debounce));
415out:
416 spin_unlock_irqrestore(&bdata->lock, flags);
417 return IRQ_HANDLED;
418}
419
370static int __devinit gpio_keys_setup_key(struct platform_device *pdev, 420static int __devinit gpio_keys_setup_key(struct platform_device *pdev,
371 struct input_dev *input, 421 struct input_dev *input,
372 struct gpio_button_data *bdata, 422 struct gpio_button_data *bdata,
@@ -374,46 +424,79 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev,
374{ 424{
375 const char *desc = button->desc ? button->desc : "gpio_keys"; 425 const char *desc = button->desc ? button->desc : "gpio_keys";
376 struct device *dev = &pdev->dev; 426 struct device *dev = &pdev->dev;
427 irq_handler_t isr;
377 unsigned long irqflags; 428 unsigned long irqflags;
378 int irq, error; 429 int irq, error;
379 430
380 setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata);
381 INIT_WORK(&bdata->work, gpio_keys_work_func);
382 bdata->input = input; 431 bdata->input = input;
383 bdata->button = button; 432 bdata->button = button;
433 spin_lock_init(&bdata->lock);
384 434
385 error = gpio_request(button->gpio, desc); 435 if (gpio_is_valid(button->gpio)) {
386 if (error < 0) {
387 dev_err(dev, "failed to request GPIO %d, error %d\n",
388 button->gpio, error);
389 goto fail2;
390 }
391 436
392 error = gpio_direction_input(button->gpio); 437 error = gpio_request(button->gpio, desc);
393 if (error < 0) { 438 if (error < 0) {
394 dev_err(dev, "failed to configure" 439 dev_err(dev, "Failed to request GPIO %d, error %d\n",
395 " direction for GPIO %d, error %d\n", 440 button->gpio, error);
396 button->gpio, error); 441 return error;
397 goto fail3; 442 }
398 }
399 443
400 if (button->debounce_interval) { 444 error = gpio_direction_input(button->gpio);
401 error = gpio_set_debounce(button->gpio, 445 if (error < 0) {
402 button->debounce_interval * 1000); 446 dev_err(dev,
403 /* use timer if gpiolib doesn't provide debounce */ 447 "Failed to configure direction for GPIO %d, error %d\n",
404 if (error < 0) 448 button->gpio, error);
405 bdata->timer_debounce = button->debounce_interval; 449 goto fail;
406 } 450 }
407 451
408 irq = gpio_to_irq(button->gpio); 452 if (button->debounce_interval) {
409 if (irq < 0) { 453 error = gpio_set_debounce(button->gpio,
410 error = irq; 454 button->debounce_interval * 1000);
411 dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", 455 /* use timer if gpiolib doesn't provide debounce */
412 button->gpio, error); 456 if (error < 0)
413 goto fail3; 457 bdata->timer_debounce =
458 button->debounce_interval;
459 }
460
461 irq = gpio_to_irq(button->gpio);
462 if (irq < 0) {
463 error = irq;
464 dev_err(dev,
465 "Unable to get irq number for GPIO %d, error %d\n",
466 button->gpio, error);
467 goto fail;
468 }
469 bdata->irq = irq;
470
471 INIT_WORK(&bdata->work, gpio_keys_gpio_work_func);
472 setup_timer(&bdata->timer,
473 gpio_keys_gpio_timer, (unsigned long)bdata);
474
475 isr = gpio_keys_gpio_isr;
476 irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
477
478 } else {
479 if (!button->irq) {
480 dev_err(dev, "No IRQ specified\n");
481 return -EINVAL;
482 }
483 bdata->irq = button->irq;
484
485 if (button->type && button->type != EV_KEY) {
486 dev_err(dev, "Only EV_KEY allowed for IRQ buttons.\n");
487 return -EINVAL;
488 }
489
490 bdata->timer_debounce = button->debounce_interval;
491 setup_timer(&bdata->timer,
492 gpio_keys_irq_timer, (unsigned long)bdata);
493
494 isr = gpio_keys_irq_isr;
495 irqflags = 0;
414 } 496 }
415 497
416 irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; 498 input_set_capability(input, button->type ?: EV_KEY, button->code);
499
417 /* 500 /*
418 * If platform has specified that the button can be disabled, 501 * If platform has specified that the button can be disabled,
419 * we don't want it to share the interrupt line. 502 * we don't want it to share the interrupt line.
@@ -421,19 +504,19 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev,
421 if (!button->can_disable) 504 if (!button->can_disable)
422 irqflags |= IRQF_SHARED; 505 irqflags |= IRQF_SHARED;
423 506
424 error = request_any_context_irq(irq, gpio_keys_isr, irqflags, desc, bdata); 507 error = request_any_context_irq(bdata->irq, isr, irqflags, desc, bdata);
425 if (error < 0) { 508 if (error < 0) {
426 dev_err(dev, "Unable to claim irq %d; error %d\n", 509 dev_err(dev, "Unable to claim irq %d; error %d\n",
427 irq, error); 510 bdata->irq, error);
428 goto fail3; 511 goto fail;
429 } 512 }
430 513
431 input_set_capability(input, button->type ?: EV_KEY, button->code);
432 return 0; 514 return 0;
433 515
434fail3: 516fail:
435 gpio_free(button->gpio); 517 if (gpio_is_valid(button->gpio))
436fail2: 518 gpio_free(button->gpio);
519
437 return error; 520 return error;
438} 521}
439 522
@@ -553,11 +636,12 @@ static int gpio_keys_get_devtree_pdata(struct device *dev,
553 636
554static void gpio_remove_key(struct gpio_button_data *bdata) 637static void gpio_remove_key(struct gpio_button_data *bdata)
555{ 638{
556 free_irq(gpio_to_irq(bdata->button->gpio), bdata); 639 free_irq(bdata->irq, bdata);
557 if (bdata->timer_debounce) 640 if (bdata->timer_debounce)
558 del_timer_sync(&bdata->timer); 641 del_timer_sync(&bdata->timer);
559 cancel_work_sync(&bdata->work); 642 cancel_work_sync(&bdata->work);
560 gpio_free(bdata->button->gpio); 643 if (gpio_is_valid(bdata->button->gpio))
644 gpio_free(bdata->button->gpio);
561} 645}
562 646
563static int __devinit gpio_keys_probe(struct platform_device *pdev) 647static int __devinit gpio_keys_probe(struct platform_device *pdev)
@@ -637,9 +721,12 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
637 goto fail3; 721 goto fail3;
638 } 722 }
639 723
640 /* get current state of buttons */ 724 /* get current state of buttons that are connected to GPIOs */
641 for (i = 0; i < pdata->nbuttons; i++) 725 for (i = 0; i < pdata->nbuttons; i++) {
642 gpio_keys_report_event(&ddata->data[i]); 726 struct gpio_button_data *bdata = &ddata->data[i];
727 if (gpio_is_valid(bdata->button->gpio))
728 gpio_keys_gpio_report_event(bdata);
729 }
643 input_sync(input); 730 input_sync(input);
644 731
645 device_init_wakeup(&pdev->dev, wakeup); 732 device_init_wakeup(&pdev->dev, wakeup);
@@ -695,16 +782,13 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
695static int gpio_keys_suspend(struct device *dev) 782static int gpio_keys_suspend(struct device *dev)
696{ 783{
697 struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); 784 struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
698 const struct gpio_keys_button *button;
699 int i; 785 int i;
700 786
701 if (device_may_wakeup(dev)) { 787 if (device_may_wakeup(dev)) {
702 for (i = 0; i < ddata->n_buttons; i++) { 788 for (i = 0; i < ddata->n_buttons; i++) {
703 button = ddata->data[i].button; 789 struct gpio_button_data *bdata = &ddata->data[i];
704 if (button->wakeup) { 790 if (bdata->button->wakeup)
705 int irq = gpio_to_irq(button->gpio); 791 enable_irq_wake(bdata->irq);
706 enable_irq_wake(irq);
707 }
708 } 792 }
709 } 793 }
710 794
@@ -714,17 +798,15 @@ static int gpio_keys_suspend(struct device *dev)
714static int gpio_keys_resume(struct device *dev) 798static int gpio_keys_resume(struct device *dev)
715{ 799{
716 struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); 800 struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
717 const struct gpio_keys_button *button;
718 int i; 801 int i;
719 802
720 for (i = 0; i < ddata->n_buttons; i++) { 803 for (i = 0; i < ddata->n_buttons; i++) {
721 button = ddata->data[i].button; 804 struct gpio_button_data *bdata = &ddata->data[i];
722 if (button->wakeup && device_may_wakeup(dev)) { 805 if (bdata->button->wakeup && device_may_wakeup(dev))
723 int irq = gpio_to_irq(button->gpio); 806 disable_irq_wake(bdata->irq);
724 disable_irq_wake(irq);
725 }
726 807
727 gpio_keys_report_event(&ddata->data[i]); 808 if (gpio_is_valid(bdata->button->gpio))
809 gpio_keys_gpio_report_event(bdata);
728 } 810 }
729 input_sync(ddata->input); 811 input_sync(ddata->input);
730 812