summaryrefslogtreecommitdiff
path: root/drivers/input/tablet/wacom_sys.c
diff options
context:
space:
mode:
authorJason Gerecke <killertofu@gmail.com>2012-10-21 00:38:03 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-25 16:02:36 -0700
commitaea2bf6a57a9e4596bfad164f986ba10ddc6adf3 (patch)
tree00429471214d5c987b1e40fcd5018599454588d0 /drivers/input/tablet/wacom_sys.c
parent2008713c7174e5c0f207bac684c6df0939047009 (diff)
Input: wacom - handle split-sensor devices with internal hubs
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> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/input/tablet/wacom_sys.c')
-rw-r--r--drivers/input/tablet/wacom_sys.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 9edf9806cff..8b89e15bcf3 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -613,6 +613,30 @@ 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)
+{
+ int port1;
+ struct usb_device *sibling;
+
+ if (vendor == 0 && product == 0)
+ return dev;
+
+ if (dev->parent == NULL)
+ return NULL;
+
+ usb_hub_for_each_child(dev->parent, port1, sibling) {
+ struct usb_device_descriptor *d;
+ if (sibling == NULL)
+ continue;
+
+ d = &sibling->descriptor;
+ if (d->idVendor == vendor && d->idProduct == product)
+ return sibling;
+ }
+
+ return NULL;
+}
+
static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev)
{
struct wacom_usbdev_data *data;
@@ -1257,13 +1281,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;
}