OSDN Git Service

HID: add autodetection of multitouch devices
authorBenjamin Tissoires <benjamin.tissoires@enac.fr>
Mon, 14 Feb 2011 12:42:12 +0000 (13:42 +0100)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Wed, 6 Apr 2011 03:14:50 +0000 (11:14 +0800)
As mentioned by http://www.microsoft.com/whdc/device/input/DigitizerDrvs_touch.mspx
multitouch devices are those that have the input report HID_CONTACTID.

This patch detects this and unload the generic-usb driver.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
drivers/hid/hid-core.c
drivers/hid/hid-input.c
include/linux/hid.h

index a5f6439..9d2664b 100644 (file)
@@ -1182,6 +1182,10 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
        if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev,
                                connect_mask & HID_CONNECT_HIDINPUT_FORCE))
                hdev->claimed |= HID_CLAIMED_INPUT;
+       if (hdev->quirks & HID_QUIRK_MULTITOUCH)
+               /* this device should be handled by hid-multitouch, skip it */
+               return -ENODEV;
+
        if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect &&
                        !hdev->hiddev_connect(hdev,
                                connect_mask & HID_CONNECT_HIDDEV_FORCE))
@@ -1326,7 +1330,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
        { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
index f53911d..020f983 100644 (file)
@@ -470,6 +470,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                        map_key_clear(BTN_STYLUS2);
                        break;
 
+               case 0x51: /* ContactID */
+                       device->quirks |= HID_QUIRK_MULTITOUCH;
+                       goto unknown;
+
                default:  goto unknown;
                }
                break;
@@ -922,6 +926,16 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
                }
        }
 
+       if (hid->quirks & HID_QUIRK_MULTITOUCH) {
+               if (!strncmp(hid->driver->name, "generic-", 8)) {
+                       /* generic hid does not know how to handle multitouch devices */
+                       if (hidinput)
+                               goto out_cleanup;
+                       goto out_unwind;
+               }
+               hid->quirks &= ~HID_QUIRK_MULTITOUCH;
+       }
+
        if (hidinput && input_register_device(hidinput->input))
                goto out_cleanup;
 
index d91c25e..6a2f168 100644 (file)
@@ -312,6 +312,7 @@ struct hid_item {
 #define HID_QUIRK_BADPAD                       0x00000020
 #define HID_QUIRK_MULTI_INPUT                  0x00000040
 #define HID_QUIRK_HIDINPUT_FORCE               0x00000080
+#define HID_QUIRK_MULTITOUCH                   0x00000100
 #define HID_QUIRK_SKIP_OUTPUT_REPORTS          0x00010000
 #define HID_QUIRK_FULLSPEED_INTERVAL           0x10000000
 #define HID_QUIRK_NO_INIT_REPORTS              0x20000000
@@ -712,6 +713,7 @@ int hid_check_keys_pressed(struct hid_device *hid);
 int hid_connect(struct hid_device *hid, unsigned int connect_mask);
 void hid_disconnect(struct hid_device *hid);
 
+
 /**
  * hid_map_usage - map usage input bits
  *