Commit aea2bf6a authored by Jason Gerecke's avatar Jason Gerecke Committed by Linus Torvalds

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: default avatarJason Gerecke <killertofu@gmail.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2008713c
...@@ -613,6 +613,30 @@ struct wacom_usbdev_data { ...@@ -613,6 +613,30 @@ struct wacom_usbdev_data {
static LIST_HEAD(wacom_udev_list); static LIST_HEAD(wacom_udev_list);
static DEFINE_MUTEX(wacom_udev_list_lock); 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) static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev)
{ {
struct wacom_usbdev_data *data; struct wacom_usbdev_data *data;
...@@ -1257,13 +1281,19 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -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)); strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
struct usb_device *other_dev;
/* Append the device type to the name */ /* Append the device type to the name */
strlcat(wacom_wac->name, strlcat(wacom_wac->name,
features->device_type == BTN_TOOL_PEN ? features->device_type == BTN_TOOL_PEN ?
" Pen" : " Finger", " Pen" : " Finger",
sizeof(wacom_wac->name)); 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) if (error)
goto fail3; goto fail3;
} }
......
...@@ -1340,7 +1340,8 @@ void wacom_setup_device_quirks(struct wacom_features *features) ...@@ -1340,7 +1340,8 @@ void wacom_setup_device_quirks(struct wacom_features *features)
/* these device have multiple inputs */ /* these device have multiple inputs */
if (features->type >= WIRELESS || 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; features->quirks |= WACOM_QUIRK_MULTI_INPUT;
/* quirk for bamboo touch with 2 low res touches */ /* quirk for bamboo touch with 2 low res touches */
......
...@@ -109,6 +109,8 @@ struct wacom_features { ...@@ -109,6 +109,8 @@ struct wacom_features {
int distance_fuzz; int distance_fuzz;
unsigned quirks; unsigned quirks;
unsigned touch_max; unsigned touch_max;
int oVid;
int oPid;
}; };
struct wacom_shared { struct wacom_shared {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment