diff options
-rw-r--r-- | drivers/hid/hid-core.c | 16 | ||||
-rw-r--r-- | drivers/hid/hid-multitouch.c | 24 | ||||
-rw-r--r-- | include/linux/hid.h | 4 |
3 files changed, 31 insertions, 13 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index ddd95f3e33c0..660dce964162 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -685,6 +685,13 @@ static void hid_scan_input_usage(struct hid_parser *parser, u32 usage) | |||
685 | hid->group = HID_GROUP_MULTITOUCH; | 685 | hid->group = HID_GROUP_MULTITOUCH; |
686 | } | 686 | } |
687 | 687 | ||
688 | static void hid_scan_feature_usage(struct hid_parser *parser, u32 usage) | ||
689 | { | ||
690 | if (usage == 0xff0000c5 && parser->global.report_count == 256 && | ||
691 | parser->global.report_size == 8) | ||
692 | parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8; | ||
693 | } | ||
694 | |||
688 | static void hid_scan_collection(struct hid_parser *parser, unsigned type) | 695 | static void hid_scan_collection(struct hid_parser *parser, unsigned type) |
689 | { | 696 | { |
690 | struct hid_device *hid = parser->device; | 697 | struct hid_device *hid = parser->device; |
@@ -714,6 +721,8 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) | |||
714 | case HID_MAIN_ITEM_TAG_OUTPUT: | 721 | case HID_MAIN_ITEM_TAG_OUTPUT: |
715 | break; | 722 | break; |
716 | case HID_MAIN_ITEM_TAG_FEATURE: | 723 | case HID_MAIN_ITEM_TAG_FEATURE: |
724 | for (i = 0; i < parser->local.usage_index; i++) | ||
725 | hid_scan_feature_usage(parser, parser->local.usage[i]); | ||
717 | break; | 726 | break; |
718 | } | 727 | } |
719 | 728 | ||
@@ -757,6 +766,13 @@ static int hid_scan_report(struct hid_device *hid) | |||
757 | while ((start = fetch_item(start, end, &item)) != NULL) | 766 | while ((start = fetch_item(start, end, &item)) != NULL) |
758 | dispatch_type[item.type](parser, &item); | 767 | dispatch_type[item.type](parser, &item); |
759 | 768 | ||
769 | /* | ||
770 | * Handle special flags set during scanning. | ||
771 | */ | ||
772 | if ((parser->scan_flags & HID_SCAN_FLAG_MT_WIN_8) && | ||
773 | (hid->group == HID_GROUP_MULTITOUCH)) | ||
774 | hid->group = HID_GROUP_MULTITOUCH_WIN_8; | ||
775 | |||
760 | vfree(parser); | 776 | vfree(parser); |
761 | return 0; | 777 | return 0; |
762 | } | 778 | } |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 0fe00e2552f2..c28ef86c7c67 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -133,6 +133,7 @@ static void mt_post_parse(struct mt_device *td); | |||
133 | #define MT_CLS_NSMU 0x000a | 133 | #define MT_CLS_NSMU 0x000a |
134 | #define MT_CLS_DUAL_CONTACT_NUMBER 0x0010 | 134 | #define MT_CLS_DUAL_CONTACT_NUMBER 0x0010 |
135 | #define MT_CLS_DUAL_CONTACT_ID 0x0011 | 135 | #define MT_CLS_DUAL_CONTACT_ID 0x0011 |
136 | #define MT_CLS_WIN_8 0x0012 | ||
136 | 137 | ||
137 | /* vendor specific classes */ | 138 | /* vendor specific classes */ |
138 | #define MT_CLS_3M 0x0101 | 139 | #define MT_CLS_3M 0x0101 |
@@ -205,6 +206,11 @@ static struct mt_class mt_classes[] = { | |||
205 | MT_QUIRK_CONTACT_CNT_ACCURATE | | 206 | MT_QUIRK_CONTACT_CNT_ACCURATE | |
206 | MT_QUIRK_SLOT_IS_CONTACTID, | 207 | MT_QUIRK_SLOT_IS_CONTACTID, |
207 | .maxcontacts = 2 }, | 208 | .maxcontacts = 2 }, |
209 | { .name = MT_CLS_WIN_8, | ||
210 | .quirks = MT_QUIRK_ALWAYS_VALID | | ||
211 | MT_QUIRK_IGNORE_DUPLICATES | | ||
212 | MT_QUIRK_HOVERING | | ||
213 | MT_QUIRK_CONTACT_CNT_ACCURATE }, | ||
208 | 214 | ||
209 | /* | 215 | /* |
210 | * vendor specific classes | 216 | * vendor specific classes |
@@ -332,19 +338,6 @@ static void mt_feature_mapping(struct hid_device *hdev, | |||
332 | td->maxcontacts = td->mtclass.maxcontacts; | 338 | td->maxcontacts = td->mtclass.maxcontacts; |
333 | 339 | ||
334 | break; | 340 | break; |
335 | case 0xff0000c5: | ||
336 | if (field->report_count == 256 && field->report_size == 8) { | ||
337 | /* Win 8 devices need special quirks */ | ||
338 | __s32 *quirks = &td->mtclass.quirks; | ||
339 | *quirks |= MT_QUIRK_ALWAYS_VALID; | ||
340 | *quirks |= MT_QUIRK_IGNORE_DUPLICATES; | ||
341 | *quirks |= MT_QUIRK_HOVERING; | ||
342 | *quirks |= MT_QUIRK_CONTACT_CNT_ACCURATE; | ||
343 | *quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; | ||
344 | *quirks &= ~MT_QUIRK_VALID_IS_INRANGE; | ||
345 | *quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; | ||
346 | } | ||
347 | break; | ||
348 | } | 341 | } |
349 | } | 342 | } |
350 | 343 | ||
@@ -1346,6 +1339,11 @@ static const struct hid_device_id mt_devices[] = { | |||
1346 | 1339 | ||
1347 | /* Generic MT device */ | 1340 | /* Generic MT device */ |
1348 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) }, | 1341 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) }, |
1342 | |||
1343 | /* Generic Win 8 certified MT device */ | ||
1344 | { .driver_data = MT_CLS_WIN_8, | ||
1345 | HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH_WIN_8, | ||
1346 | HID_ANY_ID, HID_ANY_ID) }, | ||
1349 | { } | 1347 | { } |
1350 | }; | 1348 | }; |
1351 | MODULE_DEVICE_TABLE(hid, mt_devices); | 1349 | MODULE_DEVICE_TABLE(hid, mt_devices); |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 0c48991b0402..cef1e9b86cc4 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -295,6 +295,7 @@ struct hid_item { | |||
295 | #define HID_GROUP_GENERIC 0x0001 | 295 | #define HID_GROUP_GENERIC 0x0001 |
296 | #define HID_GROUP_MULTITOUCH 0x0002 | 296 | #define HID_GROUP_MULTITOUCH 0x0002 |
297 | #define HID_GROUP_SENSOR_HUB 0x0003 | 297 | #define HID_GROUP_SENSOR_HUB 0x0003 |
298 | #define HID_GROUP_MULTITOUCH_WIN_8 0x0004 | ||
298 | 299 | ||
299 | /* | 300 | /* |
300 | * This is the global environment of the parser. This information is | 301 | * This is the global environment of the parser. This information is |
@@ -532,6 +533,8 @@ static inline void hid_set_drvdata(struct hid_device *hdev, void *data) | |||
532 | #define HID_GLOBAL_STACK_SIZE 4 | 533 | #define HID_GLOBAL_STACK_SIZE 4 |
533 | #define HID_COLLECTION_STACK_SIZE 4 | 534 | #define HID_COLLECTION_STACK_SIZE 4 |
534 | 535 | ||
536 | #define HID_SCAN_FLAG_MT_WIN_8 0x00000001 | ||
537 | |||
535 | struct hid_parser { | 538 | struct hid_parser { |
536 | struct hid_global global; | 539 | struct hid_global global; |
537 | struct hid_global global_stack[HID_GLOBAL_STACK_SIZE]; | 540 | struct hid_global global_stack[HID_GLOBAL_STACK_SIZE]; |
@@ -540,6 +543,7 @@ struct hid_parser { | |||
540 | unsigned collection_stack[HID_COLLECTION_STACK_SIZE]; | 543 | unsigned collection_stack[HID_COLLECTION_STACK_SIZE]; |
541 | unsigned collection_stack_ptr; | 544 | unsigned collection_stack_ptr; |
542 | struct hid_device *device; | 545 | struct hid_device *device; |
546 | unsigned scan_flags; | ||
543 | }; | 547 | }; |
544 | 548 | ||
545 | struct hid_class_descriptor { | 549 | struct hid_class_descriptor { |