30d6f80
Bugzilla: 1046238
30d6f80
Upstream-status: Queued for 3.14
30d6f80
30d6f80
From b5fd2a3e92ca5c8c1f3c20d31ac5daed3ec4d604 Mon Sep 17 00:00:00 2001
30d6f80
From: Ping Cheng <pinglinux@gmail.com>
30d6f80
Date: Mon, 25 Nov 2013 18:44:55 -0800
30d6f80
Subject: [PATCH] Input: wacom - add support for three new Intuos devices
30d6f80
30d6f80
Two tablets in this series support both pen and touch. One (Intuos S)
30d6f80
only supports pen. This patch also updates the driver to process wireless
30d6f80
devices that do not support touch interface.
30d6f80
30d6f80
Tested-by: Jason Gerecke <killertofu@gmail.com>
30d6f80
Reviewed-by: Chris Bagwell <chris@cnpbagwell.com>
30d6f80
Signed-off-by: Ping Cheng <pingc@wacom.com>
30d6f80
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
30d6f80
---
30d6f80
 drivers/input/tablet/wacom_sys.c |  6 ++--
30d6f80
 drivers/input/tablet/wacom_wac.c | 61 ++++++++++++++++++++++++++++++----------
30d6f80
 drivers/input/tablet/wacom_wac.h |  2 ++
30d6f80
 3 files changed, 51 insertions(+), 18 deletions(-)
30d6f80
30d6f80
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
30d6f80
index 3d71b60..3a7d99c 100644
30d6f80
--- a/drivers/input/tablet/wacom_sys.c
30d6f80
+++ b/drivers/input/tablet/wacom_sys.c
30d6f80
@@ -1198,7 +1198,8 @@ static void wacom_wireless_work(struct work_struct *work)
30d6f80
 			goto fail;
30d6f80
 
30d6f80
 		/* Touch interface */
30d6f80
-		if (wacom_wac1->features.touch_max) {
30d6f80
+		if (wacom_wac1->features.touch_max ||
30d6f80
+		    wacom_wac1->features.type == INTUOSHT) {
30d6f80
 			wacom_wac2->features =
30d6f80
 				*((struct wacom_features *)id->driver_info);
30d6f80
 			wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
30d6f80
@@ -1321,7 +1322,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
30d6f80
 	 * HID descriptor. If this is the touch interface (wMaxPacketSize
30d6f80
 	 * of WACOM_PKGLEN_BBTOUCH3), override the table values.
30d6f80
 	 */
30d6f80
-	if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
30d6f80
+	if (features->type >= INTUOS5S && features->type <= INTUOSHT) {
30d6f80
 		if (endpoint->wMaxPacketSize == WACOM_PKGLEN_BBTOUCH3) {
30d6f80
 			features->device_type = BTN_TOOL_FINGER;
30d6f80
 			features->pktlen = WACOM_PKGLEN_BBTOUCH3;
30d6f80
@@ -1391,7 +1392,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
30d6f80
 			goto fail5;
30d6f80
 		}
30d6f80
 	}
30d6f80
-
30d6f80
 	return 0;
30d6f80
 
30d6f80
  fail5: wacom_destroy_leds(wacom);
30d6f80
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
30d6f80
index 3f75f1d..eb60a28 100644
30d6f80
--- a/drivers/input/tablet/wacom_wac.c
30d6f80
+++ b/drivers/input/tablet/wacom_wac.c
30d6f80
@@ -1176,10 +1176,16 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
30d6f80
 static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
30d6f80
 {
30d6f80
 	struct input_dev *input = wacom->input;
30d6f80
+	struct wacom_features *features = &wacom->features;
30d6f80
 
30d6f80
-	input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
30d6f80
+	if (features->type == INTUOSHT) {
30d6f80
+		input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0);
30d6f80
+		input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0);
30d6f80
+	} else {
30d6f80
+		input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
30d6f80
+		input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
30d6f80
+	}
30d6f80
 	input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
30d6f80
-	input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
30d6f80
 	input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
30d6f80
 }
30d6f80
 
