diff mbox

[resend2] Input: usbtouchscreen - initialize eGalax devices

Message ID 20120903173349.GA18666@alittletooquiet.net (mailing list archive)
State New, archived
Headers show

Commit Message

Forest Bond Sept. 3, 2012, 5:33 p.m. UTC
From: Forest Bond <forest.bond@rapidrollout.com>

Certain eGalax devices expose an interface with class HID and protocol
None.  Some work with usbhid and some work with usbtouchscreen, but
there is no easy way to differentiate.  Sending an eGalax diagnostic
packet seems to kick them all into using the right protocol for
usbtouchscreen, so we can continue to bind them all there (as opposed to
handing some off to usbhid).

This fixes a regression for devices that were claimed by (and worked
with) usbhid prior to commit 139ebe8dc80dd74cb2ac9f5603d18fbf5cff049f
("Input: usbtouchscreen - fix eGalax HID ignoring"), which made
usbtouchscreen claim them instead.  With this patch they will still be
claimed by usbtouchscreen, but they will actually report events
usbtouchscreen can understand.  Note that these devices will be limited
to the usbtouchscreen feature set so e.g. dual touch features are not
supported.

I have the distinct pleasure of needing to support devices of both types
and have tested accordingly.

Signed-off-by: Forest Bond <forest.bond@rapidrollout.com>
---
 drivers/input/touchscreen/usbtouchscreen.c |   39 ++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

Comments

Dmitry Torokhov Sept. 5, 2012, 6:07 a.m. UTC | #1
On Mon, Sep 03, 2012 at 01:33:50PM -0400, Forest Bond wrote:
> From: Forest Bond <forest.bond@rapidrollout.com>
> 
> Certain eGalax devices expose an interface with class HID and protocol
> None.  Some work with usbhid and some work with usbtouchscreen, but
> there is no easy way to differentiate.  Sending an eGalax diagnostic
> packet seems to kick them all into using the right protocol for
> usbtouchscreen, so we can continue to bind them all there (as opposed to
> handing some off to usbhid).
> 
> This fixes a regression for devices that were claimed by (and worked
> with) usbhid prior to commit 139ebe8dc80dd74cb2ac9f5603d18fbf5cff049f
> ("Input: usbtouchscreen - fix eGalax HID ignoring"), which made
> usbtouchscreen claim them instead.  With this patch they will still be
> claimed by usbtouchscreen, but they will actually report events
> usbtouchscreen can understand.  Note that these devices will be limited
> to the usbtouchscreen feature set so e.g. dual touch features are not
> supported.
> 
> I have the distinct pleasure of needing to support devices of both types
> and have tested accordingly.
> 
> Signed-off-by: Forest Bond <forest.bond@rapidrollout.com>

Applied, thank you Forest.

> ---
>  drivers/input/touchscreen/usbtouchscreen.c |   39 ++++++++++++++++++++++++++++
>  1 files changed, 39 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
> index e32709e..c5f4dc0 100644
> --- a/drivers/input/touchscreen/usbtouchscreen.c
> +++ b/drivers/input/touchscreen/usbtouchscreen.c
> @@ -304,6 +304,44 @@ static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
>  #define EGALAX_PKT_TYPE_REPT		0x80
>  #define EGALAX_PKT_TYPE_DIAG		0x0A
>  
> +static int egalax_init(struct usbtouch_usb *usbtouch)
> +{
> +	int ret, i;
> +	unsigned char *buf;
> +	struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
> +
> +	/* An eGalax diagnostic packet kicks the device into using the right
> +	 * protocol.  We send a "check active" packet.  The response will be
> +	 * read later and ignored.
> +	 */
> +
> +	buf = kmalloc(3, GFP_KERNEL);
> +	if (!buf)
> +		return -ENOMEM;
> +
> +	buf[0] = EGALAX_PKT_TYPE_DIAG;
> +	buf[1] = 1;	/* length */
> +	buf[2] = 'A';	/* command - check active */
> +
> +	for (i = 0; i < 3; i++) {
> +		ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
> +				      0,
> +				      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
> +				      0, 0, buf, 3,
> +				      USB_CTRL_SET_TIMEOUT);
> +		if (ret >= 0) {
> +			ret = 0;
> +			break;
> +		}
> +		if (ret != -EPIPE)
> +			break;
> +	}
> +
> +	kfree(buf);
> +
> +	return ret;
> +}
> +
>  static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
>  {
>  	if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
> @@ -1056,6 +1094,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
>  		.process_pkt	= usbtouch_process_multi,
>  		.get_pkt_len	= egalax_get_pkt_len,
>  		.read_data	= egalax_read_data,
> +		.init		= egalax_init,
>  	},
>  #endif
>  
> -- 
> 1.7.0.4
Forest Bond Sept. 7, 2012, 8:42 p.m. UTC | #2
Hi Dmitry,

