summaryrefslogtreecommitdiff
path: root/drivers/input/misc/gpio_output.c
diff options
context:
space:
mode:
authorArve Hjønnevåg <arve@android.com>2009-07-24 15:19:56 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:37:56 -0800
commit029dcd0b6f943f31f86b625c9c8e16d88381acb4 (patch)
tree322d08f08e9ca08d6548b8f02788d860210030c6 /drivers/input/misc/gpio_output.c
parent27dea20c8713e6d28c119e6668a0ea50e17d94b3 (diff)
Input: gpio_event: Allow multiple input devices per gpio_event device
This is needed to support devices that put non-keyboard buttons in the keyboard matrix. For instance several devices put the trackball button in the keyboard matrix. In this case BTN_MOUSE should be reported from the same input device as REL_X/Y. It is also useful for devices that have multiple logical keyboard in the same matrix. The HTC dream has a menu key on the external keyboard and another menu key on the slide-out keyboard. With a single input device only one of these menu keys can be mapped to KEY_MENU. Signed-off-by: Arve Hjønnevåg <arve@android.com>
Diffstat (limited to 'drivers/input/misc/gpio_output.c')
-rw-r--r--drivers/input/misc/gpio_output.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/input/misc/gpio_output.c b/drivers/input/misc/gpio_output.c
index 6f8453c97bd2..2aac2fad0a17 100644
--- a/drivers/input/misc/gpio_output.c
+++ b/drivers/input/misc/gpio_output.c
@@ -18,8 +18,9 @@
#include <linux/gpio_event.h>
int gpio_event_output_event(
- struct input_dev *input_dev, struct gpio_event_info *info, void **data,
- unsigned int type, unsigned int code, int value)
+ struct gpio_event_input_devs *input_devs, struct gpio_event_info *info,
+ void **data, unsigned int dev, unsigned int type,
+ unsigned int code, int value)
{
int i;
struct gpio_event_output_info *oi;
@@ -29,14 +30,14 @@ int gpio_event_output_event(
if (!(oi->flags & GPIOEDF_ACTIVE_HIGH))
value = !value;
for (i = 0; i < oi->keymap_size; i++)
- if (code == oi->keymap[i].code)
+ if (dev == oi->keymap[i].dev && code == oi->keymap[i].code)
gpio_set_value(oi->keymap[i].gpio, value);
return 0;
}
int gpio_event_output_func(
- struct input_dev *input_dev, struct gpio_event_info *info, void **data,
- int func)
+ struct gpio_event_input_devs *input_devs, struct gpio_event_info *info,
+ void **data, int func)
{
int ret;
int i;
@@ -48,9 +49,20 @@ int gpio_event_output_func(
if (func == GPIO_EVENT_FUNC_INIT) {
int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH);
- for (i = 0; i < oi->keymap_size; i++)
- input_set_capability(input_dev, oi->type,
+
+ for (i = 0; i < oi->keymap_size; i++) {
+ int dev = oi->keymap[i].dev;
+ if (dev >= input_devs->count) {
+ pr_err("gpio_event_output_func: bad device "
+ "index %d >= %d for key code %d\n",
+ dev, input_devs->count,
+ oi->keymap[i].code);
+ ret = -EINVAL;
+ goto err_bad_keymap;
+ }
+ input_set_capability(input_devs->dev[dev], oi->type,
oi->keymap[i].code);
+ }
for (i = 0; i < oi->keymap_size; i++) {
ret = gpio_request(oi->keymap[i].gpio,
@@ -79,6 +91,7 @@ err_gpio_direction_output_failed:
err_gpio_request_failed:
;
}
+err_bad_keymap:
return ret;
}