linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Jiri Kosina <jkosina@suse.cz>, Ping Cheng <pinglinux@gmail.com>,
	Jason Gerecke <killertofu@gmail.com>
Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	linuxwacom-devel@lists.sourceforge.net
Subject: [PATCH 08/15] Input - wacom: remove usb dependency for siblings devices
Date: Mon, 30 Jun 2014 17:26:19 -0400	[thread overview]
Message-ID: <1404163586-29582-9-git-send-email-benjamin.tissoires@redhat.com> (raw)
In-Reply-To: <1404163586-29582-1-git-send-email-benjamin.tissoires@redhat.com>

Wacom tablets can share different physical sensors on one physical device.
These are called siblings in the code. The current way of implementation
relies on the USB topology to be able to share data amongs those sensors.

We can replace the code to match a HID subsystem, without involving the USB
topology:
- the first probed sensor does not find any siblings in the list
  wacom_udev_list, so it creates its own wacom_hdev_data with its own
  struct hid_device
- the other sensor checks the current list of siblings in wacom_hdev_data,
  and if there is a match, it associates itself to the matched device.

To be sure that we are not associating different sensors from different
physical devices, we also check for the phys path of the hid device which
contains the USB topology.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/input/tablet/wacom_sys.c | 75 +++++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 40 deletions(-)

diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 0d0397d..6fe7a6c 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -488,46 +488,45 @@ static int wacom_retrieve_hid_descriptor(struct hid_device *hdev,
 	return error;
 }
 
-struct wacom_usbdev_data {
+struct wacom_hdev_data {
 	struct list_head list;
 	struct kref kref;
-	struct usb_device *dev;
+	struct hid_device *dev;
 	struct wacom_shared shared;
 };
 
 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)
+static bool wacom_are_sibling(struct hid_device *hdev,
+		struct hid_device *sibling)
 {
-	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;
+	struct wacom *wacom = hid_get_drvdata(hdev);
+	struct wacom_features *features = &wacom->wacom_wac.features;
+	int vid = features->oVid;
+	int pid = features->oPid;
 
-		d = &sibling->descriptor;
-		if (d->idVendor == vendor && d->idProduct == product)
-			return sibling;
+	if (vid == 0 && pid == 0) {
+		vid = hdev->vendor;
+		pid = hdev->product;
 	}
 
-	return NULL;
+	if (vid != sibling->vendor || pid != sibling->product)
+		return false;
+
+	/*
+	 * Compare the physical path.
+	 * Dump the last two chars which should contain the input number.
+	 */
+	return !strncmp(hdev->phys, sibling->phys, strlen(hdev->phys) - 2);
 }
 