On Tue, Sep 04, 2012 at 11:07:04PM -0700, Dmitry Torokhov wrote:
> On Mon, Sep 03, 2012 at 01:33:50PM -0400, Forest Bond wrote:
> > From: Forest Bond <forest.bond@rapidrollout.com>
> > 
> > Certain eGalax devices expose an interface with class HID and protocol
> > None.  Some work with usbhid and some work with usbtouchscreen, but
> > there is no easy way to differentiate.  Sending an eGalax diagnostic
> > packet seems to kick them all into using the right protocol for
> > usbtouchscreen, so we can continue to bind them all there (as opposed to
> > handing some off to usbhid).
> > 
> > This fixes a regression for devices that were claimed by (and worked
> > with) usbhid prior to commit 139ebe8dc80dd74cb2ac9f5603d18fbf5cff049f
> > ("Input: usbtouchscreen - fix eGalax HID ignoring"), which made
> > usbtouchscreen claim them instead.  With this patch they will still be
> > claimed by usbtouchscreen, but they will actually report events
> > usbtouchscreen can understand.  Note that these devices will be limited
> > to the usbtouchscreen feature set so e.g. dual touch features are not
> > supported.
> > 
> > I have the distinct pleasure of needing to support devices of both types
> > and have tested accordingly.
> > 
> > Signed-off-by: Forest Bond <forest.bond@rapidrollout.com>
> 
> Applied, thank you Forest.

Great, thanks a lot.

The other piece to this puzzle is that usbhid should blacklist these devices to
avoid binding if it happens to be loaded before usbtouchscreen.  To do this,
usbhid needs to be able to blacklist devices based on interface protocol (right
now it only supports blacklist on VID + PID).

Would you accept a patch set that implements this?

Thanks,
Forest
Dmitry Torokhov Sept. 10, 2012, 9:11 p.m. UTC | #3
On Friday, September 07, 2012 04:42:32 PM Forest Bond wrote:
> Hi Dmitry,
> 
> On Tue, Sep 04, 2012 at 11:07:04PM -0700, Dmitry Torokhov wrote:
> > On Mon, Sep 03, 2012 at 01:33:50PM -0400, Forest Bond wrote:
> > > From: Forest Bond <forest.bond@rapidrollout.com>
> > > 
> > > Certain eGalax devices expose an interface with class HID and protocol
> > > None.  Some work with usbhid and some work with usbtouchscreen, but
> > > there is no easy way to differentiate.  Sending an eGalax diagnostic
> > > packet seems to kick them all into using the right protocol for
> > > usbtouchscreen, so we can continue to bind them all there (as opposed to
> > > handing some off to usbhid).
> > > 
> > > This fixes a regression for devices that were claimed by (and worked
> > > with) usbhid prior to commit 139ebe8dc80dd74cb2ac9f5603d18fbf5cff049f
> > > ("Input: usbtouchscreen - fix eGalax HID ignoring"), which made
> > > usbtouchscreen claim them instead.  With this patch they will still be
> > > claimed by usbtouchscreen, but they will actually report events
> > > usbtouchscreen can understand.  Note that these devices will be limited
> > > to the usbtouchscreen feature set so e.g. dual touch features are not
> > > supported.
> > > 
> > > I have the distinct pleasure of needing to support devices of both types
> > > and have tested accordingly.
> > > 
> > > Signed-off-by: Forest Bond <forest.bond@rapidrollout.com>
> > 
> > Applied, thank you Forest.
> 
> Great, thanks a lot.
> 
> The other piece to this puzzle is that usbhid should blacklist these devices
> to avoid binding if it happens to be loaded before usbtouchscreen.  To do
> this, usbhid needs to be able to blacklist devices based on interface
> protocol (right now it only supports blacklist on VID + PID).
> 
> Would you accept a patch set that implements this?

Juri, this question is really for you...

Thanks!
Jiri Kosina Nov. 1, 2012, 10:38 a.m. UTC | #4
On Mon, 10 Sep 2012, Dmitry Torokhov wrote:

> > The other piece to this puzzle is that usbhid should blacklist these devices
> > to avoid binding if it happens to be loaded before usbtouchscreen.  To do
> > this, usbhid needs to be able to blacklist devices based on interface
> > protocol (right now it only supports blacklist on VID + PID).
> > 
> > Would you accept a patch set that implements this?
> 
> Juri, this question is really for you...

Generally, I am not objecting to this idea in general.

What is the particular use case here, so that it's needed?

Thanks,
Forest Bond Nov. 2, 2012, 7:51 p.m. UTC | #5
Hi Jiri,

Thanks for your message.  Pretty good timing, actually, as I was just about to
pick this back up. ;)

On Thu, Nov 01, 2012 at 11:38:19AM +0100, Jiri Kosina wrote:
> On Mon, 10 Sep 2012, Dmitry Torokhov wrote:
> 
> > > The other piece to this puzzle is that usbhid should blacklist these devices
> > > to avoid binding if it happens to be loaded before usbtouchscreen.  To do
> > > this, usbhid needs to be able to blacklist devices based on interface
> > > protocol (right now it only supports blacklist on VID + PID).
> > > 
> > > Would you accept a patch set that implements this?
> > 
> > Juri, this question is really for you...
> 
> Generally, I am not objecting to this idea in general.
> 
> What is the particular use case here, so that it's needed?

