Chuck Ebbert 1d13b01
From: Henrik Rydberg <rydberg@euromail.se>
Chuck Ebbert 1d13b01
Date: Sun, 5 Sep 2010 19:53:16 +0000 (-0700)
Chuck Ebbert 1d13b01
Subject: Input: wacom - add support for the Bamboo Touch trackpad
Chuck Ebbert 1d13b01
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=cb734c03680eaaad64a20a666300eafd1ac260b2
Chuck Ebbert 1d13b01
Chuck Ebbert 1d13b01
Input: wacom - add support for the Bamboo Touch trackpad
Chuck Ebbert 1d13b01
Chuck Ebbert 1d13b01
Add support for the Bamboo Touch trackpad, and make it work with
Chuck Ebbert 1d13b01
both the Synaptics X Driver and the Multitouch X Driver. The device
Chuck Ebbert 1d13b01
uses MT slots internally, so the choice of protocol is a given.
Chuck Ebbert 1d13b01
Chuck Ebbert 1d13b01
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Chuck Ebbert 1d13b01
Acked-by: Ping Cheng <pingc@wacom.com>
Chuck Ebbert 1d13b01
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Chuck Ebbert 1d13b01
---
Chuck Ebbert 1d13b01
Chuck Ebbert 1d13b01
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
Chuck Ebbert 1d13b01
index 44b4a59..4e9b1dd 100644
Chuck Ebbert 1d13b01
--- a/drivers/input/tablet/wacom_wac.c
Chuck Ebbert 1d13b01
+++ b/drivers/input/tablet/wacom_wac.c
Chuck Ebbert 1d13b01
@@ -855,6 +855,53 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
Chuck Ebbert 1d13b01
 	return retval;
Chuck Ebbert 1d13b01
 }
Chuck Ebbert 1d13b01
 
Chuck Ebbert 1d13b01
+static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
Chuck Ebbert 1d13b01
+{
Chuck Ebbert 1d13b01
+	struct input_dev *input = wacom->input;
Chuck Ebbert 1d13b01
+	unsigned char *data = wacom->data;
Chuck Ebbert 1d13b01
+	int sp = 0, sx = 0, sy = 0, count = 0;
Chuck Ebbert 1d13b01
+	int i;
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+	if (len != WACOM_PKGLEN_BBTOUCH)
Chuck Ebbert 1d13b01
+		return 0;
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+	for (i = 0; i < 2; i++) {
Chuck Ebbert 1d13b01
+		int p = data[9 * i + 2];
Chuck Ebbert 1d13b01
+		input_mt_slot(input, i);
Chuck Ebbert 1d13b01
+		if (p) {
Chuck Ebbert 1d13b01
+			int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;
Chuck Ebbert 1d13b01
+			int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;
Chuck Ebbert 1d13b01
+			input_report_abs(input, ABS_MT_PRESSURE, p);
Chuck Ebbert 1d13b01
+			input_report_abs(input, ABS_MT_POSITION_X, x);
Chuck Ebbert 1d13b01
+			input_report_abs(input, ABS_MT_POSITION_Y, y);
Chuck Ebbert 1d13b01
+			if (wacom->id[i] < 0)
Chuck Ebbert 1d13b01
+				wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID;
Chuck Ebbert 1d13b01
+			if (!count++)
Chuck Ebbert 1d13b01
+				sp = p, sx = x, sy = y;
Chuck Ebbert 1d13b01
+		} else {
Chuck Ebbert 1d13b01
+			wacom->id[i] = -1;
Chuck Ebbert 1d13b01
+		}
Chuck Ebbert 1d13b01
+		input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]);
Chuck Ebbert 1d13b01
+	}
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+	input_report_key(input, BTN_TOUCH, count > 0);
Chuck Ebbert 1d13b01
+	input_report_key(input, BTN_TOOL_FINGER, count == 1);
Chuck Ebbert 1d13b01
+	input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2);
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+	input_report_abs(input, ABS_PRESSURE, sp);
Chuck Ebbert 1d13b01
+	input_report_abs(input, ABS_X, sx);
Chuck Ebbert 1d13b01
+	input_report_abs(input, ABS_Y, sy);
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+	input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
Chuck Ebbert 1d13b01
+	input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
Chuck Ebbert 1d13b01
+	input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
Chuck Ebbert 1d13b01
+	input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+	input_sync(input);
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+	return 0;
Chuck Ebbert 1d13b01
+}
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
 void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
