diff options
| -rw-r--r-- | drivers/hid/hid-multitouch.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 61543c02ea0b..13b94619b5d0 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
| @@ -85,6 +85,7 @@ struct mt_device { | |||
| 85 | multitouch fields */ | 85 | multitouch fields */ |
| 86 | unsigned last_field_index; /* last field index of the report */ | 86 | unsigned last_field_index; /* last field index of the report */ |
| 87 | unsigned last_slot_field; /* the last field of a slot */ | 87 | unsigned last_slot_field; /* the last field of a slot */ |
| 88 | unsigned mt_report_id; /* the report ID of the multitouch device */ | ||
| 88 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | 89 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ |
| 89 | __s8 inputmode_index; /* InputMode HID feature index in the report */ | 90 | __s8 inputmode_index; /* InputMode HID feature index in the report */ |
| 90 | __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, | 91 | __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, |
| @@ -428,6 +429,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 428 | mt_store_field(usage, td, hi); | 429 | mt_store_field(usage, td, hi); |
| 429 | td->last_field_index = field->index; | 430 | td->last_field_index = field->index; |
| 430 | td->touches_by_report++; | 431 | td->touches_by_report++; |
| 432 | td->mt_report_id = field->report->id; | ||
| 431 | return 1; | 433 | return 1; |
| 432 | case HID_DG_WIDTH: | 434 | case HID_DG_WIDTH: |
| 433 | hid_map_usage(hi, usage, bit, max, | 435 | hid_map_usage(hi, usage, bit, max, |
| @@ -578,6 +580,16 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input) | |||
| 578 | static int mt_event(struct hid_device *hid, struct hid_field *field, | 580 | static int mt_event(struct hid_device *hid, struct hid_field *field, |
| 579 | struct hid_usage *usage, __s32 value) | 581 | struct hid_usage *usage, __s32 value) |
| 580 | { | 582 | { |
| 583 | /* we will handle the hidinput part later, now remains hiddev */ | ||
| 584 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | ||
| 585 | hid->hiddev_hid_event(hid, field, usage, value); | ||
| 586 | |||
| 587 | return 1; | ||
| 588 | } | ||
| 589 | |||
| 590 | static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, | ||
| 591 | struct hid_usage *usage, __s32 value) | ||
| 592 | { | ||
| 581 | struct mt_device *td = hid_get_drvdata(hid); | 593 | struct mt_device *td = hid_get_drvdata(hid); |
| 582 | __s32 quirks = td->mtclass.quirks; | 594 | __s32 quirks = td->mtclass.quirks; |
| 583 | 595 | ||
| @@ -635,8 +647,7 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
| 635 | break; | 647 | break; |
| 636 | 648 | ||
| 637 | default: | 649 | default: |
| 638 | /* fallback to the generic hidinput handling */ | 650 | return; |
| 639 | return 0; | ||
| 640 | } | 651 | } |
| 641 | 652 | ||
| 642 | if (usage->usage_index + 1 == field->report_count) { | 653 | if (usage->usage_index + 1 == field->report_count) { |
| @@ -650,12 +661,32 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
| 650 | } | 661 | } |
| 651 | 662 | ||
| 652 | } | 663 | } |
| 664 | } | ||
| 653 | 665 | ||
| 654 | /* we have handled the hidinput part, now remains hiddev */ | 666 | static void mt_report(struct hid_device *hid, struct hid_report *report) |
| 655 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | 667 | { |
| 656 | hid->hiddev_hid_event(hid, field, usage, value); | 668 | struct mt_device *td = hid_get_drvdata(hid); |
| 669 | struct hid_field *field; | ||
| 670 | unsigned count; | ||
| 671 | int r, n; | ||
| 657 | 672 | ||
| 658 | return 1; | 673 | if (report->id != td->mt_report_id) |
| 674 | return; | ||
| 675 | |||
| 676 | if (!(hid->claimed & HID_CLAIMED_INPUT)) | ||
| 677 | return; | ||
| 678 | |||
| 679 | for (r = 0; r < report->maxfield; r++) { | ||
| 680 | field = report->field[r]; | ||
| 681 | count = field->report_count; | ||
| 682 | |||
| 683 | if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) | ||
| 684 | continue; | ||
| 685 | |||
| 686 | for (n = 0; n < count; n++) | ||
| 687 | mt_process_mt_event(hid, field, &field->usage[n], | ||
| 688 | field->value[n]); | ||
| 689 | } | ||
| 659 | } | 690 | } |
| 660 | 691 | ||
| 661 | static void mt_set_input_mode(struct hid_device *hdev) | 692 | static void mt_set_input_mode(struct hid_device *hdev) |
| @@ -1193,6 +1224,7 @@ static struct hid_driver mt_driver = { | |||
| 1193 | .feature_mapping = mt_feature_mapping, | 1224 | .feature_mapping = mt_feature_mapping, |
| 1194 | .usage_table = mt_grabbed_usages, | 1225 | .usage_table = mt_grabbed_usages, |
| 1195 | .event = mt_event, | 1226 | .event = mt_event, |
| 1227 | .report = mt_report, | ||
| 1196 | #ifdef CONFIG_PM | 1228 | #ifdef CONFIG_PM |
| 1197 | .reset_resume = mt_reset_resume, | 1229 | .reset_resume = mt_reset_resume, |
| 1198 | .resume = mt_resume, | 1230 | .resume = mt_resume, |