We have some eGalax devices with class HID and protocol None that both usbhid
and usbtouchscreen will bind to, but we only want them bound to usbtouchscreen.
Some do in fact work with usbhid, but not all of them do.  OTOH they all work
with usbtouchscreen as of commit 037a833ed05a86d01ea27a2c32043b86c549be1b.

We want to blacklist these devices in usbhid to avoid binding to it if it is
loaded first.  But usbhid should continue to handle eGalax devices with class
HID and protocol other than None (e.g. Mouse).  They all have the same vendor
and product IDs, so we need to be able to blacklist on (VID, PID, protocol)
instead of just (VID, PID).

Does that make sense?

Thanks,
Forest
Jiri Kosina Nov. 5, 2012, 2:19 p.m. UTC | #6
On Fri, 2 Nov 2012, Forest Bond wrote:

> We have some eGalax devices with class HID and protocol None that both 
> usbhid and usbtouchscreen will bind to, but we only want them bound to 
> usbtouchscreen. Some do in fact work with usbhid, but not all of them 
> do.  OTOH they all work with usbtouchscreen as of commit 
> 037a833ed05a86d01ea27a2c32043b86c549be1b.
> 
> We want to blacklist these devices in usbhid to avoid binding to it if 
> it is loaded first.  But usbhid should continue to handle eGalax devices 
> with class HID and protocol other than None (e.g. Mouse).  They all have 
> the same vendor and product IDs, so we need to be able to blacklist on 
> (VID, PID, protocol) instead of just (VID, PID).

I see, thanks for the explanation.

As this is the first time we are having this problem, I'd just propose to 
put just another switch into hid_ignore() for USB_VENDOR_ID_DWAV, and 
looking at hdev->type there to see whether we should ignore the device or 
not.

If it turns, over time, to be a more general problem for multiple devices, 
we'll just introduce the more general blacklist matching then.

How does that sound?
Forest Bond Nov. 5, 2012, 6:34 p.m. UTC | #7
Hi Jiri,

On Mon, Nov 05, 2012 at 03:19:34PM +0100, Jiri Kosina wrote:
> On Fri, 2 Nov 2012, Forest Bond wrote:
> 
> > We have some eGalax devices with class HID and protocol None that both 
> > usbhid and usbtouchscreen will bind to, but we only want them bound to 
> > usbtouchscreen. Some do in fact work with usbhid, but not all of them 
> > do.  OTOH they all work with usbtouchscreen as of commit 
> > 037a833ed05a86d01ea27a2c32043b86c549be1b.
> > 
> > We want to blacklist these devices in usbhid to avoid binding to it if 
> > it is loaded first.  But usbhid should continue to handle eGalax devices 
> > with class HID and protocol other than None (e.g. Mouse).  They all have 
> > the same vendor and product IDs, so we need to be able to blacklist on 
> > (VID, PID, protocol) instead of just (VID, PID).
> 
> I see, thanks for the explanation.
> 
> As this is the first time we are having this problem, I'd just propose to 
> put just another switch into hid_ignore() for USB_VENDOR_ID_DWAV, and 
> looking at hdev->type there to see whether we should ignore the device or 
> not.
> 
> If it turns, over time, to be a more general problem for multiple devices, 
> we'll just introduce the more general blacklist matching then.
> 
> How does that sound?

Makes sense to me.  I didn't notice the checks in hid_ignore until now.

I'll send a patch in shortly.

Thanks,
Forest
diff mbox

Patch

diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index e32709e..c5f4dc0 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -304,6 +304,44 @@  static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 #define EGALAX_PKT_TYPE_REPT		0x80
 #define EGALAX_PKT_TYPE_DIAG		0x0A
 
+static int egalax_init(struct usbtouch_usb *usbtouch)
+{
+	int ret, i;
+	unsigned char *buf;
+	struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
+
+	/* An eGalax diagnostic packet kicks the device into using the right
+	 * protocol.  We send a "check active" packet.  The response will be
+	 * read later and ignored.
+	 */
+
+	buf = kmalloc(3, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	buf[0] = EGALAX_PKT_TYPE_DIAG;
+	buf[1] = 1;	/* length */
+	buf[2] = 'A';	/* command - check active */
+
+	for (i = 0; i < 3; i++) {
+		ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+				      0,
+				      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				      0, 0, buf, 3,
+				      USB_CTRL_SET_TIMEOUT);
+		if (ret >= 0) {
+			ret = 0;
+			break;
+		}
+		if (ret != -EPIPE)
+			break;
+	}
+
+	kfree(buf);
+
+	return ret;
+}
+
 static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 {
 	if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
@@ -1056,6 +1094,7 @@  static struct usbtouch_device_info usbtouch_dev_info[] = {
 		.process_pkt	= usbtouch_process_multi,
 		.get_pkt_len	= egalax_get_pkt_len,
 		.read_data	= egalax_read_data,
+		.init		= egalax_init,
 	},
 #endif