Skip to content

Commit 3fe3a45

Browse files
committed
backport: 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]> [[email protected]: Backported from input-wacom (49dc331)] Signed-off-by: Jason Gerecke <[email protected]>
1 parent be51818 commit 3fe3a45

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

3.17/wacom.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
#include <linux/kfifo.h>
9292
#include <linux/usb/input.h>
9393
#include <linux/power_supply.h>
94+
#include <linux/timer.h>
9495
#include <asm/unaligned.h>
9596
#include <linux/version.h>
9697

@@ -186,6 +187,7 @@ struct wacom {
186187
struct delayed_work init_work;
187188
struct wacom_remote *remote;
188189
struct work_struct mode_change_work;
190+
struct timer_list idleprox_timer;
189191
bool generic_has_leds;
190192
struct wacom_leds {
191193
struct wacom_group_leds *groups;
@@ -251,4 +253,5 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report);
251253
void wacom_battery_work(struct work_struct *work);
252254
int wacom_equivalent_usage(int usage);
253255
int wacom_initialize_leds(struct wacom *wacom);
256+
void wacom_idleprox_timeout(unsigned long data);
254257
#endif

3.17/wacom_sys.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2700,6 +2700,7 @@ static int wacom_probe(struct hid_device *hdev,
27002700
INIT_WORK(&wacom->battery_work, wacom_battery_work);
27012701
INIT_WORK(&wacom->remote_work, wacom_remote_work);
27022702
INIT_WORK(&wacom->mode_change_work, wacom_mode_change_work);
2703+
setup_timer(&wacom->idleprox_timer, &wacom_idleprox_timeout, (unsigned long) wacom);
27032704

27042705
/* ask for the report descriptor to be loaded by HID */
27052706
error = hid_parse(hdev);
@@ -2744,6 +2745,7 @@ static void wacom_remove(struct hid_device *hdev)
27442745
cancel_work_sync(&wacom->battery_work);
27452746
cancel_work_sync(&wacom->remote_work);
27462747
cancel_work_sync(&wacom->mode_change_work);
2748+
del_timer_sync(&wacom->idleprox_timer);
27472749
if (hdev->bus == BUS_BLUETOOTH)
27482750
device_remove_file(&hdev->dev, &dev_attr_speed);
27492751
#ifndef WACOM_POWERSUPPLY_41

3.17/wacom_wac.c

Lines changed: 38 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 INPUT_PROP_ACCELEROMETER
1617
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
@@ -55,6 +56,42 @@ static void wacom_report_numbered_buttons(struct input_dev *input_dev,
5556

5657
static int wacom_numbered_button_to_key(int n);
5758

59+
static void wacom_force_proxout(struct wacom_wac *wacom_wac)
60+
{
61+
struct input_dev *input = wacom_wac->pen_input;
62+
63+
wacom_wac->shared->stylus_in_proximity = 0;
64+
65+
input_report_key(input, BTN_TOUCH, 0);
66+
input_report_key(input, BTN_STYLUS, 0);
67+
input_report_key(input, BTN_STYLUS2, 0);
68+
input_report_key(input, BTN_STYLUS3, 0);
69+
input_report_key(input, wacom_wac->tool[0], 0);
70+
if (wacom_wac->serial[0]) {
71+
input_report_abs(input, ABS_MISC, 0);
72+
}
73+
input_report_abs(input, ABS_PRESSURE, 0);
74+
75+
wacom_wac->tool[0] = 0;
76+
wacom_wac->id[0] = 0;
77+
wacom_wac->serial[0] = 0;
78+
79+
input_sync(input);
80+
}
81+
82+
void wacom_idleprox_timeout(unsigned long data)
83+
{
84+
struct wacom *wacom = (struct wacom *)data;
85+
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
86+
87+
if (!wacom_wac->hid_data.sense_state) {
88+
return;
89+
}
90+
91+
hid_warn(wacom->hdev, "%s: tool appears to be hung in-prox. forcing it out.\n", __func__);
92+
wacom_force_proxout(wacom_wac);
93+
}
94+
5895
/*
5996
* Percent of battery capacity for Graphire.
6097
* 8th value means AC online and show 100% capacity.
@@ -2345,6 +2382,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
23452382
value = field->logical_maximum - value;
23462383
break;
23472384
case HID_DG_INRANGE:
2385+
mod_timer(&wacom->idleprox_timer, jiffies + msecs_to_jiffies(100));
23482386
wacom_wac->hid_data.inrange_state = value;
23492387
if (!(features->quirks & WACOM_QUIRK_SENSE))
23502388
wacom_wac->hid_data.sense_state = value;

0 commit comments

Comments
 (0)