On Fri, Aug 31, 2012 at 08:37:26PM -0400, Forest Bond wrote:
> From: Forest Bond <forest.b...@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.b...@rapidrollout.com>
> ---
>  drivers/input/touchscreen/usbtouchscreen.c |   36 
> ++++++++++++++++++++++++++++
>  1 files changed, 36 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/usbtouchscreen.c 
> b/drivers/input/touchscreen/usbtouchscreen.c
> index e32709e..64b4b17 100644
> --- a/drivers/input/touchscreen/usbtouchscreen.c
> +++ b/drivers/input/touchscreen/usbtouchscreen.c
> @@ -304,6 +304,41 @@ 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;
> +}

Attachment: signature.asc
Description: Digital signature

Reply via email to