Chuck Ebbert 1d13b01
 {
Chuck Ebbert 1d13b01
 	bool sync;
Chuck Ebbert 1d13b01
@@ -900,6 +947,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
Chuck Ebbert 1d13b01
 		sync = wacom_tpc_irq(wacom_wac, len);
Chuck Ebbert 1d13b01
 		break;
Chuck Ebbert 1d13b01
 
Chuck Ebbert 1d13b01
+	case BAMBOO_PT:
Chuck Ebbert 1d13b01
+		sync = wacom_bpt_irq(wacom_wac, len);
Chuck Ebbert 1d13b01
+		break;
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
 	default:
Chuck Ebbert 1d13b01
 		sync = false;
Chuck Ebbert 1d13b01
 		break;
Chuck Ebbert 1d13b01
@@ -955,6 +1006,13 @@ void wacom_setup_device_quirks(struct wacom_features *features)
Chuck Ebbert 1d13b01
 	if (features->type == TABLETPC || features->type == TABLETPC2FG ||
Chuck Ebbert 1d13b01
 	    features->type == BAMBOO_PT)
Chuck Ebbert 1d13b01
 		features->quirks |= WACOM_QUIRK_MULTI_INPUT;
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+	/* quirks for bamboo touch */
Chuck Ebbert 1d13b01
+	if (features->type == BAMBOO_PT &&
Chuck Ebbert 1d13b01
+	    features->device_type == BTN_TOOL_TRIPLETAP) {
Chuck Ebbert 1d13b01
+		features->pressure_max = 256;
Chuck Ebbert 1d13b01
+		features->pressure_fuzz = 16;
Chuck Ebbert 1d13b01
+	}
Chuck Ebbert 1d13b01
 }
Chuck Ebbert 1d13b01
 
Chuck Ebbert 1d13b01
 void wacom_setup_input_capabilities(struct input_dev *input_dev,
Chuck Ebbert 1d13b01
@@ -1095,6 +1153,33 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
Chuck Ebbert 1d13b01
 	case PENPARTNER:
Chuck Ebbert 1d13b01
 		__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
Chuck Ebbert 1d13b01
 		break;
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+	case BAMBOO_PT:
Chuck Ebbert 1d13b01
+		__clear_bit(ABS_MISC, input_dev->absbit);
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+		if (features->device_type == BTN_TOOL_TRIPLETAP) {
Chuck Ebbert 1d13b01
+			__set_bit(BTN_LEFT, input_dev->keybit);
Chuck Ebbert 1d13b01
+			__set_bit(BTN_FORWARD, input_dev->keybit);
Chuck Ebbert 1d13b01
+			__set_bit(BTN_BACK, input_dev->keybit);
Chuck Ebbert 1d13b01
+			__set_bit(BTN_RIGHT, input_dev->keybit);
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+			__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
Chuck Ebbert 1d13b01
+			__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
+			input_mt_create_slots(input_dev, 2);
Chuck Ebbert 1d13b01
+			input_set_abs_params(input_dev, ABS_MT_POSITION_X,
Chuck Ebbert 1d13b01
+					     0, features->x_max,
Chuck Ebbert 1d13b01
+					     features->x_fuzz, 0);
Chuck Ebbert 1d13b01
+			input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
Chuck Ebbert 1d13b01
+					     0, features->y_max,
Chuck Ebbert 1d13b01
+					     features->y_fuzz, 0);
Chuck Ebbert 1d13b01
+			input_set_abs_params(input_dev, ABS_MT_PRESSURE,
Chuck Ebbert 1d13b01
+					     0, features->pressure_max,
Chuck Ebbert 1d13b01
+					     features->pressure_fuzz, 0);
Chuck Ebbert 1d13b01
+			input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
Chuck Ebbert 1d13b01
+					     MAX_TRACKING_ID, 0, 0);
Chuck Ebbert 1d13b01
+		}
Chuck Ebbert 1d13b01
+		break;
Chuck Ebbert 1d13b01
 	}