30d6f80
@@ -1217,7 +1223,7 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
30d6f80
 	unsigned char *data = wacom->data;
30d6f80
 	int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
30d6f80
 
30d6f80
-	if (data[0] != 0x02)
30d6f80
+	if (data[0] != WACOM_REPORT_PENABLED)
30d6f80
 	    return 0;
30d6f80
 
30d6f80
 	prox = (data[1] & 0x20) == 0x20;
30d6f80
@@ -1297,7 +1303,7 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
30d6f80
 	unsigned char *data = wacom->data;
30d6f80
 	int connected;
30d6f80
 
30d6f80
-	if (len != WACOM_PKGLEN_WIRELESS || data[0] != 0x80)
30d6f80
+	if (len != WACOM_PKGLEN_WIRELESS || data[0] != WACOM_REPORT_WL)
30d6f80
 		return 0;
30d6f80
 
30d6f80
 	connected = data[1] & 0x01;
30d6f80
@@ -1391,6 +1397,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
30d6f80
 		break;
30d6f80
 
30d6f80
 	case BAMBOO_PT:
30d6f80
+	case INTUOSHT:
30d6f80
 		sync = wacom_bpt_irq(wacom_wac, len);
30d6f80
 		break;
30d6f80
 
30d6f80
@@ -1459,7 +1466,7 @@ void wacom_setup_device_quirks(struct wacom_features *features)
30d6f80
 
30d6f80
 	/* these device have multiple inputs */
30d6f80
 	if (features->type >= WIRELESS ||
30d6f80
-	    (features->type >= INTUOS5S && features->type <= INTUOSPL) ||
30d6f80
+	    (features->type >= INTUOS5S && features->type <= INTUOSHT) ||
30d6f80
 	    (features->oVid && features->oPid))
30d6f80
 		features->quirks |= WACOM_QUIRK_MULTI_INPUT;
30d6f80
 
30d6f80
@@ -1771,33 +1778,43 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
30d6f80
 		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
30d6f80
 		break;
30d6f80
 
30d6f80
+	case INTUOSHT:
30d6f80
 	case BAMBOO_PT:
30d6f80
 		__clear_bit(ABS_MISC, input_dev->absbit);
30d6f80
 
