summaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/usbtouchscreen.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/usbtouchscreen.c')
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c104
1 files changed, 100 insertions, 4 deletions
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 68ece58..09a5e73 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -14,6 +14,7 @@
* - General Touch
* - GoTop Super_Q2/GogoPen/PenPower tablets
* - JASTEC USB touch controller/DigiTech DTR-02U
+ * - Zytronic capacitive touchscreen
*
* Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
* Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -73,6 +74,15 @@ struct usbtouch_device_info {
int min_press, max_press;
int rept_size;
+ /*
+ * Always service the USB devices irq not just when the input device is
+ * open. This is useful when devices have a watchdog which prevents us
+ * from periodically polling the device. Leave this unset unless your
+ * touchscreen device requires it, as it does consume more of the USB
+ * bandwidth.
+ */
+ bool irq_always;
+
void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len);
/*
@@ -121,6 +131,8 @@ enum {
DEVTYPE_GOTOP,
DEVTYPE_JASTEC,
DEVTYPE_E2I,
+ DEVTYPE_ZYTRONIC,
+ DEVTYPE_TC5UH,
};
#define USB_DEVICE_HID_CLASS(vend, prod) \
@@ -201,6 +213,15 @@ static struct usb_device_id usbtouch_devices[] = {
#ifdef CONFIG_TOUCHSCREEN_USB_E2I
{USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I},
#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
+ {USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC},
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
+ {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH},
+#endif
+
{}
};
@@ -538,6 +559,19 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
}
#endif
+/*****************************************************************************
+ * ET&T TC5UH part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
+static int tc5uh_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+ dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1];
+ dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3];
+ dev->touch = pkt[0] & 0x01;
+
+ return 1;
+}
+#endif
/*****************************************************************************
* IdealTEK URTC1000 Part
@@ -621,6 +655,39 @@ static int jastec_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
}
#endif
+/*****************************************************************************
+ * Zytronic Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
+static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+ switch (pkt[0]) {
+ case 0x3A: /* command response */
+ dbg("%s: Command response %d", __func__, pkt[1]);
+ break;
+
+ case 0xC0: /* down */
+ dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7);
+ dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7);
+ dev->touch = 1;
+ dbg("%s: down %d,%d", __func__, dev->x, dev->y);
+ return 1;
+
+ case 0x80: /* up */
+ dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7);
+ dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7);
+ dev->touch = 0;
+ dbg("%s: up %d,%d", __func__, dev->x, dev->y);
+ return 1;
+
+ default:
+ dbg("%s: Unknown return %d", __func__, pkt[0]);
+ break;
+ }
+
+ return 0;
+}
+#endif
/*****************************************************************************
* the different device descriptors
@@ -783,6 +850,29 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
.read_data = e2i_read_data,
},
#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
+ [DEVTYPE_ZYTRONIC] = {
+ .min_xc = 0x0,
+ .max_xc = 0x03ff,
+ .min_yc = 0x0,
+ .max_yc = 0x03ff,
+ .rept_size = 5,
+ .read_data = zytronic_read_data,
+ .irq_always = true,
+ },
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH
+ [DEVTYPE_TC5UH] = {
+ .min_xc = 0x0,
+ .max_xc = 0x0fff,
+ .min_yc = 0x0,
+ .max_yc = 0x0fff,
+ .rept_size = 5,
+ .read_data = tc5uh_read_data,
+ },
+#endif
};
@@ -933,8 +1023,10 @@ static int usbtouch_open(struct input_dev *input)
usbtouch->irq->dev = usbtouch->udev;
- if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
- return -EIO;
+ if (!usbtouch->type->irq_always) {
+ if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
+ return -EIO;
+ }
return 0;
}
@@ -943,7 +1035,8 @@ static void usbtouch_close(struct input_dev *input)
{
struct usbtouch_usb *usbtouch = input_get_drvdata(input);
- usb_kill_urb(usbtouch->irq);
+ if (!usbtouch->type->irq_always)
+ usb_kill_urb(usbtouch->irq);
}
@@ -1066,6 +1159,9 @@ static int usbtouch_probe(struct usb_interface *intf,
usb_set_intfdata(intf, usbtouch);
+ if (usbtouch->type->irq_always)
+ usb_submit_urb(usbtouch->irq, GFP_KERNEL);
+
return 0;
out_free_buffers:
@@ -1087,7 +1183,7 @@ static void usbtouch_disconnect(struct usb_interface *intf)
dbg("%s - usbtouch is initialized, cleaning up", __func__);
usb_set_intfdata(intf, NULL);
- usb_kill_urb(usbtouch->irq);
+ /* this will stop IO via close */
input_unregister_device(usbtouch->input);
usb_free_urb(usbtouch->irq);
usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);
OpenPOWER on IntegriCloud