- patches.suse/slab-handle-memoryless-nodes-v2a.patch: Refresh.
[linux-flexiantxendom0-3.2.10.git] / drivers / input / touchscreen / usbtouchscreen.c
index 68ece58..09a5e73 100644 (file)
@@ -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);