aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-multitouch.c
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@enac.fr>2012-02-04 11:08:49 -0500
committerJiri Kosina <jkosina@suse.cz>2012-02-06 07:22:39 -0500
commit31ae9bddb935c74b51ead08d54948e5bea0f0344 (patch)
treebb56ab427441efb72af0018a231c858740bc1b81 /drivers/hid/hid-multitouch.c
parentc2ef8f21ea8f7c34dfa0b569fdee431348205955 (diff)
HID: multitouch: add control of the feature "Maximum Contact Number"
Some devices, like Perixx Peripad 701 do not work if the feature "Maximum Contact Number" is not set to the right value. This patch allows hid-multitouch to control this feature. If the programmer fills the field maxcontacts in the mt_class, then the driver will set the feature to this value. It is safe for current drivers as the feature is read/write in the HID norm and all devices should implement the norm. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr> Acked-by: Henrik Rydberg <rydberg@euromail.se> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-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}