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/include/linux/gpio_event.h b/include/linux/gpio_event.h
index 5ff828b..360b4dd 100644
--- a/include/linux/gpio_event.h
+++ b/include/linux/gpio_event.h
@@ -18,6 +18,10 @@
 
 #include <linux/input.h>
 
+struct gpio_event_input_devs {
+	int count;
+	struct input_dev *dev[];
+};
 enum {
 	GPIO_EVENT_FUNC_UNINIT  = 0x0,
 	GPIO_EVENT_FUNC_INIT    = 0x1,
@@ -25,13 +29,14 @@
 	GPIO_EVENT_FUNC_RESUME  = 0x3,
 };
 struct gpio_event_info {
-	int (*func)(struct input_dev *input_dev,
+	int (*func)(struct gpio_event_input_devs *input_devs,
 		    struct gpio_event_info *info,
 		    void **data, int func);
-	int (*event)(struct input_dev *input_dev,
+	int (*event)(struct gpio_event_input_devs *input_devs,
 		     struct gpio_event_info *info,
-		     void **data, unsigned int type,
+		     void **data, unsigned int dev, unsigned int type,
 		     unsigned int code, int value); /* out events */
+	bool no_suspend;
 };
 
 struct gpio_event_platform_data {
@@ -39,6 +44,8 @@
 	struct gpio_event_info **info;
 	size_t info_count;
 	int (*power)(const struct gpio_event_platform_data *pdata, bool on);
+	const char *names[]; /* If name is NULL, names contain a NULL */
+			     /* terminated list of input devices to create */
 };
 
 #define GPIO_EVENT_DEV_NAME "gpio-event"
@@ -59,7 +66,12 @@
 	GPIOKPF_PRINT_PHANTOM_KEYS       = 1U << 18,
 };
 
-extern int gpio_event_matrix_func(struct input_dev *input_dev,
+#define MATRIX_CODE_BITS (10)
+#define MATRIX_KEY_MASK ((1U << MATRIX_CODE_BITS) - 1)
+#define MATRIX_KEY(dev, code) \
+	(((dev) << MATRIX_CODE_BITS) | (code & MATRIX_KEY_MASK))
+
+extern int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs,
 			struct gpio_event_info *info, void **data, int func);
 struct gpio_event_matrix_info {
 	/* initialize to gpio_event_matrix_func */
@@ -89,12 +101,13 @@
 };
 
 struct gpio_event_direct_entry {
-	uint32_t gpio:23;
-	uint32_t code:9;
+	uint32_t gpio:16;
+	uint32_t code:10;
+	uint32_t dev:6;
 };
 
 /* inputs */
-extern int gpio_event_input_func(struct input_dev *input_dev,
+extern int gpio_event_input_func(struct gpio_event_input_devs *input_devs,
 			struct gpio_event_info *info, void **data, int func);
 struct gpio_event_input_info {
 	/* initialize to gpio_event_input_func */
@@ -108,11 +121,12 @@
 };
 
 /* outputs */
-extern int gpio_event_output_func(struct input_dev *input_dev,
+extern int gpio_event_output_func(struct gpio_event_input_devs *input_devs,
 			struct gpio_event_info *info, void **data, int func);
-extern int gpio_event_output_event(struct input_dev *input_dev,
+extern int gpio_event_output_event(struct gpio_event_input_devs *input_devs,
 			struct gpio_event_info *info, void **data,
-			unsigned int type, unsigned int code, int value);
+			unsigned int dev, unsigned int type,
+			unsigned int code, int value);
 struct gpio_event_output_info {
 	/* initialize to gpio_event_output_func and gpio_event_output_event */
 	struct gpio_event_info info;
@@ -131,12 +145,13 @@
 	GPIOEAF_PRINT_EVENT              = 1U << 18,
 };
 
-extern int gpio_event_axis_func(struct input_dev *input_dev,
+extern int gpio_event_axis_func(struct gpio_event_input_devs *input_devs,
 			struct gpio_event_info *info, void **data, int func);
 struct gpio_event_axis_info {
 	/* initialize to gpio_event_axis_func */
 	struct gpio_event_info info;
-	uint8_t  count;
+	uint8_t  count; /* number of gpios for this axis */
+	uint8_t  dev; /* device index when using multiple input devices */
 	uint8_t  type; /* EV_REL or EV_ABS */
 	uint16_t code;
 	uint16_t decoded_size;