diff mbox series

HID: input: Handle OOC toggle switches mapped to keys

Message ID 20220214165021.1.I89632f95e6af380102cdb1ec9f7a6d5cb948b029@changeid (mailing list archive)
State New, archived
Delegated to: Jiri Kosina
Headers show
Series HID: input: Handle OOC toggle switches mapped to keys | expand

Commit Message

Pablo Ceballos Feb. 14, 2022, 9:51 p.m. UTC
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@google.com>

---
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(+)

Comments

Pablo Ceballos Feb. 23, 2022, 5:17 a.m. UTC | #1
On Mon, Feb 14, 2022 at 1:51 PM Pablo Ceballos <pceballos@google.com> wrote:
> 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.

Further testing shows that this won't work. The problem with this
approach is that there is no way to know the initial state of the
toggle switch. Please ignore this patch.
diff mbox series

Patch

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) &&