diff mbox

[2/5] Input: wacom - handle split-sensor devices with internal hubs

Message ID 1346972010-1330-2-git-send-email-killertofu@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gerecke, Jason Sept. 6, 2012, 10:53 p.m. UTC
Like our other pen-and-touch products, the Cintiq 24HD touch
needs data to be shared between its two sensors to facilitate
proximity-based palm rejection.

Unlike other tablets that report sensor data through separate
interfaces of the same USB device, the Cintiq 24HD touch has
separate USB devices that are connected to an internal USB hub.

This patch makes it possible to designate the USB VID/PID of
the other device so that the two may share data. To ensure
we don't accidentally link to a sensor from a physically separate
device (if several have been plugged in), we limit the search
to siblings (i.e., devices directly connected to the same
hub).

Signed-off-by: Jason Gerecke <killertofu@gmail.com>
---
 drivers/input/tablet/wacom_sys.c | 31 ++++++++++++++++++++++++++++++-
 drivers/input/tablet/wacom_wac.c |  3 ++-
 drivers/input/tablet/wacom_wac.h |  2 ++
 3 files changed, 34 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 0d3219f..d67a996 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -546,6 +546,29 @@  struct wacom_usbdev_data {
 static LIST_HEAD(wacom_udev_list);
 static DEFINE_MUTEX(wacom_udev_list_lock);
 
+static struct usb_device *wacom_get_sibling(struct usb_device *dev, int vendor, int product)
+{
+	struct usb_device **sibling;
+
+	if (vendor == 0 && product == 0)
+		return dev;
+
+	if (dev->parent == NULL)
+		return NULL;
+
+	sibling = dev->parent->children;
+	while (sibling != NULL && *sibling != NULL) {
+		struct usb_device_descriptor d = (*sibling)->descriptor;
+
+		if (d.idVendor == vendor && d.idProduct == product)
+			return *sibling;
+
+		sibling++;
+	}
+
+	return NULL;
+}
+
 static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev)
 {
 	struct wacom_usbdev_data *data;
@@ -1190,13 +1213,19 @@  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->quirks & WACOM_QUIRK_MULTI_INPUT) {
+		struct usb_device *other_dev;
+
 		/* Append the device type to the name */
 		strlcat(wacom_wac->name,
 			features->device_type == BTN_TOOL_PEN ?
 				" Pen" : " Finger",
 			sizeof(wacom_wac->name));
 
-		error = wacom_add_shared_data(wacom_wac, dev);
+
+		other_dev = wacom_get_sibling(dev, features->oVid, features->oPid);
+		if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL)
+			other_dev = dev;
+		error = wacom_add_shared_data(wacom_wac, other_dev);
 		if (error)
 			goto fail3;
 	}
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index a8bc6c9..9f52ba0 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1327,7 +1327,8 @@  void wacom_setup_device_quirks(struct wacom_features *features)
 
 	/* these device have multiple inputs */
 	if (features->type >= WIRELESS ||
-	    (features->type >= INTUOS5S && features->type <= INTUOS5L))
+	    (features->type >= INTUOS5S && features->type <= INTUOS5L) ||
+	    (features->oVid && features->oPid))
 		features->quirks |= WACOM_QUIRK_MULTI_INPUT;
 
 	/* quirk for bamboo touch with 2 low res touches */
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 96c185c..3f926ec 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -109,6 +109,8 @@  struct wacom_features {
 	int distance_fuzz;
 	unsigned quirks;
 	unsigned touch_max;
+	int oVid;
+	int oPid;
 };
 
 struct wacom_shared {