[kernel] Add preliminary support for Wacom Bamboo pen and touch devices.

Chuck Ebbert cebbert at fedoraproject.org
Mon Sep 13 19:58:24 UTC 2010


commit 1d13b01aba24af0a9dffa76d85abaa02e80ba687
Author: Chuck Ebbert <cebbert at redhat.com>
Date:   Mon Sep 13 15:57:40 2010 -0400

    Add preliminary support for Wacom Bamboo pen and touch devices.

 kernel.spec                                        |   23 +++
 wacom-01-add-fuzz-parameters-to-features.patch     |   69 ++++++++
 wacom-02-parse-the-bamboo-device-family.patch      |  122 ++++++++++++++
 ...ollect-device-quirks-into-single-function.patch |  107 ++++++++++++
 ...add-support-for-the-bamboo-touch-trackpad.patch |  172 ++++++++++++++++++++
 ...a-quirk-for-low-resolution-bamboo-devices.patch |   69 ++++++++
 wacom-06-request-tablet-data-for-bamboo-pens.patch |   55 +++++++
 ...move-bamboo-touch-irq-to-its-own-function.patch |   52 ++++++
 wacom-08-add-support-for-bamboo-pen.patch          |  130 +++++++++++++++
 ...le-bamboo-touchpad-when-pen-is-being-used.patch |   31 ++++
 10 files changed, 830 insertions(+), 0 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index b932c4a..60d4fcc 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -698,6 +698,17 @@ Patch12020: alsa-fix-substream-proc-status-read.patch
 
 Patch12030: tpm-fix-stall-on-boot.patch
 
+# Wacom Bamboo
+Patch12100: wacom-01-add-fuzz-parameters-to-features.patch
+Patch12105: wacom-02-parse-the-bamboo-device-family.patch
+Patch12110: wacom-03-collect-device-quirks-into-single-function.patch
+Patch12115: wacom-04-add-support-for-the-bamboo-touch-trackpad.patch
+Patch12120: wacom-05-add-a-quirk-for-low-resolution-bamboo-devices.patch
+Patch12125: wacom-06-request-tablet-data-for-bamboo-pens.patch
+Patch12130: wacom-07-move-bamboo-touch-irq-to-its-own-function.patch
+Patch12035: wacom-08-add-support-for-bamboo-pen.patch
+Patch12040: wacom-09-disable-bamboo-touchpad-when-pen-is-being-used.patch
+
 %endif
 
 BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1275,6 +1286,17 @@ ApplyPatch neuter_intel_microcode_load.patch
 # try to fix stalls during boot (#530393)
 ApplyPatch tpm-fix-stall-on-boot.patch
 
+# Wacom Bamboo
+ApplyPatch wacom-01-add-fuzz-parameters-to-features.patch
+ApplyPatch wacom-02-parse-the-bamboo-device-family.patch
+ApplyPatch wacom-03-collect-device-quirks-into-single-function.patch
+ApplyPatch wacom-04-add-support-for-the-bamboo-touch-trackpad.patch
+ApplyPatch wacom-05-add-a-quirk-for-low-resolution-bamboo-devices.patch
+ApplyPatch wacom-06-request-tablet-data-for-bamboo-pens.patch
+ApplyPatch wacom-07-move-bamboo-touch-irq-to-its-own-function.patch
+ApplyPatch wacom-08-add-support-for-bamboo-pen.patch
+ApplyPatch wacom-09-disable-bamboo-touchpad-when-pen-is-being-used.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -1884,6 +1906,7 @@ fi
 %changelog
 * Sat Sep 11 2010 Chuck Ebbert <cebbert at redhat.com>
 - Linux 2.6.36-rc4
+- Add preliminary support for Wacom Bamboo pen and touch devices.
 
 * Sat Sep 11 2010 Chuck Ebbert <cebbert at redhat.com> - 2.6.36-0.20.rc3.git4
 - Linux 2.6.36-rc3-git4
