linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Input: gpio-keys: Support for one-directional interrupts
@ 2009-12-05 22:38 Cory Maccarrone
  2009-12-09 11:32 ` Ferenc Wagner
  0 siblings, 1 reply; 7+ messages in thread
From: Cory Maccarrone @ 2009-12-05 22:38 UTC (permalink / raw)
  To: linux-input, linux-omap; +Cc: Cory Maccarrone

The current gpio-keys driver assumes that each given GPIO has
the ability to respond to both rising and falling interrupts
at the same time.  For some GPIOs on certain devices, the interrupt
is only one-directional -- either rising or falling, depending on
what's being listened for.  In particular, the HTC Herald keyboard
slide switch interrupt must be switched from rising to falling and
back on each event, otherwise only one transition will be detected.

This change adds a new entry to the gpio_keys_button structure to
allow for this condition to be specified in board configurations.
When set, the driver detects the current state of the GPIO and sets
the direction of the interrupt accordingly.  Then, on each event,
the interrupt direction is switched.

Signed-off-by: Cory Maccarrone <darkstar6262@gmail.com>
---
 drivers/input/keyboard/gpio_keys.c |   27 +++++++++++++++++++++++----
 include/linux/gpio_keys.h          |    1 +
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 77d1309..05c599a 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -45,7 +45,18 @@ static void gpio_keys_report_event(struct work_struct *work)
 	struct gpio_keys_button *button = bdata->button;
 	struct input_dev *input = bdata->input;
 	unsigned int type = button->type ?: EV_KEY;
-	int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
+	int state = gpio_get_value(button->gpio) ? 1 : 0;
+
+	/* If the hardware can't do both edges, set the appropriate
+	 * interrupt control */
+	if (button->not_both_edges) {
+		if (state)
+			set_irq_type(gpio_to_irq(button->gpio), IRQ_TYPE_EDGE_FALLING);
+		else
+			set_irq_type(gpio_to_irq(button->gpio), IRQ_TYPE_EDGE_RISING);
+	}
+
+	state ^= button->active_low;
 
 	input_event(input, type, button->code, !!state);
 	input_sync(input);
@@ -79,7 +90,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
 	struct gpio_keys_drvdata *ddata;
 	struct input_dev *input;
-	int i, error;
+	int i, error, trigger;
 	int wakeup = 0;
 
 	ddata = kzalloc(sizeof(struct gpio_keys_drvdata) +
@@ -146,9 +157,17 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 			goto fail2;
 		}
 
+		if (button->not_both_edges) {
+			if (gpio_get_value(button->gpio))
+				trigger = IRQF_TRIGGER_FALLING;
+			else
+				trigger = IRQF_TRIGGER_RISING;
+		} else {
+			trigger = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;
+		}
+
 		error = request_irq(irq, gpio_keys_isr,
-				    IRQF_SHARED |
-				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				    IRQF_SHARED | trigger,
 				    button->desc ? button->desc : "gpio_keys",
 				    bdata);
 		if (error) {
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
index 1289fa7..493426d 100644
--- a/include/linux/gpio_keys.h
+++ b/include/linux/gpio_keys.h
@@ -10,6 +10,7 @@ struct gpio_keys_button {
 	int type;		/* input event type (EV_KEY, EV_SW) */
 	int wakeup;		/* configure the button as a wake-up source */
 	int debounce_interval;	/* debounce ticks interval in msecs */
+	int not_both_edges;	/* some hardware can't do interrupts on both edges */
 };
 
 struct gpio_keys_platform_data {
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-01-09 17:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-05 22:38 [PATCH] Input: gpio-keys: Support for one-directional interrupts Cory Maccarrone
2009-12-09 11:32 ` Ferenc Wagner
2009-12-09 16:15   ` Cory Maccarrone
2009-12-09 17:58     ` Dmitry Torokhov
2009-12-09 22:03       ` Cory Maccarrone
2009-12-11  4:03         ` Cory Maccarrone
2010-01-09 17:56           ` Cory Maccarrone

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).