HID: multitouch: correct eGalax a001 protocol
[linux-flexiantxendom0.git] / drivers / hid / hid-multitouch.c
index 62cac4d..a3312ac 100644 (file)
@@ -47,10 +47,11 @@ MODULE_LICENSE("GPL");
 #define MT_QUIRK_SLOT_IS_CONTACTID     (1 << 1)
 #define MT_QUIRK_CYPRESS               (1 << 2)
 #define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3)
-#define MT_QUIRK_VALID_IS_INRANGE      (1 << 4)
-#define MT_QUIRK_VALID_IS_CONFIDENCE   (1 << 5)
-#define MT_QUIRK_EGALAX_XYZ_FIXUP      (1 << 6)
-#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE   (1 << 7)
+#define MT_QUIRK_ALWAYS_VALID          (1 << 4)
+#define MT_QUIRK_VALID_IS_INRANGE      (1 << 5)
+#define MT_QUIRK_VALID_IS_CONFIDENCE   (1 << 6)
+#define MT_QUIRK_EGALAX_XYZ_FIXUP      (1 << 7)
+#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE   (1 << 8)
 
 struct mt_slot {
        __s32 x, y, p, w, h;
@@ -86,16 +87,19 @@ struct mt_class {
 /* classes of device behavior */
 #define MT_CLS_DEFAULT                         0x0001
 
-#define MT_CLS_CONFIDENCE                      0x0002
-#define MT_CLS_CONFIDENCE_MINUS_ONE            0x0003
-#define MT_CLS_DUAL_INRANGE_CONTACTID          0x0004
-#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER      0x0005
-#define MT_CLS_DUAL_NSMU_CONTACTID             0x0006
+#define MT_CLS_SERIAL                          0x0002
+#define MT_CLS_CONFIDENCE                      0x0003
+#define MT_CLS_CONFIDENCE_CONTACT_ID           0x0004
+#define MT_CLS_CONFIDENCE_MINUS_ONE            0x0005
+#define MT_CLS_DUAL_INRANGE_CONTACTID          0x0006
+#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER      0x0007
+#define MT_CLS_DUAL_NSMU_CONTACTID             0x0008
 
 /* vendor specific classes */
 #define MT_CLS_3M                              0x0101
 #define MT_CLS_CYPRESS                         0x0102
 #define MT_CLS_EGALAX                          0x0103
+#define MT_CLS_EGALAX_SERIAL                   0x0104
 
 #define MT_DEFAULT_MAXCONTACT  10
 
@@ -134,8 +138,13 @@ static int find_slot_from_contactid(struct mt_device *td)
 struct mt_class mt_classes[] = {
        { .name = MT_CLS_DEFAULT,
                .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
+       { .name = MT_CLS_SERIAL,
+               .quirks = MT_QUIRK_ALWAYS_VALID},
        { .name = MT_CLS_CONFIDENCE,
                .quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
+       { .name = MT_CLS_CONFIDENCE_CONTACT_ID,
+               .quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
+                       MT_QUIRK_SLOT_IS_CONTACTID },
        { .name = MT_CLS_CONFIDENCE_MINUS_ONE,
                .quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
                        MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE },
@@ -173,6 +182,12 @@ struct mt_class mt_classes[] = {
                .sn_move = 4096,
                .sn_pressure = 32,
        },
+       { .name = MT_CLS_EGALAX_SERIAL,
+               .quirks =  MT_QUIRK_SLOT_IS_CONTACTID |
+                       MT_QUIRK_ALWAYS_VALID,
+               .sn_move = 4096,
+               .sn_pressure = 32,
+       },
 
        { }
 };
@@ -213,6 +228,16 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
        struct mt_class *cls = td->mtclass;
        __s32 quirks = cls->quirks;
 
+       /* Only map fields from TouchScreen or TouchPad collections.
+         * We need to ignore fields that belong to other collections
+         * such as Mouse that might have the same GenericDesktop usages. */
+       if (field->application == HID_DG_TOUCHSCREEN)
+               set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
+       else if (field->application == HID_DG_TOUCHPAD)
+               set_bit(INPUT_PROP_POINTER, hi->input->propbit);
+       else
+               return 0;
+
        switch (usage->hid & HID_USAGE_PAGE) {
 
        case HID_UP_GENDESK:
@@ -435,7 +460,9 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
        if (hid->claimed & HID_CLAIMED_INPUT && td->slots) {
                switch (usage->hid) {
                case HID_DG_INRANGE:
-                       if (quirks & MT_QUIRK_VALID_IS_INRANGE)
+                       if (quirks & MT_QUIRK_ALWAYS_VALID)
+                               td->curvalid = true;
+                       else if (quirks & MT_QUIRK_VALID_IS_INRANGE)
                                td->curvalid = value;
                        break;
                case HID_DG_TIPSWITCH:
@@ -593,12 +620,20 @@ static const struct hid_device_id mt_devices[] = {
        { .driver_data = MT_CLS_3M,
                HID_USB_DEVICE(USB_VENDOR_ID_3M,
                        USB_DEVICE_ID_3M2256) },
+       { .driver_data = MT_CLS_3M,
+               HID_USB_DEVICE(USB_VENDOR_ID_3M,
+                       USB_DEVICE_ID_3M3266) },
 
        /* ActionStar panels */
        { .driver_data = MT_CLS_DEFAULT,
                HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR,
                        USB_DEVICE_ID_ACTIONSTAR_1011) },
 
+       /* Atmel panels */
+       { .driver_data = MT_CLS_SERIAL,
+               HID_USB_DEVICE(USB_VENDOR_ID_ATMEL,
+                       USB_DEVICE_ID_ATMEL_MULTITOUCH) },
+
        /* Cando panels */
        { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
                HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
@@ -629,23 +664,32 @@ static const struct hid_device_id mt_devices[] = {
                        USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
 
        /* eGalax devices (resistive) */
-       {  .driver_data = MT_CLS_EGALAX,
+       { .driver_data = MT_CLS_EGALAX,
                HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
-       {  .driver_data = MT_CLS_EGALAX,
+                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) },
+       { .driver_data = MT_CLS_EGALAX,
                HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
+                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) },
 
        /* eGalax devices (capacitive) */
-       {  .driver_data = MT_CLS_EGALAX,
+       { .driver_data = MT_CLS_EGALAX,
+               HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
+       { .driver_data = MT_CLS_EGALAX,
                HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
-       {  .driver_data = MT_CLS_EGALAX,
+                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
+       { .driver_data = MT_CLS_EGALAX,
                HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
-       {  .driver_data = MT_CLS_EGALAX,
+                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) },
+       { .driver_data = MT_CLS_EGALAX,
                HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
+                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) },
+       { .driver_data = MT_CLS_EGALAX,
+               HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) },
+       { .driver_data = MT_CLS_EGALAX_SERIAL,
+               HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+                       USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
 
        /* Elo TouchSystems IntelliTouch Plus panel */
        { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID,
@@ -662,6 +706,16 @@ static const struct hid_device_id mt_devices[] = {
                HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH,
                        USB_DEVICE_ID_GOODTOUCH_000f) },
 
+       /* Hanvon panels */
+       { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
+               HID_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT,
+                       USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
+
+       /* Ideacom panel */
+       { .driver_data = MT_CLS_SERIAL,
+               HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM,
+                       USB_DEVICE_ID_IDEACOM_IDC6650) },
+
        /* Ilitek dual touch panel */
        {  .driver_data = MT_CLS_DEFAULT,
                HID_USB_DEVICE(USB_VENDOR_ID_ILITEK,
@@ -672,6 +726,11 @@ static const struct hid_device_id mt_devices[] = {
                HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
                        USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
 
+       /* LG Display panels */
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_LG,
+                       USB_DEVICE_ID_LG_MULTITOUCH) },
+
        /* Lumio panels */
        { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
                HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
@@ -704,6 +763,17 @@ static const struct hid_device_id mt_devices[] = {
                HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
                        USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
 
+       /* Quanta-based panels */
+       { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID,
+               HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
+                       USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
+       { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID,
+               HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
+                       USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) },
+       { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID,
+               HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
+                       USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008) },
+
        /* Stantum panels */
        { .driver_data = MT_CLS_CONFIDENCE,
                HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
@@ -727,6 +797,39 @@ static const struct hid_device_id mt_devices[] = {
        { .driver_data = MT_CLS_DEFAULT,
                HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
                        USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
+       /* XAT */
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_XAT,
+                       USB_DEVICE_ID_XAT_CSR) },
+
+       /* Xiroku */
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
+                       USB_DEVICE_ID_XIROKU_SPX) },
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
+                       USB_DEVICE_ID_XIROKU_MPX) },
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
+                       USB_DEVICE_ID_XIROKU_CSR) },
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
+                       USB_DEVICE_ID_XIROKU_SPX1) },
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
+                       USB_DEVICE_ID_XIROKU_MPX1) },
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
+                       USB_DEVICE_ID_XIROKU_CSR1) },
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
+                       USB_DEVICE_ID_XIROKU_SPX2) },
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
+                       USB_DEVICE_ID_XIROKU_MPX2) },
+       { .driver_data = MT_CLS_DEFAULT,
+               HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
+                       USB_DEVICE_ID_XIROKU_CSR2) },
 
        { }
 };