diff --git a/wacom-01-add-fuzz-parameters-to-features.patch b/wacom-01-add-fuzz-parameters-to-features.patch
new file mode 100644
index 0000000..4162726
--- /dev/null
+++ b/wacom-01-add-fuzz-parameters-to-features.patch
@@ -0,0 +1,69 @@
+From: Henrik Rydberg <rydberg at euromail.se>
+Date: Sun, 5 Sep 2010 19:25:11 +0000 (-0700)
+Subject: Input: wacom - add fuzz parameters to features
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=fed87e655a2c20468d628b37424af58287803afe
+
+Input: wacom - add fuzz parameters to features
+
+The signal-to-noise ratio varies between devices, but currently all
+devices are treated the same way. Add fuzz parameters to the feature
+struct, allowing for tailored treatment of devices.
+
+Signed-off-by: Henrik Rydberg <rydberg at euromail.se>
+Acked-by: Ping Cheng <pingc at wacom.com>
+Signed-off-by: Dmitry Torokhov <dtor at mail.ru>
+---
+
+diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
+index 42ba369..e510e4f 100644
+--- a/drivers/input/tablet/wacom_sys.c
++++ b/drivers/input/tablet/wacom_sys.c
+@@ -333,8 +333,12 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
+ 	struct usb_host_interface *interface = intf->cur_altsetting;
+ 	struct hid_descriptor *hid_desc;
+ 
+-	/* default device to penabled */
++	/* default features */
+ 	features->device_type = BTN_TOOL_PEN;
++	features->x_fuzz = 4;
++	features->y_fuzz = 4;
++	features->pressure_fuzz = 0;
++	features->distance_fuzz = 0;
+ 
+ 	/* only Tablet PCs need to retrieve the info */
+ 	if ((features->type != TABLETPC) && (features->type != TABLETPC2FG))
+diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
+index 6e29bad..6d7e164 100644
+--- a/drivers/input/tablet/wacom_wac.c
++++ b/drivers/input/tablet/wacom_wac.c
+@@ -951,9 +951,12 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
+ 
+ 	__set_bit(BTN_TOUCH, input_dev->keybit);
+ 
+-	input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0);
+-	input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0);
+-	input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0);
++	input_set_abs_params(input_dev, ABS_X, 0, features->x_max,
++			     features->x_fuzz, 0);
++	input_set_abs_params(input_dev, ABS_Y, 0, features->y_max,
++			     features->y_fuzz, 0);
++	input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max,
++			     features->pressure_fuzz, 0);
+ 
+ 	__set_bit(ABS_MISC, input_dev->absbit);
+ 
+diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
+index 99e1a54..d769e9a 100644
+--- a/drivers/input/tablet/wacom_wac.h
++++ b/drivers/input/tablet/wacom_wac.h
+@@ -73,6 +73,10 @@ struct wacom_features {
+ 	int y_phy;
+ 	unsigned char unit;
+ 	unsigned char unitExpo;
++	int x_fuzz;
++	int y_fuzz;
++	int pressure_fuzz;
++	int distance_fuzz;
+ };
+ 
+ struct wacom_shared {
diff --git a/wacom-02-parse-the-bamboo-device-family.patch b/wacom-02-parse-the-bamboo-device-family.patch
new file mode 100644
index 0000000..f24d04d
--- /dev/null
+++ b/wacom-02-parse-the-bamboo-device-family.patch
@@ -0,0 +1,122 @@
+From: Ping Cheng <pinglinux at gmail.com>
+Date: Sun, 5 Sep 2010 19:25:40 +0000 (-0700)
+Subject: Input: wacom - parse the Bamboo device family
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=4a88081e739a41d6d70bace7e0a027f9054ab540
+
+Input: wacom - parse the Bamboo device family
+
+The Bamboo devices have multiple interfaces which need to be setup
+separately. Use the HID parsing mechanism to achieve that.
+
+Signed-off-by: Ping Cheng <pinglinux at gmail.com>
+Signed-off-by: Henrik Rydberg <rydberg at euromail.se>
+Signed-off-by: Dmitry Torokhov <dtor at mail.ru>
+---
+
+diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
+index e510e4f..98cba08 100644
+--- a/drivers/input/tablet/wacom_sys.c
++++ b/drivers/input/tablet/wacom_sys.c
+@@ -195,17 +195,30 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
+ 							features->pktlen = WACOM_PKGLEN_TPC2FG;
+ 							features->device_type = BTN_TOOL_TRIPLETAP;
+ 						}
+-						features->x_max =
+-							get_unaligned_le16(&report[i + 3]);
+-						features->x_phy =
+-							get_unaligned_le16(&report[i + 6]);
+-						features->unit = report[i + 9];
+-						features->unitExpo = report[i + 11];
+-						i += 12;
++						if (features->type == BAMBOO_PT) {
++							/* need to reset back */
++							features->pktlen = WACOM_PKGLEN_BBTOUCH;
++							features->device_type = BTN_TOOL_TRIPLETAP;
++							features->x_phy =
++								get_unaligned_le16(&report[i + 5]);
++							features->x_max =
++								get_unaligned_le16(&report[i + 8]);
++							i += 15;
++						} else {
++							features->x_max =
++								get_unaligned_le16(&report[i + 3]);
++							features->x_phy =
++								get_unaligned_le16(&report[i + 6]);
++							features->unit = report[i + 9];
++							features->unitExpo = report[i + 11];
++							i += 12;
++						}
+ 					} else if (pen) {
+ 						/* penabled only accepts exact bytes of data */
+ 						if (features->type == TABLETPC2FG)
+ 							features->pktlen = WACOM_PKGLEN_GRAPHIRE;
++						if (features->type == BAMBOO_PT)
++							features->pktlen = WACOM_PKGLEN_BBFUN;
+ 						features->device_type = BTN_TOOL_PEN;
+ 						features->x_max =
+ 							get_unaligned_le16(&report[i + 3]);
+@@ -234,6 +247,15 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
+ 							features->y_phy =
+ 								get_unaligned_le16(&report[i + 6]);
+ 							i += 7;
++						} else if (features->type == BAMBOO_PT) {
++							/* need to reset back */
++							features->pktlen = WACOM_PKGLEN_BBTOUCH;
++							features->device_type = BTN_TOOL_TRIPLETAP;
++							features->y_phy =
++								get_unaligned_le16(&report[i + 3]);
++							features->y_max =
++								get_unaligned_le16(&report[i + 6]);
++							i += 12;
+ 						} else {
+ 							features->y_max =
+ 								features->x_max;
+@@ -245,6 +267,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
+ 						/* penabled only accepts exact bytes of data */
+ 						if (features->type == TABLETPC2FG)
+ 							features->pktlen = WACOM_PKGLEN_GRAPHIRE;
++						if (features->type == BAMBOO_PT)
++							features->pktlen = WACOM_PKGLEN_BBFUN;
+ 						features->device_type = BTN_TOOL_PEN;
+ 						features->y_max =
+ 							get_unaligned_le16(&report[i + 3]);
+@@ -341,7 +365,8 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
+ 	features->distance_fuzz = 0;
+ 
+ 	/* only Tablet PCs need to retrieve the info */
+-	if ((features->type != TABLETPC) && (features->type != TABLETPC2FG))
++	if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) &&
++	    (features->type != BAMBOO_PT))
+ 		goto out;
+ 
+ 	if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
+@@ -499,7 +524,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
+ 
+ 	strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
+ 
+-	if (features->type == TABLETPC || features->type == TABLETPC2FG) {
++	if (features->type == TABLETPC || features->type == TABLETPC2FG ||
++	    features->type == BAMBOO_PT) {
+ 		/* Append the device type to the name */
+ 		strlcat(wacom_wac->name,
+ 			features->device_type == BTN_TOOL_PEN ?
+diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
+index d769e9a..fb30895 100644
+--- a/drivers/input/tablet/wacom_wac.h
++++ b/drivers/input/tablet/wacom_wac.h
+@@ -21,6 +21,7 @@
+ #define WACOM_PKGLEN_INTUOS	10
+ #define WACOM_PKGLEN_TPC1FG	 5
+ #define WACOM_PKGLEN_TPC2FG	14
++#define WACOM_PKGLEN_BBTOUCH	20
+ 
+ /* device IDs */
+ #define STYLUS_DEVICE_ID	0x02
+@@ -44,6 +45,7 @@ enum {
+ 	PTU,
+ 	PL,
+ 	DTU,
++	BAMBOO_PT,
+ 	INTUOS,
+ 	INTUOS3S,
+ 	INTUOS3,
diff --git a/wacom-03-collect-device-quirks-into-single-function.patch b/wacom-03-collect-device-quirks-into-single-function.patch
new file mode 100644
index 0000000..7bf7687
--- /dev/null
+++ b/wacom-03-collect-device-quirks-into-single-function.patch
@@ -0,0 +1,107 @@
+From: Henrik Rydberg <rydberg at euromail.se>
+Date: Sun, 5 Sep 2010 19:26:16 +0000 (-0700)
+Subject: Input: wacom - collect device quirks into single function
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=bc73dd39e78dd6e5b34cd938b7f037a8bc041bdd
+
+Input: wacom - collect device quirks into single function
+
+Collect device-specific code into a single function, and use quirks to
+flag specific behavior instead.
+
+Signed-off-by: Henrik Rydberg <rydberg at euromail.se>
+Acked-by: Ping Cheng <pingc at wacom.com>
+Signed-off-by: Dmitry Torokhov <dtor at mail.ru>
+---
+
+diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
+index 284dfaa..de5adb1 100644
+--- a/drivers/input/tablet/wacom.h
++++ b/drivers/input/tablet/wacom.h
+@@ -118,6 +118,7 @@ struct wacom {
+ extern const struct usb_device_id wacom_ids[];
+ 
+ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
++void wacom_setup_device_quirks(struct wacom_features *features);
+ void wacom_setup_input_capabilities(struct input_dev *input_dev,
+ 				    struct wacom_wac *wacom_wac);
+ #endif
+diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
+index 98cba08..fc6fd53 100644
+--- a/drivers/input/tablet/wacom_sys.c
++++ b/drivers/input/tablet/wacom_sys.c
+@@ -381,12 +381,6 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
+ 	if (error)
+ 		goto out;
+ 
+-	/* touch device found but size is not defined. use default */
+-	if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) {
+-		features->x_max = 1023;
+-		features->y_max = 1023;
+-	}
+-
+  out:
+ 	return error;
+ }
+@@ -522,10 +516,11 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
+ 	if (error)
+ 		goto fail2;
+ 
++	wacom_setup_device_quirks(features);
++
+ 	strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
+ 
+-	if (features->type == TABLETPC || features->type == TABLETPC2FG ||
+-	    features->type == BAMBOO_PT) {
++	if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
+ 		/* Append the device type to the name */
+ 		strlcat(wacom_wac->name,
+ 			features->device_type == BTN_TOOL_PEN ?
+diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
+index 6d7e164..44b4a59 100644
+--- a/drivers/input/tablet/wacom_wac.c
++++ b/drivers/input/tablet/wacom_wac.c
+@@ -941,6 +941,22 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac)
+ 	input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
+ }
+ 
++
++void wacom_setup_device_quirks(struct wacom_features *features)
++{
++
++	/* touch device found but size is not defined. use default */
++	if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) {
++		features->x_max = 1023;
++		features->y_max = 1023;
++	}
++
++	/* these device have multiple inputs */
++	if (features->type == TABLETPC || features->type == TABLETPC2FG ||
++	    features->type == BAMBOO_PT)
++		features->quirks |= WACOM_QUIRK_MULTI_INPUT;
++}
++
+ void wacom_setup_input_capabilities(struct input_dev *input_dev,
+ 				    struct wacom_wac *wacom_wac)
+ {
+diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
+index fb30895..6a1ff10 100644
+--- a/drivers/input/tablet/wacom_wac.h
++++ b/drivers/input/tablet/wacom_wac.h
+@@ -38,6 +38,9 @@
+ #define WACOM_REPORT_TPC1FG		6
+ #define WACOM_REPORT_TPC2FG		13
+ 
++/* device quirks */
++#define WACOM_QUIRK_MULTI_INPUT		0x0001
++
+ enum {
+ 	PENPARTNER = 0,
+ 	GRAPHIRE,
+@@ -79,6 +82,7 @@ struct wacom_features {
+ 	int y_fuzz;
+ 	int pressure_fuzz;
+ 	int distance_fuzz;
++	unsigned quirks;
+ };
+ 
+ struct wacom_shared {
diff --git a/wacom-04-add-support-for-the-bamboo-touch-trackpad.patch b/wacom-04-add-support-for-the-bamboo-touch-trackpad.patch
new file mode 100644
index 0000000..f104b2c
--- /dev/null
+++ b/wacom-04-add-support-for-the-bamboo-touch-trackpad.patch
@@ -0,0 +1,172 @@
+From: Henrik Rydberg <rydberg at euromail.se>
+Date: Sun, 5 Sep 2010 19:53:16 +0000 (-0700)
+Subject: Input: wacom - add support for the Bamboo Touch trackpad
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=cb734c03680eaaad64a20a666300eafd1ac260b2
+
+Input: wacom - add support for the Bamboo Touch trackpad
+
+Add support for the Bamboo Touch trackpad, and make it work with
+both the Synaptics X Driver and the Multitouch X Driver. The device
+uses MT slots internally, so the choice of protocol is a given.
+
+Signed-off-by: Henrik Rydberg <rydberg at euromail.se>
+Acked-by: Ping Cheng <pingc at wacom.com>
+Signed-off-by: Dmitry Torokhov <dtor at mail.ru>
+---
+
+diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
+index 44b4a59..4e9b1dd 100644
+--- a/drivers/input/tablet/wacom_wac.c
++++ b/drivers/input/tablet/wacom_wac.c
+@@ -855,6 +855,53 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
+ 	return retval;
+ }
+ 
++static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
++{
++	struct input_dev *input = wacom->input;
++	unsigned char *data = wacom->data;
++	int sp = 0, sx = 0, sy = 0, count = 0;
++	int i;
++
++	if (len != WACOM_PKGLEN_BBTOUCH)
++		return 0;
++
++	for (i = 0; i < 2; i++) {
++		int p = data[9 * i + 2];
++		input_mt_slot(input, i);
++		if (p) {
++			int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;
++			int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;
++			input_report_abs(input, ABS_MT_PRESSURE, p);
++			input_report_abs(input, ABS_MT_POSITION_X, x);
++			input_report_abs(input, ABS_MT_POSITION_Y, y);
++			if (wacom->id[i] < 0)
++				wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID;
++			if (!count++)
++				sp = p, sx = x, sy = y;
++		} else {
++			wacom->id[i] = -1;
++		}
++		input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]);
++	}
++
++	input_report_key(input, BTN_TOUCH, count > 0);
++	input_report_key(input, BTN_TOOL_FINGER, count == 1);
++	input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2);
++
++	input_report_abs(input, ABS_PRESSURE, sp);
++	input_report_abs(input, ABS_X, sx);
++	input_report_abs(input, ABS_Y, sy);
++
++	input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
++	input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
++	input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
++	input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
++
++	input_sync(input);
++
++	return 0;
++}
++
+ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
+ {
+ 	bool sync;
+@@ -900,6 +947,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
+ 		sync = wacom_tpc_irq(wacom_wac, len);
+ 		break;
+ 
++	case BAMBOO_PT:
++		sync = wacom_bpt_irq(wacom_wac, len);
++		break;
++
+ 	default:
+ 		sync = false;
+ 		break;
+@@ -955,6 +1006,13 @@ void wacom_setup_device_quirks(struct wacom_features *features)
+ 	if (features->type == TABLETPC || features->type == TABLETPC2FG ||
+ 	    features->type == BAMBOO_PT)
+ 		features->quirks |= WACOM_QUIRK_MULTI_INPUT;
++
++	/* quirks for bamboo touch */
++	if (features->type == BAMBOO_PT &&
++	    features->device_type == BTN_TOOL_TRIPLETAP) {
++		features->pressure_max = 256;
++		features->pressure_fuzz = 16;
++	}
+ }
+ 
+ void wacom_setup_input_capabilities(struct input_dev *input_dev,
+@@ -1095,6 +1153,33 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
+ 	case PENPARTNER:
+ 		__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
+ 		break;
++
++	case BAMBOO_PT:
++		__clear_bit(ABS_MISC, input_dev->absbit);
++
++		if (features->device_type == BTN_TOOL_TRIPLETAP) {
++			__set_bit(BTN_LEFT, input_dev->keybit);
++			__set_bit(BTN_FORWARD, input_dev->keybit);
++			__set_bit(BTN_BACK, input_dev->keybit);
++			__set_bit(BTN_RIGHT, input_dev->keybit);
++
++			__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
++			__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
++
++			input_mt_create_slots(input_dev, 2);
++			input_set_abs_params(input_dev, ABS_MT_POSITION_X,
++					     0, features->x_max,
++					     features->x_fuzz, 0);
++			input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
++					     0, features->y_max,
++					     features->y_fuzz, 0);
++			input_set_abs_params(input_dev, ABS_MT_PRESSURE,
++					     0, features->pressure_max,
++					     features->pressure_fuzz, 0);
++			input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
++					     MAX_TRACKING_ID, 0, 0);
++		}
++		break;
+ 	}
+ }
+ 
+@@ -1232,6 +1317,8 @@ static const struct wacom_features wacom_features_0xE3 =
+ 	{ "Wacom ISDv4 E3",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,  0, TABLETPC2FG };
+ static const struct wacom_features wacom_features_0x47 =
+ 	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS };
++static struct wacom_features wacom_features_0xD0 =
++	{ "Wacom Bamboo 2FG",     WACOM_PKGLEN_BBFUN,     14720,  9200, 1023, 63, BAMBOO_PT };
+ 
+ #define USB_DEVICE_WACOM(prod)					\
+ 	USB_DEVICE(USB_VENDOR_ID_WACOM, prod),			\
+@@ -1296,6 +1383,7 @@ const struct usb_device_id wacom_ids[] = {
+ 	{ USB_DEVICE_WACOM(0xC6) },
+ 	{ USB_DEVICE_WACOM(0xC7) },
+ 	{ USB_DEVICE_WACOM(0xCE) },
++	{ USB_DEVICE_WACOM(0xD0) },
+ 	{ USB_DEVICE_WACOM(0xF0) },
+ 	{ USB_DEVICE_WACOM(0xCC) },
+ 	{ USB_DEVICE_WACOM(0x90) },
+diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
+index 6a1ff10..a23d6a5 100644
+--- a/drivers/input/tablet/wacom_wac.h
++++ b/drivers/input/tablet/wacom_wac.h
+@@ -41,6 +41,9 @@
+ /* device quirks */
+ #define WACOM_QUIRK_MULTI_INPUT		0x0001
+ 
++/* largest reported tracking id */
++#define MAX_TRACKING_ID			0xfff
++
+ enum {
+ 	PENPARTNER = 0,
+ 	GRAPHIRE,
+@@ -96,6 +99,7 @@ struct wacom_wac {
+ 	int id[3];
+ 	__u32 serial[2];
+ 	int last_finger;
++	int trk_id;
+ 	struct wacom_features features;
+ 	struct wacom_shared *shared;
+ 	struct input_dev *input;
diff --git a/wacom-05-add-a-quirk-for-low-resolution-bamboo-devices.patch b/wacom-05-add-a-quirk-for-low-resolution-bamboo-devices.patch
new file mode 100644
index 0000000..1809ec0
--- /dev/null
+++ b/wacom-05-add-a-quirk-for-low-resolution-bamboo-devices.patch
@@ -0,0 +1,69 @@
+From: Henrik Rydberg <rydberg at euromail.se>
+Date: Sun, 5 Sep 2010 19:57:13 +0000 (-0700)
+Subject: Input: wacom - add a quirk for low resolution Bamboo devices
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=f4ccbef2886968ed409939531f6dd0474d53a12a
+
+Input: wacom - add a quirk for low resolution Bamboo devices
+
+The Bamboo Touch reports a sub-screen resolution of 480x320.  The
+signal-to-noise ratio is only about 100, so filtering is needed in
+order to reduce the jitter to a usable level. However, the low
+resolution leads to round-off errors in the EWMA filter, resulting in
+extremely jerky pointer motion. This patch explicitly sets a higher
+resolution for those devices, and tells this to the completion handler
+via a low-resolution quirk.
+
+Signed-off-by: Henrik Rydberg <rydberg at euromail.se>
+Acked-by: Ping Cheng <pingc at wacom.com>
+Signed-off-by: Dmitry Torokhov <dtor at mail.ru>
+---
+
+diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
+index 4e9b1dd..2f4411a 100644
+--- a/drivers/input/tablet/wacom_wac.c
++++ b/drivers/input/tablet/wacom_wac.c
+@@ -857,6 +857,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
+ 
+ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
+ {
++	struct wacom_features *features = &wacom->features;
+ 	struct input_dev *input = wacom->input;
+ 	unsigned char *data = wacom->data;
+ 	int sp = 0, sx = 0, sy = 0, count = 0;
+@@ -871,6 +872,10 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
+ 		if (p) {
+ 			int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;
+ 			int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;
++			if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
++				x <<= 5;
++				y <<= 5;
++			}
+ 			input_report_abs(input, ABS_MT_PRESSURE, p);
+ 			input_report_abs(input, ABS_MT_POSITION_X, x);
+ 			input_report_abs(input, ABS_MT_POSITION_Y, y);
+@@ -1010,8 +1015,13 @@ void wacom_setup_device_quirks(struct wacom_features *features)
+ 	/* quirks for bamboo touch */
+ 	if (features->type == BAMBOO_PT &&
+ 	    features->device_type == BTN_TOOL_TRIPLETAP) {
++		features->x_max <<= 5;
++		features->y_max <<= 5;
++		features->x_fuzz <<= 5;
++		features->y_fuzz <<= 5;
+ 		features->pressure_max = 256;
+ 		features->pressure_fuzz = 16;
++		features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES;
+ 	}
+ }
+ 
+diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
+index a23d6a5..00ca015 100644
+--- a/drivers/input/tablet/wacom_wac.h
++++ b/drivers/input/tablet/wacom_wac.h
+@@ -40,6 +40,7 @@
+ 
+ /* device quirks */
+ #define WACOM_QUIRK_MULTI_INPUT		0x0001
++#define WACOM_QUIRK_BBTOUCH_LOWRES	0x0002
+ 
+ /* largest reported tracking id */
+ #define MAX_TRACKING_ID			0xfff
diff --git a/wacom-06-request-tablet-data-for-bamboo-pens.patch b/wacom-06-request-tablet-data-for-bamboo-pens.patch
new file mode 100644
index 0000000..8b31d4e
--- /dev/null
+++ b/wacom-06-request-tablet-data-for-bamboo-pens.patch
@@ -0,0 +1,55 @@
+From: Chris Bagwell <chris at cnpbagwell.com>
+Date: Sun, 12 Sep 2010 07:08:40 +0000 (-0700)
+Subject: Input: wacom - request tablet data for Bamboo Pens
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=3dc9f40de4dddf9147b80cf15be633189a2b70f4
+
+Input: wacom - request tablet data for Bamboo Pens
+
+Bamboo P&T need to use second form of usb_set_report() to
+ask to report tablet data.
+
+With previous addition of Bamboo Touch, BTN_TOOL_TRIPLETAP is now used
+for both TABLETPC2FG and BAMBOO_PT types.  So reduced check to
+match type=TABLETPC2FG.
+
+This change shows redundant check for !TABLETPC2FG in else statement.
+
+Signed-off-by: Chris Bagwell <chris at cnpbagwell.com>
+Acked-by: Ping Cheng <pingc at wacom.com>
+Signed-off-by: Dmitry Torokhov <dtor at mail.ru>
+---
+
+diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
+index fc6fd53..1e3af29 100644
+--- a/drivers/input/tablet/wacom_sys.c
++++ b/drivers/input/tablet/wacom_sys.c
+@@ -319,8 +319,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
+ 	if (!rep_data)
+ 		return error;
+ 
+-	/* ask to report tablet data if it is 2FGT or not a Tablet PC */
+-	if (features->device_type == BTN_TOOL_TRIPLETAP) {
++	/* ask to report tablet data if it is 2FGT Tablet PC or
++	 * not a Tablet PC */
++	if (features->type == TABLETPC2FG) {
+ 		do {
+ 			rep_data[0] = 3;
+ 			rep_data[1] = 4;
+@@ -332,7 +333,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
+ 					WAC_HID_FEATURE_REPORT, report_id,
+ 					rep_data, 3);
+ 		} while ((error < 0 || rep_data[1] != 4) && limit++ < 5);
+-	} else if (features->type != TABLETPC && features->type != TABLETPC2FG) {
++	} else if (features->type != TABLETPC) {
+ 		do {
+ 			rep_data[0] = 2;
+ 			rep_data[1] = 2;
+@@ -364,7 +365,7 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
+ 	features->pressure_fuzz = 0;
+ 	features->distance_fuzz = 0;
+ 
+-	/* only Tablet PCs need to retrieve the info */
++	/* only Tablet PCs and Bamboo P&T need to retrieve the info */
+ 	if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) &&
+ 	    (features->type != BAMBOO_PT))
+ 		goto out;
diff --git a/wacom-07-move-bamboo-touch-irq-to-its-own-function.patch b/wacom-07-move-bamboo-touch-irq-to-its-own-function.patch
new file mode 100644
index 0000000..7495ac3
--- /dev/null
+++ b/wacom-07-move-bamboo-touch-irq-to-its-own-function.patch
@@ -0,0 +1,52 @@
+From: Chris Bagwell <chris at cnpbagwell.com>
+Date: Sun, 12 Sep 2010 07:09:27 +0000 (-0700)
+Subject: Input: wacom - move Bamboo Touch irq to its own function
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=e1d38e49ad97eec5024342e1244279b645e36688
+
+Input: wacom - move Bamboo Touch irq to its own function
+
+This is in preparation of pen support in same irq handler.
+
+Signed-off-by: Chris Bagwell <chris at cnpbagwell.com>
+Acked-by: Ping Cheng <pingc at wacom.com>
+Signed-off-by: Dmitry Torokhov <dtor at mail.ru>
+---
+
+diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
+index 2f4411a..2f7ed9a 100644
+--- a/drivers/input/tablet/wacom_wac.c
++++ b/drivers/input/tablet/wacom_wac.c
+@@ -855,7 +855,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
+ 	return retval;
+ }
+ 
+-static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
++static int wacom_bpt_touch(struct wacom_wac *wacom)
+ {
+ 	struct wacom_features *features = &wacom->features;
+ 	struct input_dev *input = wacom->input;
+@@ -863,9 +863,6 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
+ 	int sp = 0, sx = 0, sy = 0, count = 0;
+ 	int i;
+ 
+-	if (len != WACOM_PKGLEN_BBTOUCH)
+-		return 0;
+-
+ 	for (i = 0; i < 2; i++) {
+ 		int p = data[9 * i + 2];
+ 		input_mt_slot(input, i);
+@@ -907,6 +904,14 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
+ 	return 0;
+ }
+ 
++static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
++{
++	if (len == WACOM_PKGLEN_BBTOUCH)
++		return wacom_bpt_touch(wacom);
++
++	return 0;
++}
++
+ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
+ {
+ 	bool sync;
diff --git a/wacom-08-add-support-for-bamboo-pen.patch b/wacom-08-add-support-for-bamboo-pen.patch
new file mode 100644
index 0000000..319bf6c
--- /dev/null
+++ b/wacom-08-add-support-for-bamboo-pen.patch
@@ -0,0 +1,130 @@
+From: Chris Bagwell <chris at cnpbagwell.com>
+Date: Sun, 12 Sep 2010 07:11:35 +0000 (-0700)
+Subject: Input: wacom - add support for Bamboo Pen
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=2aaacb153689dbe9064e4db7e9d00de0edfc1fa0
+
+Input: wacom - add support for Bamboo Pen
+
+This adds support for Pen on Bamboo Pen and Bamboo Pen&Touch devices.
+Touchpad is handled by previous Bamboo Touch logic.
+
+Signed-off-by: Chris Bagwell <chris at cnpbagwell.com>
+Acked-by: Ping Cheng <pingc at wacom.com>
+Signed-off-by: Dmitry Torokhov <dtor at mail.ru>
+---
+
+diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
+index 2f7ed9a..536156b 100644
+--- a/drivers/input/tablet/wacom_wac.c
++++ b/drivers/input/tablet/wacom_wac.c
+@@ -904,10 +904,75 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
+ 	return 0;
+ }
+ 
++static int wacom_bpt_pen(struct wacom_wac *wacom)
++{
++	struct input_dev *input = wacom->input;
++	unsigned char *data = wacom->data;
++	int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
++
++	/*
++	 * Similar to Graphire protocol, data[1] & 0x20 is proximity and
++	 * data[1] & 0x18 is tool ID.  0x30 is safety check to ignore
++	 * 2 unused tool ID's.
++	 */
++	prox = (data[1] & 0x30) == 0x30;
++
++	/*
++	 * All reports shared between PEN and RUBBER tool must be
++	 * forced to a known starting value (zero) when transitioning to
++	 * out-of-prox.
++	 *
++	 * If not reset then, to userspace, it will look like lost events
++	 * if new tool comes in-prox with same values as previous tool sent.
++	 *
++	 * Hardware does report zero in most out-of-prox cases but not all.
++	 */
++	if (prox) {
++		if (!wacom->shared->stylus_in_proximity) {
++			if (data[1] & 0x08) {
++				wacom->tool[0] = BTN_TOOL_RUBBER;
++				wacom->id[0] = ERASER_DEVICE_ID;
++			} else {
++				wacom->tool[0] = BTN_TOOL_PEN;
++				wacom->id[0] = STYLUS_DEVICE_ID;
++			}
++			wacom->shared->stylus_in_proximity = true;
++		}
++		x = le16_to_cpup((__le16 *)&data[2]);
++		y = le16_to_cpup((__le16 *)&data[4]);
++		p = le16_to_cpup((__le16 *)&data[6]);
++		d = data[8];
++		pen = data[1] & 0x01;
++		btn1 = data[1] & 0x02;
++		btn2 = data[1] & 0x04;
++	}
++
++	input_report_key(input, BTN_TOUCH, pen);
++	input_report_key(input, BTN_STYLUS, btn1);
++	input_report_key(input, BTN_STYLUS2, btn2);
++
++	input_report_abs(input, ABS_X, x);
++	input_report_abs(input, ABS_Y, y);
++	input_report_abs(input, ABS_PRESSURE, p);
++	input_report_abs(input, ABS_DISTANCE, d);
++
++	if (!prox) {
++		wacom->id[0] = 0;
++		wacom->shared->stylus_in_proximity = false;
++	}
++
++	input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */
++	input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */
++
++	return 1;
++}
++
+ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
+ {
+ 	if (len == WACOM_PKGLEN_BBTOUCH)
+ 		return wacom_bpt_touch(wacom);
++	else if (len == WACOM_PKGLEN_BBFUN)
++		return wacom_bpt_pen(wacom);
+ 
+ 	return 0;
+ }
+@@ -1193,6 +1258,11 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
+ 					     features->pressure_fuzz, 0);
+ 			input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
+ 					     MAX_TRACKING_ID, 0, 0);
++		} else if (features->device_type == BTN_TOOL_PEN) {
++			__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
++			__set_bit(BTN_TOOL_PEN, input_dev->keybit);
++			__set_bit(BTN_STYLUS, input_dev->keybit);
++			__set_bit(BTN_STYLUS2, input_dev->keybit);
+ 		}
+ 		break;
+ 	}
+@@ -1334,6 +1404,12 @@ static const struct wacom_features wacom_features_0x47 =
+ 	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023, 31, INTUOS };
+ static struct wacom_features wacom_features_0xD0 =
+ 	{ "Wacom Bamboo 2FG",     WACOM_PKGLEN_BBFUN,     14720,  9200, 1023, 63, BAMBOO_PT };
++static struct wacom_features wacom_features_0xD1 =
++	{ "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN,     14720,  9200, 1023, 63, BAMBOO_PT };
++static struct wacom_features wacom_features_0xD2 =
++	{ "Wacom Bamboo Craft",   WACOM_PKGLEN_BBFUN,     14720,  9200, 1023, 63, BAMBOO_PT };
++static struct wacom_features wacom_features_0xD3 =
++	{ "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN,     21648, 13530, 1023, 63, BAMBOO_PT };
+ 
+ #define USB_DEVICE_WACOM(prod)					\
+ 	USB_DEVICE(USB_VENDOR_ID_WACOM, prod),			\
+@@ -1399,6 +1475,9 @@ const struct usb_device_id wacom_ids[] = {
+ 	{ USB_DEVICE_WACOM(0xC7) },
+ 	{ USB_DEVICE_WACOM(0xCE) },
+ 	{ USB_DEVICE_WACOM(0xD0) },
++	{ USB_DEVICE_WACOM(0xD1) },
++	{ USB_DEVICE_WACOM(0xD2) },
++	{ USB_DEVICE_WACOM(0xD3) },
+ 	{ USB_DEVICE_WACOM(0xF0) },
+ 	{ USB_DEVICE_WACOM(0xCC) },
+ 	{ USB_DEVICE_WACOM(0x90) },
diff --git a/wacom-09-disable-bamboo-touchpad-when-pen-is-being-used.patch b/wacom-09-disable-bamboo-touchpad-when-pen-is-being-used.patch
new file mode 100644
index 0000000..e149540
--- /dev/null
+++ b/wacom-09-disable-bamboo-touchpad-when-pen-is-being-used.patch
@@ -0,0 +1,31 @@
+From: Chris Bagwell <chris at cnpbagwell.com>
+Date: Sun, 12 Sep 2010 07:12:28 +0000 (-0700)
+Subject: Input: wacom - disable Bamboo touchpad when pen is being used
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdtor%2Finput.git;a=commitdiff_plain;h=33d5f713a19b0f5cb93e0594f7206d2730cf39da
+
+Input: wacom - disable Bamboo touchpad when pen is being used
+
+Signed-off-by: Chris Bagwell <chris at cnpbagwell.com>
+Acked-by: Ping Cheng <pingc at wacom.com>
+Signed-off-by: Dmitry Torokhov <dtor at mail.ru>
+---
+
+diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
+index 536156b..e1b65ba 100644
+--- a/drivers/input/tablet/wacom_wac.c
++++ b/drivers/input/tablet/wacom_wac.c
+@@ -866,7 +866,13 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
+ 	for (i = 0; i < 2; i++) {
+ 		int p = data[9 * i + 2];
+ 		input_mt_slot(input, i);
+-		if (p) {
++		/*
++		 * Touch events need to be disabled while stylus is
++		 * in proximity because user's hand is resting on touchpad
++		 * and sending unwanted events.  User expects tablet buttons
++		 * to continue working though.
++		 */
++		if (p && !wacom->shared->stylus_in_proximity) {
+ 			int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;
+ 			int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;
+ 			if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {


More information about the scm-commits mailing list