From: Xing Wei <weixing@hanwang.com.cn>
Date: Sun, 12 Sep 2010 07:24:17 +0000 (-0700)
Subject: Input: hanwang - make compatible with xf86-input-wacom driver
X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=24dd3b58228d463254ee57c3811afea831b8a024;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git

Input: hanwang - make compatible with xf86-input-wacom driver

Add necessary events so that Hanwang Art Master III tablet can be handled
by the stock xf86-input-wacom driver.

Signed-off-by: Xing Wei <weixing@hanwang.com.cn>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c
index 3554e30ab41b..0701d948cdf3 100644
--- a/drivers/input/tablet/hanwang.c
+++ b/drivers/input/tablet/hanwang.c
@@ -44,6 +44,13 @@ MODULE_LICENSE(DRIVER_LICENSE);
 
 #define ART_MASTERIII_PKGLEN_MAX	10
 
+/* device IDs */
+#define STYLUS_DEVICE_ID	0x02
+#define TOUCH_DEVICE_ID		0x03
+#define CURSOR_DEVICE_ID	0x06
+#define ERASER_DEVICE_ID	0x0A
+#define PAD_DEVICE_ID		0x0F
+
 /* match vendor and interface info  */
 #define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \
 	.match_flags = USB_DEVICE_ID_MATCH_VENDOR \
@@ -61,6 +68,7 @@ struct hanwang {
 	struct urb *irq;
 	const struct hanwang_features *features;
 	unsigned int current_tool;
+	unsigned int current_id;
 	char name[64];
 	char phys[32];
 };
@@ -86,16 +94,22 @@ static const struct hanwang_features features_array[] = {
 };
 
 static const int hw_eventtypes[] = {
-	EV_KEY, EV_ABS,
+	EV_KEY, EV_ABS, EV_MSC,
 };
 
 static const int hw_absevents[] = {
-	ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL, ABS_PRESSURE,
+	ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL,
+	ABS_PRESSURE, ABS_MISC,
 };
 
 static const int hw_btnevents[] = {
-	BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_MOUSE,
-	BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8
+	BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER,
+	BTN_TOOL_MOUSE, BTN_TOOL_FINGER,
+	BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8,
+};
+
+static const int hw_mscevents[] = {
+	MSC_SERIAL,
 };
 
 static void hanwang_parse_packet(struct hanwang *hanwang)
@@ -109,20 +123,24 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
 	case 0x02:	/* data packet */
 		switch (data[1]) {
 		case 0x80:	/* tool prox out */
+			hanwang->current_id = 0;
 			input_report_key(input_dev, hanwang->current_tool, 0);
 			break;
 
 		case 0xc2:	/* first time tool prox in */
 			switch (data[3] & 0xf0) {
 			case 0x20:
+				hanwang->current_id = STYLUS_DEVICE_ID;
 				hanwang->current_tool = BTN_TOOL_PEN;
 				input_report_key(input_dev, BTN_TOOL_PEN, 1);
 				break;
 			case 0xa0:
+				hanwang->current_id = ERASER_DEVICE_ID;
 				hanwang->current_tool = BTN_TOOL_RUBBER;
 				input_report_key(input_dev, BTN_TOOL_RUBBER, 1);
 				break;
 			default:
+				hanwang->current_id = 0;
 				dev_dbg(&dev->dev,
 					"unknown tablet tool %02x ", data[0]);
 				break;
@@ -144,15 +162,23 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
 			input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04);
 			break;
 		}
+		input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
+		input_event(input_dev, EV_MSC, MSC_SERIAL,
+				hanwang->features->pid);
 		break;
 
 	case 0x0c:
 		/* roll wheel */
+		hanwang->current_id = PAD_DEVICE_ID;
+		input_report_key(input_dev, BTN_TOOL_FINGER, data[1] ||
+						data[2] || data[3]);
 		input_report_abs(input_dev, ABS_WHEEL, data[1]);
 		input_report_key(input_dev, BTN_0, data[2]);
 		for (i = 0; i < 8; i++)
 			input_report_key(input_dev,
 					 BTN_1 + i, data[3] & (1 << i));
+		input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
+		input_event(input_dev, EV_MSC, MSC_SERIAL, 0xffffffff);
 		break;
 
 	default:
@@ -287,6 +313,9 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id
 	for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i)
 		__set_bit(hw_btnevents[i], input_dev->keybit);
 
+	for (i = 0; i < ARRAY_SIZE(hw_mscevents); ++i)
+		__set_bit(hw_mscevents[i], input_dev->mscbit);
+
 	input_set_abs_params(input_dev, ABS_X,
 			     0, hanwang->features->max_x, 4, 0);
 	input_set_abs_params(input_dev, ABS_Y,