[PATCH] HID: input: Handle OOC toggle switches mapped to keys

From: Pablo Ceballos
Date: Mon Feb 14 2022 - 16:51:35 EST


Section 3.4.1.2 of the HID Usage Tables specification describes an
on/off control (OOC) implemented as a toggle switch that maintains its
state. This is encoded as a 1-bit absolute value with a logical minimum
of 0 and a logical maximum of 1.

The telephony device usage page (0x0B) defines a "Phone Mute" usage
(0x2F) with an OOC usage type. The hid-input driver currently maps this
usage to input event code KEY_MICMUTE, which is an EV_KEY event type.

EV_KEY events are expected to be emitted with a value of 1 when a key is
depressed, and a value of 0 when a key is released.

This patch emits a key depress and release event when an OOC toggle
switch that is mapped to an EV_KEY event type is toggled.

Signed-off-by: Pablo Ceballos <pceballos@xxxxxxxxxx>

---
I'm not sure if this is the best way to resolve this issue that's
happening with the "Phone Mute" HID usage. Or if this approach will
cause issues with other HID devices.

drivers/hid/hid-input.c | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 112901d2d8d2a..102150bde4e72 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1450,6 +1450,17 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
(!test_bit(usage->code, input->key)) == value)
input_event(input, EV_MSC, MSC_SCAN, usage->hid);

+ if (usage->type == EV_KEY &&
+ (field->flags & HID_MAIN_ITEM_VARIABLE) &&
+ !(field->flags & HID_MAIN_ITEM_RELATIVE) &&
+ field->logical_minimum == 0 &&
+ field->logical_maximum == 1) {
+ input_event(input, EV_KEY, usage->code, 1);
+ input_sync(input);
+ input_event(input, EV_KEY, usage->code, 0);
+ return;
+ }
+
input_event(input, usage->type, usage->code, value);

if ((field->flags & HID_MAIN_ITEM_RELATIVE) &&
--
2.35.1.265.g69c8d7142f-goog