aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-multitouch.c32
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
612static 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
609static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) 638static 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
666static int mt_reset_resume(struct hid_device *hdev) 697static 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}