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",