diff options
author | Jason Gerecke <killertofu@gmail.com> | 2022-07-15 16:05:19 -0700 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2022-07-21 13:49:32 +0200 |
commit | 94b179052f95c294d83e9c9c34f7833cf3cd4305 (patch) | |
tree | e959d72bf1a008d282674043788656fa822e8208 /drivers/hid/wacom_wac.c | |
parent | ab5f3404b7762b88403fbddbdda6b1b464bd6cbc (diff) |
HID: wacom: Force pen out of prox if no events have been received in a while
Prox-out events may not be reliably sent by some AES firmware. This can
cause problems for users, particularly due to arbitration logic disabling
touch input while the pen is in prox.
This commit adds a timer which is reset every time a new prox event is
received. When the timer expires we check to see if the pen is still in
prox and force it out if necessary. This is patterend off of the same
solution used by 'hid-letsketch' driver which has a similar problem.
Link: https://github.com/linuxwacom/input-wacom/issues/310
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/wacom_wac.c')
-rw-r--r-- | drivers/hid/wacom_wac.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index f8cc4bb3e3a7..d049239256a2 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -11,6 +11,7 @@ #include "wacom_wac.h" #include "wacom.h" #include <linux/input/mt.h> +#include <linux/jiffies.h> /* resolution for penabled devices */ #define WACOM_PL_RES 20 @@ -41,6 +42,43 @@ static int wacom_numbered_button_to_key(int n); static void wacom_update_led(struct wacom *wacom, int button_count, int mask, int group); + +static void wacom_force_proxout(struct wacom_wac *wacom_wac) +{ + struct input_dev *input = wacom_wac->pen_input; + + wacom_wac->shared->stylus_in_proximity = 0; + + input_report_key(input, BTN_TOUCH, 0); + input_report_key(input, BTN_STYLUS, 0); + input_report_key(input, BTN_STYLUS2, 0); + input_report_key(input, BTN_STYLUS3, 0); + input_report_key(input, wacom_wac->tool[0], 0); + if (wacom_wac->serial[0]) { + input_report_abs(input, ABS_MISC, 0); + } + input_report_abs(input, ABS_PRESSURE, 0); + + wacom_wac->tool[0] = 0; + wacom_wac->id[0] = 0; + wacom_wac->serial[0] = 0; + + input_sync(input); +} + +void wacom_idleprox_timeout(struct timer_list *list) +{ + struct wacom *wacom = from_timer(wacom, list, idleprox_timer); + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + + if (!wacom_wac->hid_data.sense_state) { + return; + } + + hid_warn(wacom->hdev, "%s: tool appears to be hung in-prox. forcing it out.\n", __func__); + wacom_force_proxout(wacom_wac); +} + /* * Percent of battery capacity for Graphire. * 8th value means AC online and show 100% capacity. @@ -2329,6 +2367,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field value = field->logical_maximum - value; break; case HID_DG_INRANGE: + mod_timer(&wacom->idleprox_timer, jiffies + msecs_to_jiffies(100)); wacom_wac->hid_data.inrange_state = value; if (!(features->quirks & WACOM_QUIRK_SENSE)) wacom_wac->hid_data.sense_state = value; |