aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/keyboard/gpio_keys.c214
-rw-r--r--include/linux/gpio_keys.h3
2 files changed, 150 insertions, 67 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 8f44f7b8c944..62bfce468f9f 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
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
index 004ff33ab38e..a7e977ff4abf 100644
--- a/include/linux/gpio_keys.h
+++ b/include/linux/gpio_keys.h
@@ -6,7 +6,7 @@ struct device;
6struct gpio_keys_button { 6struct gpio_keys_button {
7 /* Configuration parameters */ 7 /* Configuration parameters */
8 unsigned int code; /* input event code (KEY_*, SW_*) */ 8 unsigned int code; /* input event code (KEY_*, SW_*) */
9 int gpio; 9 int gpio; /* -1 if this key does not support gpio */
10 int active_low; 10 int active_low;
11 const char *desc; 11 const char *desc;
12 unsigned int type; /* input event type (EV_KEY, EV_SW, EV_ABS) */ 12 unsigned int type; /* input event type (EV_KEY, EV_SW, EV_ABS) */
@@ -14,6 +14,7 @@ struct gpio_keys_button {
14 int debounce_interval; /* debounce ticks interval in msecs */ 14 int debounce_interval; /* debounce ticks interval in msecs */
15 bool can_disable; 15 bool can_disable;
16 int value; /* axis value for EV_ABS */ 16 int value; /* axis value for EV_ABS */
17 unsigned int irq; /* Irq number in case of interrupt keys */
17}; 18};
18 19
19struct gpio_keys_platform_data { 20struct gpio_keys_platform_data {