Skip to content

Commit 276e14e

Browse files
iostapyshynJiri Kosina
authored andcommitted
HID: input: Support devices sending Eraser without Invert
Some digitizers (notably XP-Pen Artist 24) do not report the Invert usage when erasing. This causes the device to be permanently stuck with the BTN_TOOL_RUBBER tool after sending Eraser, as Invert is the only usage that can release the tool. In this state, Touch and Inrange are no longer reported to userspace, rendering the pen unusable. Prior to commit 87562fc ("HID: input: remove the need for HID_QUIRK_INVERT"), BTN_TOOL_RUBBER was never set and Eraser events were simply translated into BTN_TOUCH without causing an inconsistent state. Introduce HID_QUIRK_NOINVERT for such digitizers and detect them during hidinput_configure_usage(). This quirk causes the tool to be released as soon as Eraser is reported as not set. Set BTN_TOOL_RUBBER in input->keybit when mapping Eraser. Fixes: 87562fc ("HID: input: remove the need for HID_QUIRK_INVERT") Co-developed-by: Nils Fuhler <[email protected]> Signed-off-by: Nils Fuhler <[email protected]> Signed-off-by: Illia Ostapyshyn <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 1d75460 commit 276e14e

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

drivers/hid/hid-input.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
988988
return;
989989

990990
case 0x3c: /* Invert */
991+
device->quirks &= ~HID_QUIRK_NOINVERT;
991992
map_key_clear(BTN_TOOL_RUBBER);
992993
break;
993994

@@ -1013,9 +1014,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
10131014
case 0x45: /* ERASER */
10141015
/*
10151016
* This event is reported when eraser tip touches the surface.
1016-
* Actual eraser (BTN_TOOL_RUBBER) is set by Invert usage when
1017-
* tool gets in proximity.
1017+
* Actual eraser (BTN_TOOL_RUBBER) is set and released either
1018+
* by Invert if tool reports proximity or by Eraser directly.
10181019
*/
1020+
if (!test_bit(BTN_TOOL_RUBBER, input->keybit)) {
1021+
device->quirks |= HID_QUIRK_NOINVERT;
1022+
set_bit(BTN_TOOL_RUBBER, input->keybit);
1023+
}
10191024
map_key_clear(BTN_TOUCH);
10201025
break;
10211026

@@ -1580,6 +1585,15 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
15801585
else if (report->tool != BTN_TOOL_RUBBER)
15811586
/* value is off, tool is not rubber, ignore */
15821587
return;
1588+
else if (*quirks & HID_QUIRK_NOINVERT &&
1589+
!test_bit(BTN_TOUCH, input->key)) {
1590+
/*
1591+
* There is no invert to release the tool, let hid_input
1592+
* send BTN_TOUCH with scancode and release the tool after.
1593+
*/
1594+
hid_report_release_tool(report, input, BTN_TOOL_RUBBER);
1595+
return;
1596+
}
15831597

15841598
/* let hid-input set BTN_TOUCH */
15851599
break;

include/linux/hid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ struct hid_item {
360360
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
361361
#define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19)
362362
#define HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE BIT(20)
363+
#define HID_QUIRK_NOINVERT BIT(21)
363364
#define HID_QUIRK_FULLSPEED_INTERVAL BIT(28)
364365
#define HID_QUIRK_NO_INIT_REPORTS BIT(29)
365366
#define HID_QUIRK_NO_IGNORE BIT(30)

0 commit comments

Comments
 (0)