aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2017-11-22 06:57:08 -0500
committerJiri Kosina <jkosina@suse.cz>2017-11-22 10:01:06 -0500
commitaf8dc4d0949092c4fba17ebb9e54448697c3d4e0 (patch)
tree84f033d92a75931415db4324418bc7d70dc694be
parentfb55b4026d88a2bdc351f5485461d9314c885b60 (diff)
HID: multitouch: Properly deal with Win8 PTP reports with 0 touches
The Windows Precision Touchpad spec "Figure 4 Button Only Down and Up" and "Table 9 Report Sequence for Button Only Down and Up" indicate that the first packet of a (possibly hybrid mode multi-packet) frame may contain a contact-count of 0 if only a button is pressed and no fingers are detected. This means that a value of 0 for contact-count is a valid value and should be used as expected contact count when it is the first packet (num_received == 0), as extra check to make sure that this is the first packet of a buttons only frame, we also check that the timestamp is different. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-multitouch.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 9ef24b518f12..d8b1cad74faf 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -119,6 +119,9 @@ struct mt_device {
119 unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */ 119 unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */
120 int cc_index; /* contact count field index in the report */ 120 int cc_index; /* contact count field index in the report */
121 int cc_value_index; /* contact count value index in the field */ 121 int cc_value_index; /* contact count value index in the field */
122 int scantime_index; /* scantime field index in the report */
123 int scantime_val_index; /* scantime value index in the field */
124 int prev_scantime; /* scantime reported in the previous packet */
122 unsigned last_slot_field; /* the last field of a slot */ 125 unsigned last_slot_field; /* the last field of a slot */
123 unsigned mt_report_id; /* the report ID of the multitouch device */ 126 unsigned mt_report_id; /* the report ID of the multitouch device */
124 unsigned long initial_quirks; /* initial quirks state */ 127 unsigned long initial_quirks; /* initial quirks state */
@@ -599,6 +602,12 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
599 EV_MSC, MSC_TIMESTAMP); 602 EV_MSC, MSC_TIMESTAMP);
600 input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP); 603 input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP);
601 mt_store_field(usage, td, hi); 604 mt_store_field(usage, td, hi);
605 /* Ignore if indexes are out of bounds. */
606 if (field->index >= field->report->maxfield ||
607 usage->usage_index >= field->report_count)
608 return 1;
609 td->scantime_index = field->index;
610 td->scantime_val_index = usage->usage_index;
602 return 1; 611 return 1;
603 case HID_DG_CONTACTCOUNT: 612 case HID_DG_CONTACTCOUNT:
604 /* Ignore if indexes are out of bounds. */ 613 /* Ignore if indexes are out of bounds. */
@@ -855,9 +864,10 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
855static void mt_touch_report(struct hid_device *hid, struct hid_report *report) 864static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
856{ 865{
857 struct mt_device *td = hid_get_drvdata(hid); 866 struct mt_device *td = hid_get_drvdata(hid);
867 __s32 cls = td->mtclass.name;
858 struct hid_field *field; 868 struct hid_field *field;
859 unsigned count; 869 unsigned count;
860 int r, n; 870 int r, n, scantime = 0;
861 871
862 /* sticky fingers release in progress, abort */ 872 /* sticky fingers release in progress, abort */
863 if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) 873 if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
@@ -867,12 +877,29 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
867 * Includes multi-packet support where subsequent 877 * Includes multi-packet support where subsequent
868 * packets are sent with zero contactcount. 878 * packets are sent with zero contactcount.
869 */ 879 */
880 if (td->scantime_index >= 0) {
881 field = report->field[td->scantime_index];
882 scantime = field->value[td->scantime_val_index];
883 }
870 if (td->cc_index >= 0) { 884 if (td->cc_index >= 0) {
871 struct hid_field *field = report->field[td->cc_index]; 885 struct hid_field *field = report->field[td->cc_index];
872 int value = field->value[td->cc_value_index]; 886 int value = field->value[td->cc_value_index];
873 if (value) 887
888 /*
889 * For Win8 PTPs the first packet (td->num_received == 0) may
890 * have a contactcount of 0 if there only is a button event.
891 * We double check that this is not a continuation packet
892 * of a possible multi-packet frame be checking that the
893 * timestamp has changed.
894 */
895 if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
896 td->num_received == 0 && td->prev_scantime != scantime)
897 td->num_expected = value;
898 /* A non 0 contact count always indicates a first packet */
899 else if (value)
874 td->num_expected = value; 900 td->num_expected = value;
875 } 901 }
902 td->prev_scantime = scantime;
876 903
877 for (r = 0; r < report->maxfield; r++) { 904 for (r = 0; r < report->maxfield; r++) {
878 field = report->field[r]; 905 field = report->field[r];
@@ -1329,6 +1356,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
1329 td->maxcontact_report_id = -1; 1356 td->maxcontact_report_id = -1;
1330 td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN; 1357 td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN;
1331 td->cc_index = -1; 1358 td->cc_index = -1;
1359 td->scantime_index = -1;
1332 td->mt_report_id = -1; 1360 td->mt_report_id = -1;
1333 hid_set_drvdata(hdev, td); 1361 hid_set_drvdata(hdev, td);
1334 1362