Skip to content

Commit

Permalink
backport: HID: wacom: Force pen out of prox if no events have been re…
Browse files Browse the repository at this point in the history
…ceived 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 <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
[jason.gerecke@wacom.com: Imported into input-wacom (94b179052f)]
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
[jason.gerecke@wacom.com: Backported from input-wacom (6752af2)]
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
  • Loading branch information
jigpu committed Jul 21, 2022
1 parent d9864fc commit 2b7d893
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
3 changes: 3 additions & 0 deletions 3.17/wacom.h
Expand Up @@ -91,6 +91,7 @@
#include <linux/kfifo.h>
#include <linux/usb/input.h>
#include <linux/power_supply.h>
#include <linux/timer.h>
#include <asm/unaligned.h>
#include <linux/version.h>

Expand Down Expand Up @@ -186,6 +187,7 @@ struct wacom {
struct delayed_work init_work;
struct wacom_remote *remote;
struct work_struct mode_change_work;
struct timer_list idleprox_timer;
bool generic_has_leds;
struct wacom_leds {
struct wacom_group_leds *groups;
Expand Down Expand Up @@ -251,4 +253,5 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report);
void wacom_battery_work(struct work_struct *work);
int wacom_equivalent_usage(int usage);
int wacom_initialize_leds(struct wacom *wacom);
void wacom_idleprox_timeout(unsigned long data);
#endif
2 changes: 2 additions & 0 deletions 3.17/wacom_sys.c
Expand Up @@ -2700,6 +2700,7 @@ static int wacom_probe(struct hid_device *hdev,
INIT_WORK(&wacom->battery_work, wacom_battery_work);
INIT_WORK(&wacom->remote_work, wacom_remote_work);
INIT_WORK(&wacom->mode_change_work, wacom_mode_change_work);
setup_timer(&wacom->idleprox_timer, &wacom_idleprox_timeout, (unsigned long) wacom);

/* ask for the report descriptor to be loaded by HID */
error = hid_parse(hdev);
Expand Down Expand Up @@ -2744,6 +2745,7 @@ static void wacom_remove(struct hid_device *hdev)
cancel_work_sync(&wacom->battery_work);
cancel_work_sync(&wacom->remote_work);
cancel_work_sync(&wacom->mode_change_work);
del_timer_sync(&wacom->idleprox_timer);
if (hdev->bus == BUS_BLUETOOTH)
device_remove_file(&hdev->dev, &dev_attr_speed);
#ifndef WACOM_POWERSUPPLY_41
Expand Down
38 changes: 38 additions & 0 deletions 3.17/wacom_wac.c
Expand Up @@ -11,6 +11,7 @@
#include "wacom_wac.h"
#include "wacom.h"
#include <linux/input/mt.h>
#include <linux/jiffies.h>

#ifndef INPUT_PROP_ACCELEROMETER
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
Expand Down Expand Up @@ -55,6 +56,42 @@ static void wacom_report_numbered_buttons(struct input_dev *input_dev,

static int wacom_numbered_button_to_key(int n);

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(unsigned long data)
{
struct wacom *wacom = (struct wacom *)data;
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.
Expand Down Expand Up @@ -2345,6 +2382,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;
Expand Down

0 comments on commit 2b7d893

Please sign in to comment.