diff options
-rw-r--r-- | drivers/hid/hid-multitouch.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 4c697498fcf9..d0fa6a7e9bc0 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -77,6 +77,8 @@ struct mt_device { | |||
77 | unsigned last_slot_field; /* the last field of a slot */ | 77 | unsigned last_slot_field; /* the last field of a slot */ |
78 | int last_mt_collection; /* last known mt-related collection */ | 78 | int last_mt_collection; /* last known mt-related collection */ |
79 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | 79 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ |
80 | __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, | ||
81 | -1 if non-existent */ | ||
80 | __u8 num_received; /* how many contacts we received */ | 82 | __u8 num_received; /* how many contacts we received */ |
81 | __u8 num_expected; /* expected last contact index */ | 83 | __u8 num_expected; /* expected last contact index */ |
82 | __u8 maxcontacts; | 84 | __u8 maxcontacts; |
@@ -242,6 +244,7 @@ static void mt_feature_mapping(struct hid_device *hdev, | |||
242 | td->inputmode = field->report->id; | 244 | td->inputmode = field->report->id; |
243 | break; | 245 | break; |
244 | case HID_DG_CONTACTMAX: | 246 | case HID_DG_CONTACTMAX: |
247 | td->maxcontact_report_id = field->report->id; | ||
245 | td->maxcontacts = field->value[0]; | 248 | td->maxcontacts = field->value[0]; |
246 | if (td->mtclass.maxcontacts) | 249 | if (td->mtclass.maxcontacts) |
247 | /* check if the maxcontacts is given by the class */ | 250 | /* check if the maxcontacts is given by the class */ |
@@ -606,6 +609,32 @@ static void mt_set_input_mode(struct hid_device *hdev) | |||
606 | } | 609 | } |
607 | } | 610 | } |
608 | 611 | ||
612 | static void mt_set_maxcontacts(struct hid_device *hdev) | ||
613 | { | ||
614 | struct mt_device *td = hid_get_drvdata(hdev); | ||
615 | struct hid_report *r; | ||
616 | struct hid_report_enum *re; | ||
617 | int fieldmax, max; | ||
618 | |||
619 | if (td->maxcontact_report_id < 0) | ||
620 | return; | ||
621 | |||
622 | if (!td->mtclass.maxcontacts) | ||
623 | return; | ||
624 | |||
625 | re = &hdev->report_enum[HID_FEATURE_REPORT]; | ||
626 | r = re->report_id_hash[td->maxcontact_report_id]; | ||
627 | if (r) { | ||
628 | max = td->mtclass.maxcontacts; | ||
629 | fieldmax = r->field[0]->logical_maximum; | ||
630 | max = min(fieldmax, max); | ||
631 | if (r->field[0]->value[0] != max) { | ||
632 | r->field[0]->value[0] = max; | ||
633 | usbhid_submit_report(hdev, r, USB_DIR_OUT); | ||
634 | } | ||
635 | } | ||
636 | } | ||
637 | |||
609 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | 638 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) |
610 | { | 639 | { |
611 | int ret, i; | 640 | int ret, i; |
@@ -631,6 +660,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
631 | } | 660 | } |
632 | td->mtclass = *mtclass; | 661 | td->mtclass = *mtclass; |
633 | td->inputmode = -1; | 662 | td->inputmode = -1; |
663 | td->maxcontact_report_id = -1; | ||
634 | td->last_mt_collection = -1; | 664 | td->last_mt_collection = -1; |
635 | hid_set_drvdata(hdev, td); | 665 | hid_set_drvdata(hdev, td); |
636 | 666 | ||
@@ -653,6 +683,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
653 | 683 | ||
654 | ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); | 684 | ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); |
655 | 685 | ||
686 | mt_set_maxcontacts(hdev); | ||
656 | mt_set_input_mode(hdev); | 687 | mt_set_input_mode(hdev); |
657 | 688 | ||
658 | return 0; | 689 | return 0; |
@@ -665,6 +696,7 @@ fail: | |||
665 | #ifdef CONFIG_PM | 696 | #ifdef CONFIG_PM |
666 | static int mt_reset_resume(struct hid_device *hdev) | 697 | static int mt_reset_resume(struct hid_device *hdev) |
667 | { | 698 | { |
699 | mt_set_maxcontacts(hdev); | ||
668 | mt_set_input_mode(hdev); | 700 | mt_set_input_mode(hdev); |
669 | return 0; | 701 | return 0; |
670 | } | 702 | } |