-static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev)
+static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev)
 {
-	struct wacom_usbdev_data *data;
+	struct wacom_hdev_data *data;
 
 	list_for_each_entry(data, &wacom_udev_list, list) {
-		if (data->dev == dev) {
+		if (wacom_are_sibling(hdev, data->dev)) {
 			kref_get(&data->kref);
 			return data;
 		}
@@ -536,28 +535,29 @@ static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev)
 	return NULL;
 }
 
-static int wacom_add_shared_data(struct wacom_wac *wacom,
-				 struct usb_device *dev)
+static int wacom_add_shared_data(struct hid_device *hdev)
 {
-	struct wacom_usbdev_data *data;
+	struct wacom *wacom = hid_get_drvdata(hdev);
+	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+	struct wacom_hdev_data *data;
 	int retval = 0;
 
 	mutex_lock(&wacom_udev_list_lock);
 
-	data = wacom_get_usbdev_data(dev);
+	data = wacom_get_hdev_data(hdev);
 	if (!data) {
-		data = kzalloc(sizeof(struct wacom_usbdev_data), GFP_KERNEL);
+		data = kzalloc(sizeof(struct wacom_hdev_data), GFP_KERNEL);
 		if (!data) {
 			retval = -ENOMEM;
 			goto out;
 		}
 
 		kref_init(&data->kref);
-		data->dev = dev;
+		data->dev = hdev;
 		list_add_tail(&data->list, &wacom_udev_list);
 	}
 
-	wacom->shared = &data->shared;
+	wacom_wac->shared = &data->shared;
 
 out:
 	mutex_unlock(&wacom_udev_list_lock);
@@ -566,8 +566,8 @@ out:
 
 static void wacom_release_shared_data(struct kref *kref)
 {
-	struct wacom_usbdev_data *data =
-		container_of(kref, struct wacom_usbdev_data, kref);
+	struct wacom_hdev_data *data =
+		container_of(kref, struct wacom_hdev_data, kref);
 
 	mutex_lock(&wacom_udev_list_lock);
 	list_del(&data->list);
@@ -578,10 +578,10 @@ static void wacom_release_shared_data(struct kref *kref)
 
 static void wacom_remove_shared_data(struct wacom_wac *wacom)
 {
-	struct wacom_usbdev_data *data;
+	struct wacom_hdev_data *data;
 
 	if (wacom->shared) {
-		data = container_of(wacom->shared, struct wacom_usbdev_data, shared);
+		data = container_of(wacom->shared, struct wacom_hdev_data, shared);
 		kref_put(&data->kref, wacom_release_shared_data);
 		wacom->shared = NULL;
 	}
@@ -1311,8 +1311,6 @@ static int wacom_probe(struct hid_device *hdev,
 		"%s Pad", features->name);
 
 	if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
-		struct usb_device *other_dev;
-
 		/* Append the device type to the name */
 		if (features->device_type != BTN_TOOL_FINGER)
 			strlcat(wacom_wac->name, " Pen", WACOM_NAME_MAX);
@@ -1321,10 +1319,7 @@ static int wacom_probe(struct hid_device *hdev,
 		else
 			strlcat(wacom_wac->name, " Pad", WACOM_NAME_MAX);
 
-		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);
+		error = wacom_add_shared_data(hdev);
 		if (error)
 			goto fail1;
 	}
-- 
2.0.0

  parent reply	other threads:[~2014-06-30 21:26 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-30 21:26 [PATCH 00/15] Input - Wacom: switch from an USB to a HID driver Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 01/15] Input - wacom: include and use linux/hid.h Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 02/15] Input - wacom: switch from an USB driver to a HID driver Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 03/15] Input - wacom: use hid communication instead of plain usb Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 04/15] Input - wacom: use HID core to actually fetch the report descriptor Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 05/15] Input - wacom: compute the HID report size to get the actual packet size Benjamin Tissoires
2014-07-11  1:09   ` Jason Gerecke
2014-07-11 13:20     ` Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 06/15] Input - wacom: install LED/OLED sysfs files in the HID device instead of USB Benjamin Tissoires
2014-07-03  9:21   ` [Linuxwacom-devel] " Przemo Firszt
2014-07-03 13:45     ` Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 07/15] Input - wacom: register the input devices on top of the HID one Benjamin Tissoires
2014-06-30 21:26 ` Benjamin Tissoires [this message]
2014-07-11  0:10   ` [PATCH 08/15] Input - wacom: remove usb dependency for siblings devices Jason Gerecke
2014-07-11 13:15     ` Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 09/15] Input - wacom: register power device at the HID level Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 10/15] Input - wacom: use hid_info instead of plain dev_info Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 11/15] HID: uhid: add and set HID_TYPE_UHID for uhid devices Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 12/15] Input - wacom: use in-kernel HID parser Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 13/15] Input - wacom: use hidinput_calc_abs_res instead of duplicating its code Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 14/15] Input - wacom: remove field pktlen declaration in the list of devices Benjamin Tissoires
2014-06-30 21:26 ` [PATCH 15/15] Input - wacom: keep wacom_ids ordered Benjamin Tissoires
2014-07-02 21:40   ` Benjamin Tissoires
2014-07-02 23:33 ` [PATCH 00/15] Input - Wacom: switch from an USB to a HID driver Jason Gerecke
2014-07-11  1:17   ` Jason Gerecke
2014-07-11 13:30     ` Benjamin Tissoires
2014-07-11 13:47       ` Jiri Kosina
2014-07-10 21:30 ` [Linuxwacom-devel] " Przemo Firszt
2014-07-11 13:28   ` Benjamin Tissoires

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1404163586-29582-9-git-send-email-benjamin.tissoires@redhat.com \
    --to=benjamin.tissoires@redhat.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=jkosina@suse.cz \
    --cc=killertofu@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxwacom-devel@lists.sourceforge.net \
    --cc=pinglinux@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).