diff options
author | Jiri Kosina <jkosina@suse.cz> | 2021-06-30 09:03:51 +0200 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2021-06-30 09:03:51 +0200 |
commit | fd73788ce6a580f2bd353e0f364d31b6c16dcd12 (patch) | |
tree | dbeecdd8155a9c1c6be3d85739d3740243907c2e /drivers/hid/hid-input.c | |
parent | Merge branch 'for-5.14/amd-sfh' into for-linus (diff) | |
parent | HID: input: Add support for Programmable Buttons (diff) | |
download | linux-fd73788ce6a580f2bd353e0f364d31b6c16dcd12.tar.xz linux-fd73788ce6a580f2bd353e0f364d31b6c16dcd12.zip |
Merge branch 'for-5.14/core' into for-linus
- device unbinding locking fix from Dmitry Torokhov
- support for programmable buttons (mapping to KEY_MACRO# event codes)
from Thomas Weißschuh
- various other small fixes and code style improvements
Diffstat (limited to 'drivers/hid/hid-input.c')
-rw-r--r-- | drivers/hid/hid-input.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 68c8644234a4..4286a51f7f16 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -569,6 +569,16 @@ static void hidinput_update_battery(struct hid_device *dev, int value) } #endif /* CONFIG_HID_BATTERY_STRENGTH */ +static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field, + unsigned int type, unsigned int usage) +{ + struct hid_collection *collection; + + collection = &device->collection[field->usage->collection_index]; + + return collection->type == type && collection->usage == usage; +} + static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, struct hid_usage *usage) { @@ -634,6 +644,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel else code += BTN_TRIGGER_HAPPY - 0x10; break; + case HID_CP_CONSUMER_CONTROL: + if (hidinput_field_in_collection(device, field, + HID_COLLECTION_NAMED_ARRAY, + HID_CP_PROGRAMMABLEBUTTONS)) { + if (code <= 0x1d) + code += KEY_MACRO1; + else + code += BTN_TRIGGER_HAPPY - 0x1e; + } else { + goto ignore; + } + break; default: switch (field->physical) { case HID_GD_MOUSE: @@ -1318,12 +1340,12 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; } - if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */ + if (usage->hid == HID_DG_INVERT) { *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT); return; } - if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */ + if (usage->hid == HID_DG_INRANGE) { if (value) { input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1); return; @@ -1333,7 +1355,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; } - if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */ + if (usage->hid == HID_DG_TIPPRESSURE && (*quirks & HID_QUIRK_NOTOUCH)) { int a = field->logical_minimum; int b = field->logical_maximum; input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3)); |