diff options
author | Ben Chan <benchan@chromium.org> | 2018-05-30 01:56:55 +0300 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2018-05-30 09:53:09 +0300 |
commit | abb36fe691b28f2a64926b61448d6b9610ed879a (patch) | |
tree | ed1c00fc939fc3b1ac6e4a97a5b3fc7a716c5bfc | |
parent | 99c703acade3e38c07b179d684045e9099f935e9 (diff) | |
download | linux-abb36fe691b28f2a64926b61448d6b9610ed879a.tar.xz |
HID: multitouch: fix calculation of last slot field in multi-touch reports
According to [1] and also seemingly agreed by [2], the Scan Time usage
(0x0D 0x56) is a report level usage, not a contact level usage.
However, the hid-multitouch driver currently includes HID_DG_SCANTIME
when calculating `td->last_slot_field', which may lead to
mt_complete_slot() being prematurely called in certain cases (e.g. when
each touch input report includes more than one contact and the Scan Time
usage appears before any contact logical collection).
This patch fixes the issue by skipping mt_store_field() on
HID_DG_SCANTIME, similar to how HID_DG_CONTACTCOUNT and
HID_DG_CONTACTMAX are handled.
[1] https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-precision-touchpad-required-hid-top-level-collections#windows-precision-touchpad-input-reports
[2] https://patchwork.kernel.org/patch/1742181/
Fixes: 29cc309d8bf19 ("HID: hid-multitouch: forward MSC_TIMESTAMP")
Signed-off-by: Ben Chan <benchan@chromium.org>
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-multitouch.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 38c4ca24343e..45968f7970f8 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -598,13 +598,16 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, hid_map_usage(hi, usage, bit, max, 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; + /* + * We don't set td->last_slot_field as scan time is + * global to the report. + */ return 1; case HID_DG_CONTACTCOUNT: /* Ignore if indexes are out of bounds. */ |