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>
diff --git a/drivers/input/misc/gpio_output.c b/drivers/input/misc/gpio_output.c
index 6f8453c..2aac2fa 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 @@
 	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 @@
 
 	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_request_failed:
 		;
 	}
+err_bad_keymap:
 	return ret;
 }