Skip to content

Commit 49dc331

Browse files
committed
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: linuxwacom#310 Signed-off-by: Jason Gerecke <[email protected]> Signed-off-by: Jiri Kosina <[email protected]> [[email protected]: Imported into input-wacom (94b179052f)] Signed-off-by: Jason Gerecke <[email protected]>
1 parent c6adafa commit 49dc331

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

.github/workflows/main.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-20.04
1010
strategy:
1111
matrix:
12-
kernel: ["5.10", "4.6", "4.5", "4.1", "3.19", "3.18", "3.17", "3.7"]
12+
kernel: ["5.10", "4.14", "4.6", "4.5", "4.1", "3.19", "3.18", "3.17", "3.7"]
1313
include:
1414
- kernel: "3.7"
1515
compile_cflags: -Wno-error=pointer-sign
@@ -25,6 +25,8 @@ jobs:
2525
compile_cflags: -Wno-error=format-truncation
2626
- kernel: "4.6"
2727
compile_cflags: -Wno-error=format-truncation
28+
- kernel: "4.14"
29+
compile_cflags: -Wno-error=format-truncation
2830
- kernel: "5.10"
2931
compile_cflags: -Wno-error=format-truncation
3032
steps:

4.5/wacom.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
#include <linux/leds.h>
9393
#include <linux/usb/input.h>
9494
#include <linux/power_supply.h>
95+
#include <linux/timer.h>
9596
#include <asm/unaligned.h>
9697
#include <linux/version.h>
9798

@@ -183,6 +184,7 @@ struct wacom {
183184
struct delayed_work init_work;
184185
struct wacom_remote *remote;
185186
struct work_struct mode_change_work;
187+
struct timer_list idleprox_timer;
186188
bool generic_has_leds;
187189
struct wacom_leds {
188190
struct wacom_group_leds *groups;
@@ -255,4 +257,9 @@ struct wacom_led *wacom_led_find(struct wacom *wacom, unsigned int group,
255257
struct wacom_led *wacom_led_next(struct wacom *wacom, struct wacom_led *cur);
256258
int wacom_equivalent_usage(int usage);
257259
int wacom_initialize_leds(struct wacom *wacom);
260+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
261+
void wacom_idleprox_timeout(struct timer_list *list);
262+
#else
263+
void wacom_idleprox_timeout(unsigned long data);
264+
#endif
258265
#endif

4.5/wacom_sys.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,6 +2841,11 @@ static int wacom_probe(struct hid_device *hdev,
28412841
INIT_WORK(&wacom->battery_work, wacom_battery_work);
28422842
INIT_WORK(&wacom->remote_work, wacom_remote_work);
28432843
INIT_WORK(&wacom->mode_change_work, wacom_mode_change_work);
2844+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
2845+
timer_setup(&wacom->idleprox_timer, &wacom_idleprox_timeout, TIMER_DEFERRABLE);
2846+
#else
2847+
setup_timer(&wacom->idleprox_timer, &wacom_idleprox_timeout, (unsigned long) wacom);
2848+
#endif
28442849

28452850
/* ask for the report descriptor to be loaded by HID */
28462851
error = hid_parse(hdev);
@@ -2881,6 +2886,7 @@ static void wacom_remove(struct hid_device *hdev)
28812886
cancel_work_sync(&wacom->battery_work);
28822887
cancel_work_sync(&wacom->remote_work);
28832888
cancel_work_sync(&wacom->mode_change_work);
2889+
del_timer_sync(&wacom->idleprox_timer);
28842890
if (hdev->bus == BUS_BLUETOOTH)
28852891
device_remove_file(&hdev->dev, &dev_attr_speed);
28862892

4.5/wacom_wac.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "wacom_wac.h"
1212
#include "wacom.h"
1313
#include <linux/input/mt.h>
14+
#include <linux/jiffies.h>
1415

1516
#ifndef KEY_ONSCREEN_KEYBOARD
1617
#define KEY_ONSCREEN_KEYBOARD 0x278
@@ -45,6 +46,49 @@ static int wacom_numbered_button_to_key(int n);
4546

4647
static void wacom_update_led(struct wacom *wacom, int button_count, int mask,
4748
int group);
49+
50+
static void wacom_force_proxout(struct wacom_wac *wacom_wac)
51+
{
52+
struct input_dev *input = wacom_wac->pen_input;
53+
54+
wacom_wac->shared->stylus_in_proximity = 0;
55+
56+
input_report_key(input, BTN_TOUCH, 0);
57+
input_report_key(input, BTN_STYLUS, 0);
58+
input_report_key(input, BTN_STYLUS2, 0);
59+
input_report_key(input, BTN_STYLUS3, 0);
60+
input_report_key(input, wacom_wac->tool[0], 0);
61+
if (wacom_wac->serial[0]) {
62+
input_report_abs(input, ABS_MISC, 0);
63+
}
64+
input_report_abs(input, ABS_PRESSURE, 0);
65+
66+
wacom_wac->tool[0] = 0;
67+
wacom_wac->id[0] = 0;
68+
wacom_wac->serial[0] = 0;
69+
70+
input_sync(input);
71+
}
72+
73+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
74+
void wacom_idleprox_timeout(struct timer_list *list)
75+
{
76+
struct wacom *wacom = from_timer(wacom, list, idleprox_timer);
77+
#else
78+
void wacom_idleprox_timeout(unsigned long data)
79+
{
80+
struct wacom *wacom = (struct wacom *)data;
81+
#endif
82+
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
83+
84+
if (!wacom_wac->hid_data.sense_state) {
85+
return;
86+
}
87+
88+
hid_warn(wacom->hdev, "%s: tool appears to be hung in-prox. forcing it out.\n", __func__);
89+
wacom_force_proxout(wacom_wac);
90+
}
91+
4892
/*
4993
* Percent of battery capacity for Graphire.
5094
* 8th value means AC online and show 100% capacity.
@@ -2338,6 +2382,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
23382382
value = field->logical_maximum - value;
23392383
break;
23402384
case HID_DG_INRANGE:
2385+
mod_timer(&wacom->idleprox_timer, jiffies + msecs_to_jiffies(100));
23412386
wacom_wac->hid_data.inrange_state = value;
23422387
if (!(features->quirks & WACOM_QUIRK_SENSE))
23432388
wacom_wac->hid_data.sense_state = value;

0 commit comments

Comments
 (0)