Commit 037a833e authored by Forest Bond's avatar Forest Bond Committed by Dmitry Torokhov

Input: usbtouchscreen - initialize eGalax devices

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 139ebe8d
("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: default avatarForest Bond <forest.bond@rapidrollout.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 6f4d0382
...@@ -304,6 +304,45 @@ static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt) ...@@ -304,6 +304,45 @@ static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
#define EGALAX_PKT_TYPE_REPT 0x80 #define EGALAX_PKT_TYPE_REPT 0x80
#define EGALAX_PKT_TYPE_DIAG 0x0A #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) static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
{ {
if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
...@@ -1056,6 +1095,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { ...@@ -1056,6 +1095,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
.process_pkt = usbtouch_process_multi, .process_pkt = usbtouch_process_multi,
.get_pkt_len = egalax_get_pkt_len, .get_pkt_len = egalax_get_pkt_len,
.read_data = egalax_read_data, .read_data = egalax_read_data,
.init = egalax_init,
}, },
#endif #endif
......
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