aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-input.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-input.c')
-rw-r--r--drivers/hid/hid-input.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 851ee86eff32..40a5645f8fe8 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -988,6 +988,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
return;
case 0x3c: /* Invert */
+ device->quirks &= ~HID_QUIRK_NOINVERT;
map_key_clear(BTN_TOOL_RUBBER);
break;
@@ -1013,9 +1014,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x45: /* ERASER */
/*
* This event is reported when eraser tip touches the surface.
- * Actual eraser (BTN_TOOL_RUBBER) is set by Invert usage when
- * tool gets in proximity.
+ * Actual eraser (BTN_TOOL_RUBBER) is set and released either
+ * by Invert if tool reports proximity or by Eraser directly.
*/
+ if (!test_bit(BTN_TOOL_RUBBER, input->keybit)) {
+ device->quirks |= HID_QUIRK_NOINVERT;
+ set_bit(BTN_TOOL_RUBBER, input->keybit);
+ }
map_key_clear(BTN_TOUCH);
break;
@@ -1580,6 +1585,15 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
else if (report->tool != BTN_TOOL_RUBBER)
/* value is off, tool is not rubber, ignore */
return;
+ else if (*quirks & HID_QUIRK_NOINVERT &&
+ !test_bit(BTN_TOUCH, input->key)) {
+ /*
+ * There is no invert to release the tool, let hid_input
+ * send BTN_TOUCH with scancode and release the tool after.
+ */
+ hid_report_release_tool(report, input, BTN_TOOL_RUBBER);
+ return;
+ }
/* let hid-input set BTN_TOUCH */
break;