30d6f80
-		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
30d6f80
-
30d6f80
 		if (features->device_type == BTN_TOOL_FINGER) {
30d6f80
-			unsigned int flags = INPUT_MT_POINTER;
30d6f80
 
30d6f80
 			__set_bit(BTN_LEFT, input_dev->keybit);
30d6f80
 			__set_bit(BTN_FORWARD, input_dev->keybit);
30d6f80
 			__set_bit(BTN_BACK, input_dev->keybit);
30d6f80
 			__set_bit(BTN_RIGHT, input_dev->keybit);
30d6f80
 
30d6f80
-			if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
30d6f80
-				input_set_abs_params(input_dev,
30d6f80
+			if (features->touch_max) {
30d6f80
+				/* touch interface */
30d6f80
+				unsigned int flags = INPUT_MT_POINTER;
30d6f80
+
30d6f80
+				__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
30d6f80
+				if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
30d6f80
+					input_set_abs_params(input_dev,
30d6f80
 						     ABS_MT_TOUCH_MAJOR,
30d6f80
 						     0, features->x_max, 0, 0);
30d6f80
-				input_set_abs_params(input_dev,
30d6f80
+					input_set_abs_params(input_dev,
30d6f80
 						     ABS_MT_TOUCH_MINOR,
30d6f80
 						     0, features->y_max, 0, 0);
30d6f80
+				} else {
30d6f80
+					__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
30d6f80
+					__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
30d6f80
+					flags = 0;
30d6f80
+				}
30d6f80
+				input_mt_init_slots(input_dev, features->touch_max, flags);
30d6f80
 			} else {
30d6f80
-				__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
30d6f80
-				__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
30d6f80
-				flags = 0;
30d6f80
+				/* buttons/keys only interface */
30d6f80
+				__clear_bit(ABS_X, input_dev->absbit);
30d6f80
+				__clear_bit(ABS_Y, input_dev->absbit);
30d6f80
+				__clear_bit(BTN_TOUCH, input_dev->keybit);
30d6f80
 			}
30d6f80
-			input_mt_init_slots(input_dev, features->touch_max, flags);
30d6f80
 		} else if (features->device_type == BTN_TOOL_PEN) {
30d6f80
+			__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
30d6f80
 			__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
30d6f80
 			__set_bit(BTN_TOOL_PEN, input_dev->keybit);
30d6f80
 			__set_bit(BTN_STYLUS, input_dev->keybit);
30d6f80
@@ -2194,6 +2211,17 @@ static const struct wacom_features wacom_features_0x300 =
30d6f80
 static const struct wacom_features wacom_features_0x301 =
30d6f80
 	{ "Wacom Bamboo One M",    WACOM_PKGLEN_BBPEN,    21648, 13530, 1023,
30d6f80
 	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
30d6f80
+static const struct wacom_features wacom_features_0x302 =
30d6f80
+	{ "Wacom Intuos PT S",     WACOM_PKGLEN_BBPEN,    15200,  9500, 1023,
30d6f80
+	  31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
30d6f80
+	  .touch_max = 16 };
30d6f80
+static const struct wacom_features wacom_features_0x303 =
30d6f80
+	{ "Wacom Intuos PT M",     WACOM_PKGLEN_BBPEN,    21600, 13500, 1023,
30d6f80
+	  31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
30d6f80
+	  .touch_max = 16 };
30d6f80
+static const struct wacom_features wacom_features_0x30E =
30d6f80
+	{ "Wacom Intuos S",        WACOM_PKGLEN_BBPEN,    15200,  9500, 1023,
30d6f80
+	  31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
30d6f80
 static const struct wacom_features wacom_features_0x6004 =
30d6f80
 	{ "ISD-V4",               WACOM_PKGLEN_GRAPHIRE,  12800,  8000,  255,
30d6f80
 	  0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
30d6f80
@@ -2329,6 +2357,9 @@ const struct usb_device_id wacom_ids[] = {
30d6f80
 	{ USB_DEVICE_WACOM(0x10D) },
30d6f80
 	{ USB_DEVICE_WACOM(0x300) },
30d6f80
 	{ USB_DEVICE_WACOM(0x301) },
30d6f80
+	{ USB_DEVICE_DETAILED(0x302, USB_CLASS_HID, 0, 0) },
30d6f80
+	{ USB_DEVICE_DETAILED(0x303, USB_CLASS_HID, 0, 0) },
30d6f80
+	{ USB_DEVICE_DETAILED(0x30E, USB_CLASS_HID, 0, 0) },
30d6f80
 	{ USB_DEVICE_WACOM(0x304) },
30d6f80
 	{ USB_DEVICE_DETAILED(0x314, USB_CLASS_HID, 0, 0) },
30d6f80
 	{ USB_DEVICE_DETAILED(0x315, USB_CLASS_HID, 0, 0) },
30d6f80
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
30d6f80
index fd23a37..854cceb 100644
30d6f80
--- a/drivers/input/tablet/wacom_wac.h
30d6f80
+++ b/drivers/input/tablet/wacom_wac.h
30d6f80
@@ -54,6 +54,7 @@
30d6f80
 #define WACOM_REPORT_TPCST		16
30d6f80
 #define WACOM_REPORT_TPC1FGE		18
30d6f80
 #define WACOM_REPORT_24HDT		1
30d6f80
+#define WACOM_REPORT_WL			128
30d6f80
 
30d6f80
 /* device quirks */
30d6f80
 #define WACOM_QUIRK_MULTI_INPUT		0x0001
30d6f80
@@ -81,6 +82,7 @@ enum {
30d6f80
 	INTUOSPS,
30d6f80
 	INTUOSPM,
30d6f80
 	INTUOSPL,
30d6f80
+	INTUOSHT,
30d6f80
 	WACOM_21UX2,
30d6f80
 	WACOM_22HD,
30d6f80
 	DTK,
30d6f80
-- 
30d6f80
1.8.4.2
30d6f80