浏览代码

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>
Xing Wei 14 年之前
父节点
当前提交
24dd3b5822
共有 1 个文件被更改,包括 33 次插入4 次删除
  1. 33 4
      drivers/input/tablet/hanwang.c

+ 33 - 4
drivers/input/tablet/hanwang.c

@@ -44,6 +44,13 @@ MODULE_LICENSE(DRIVER_LICENSE);
 
 
 #define ART_MASTERIII_PKGLEN_MAX	10
 #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  */
 /* match vendor and interface info  */
 #define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \
 #define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \
 	.match_flags = USB_DEVICE_ID_MATCH_VENDOR \
 	.match_flags = USB_DEVICE_ID_MATCH_VENDOR \
@@ -61,6 +68,7 @@ struct hanwang {
 	struct urb *irq;
 	struct urb *irq;
 	const struct hanwang_features *features;
 	const struct hanwang_features *features;
 	unsigned int current_tool;
 	unsigned int current_tool;
+	unsigned int current_id;
 	char name[64];
 	char name[64];
 	char phys[32];
 	char phys[32];
 };
 };
@@ -86,16 +94,22 @@ static const struct hanwang_features features_array[] = {
 };
 };
 
 
 static const int hw_eventtypes[] = {
 static const int hw_eventtypes[] = {
-	EV_KEY, EV_ABS,
+	EV_KEY, EV_ABS, EV_MSC,
 };
 };
 
 
 static const int hw_absevents[] = {
 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[] = {
 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)
 static void hanwang_parse_packet(struct hanwang *hanwang)
@@ -109,20 +123,24 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
 	case 0x02:	/* data packet */
 	case 0x02:	/* data packet */
 		switch (data[1]) {
 		switch (data[1]) {
 		case 0x80:	/* tool prox out */
 		case 0x80:	/* tool prox out */
+			hanwang->current_id = 0;
 			input_report_key(input_dev, hanwang->current_tool, 0);
 			input_report_key(input_dev, hanwang->current_tool, 0);
 			break;
 			break;
 
 
 		case 0xc2:	/* first time tool prox in */
 		case 0xc2:	/* first time tool prox in */
 			switch (data[3] & 0xf0) {
 			switch (data[3] & 0xf0) {
 			case 0x20:
 			case 0x20:
+				hanwang->current_id = STYLUS_DEVICE_ID;
 				hanwang->current_tool = BTN_TOOL_PEN;
 				hanwang->current_tool = BTN_TOOL_PEN;
 				input_report_key(input_dev, BTN_TOOL_PEN, 1);
 				input_report_key(input_dev, BTN_TOOL_PEN, 1);
 				break;
 				break;
 			case 0xa0:
 			case 0xa0:
+				hanwang->current_id = ERASER_DEVICE_ID;
 				hanwang->current_tool = BTN_TOOL_RUBBER;
 				hanwang->current_tool = BTN_TOOL_RUBBER;
 				input_report_key(input_dev, BTN_TOOL_RUBBER, 1);
 				input_report_key(input_dev, BTN_TOOL_RUBBER, 1);
 				break;
 				break;
 			default:
 			default:
+				hanwang->current_id = 0;
 				dev_dbg(&dev->dev,
 				dev_dbg(&dev->dev,
 					"unknown tablet tool %02x ", data[0]);
 					"unknown tablet tool %02x ", data[0]);
 				break;
 				break;
@@ -144,15 +162,23 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
 			input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04);
 			input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04);
 			break;
 			break;
 		}
 		}
+		input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
+		input_event(input_dev, EV_MSC, MSC_SERIAL,
+				hanwang->features->pid);
 		break;
 		break;
 
 
 	case 0x0c:
 	case 0x0c:
 		/* roll wheel */
 		/* 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_abs(input_dev, ABS_WHEEL, data[1]);
 		input_report_key(input_dev, BTN_0, data[2]);
 		input_report_key(input_dev, BTN_0, data[2]);
 		for (i = 0; i < 8; i++)
 		for (i = 0; i < 8; i++)
 			input_report_key(input_dev,
 			input_report_key(input_dev,
 					 BTN_1 + i, data[3] & (1 << i));
 					 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;
 		break;
 
 
 	default:
 	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)
 	for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i)
 		__set_bit(hw_btnevents[i], input_dev->keybit);
 		__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,
 	input_set_abs_params(input_dev, ABS_X,
 			     0, hanwang->features->max_x, 4, 0);
 			     0, hanwang->features->max_x, 4, 0);
 	input_set_abs_params(input_dev, ABS_Y,
 	input_set_abs_params(input_dev, ABS_Y,