diff options
author | Laura Abbott <labbott@redhat.com> | 2018-02-05 11:20:04 -0800 |
---|---|---|
committer | Laura Abbott <labbott@redhat.com> | 2018-02-05 11:35:34 -0800 |
commit | c41960f76806a516b0c4fd1953779fcd20bc7633 (patch) | |
tree | b71e9707b6ad3b47e8f80bddf5874777d6582b10 /0001-HID-multitouch-Properly-deal-with-Win8-PTP-reports-w.patch | |
parent | 622598fecff89da5536a5182e8f9dd5527b8471e (diff) | |
download | kernel-c41960f76806a516b0c4fd1953779fcd20bc7633.tar.gz kernel-c41960f76806a516b0c4fd1953779fcd20bc7633.tar.xz kernel-c41960f76806a516b0c4fd1953779fcd20bc7633.zip |
Linux v4.15
Diffstat (limited to '0001-HID-multitouch-Properly-deal-with-Win8-PTP-reports-w.patch')
-rw-r--r-- | 0001-HID-multitouch-Properly-deal-with-Win8-PTP-reports-w.patch | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/0001-HID-multitouch-Properly-deal-with-Win8-PTP-reports-w.patch b/0001-HID-multitouch-Properly-deal-with-Win8-PTP-reports-w.patch new file mode 100644 index 000000000..e15ec6bb1 --- /dev/null +++ b/0001-HID-multitouch-Properly-deal-with-Win8-PTP-reports-w.patch @@ -0,0 +1,106 @@ +From f5c1da991de077420fda17a236342de5a0068f5d Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Wed, 22 Nov 2017 12:57:08 +0100 +Subject: [PATCH v2 1/3] 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> +--- + drivers/hid/hid-multitouch.c | 32 ++++++++++++++++++++++++++++++-- + 1 file 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 { + unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */ + int cc_index; /* contact count field index in the report */ + int cc_value_index; /* contact count value index in the field */ ++ int scantime_index; /* scantime field index in the report */ ++ int scantime_val_index; /* scantime value index in the field */ ++ int prev_scantime; /* scantime reported in the previous packet */ + unsigned last_slot_field; /* the last field of a slot */ + unsigned mt_report_id; /* the report ID of the multitouch device */ + 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, + EV_MSC, MSC_TIMESTAMP); + input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP); + mt_store_field(usage, td, hi); ++ /* Ignore if indexes are out of bounds. */ ++ if (field->index >= field->report->maxfield || ++ usage->usage_index >= field->report_count) ++ return 1; ++ td->scantime_index = field->index; ++ td->scantime_val_index = usage->usage_index; + return 1; + case HID_DG_CONTACTCOUNT: + /* 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, + static void mt_touch_report(struct hid_device *hid, struct hid_report *report) + { + struct mt_device *td = hid_get_drvdata(hid); ++ __s32 cls = td->mtclass.name; + struct hid_field *field; + unsigned count; +- int r, n; ++ int r, n, scantime = 0; + + /* sticky fingers release in progress, abort */ + 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) + * Includes multi-packet support where subsequent + * packets are sent with zero contactcount. + */ ++ if (td->scantime_index >= 0) { ++ field = report->field[td->scantime_index]; ++ scantime = field->value[td->scantime_val_index]; ++ } + if (td->cc_index >= 0) { + struct hid_field *field = report->field[td->cc_index]; + int value = field->value[td->cc_value_index]; +- if (value) ++ ++ /* ++ * For Win8 PTPs the first packet (td->num_received == 0) may ++ * have a contactcount of 0 if there only is a button event. ++ * We double check that this is not a continuation packet ++ * of a possible multi-packet frame be checking that the ++ * timestamp has changed. ++ */ ++ if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) && ++ td->num_received == 0 && td->prev_scantime != scantime) ++ td->num_expected = value; ++ /* A non 0 contact count always indicates a first packet */ ++ else if (value) + td->num_expected = value; + } ++ td->prev_scantime = scantime; + + for (r = 0; r < report->maxfield; r++) { + field = report->field[r]; +@@ -1329,6 +1356,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) + td->maxcontact_report_id = -1; + td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN; + td->cc_index = -1; ++ td->scantime_index = -1; + td->mt_report_id = -1; + hid_set_drvdata(hdev, td); + +-- +2.14.3 + |