diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2018-04-24 10:04:37 +0200 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2018-04-26 14:17:55 +0200 |
commit | 02946f4b43b11026b1a76857a33b09078b900939 (patch) | |
tree | 30c29479630913323655eacd359a53de78094b78 | |
parent | 7f81c8db54898a793cc2916a936f6bf3fca41434 (diff) | |
download | op-kernel-dev-02946f4b43b11026b1a76857a33b09078b900939.zip op-kernel-dev-02946f4b43b11026b1a76857a33b09078b900939.tar.gz |
HID: multitouch: implement precision touchpad latency and switches
The Win 8.1 precision touchpad spec introduce new modes for touchpads
that can come in handy[1].
Implement the settings of these modes, so we are not taken off-guard if
a firmware decides to enforce them.
[1] https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-precision-touchpad-required-hid-top-level-collections
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/hid-multitouch.c | 34 | ||||
-rw-r--r-- | include/linux/hid.h | 3 |
2 files changed, 32 insertions, 5 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 8878de9..82c98bf 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -81,6 +81,11 @@ MODULE_LICENSE("GPL"); #define MT_BUTTONTYPE_CLICKPAD 0 +enum latency_mode { + HID_LATENCY_NORMAL = 0, + HID_LATENCY_HIGH = 1, +}; + #define MT_IO_FLAGS_RUNNING 0 #define MT_IO_FLAGS_ACTIVE_SLOTS 1 #define MT_IO_FLAGS_PENDING_SLOTS 2 @@ -1156,7 +1161,10 @@ static void mt_report(struct hid_device *hid, struct hid_report *report) static bool mt_need_to_apply_feature(struct hid_device *hdev, struct hid_field *field, - struct hid_usage *usage) + struct hid_usage *usage, + enum latency_mode latency, + bool surface_switch, + bool button_switch) { struct mt_device *td = hid_get_drvdata(hdev); struct mt_class *cls = &td->mtclass; @@ -1195,12 +1203,25 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev, } } break; + + case HID_DG_LATENCYMODE: + field->value[index] = latency; + return 1; + + case HID_DG_SURFACESWITCH: + field->value[index] = surface_switch; + return 1; + + case HID_DG_BUTTONSWITCH: + field->value[index] = button_switch; + return 1; } return false; /* no need to update the report */ } -static void mt_set_modes(struct hid_device *hdev) +static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency, + bool surface_switch, bool button_switch) { struct hid_report_enum *rep_enum; struct hid_report *rep; @@ -1222,7 +1243,10 @@ static void mt_set_modes(struct hid_device *hdev) if (mt_need_to_apply_feature(hdev, rep->field[i], - usage)) + usage, + latency, + surface_switch, + button_switch)) update_report = true; } } @@ -1467,7 +1491,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) dev_warn(&hdev->dev, "Cannot allocate sysfs group for %s\n", hdev->name); - mt_set_modes(hdev); + mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); /* release .fields memory as it is not used anymore */ devm_kfree(&hdev->dev, td->fields); @@ -1480,7 +1504,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) static int mt_reset_resume(struct hid_device *hdev) { mt_release_contacts(hdev); - mt_set_modes(hdev); + mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); return 0; } diff --git a/include/linux/hid.h b/include/linux/hid.h index f03d7a41..a1be991 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -292,9 +292,12 @@ struct hid_item { #define HID_DG_CONTACTCOUNT 0x000d0054 #define HID_DG_CONTACTMAX 0x000d0055 #define HID_DG_SCANTIME 0x000d0056 +#define HID_DG_SURFACESWITCH 0x000d0057 +#define HID_DG_BUTTONSWITCH 0x000d0058 #define HID_DG_BUTTONTYPE 0x000d0059 #define HID_DG_BARRELSWITCH2 0x000d005a #define HID_DG_TOOLSERIALNUMBER 0x000d005b +#define HID_DG_LATENCYMODE 0x000d0060 #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076 /* |