Chuck Ebbert 1d13b01
 }
Chuck Ebbert 1d13b01
 
Chuck Ebbert 1d13b01
@@ -1232,6 +1317,8 @@ static const struct wacom_features wacom_features_0xE3 =
Chuck Ebbert 1d13b01
 	{ "Wacom ISDv4 E3",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,  0, TABLETPC2FG };
Chuck Ebbert 1d13b01
 static const struct wacom_features wacom_features_0x47 =
Chuck Ebbert 1d13b01
 	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS };
Chuck Ebbert 1d13b01
+static struct wacom_features wacom_features_0xD0 =
Chuck Ebbert 1d13b01
+	{ "Wacom Bamboo 2FG",     WACOM_PKGLEN_BBFUN,     14720,  9200, 1023, 63, BAMBOO_PT };
Chuck Ebbert 1d13b01
 
Chuck Ebbert 1d13b01
 #define USB_DEVICE_WACOM(prod)					\
Chuck Ebbert 1d13b01
 	USB_DEVICE(USB_VENDOR_ID_WACOM, prod),			\
Chuck Ebbert 1d13b01
@@ -1296,6 +1383,7 @@ const struct usb_device_id wacom_ids[] = {
Chuck Ebbert 1d13b01
 	{ USB_DEVICE_WACOM(0xC6) },
Chuck Ebbert 1d13b01
 	{ USB_DEVICE_WACOM(0xC7) },
Chuck Ebbert 1d13b01
 	{ USB_DEVICE_WACOM(0xCE) },
Chuck Ebbert 1d13b01
+	{ USB_DEVICE_WACOM(0xD0) },
Chuck Ebbert 1d13b01
 	{ USB_DEVICE_WACOM(0xF0) },
Chuck Ebbert 1d13b01
 	{ USB_DEVICE_WACOM(0xCC) },
Chuck Ebbert 1d13b01
 	{ USB_DEVICE_WACOM(0x90) },
Chuck Ebbert 1d13b01
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
Chuck Ebbert 1d13b01
index 6a1ff10..a23d6a5 100644
Chuck Ebbert 1d13b01
--- a/drivers/input/tablet/wacom_wac.h
Chuck Ebbert 1d13b01
+++ b/drivers/input/tablet/wacom_wac.h
Chuck Ebbert 1d13b01
@@ -41,6 +41,9 @@
Chuck Ebbert 1d13b01
 /* device quirks */
Chuck Ebbert 1d13b01
 #define WACOM_QUIRK_MULTI_INPUT		0x0001
Chuck Ebbert 1d13b01
 
Chuck Ebbert 1d13b01
+/* largest reported tracking id */
Chuck Ebbert 1d13b01
+#define MAX_TRACKING_ID			0xfff
Chuck Ebbert 1d13b01
+
Chuck Ebbert 1d13b01
 enum {
Chuck Ebbert 1d13b01
 	PENPARTNER = 0,
Chuck Ebbert 1d13b01
 	GRAPHIRE,
Chuck Ebbert 1d13b01
@@ -96,6 +99,7 @@ struct wacom_wac {
Chuck Ebbert 1d13b01
 	int id[3];
Chuck Ebbert 1d13b01
 	__u32 serial[2];
Chuck Ebbert 1d13b01
 	int last_finger;
Chuck Ebbert 1d13b01
+	int trk_id;
Chuck Ebbert 1d13b01
 	struct wacom_features features;
Chuck Ebbert 1d13b01
 	struct wacom_shared *shared;
Chuck Ebbert 1d13b01
 	struct input_dev *input;