Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / drivers / input / touchscreen / usbtouchscreen.c
index b407028..19055e7 100644 (file)
  *  - Gunze AHL61
  *  - DMC TSC-10/25
  *  - IRTOUCHSYSTEMS/UNITOP
+ *  - IdealTEK URTC1000
+ *  - GoTop Super_Q2/GogoPen/PenPower tablets
  *
- * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
+ * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
  *
  * This program is free software; you can redistribute it and/or
@@ -92,7 +94,7 @@ struct usbtouch_usb {
 };
 
 
-#if defined(CONFIG_TOUCHSCREEN_USB_EGALAX) || defined(CONFIG_TOUCHSCREEN_USB_ETURBO)
+#if defined(CONFIG_TOUCHSCREEN_USB_EGALAX) || defined(CONFIG_TOUCHSCREEN_USB_ETURBO) || defined(CONFIG_TOUCHSCREEN_USB_IDEALTEK)
 #define MULTI_PACKET
 #endif
 
@@ -112,6 +114,9 @@ enum {
        DEVTYPE_GUNZE,
        DEVTYPE_DMC_TSC10,
        DEVTYPE_IRTOUCH,
+       DEVTYPE_IDEALTEK,
+       DEVTYPE_GENERAL_TOUCH,
+       DEVTYPE_GOTOP,
 };
 
 static struct usb_device_id usbtouch_devices[] = {
@@ -157,6 +162,20 @@ static struct usb_device_id usbtouch_devices[] = {
        {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
 #endif
 
+#ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK
+       {USB_DEVICE(0x1391, 0x1000), .driver_info = DEVTYPE_IDEALTEK},
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
+       {USB_DEVICE(0x0dfc, 0x0001), .driver_info = DEVTYPE_GENERAL_TOUCH},
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+       {USB_DEVICE(0x08f2, 0x007f), .driver_info = DEVTYPE_GOTOP},
+       {USB_DEVICE(0x08f2, 0x00ce), .driver_info = DEVTYPE_GOTOP},
+       {USB_DEVICE(0x08f2, 0x00f4), .driver_info = DEVTYPE_GOTOP},
+#endif
+
        {}
 };
 
@@ -396,7 +415,8 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
                              TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT);
        if (ret < 0)
                return ret;
-       if (buf[0] != 0x06 || buf[1] != 0x00)
+       if ((buf[0] != 0x06 || buf[1] != 0x00) &&
+           (buf[0] != 0x15 || buf[1] != 0x01))
                return -ENODEV;
 
        /* start sending data */
@@ -437,6 +457,71 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 #endif
 
 
+/*****************************************************************************
+ * IdealTEK URTC1000 Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK
+static int idealtek_get_pkt_len(unsigned char *buf, int len)
+{
+       if (buf[0] & 0x80)
+               return 5;
+       if (buf[0] == 0x01)
+               return len;
+       return 0;
+}
+
+static int idealtek_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+       switch (pkt[0] & 0x98) {
+       case 0x88:
+               /* touch data in IdealTEK mode */
+               dev->x = (pkt[1] << 5) | (pkt[2] >> 2);
+               dev->y = (pkt[3] << 5) | (pkt[4] >> 2);
+               dev->touch = (pkt[0] & 0x40) ? 1 : 0;
+               return 1;
+
+       case 0x98:
+               /* touch data in MT emulation mode */
+               dev->x = (pkt[2] << 5) | (pkt[1] >> 2);
+               dev->y = (pkt[4] << 5) | (pkt[3] >> 2);
+               dev->touch = (pkt[0] & 0x40) ? 1 : 0;
+               return 1;
+
+       default:
+               return 0;
+       }
+}
+#endif
+
+/*****************************************************************************
+ * General Touch Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
+static int general_touch_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->press = pkt[5] & 0xff;
+       dev->touch = pkt[0] & 0x01;
+
+       return 1;
+}
+#endif
+
+/*****************************************************************************
+ * GoTop Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+static int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+       dev->x = ((pkt[1] & 0x38) << 4) | pkt[2];
+       dev->y = ((pkt[1] & 0x07) << 7) | pkt[3];
+       dev->touch = pkt[0] & 0x01;
+       return 1;
+}
+#endif
+
+
 /*****************************************************************************
  * the different device descriptors
  */
@@ -537,6 +622,42 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
                .read_data      = irtouch_read_data,
        },
 #endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK
+       [DEVTYPE_IDEALTEK] = {
+               .min_xc         = 0x0,
+               .max_xc         = 0x0fff,
+               .min_yc         = 0x0,
+               .max_yc         = 0x0fff,
+               .rept_size      = 8,
+               .flags          = USBTOUCH_FLG_BUFFER,
+               .process_pkt    = usbtouch_process_multi,
+               .get_pkt_len    = idealtek_get_pkt_len,
+               .read_data      = idealtek_read_data,
+       },
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
+       [DEVTYPE_GENERAL_TOUCH] = {
+               .min_xc         = 0x0,
+               .max_xc         = 0x0500,
+               .min_yc         = 0x0,
+               .max_yc         = 0x0500,
+               .rept_size      = 7,
+               .read_data      = general_touch_read_data,
+       },
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+       [DEVTYPE_GOTOP] = {
+               .min_xc         = 0x0,
+               .max_xc         = 0x03ff,
+               .min_yc         = 0x0,
+               .max_yc         = 0x03ff,
+               .rept_size      = 4,
+               .read_data      = gotop_read_data,
+       },
+#endif
 };
 
 
@@ -767,7 +888,7 @@ static int usbtouch_probe(struct usb_interface *intf,
                         le16_to_cpu(udev->descriptor.idProduct));
 
        usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys));
-       strlcpy(usbtouch->phys, "/input0", sizeof(usbtouch->phys));
+       strlcat(usbtouch->phys, "/input0", sizeof(usbtouch->phys));
 
        input_dev->name = usbtouch->name;
        input_dev->phys = usbtouch->phys;
@@ -779,8 +900,8 @@ static int usbtouch_probe(struct usb_interface *intf,
        input_dev->open = usbtouch_open;
        input_dev->close = usbtouch_close;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);
        if (type->max_press)