diff options
author | Arve Hjønnevåg <arve@android.com> | 2009-07-24 15:19:56 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2011-06-14 09:08:48 -0700 |
commit | 0da26bfb4ecea69226775572153fd85e2ab3785f (patch) | |
tree | 0b822ed2172da054bda51a2e3f42fd3400a9fea2 /drivers/input/misc/gpio_output.c | |
parent | 8f836aa8da5032979071b1b650b2ab240b60b7f7 (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.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/input/misc/gpio_output.c b/drivers/input/misc/gpio_output.c index 6f8453c97bd..2aac2fad0a1 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; } |