|
Takashi Iwai |
f0a979 |
From 94b179052f95c294d83e9c9c34f7833cf3cd4305 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
f0a979 |
From: Jason Gerecke <killertofu@gmail.com>
|
|
Takashi Iwai |
f0a979 |
Date: Fri, 15 Jul 2022 16:05:19 -0700
|
|
Takashi Iwai |
f0a979 |
Subject: [PATCH] HID: wacom: Force pen out of prox if no events have been received in a while
|
|
Takashi Iwai |
f0a979 |
Git-commit: 94b179052f95c294d83e9c9c34f7833cf3cd4305
|
|
Takashi Iwai |
f0a979 |
Patch-mainline: v6.0-rc1
|
|
Takashi Iwai |
f0a979 |
References: git-fixes
|
|
Takashi Iwai |
f0a979 |
|
|
Takashi Iwai |
f0a979 |
Prox-out events may not be reliably sent by some AES firmware. This can
|
|
Takashi Iwai |
f0a979 |
cause problems for users, particularly due to arbitration logic disabling
|
|
Takashi Iwai |
f0a979 |
touch input while the pen is in prox.
|
|
Takashi Iwai |
f0a979 |
|
|
Takashi Iwai |
f0a979 |
This commit adds a timer which is reset every time a new prox event is
|
|
Takashi Iwai |
f0a979 |
received. When the timer expires we check to see if the pen is still in
|
|
Takashi Iwai |
f0a979 |
prox and force it out if necessary. This is patterend off of the same
|
|
Takashi Iwai |
f0a979 |
solution used by 'hid-letsketch' driver which has a similar problem.
|
|
Takashi Iwai |
f0a979 |
|
|
Takashi Iwai |
f0a979 |
Link: https://github.com/linuxwacom/input-wacom/issues/310
|
|
Takashi Iwai |
f0a979 |
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
|
|
Takashi Iwai |
f0a979 |
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
Takashi Iwai |
f0a979 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
f0a979 |
|
|
Takashi Iwai |
f0a979 |
---
|
|
Takashi Iwai |
f0a979 |
drivers/hid/wacom.h | 3 +++
|
|
Takashi Iwai |
f0a979 |
drivers/hid/wacom_sys.c | 2 ++
|
|
Takashi Iwai |
f0a979 |
drivers/hid/wacom_wac.c | 39 +++++++++++++++++++++++++++++++++++++++
|
|
Takashi Iwai |
f0a979 |
3 files changed, 44 insertions(+)
|
|
Takashi Iwai |
f0a979 |
|
|
Takashi Iwai |
f0a979 |
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
|
|
Takashi Iwai |
f0a979 |
index 203d27d198b8..3f8b24a57014 100644
|
|
Takashi Iwai |
f0a979 |
--- a/drivers/hid/wacom.h
|
|
Takashi Iwai |
f0a979 |
+++ b/drivers/hid/wacom.h
|
|
Takashi Iwai |
f0a979 |
@@ -91,6 +91,7 @@
|
|
Takashi Iwai |
f0a979 |
#include <linux/leds.h>
|
|
Takashi Iwai |
f0a979 |
#include <linux/usb/input.h>
|
|
Takashi Iwai |
f0a979 |
#include <linux/power_supply.h>
|
|
Takashi Iwai |
f0a979 |
+#include <linux/timer.h>
|
|
Takashi Iwai |
f0a979 |
#include <asm/unaligned.h>
|
|
Takashi Iwai |
f0a979 |
|
|
Takashi Iwai |
f0a979 |
/*
|
|
Takashi Iwai |
f0a979 |
@@ -167,6 +168,7 @@ struct wacom {
|
|
Takashi Iwai |
f0a979 |
struct delayed_work init_work;
|
|
Takashi Iwai |
f0a979 |
struct wacom_remote *remote;
|
|
Takashi Iwai |
f0a979 |
struct work_struct mode_change_work;
|
|
Takashi Iwai |
f0a979 |
+ struct timer_list idleprox_timer;
|
|
Takashi Iwai |
f0a979 |
bool generic_has_leds;
|
|
Takashi Iwai |
f0a979 |
struct wacom_leds {
|
|
Takashi Iwai |
f0a979 |
struct wacom_group_leds *groups;
|
|
Takashi Iwai |
f0a979 |
@@ -239,4 +241,5 @@ struct wacom_led *wacom_led_find(struct wacom *wacom, unsigned int group,
|
|
Takashi Iwai |
f0a979 |
struct wacom_led *wacom_led_next(struct wacom *wacom, struct wacom_led *cur);
|
|
Takashi Iwai |
f0a979 |
int wacom_equivalent_usage(int usage);
|
|
Takashi Iwai |
f0a979 |
int wacom_initialize_leds(struct wacom *wacom);
|
|
Takashi Iwai |
f0a979 |
+void wacom_idleprox_timeout(struct timer_list *list);
|
|
Takashi Iwai |
f0a979 |
#endif
|
|
Takashi Iwai |
f0a979 |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
|
|
Takashi Iwai |
f0a979 |
index 98384b911288..194a2e327591 100644
|
|
Takashi Iwai |
f0a979 |
--- a/drivers/hid/wacom_sys.c
|
|
Takashi Iwai |
f0a979 |
+++ b/drivers/hid/wacom_sys.c
|
|
Takashi Iwai |
f0a979 |
@@ -2781,6 +2781,7 @@ static int wacom_probe(struct hid_device *hdev,
|
|
Takashi Iwai |
f0a979 |
INIT_WORK(&wacom->battery_work, wacom_battery_work);
|
|
Takashi Iwai |
f0a979 |
INIT_WORK(&wacom->remote_work, wacom_remote_work);
|
|
Takashi Iwai |
f0a979 |
INIT_WORK(&wacom->mode_change_work, wacom_mode_change_work);
|
|
Takashi Iwai |
f0a979 |
+ timer_setup(&wacom->idleprox_timer, &wacom_idleprox_timeout, TIMER_DEFERRABLE);
|
|
Takashi Iwai |
f0a979 |
|
|
Takashi Iwai |
f0a979 |
/* ask for the report descriptor to be loaded by HID */
|
|
Takashi Iwai |
f0a979 |
error = hid_parse(hdev);
|
|
Takashi Iwai |
f0a979 |
@@ -2821,6 +2822,7 @@ static void wacom_remove(struct hid_device *hdev)
|
|
Takashi Iwai |
f0a979 |
cancel_work_sync(&wacom->battery_work);
|
|
Takashi Iwai |
f0a979 |
cancel_work_sync(&wacom->remote_work);
|
|
Takashi Iwai |
f0a979 |
cancel_work_sync(&wacom->mode_change_work);
|
|
Takashi Iwai |
f0a979 |
+ del_timer_sync(&wacom->idleprox_timer);
|
|
Takashi Iwai |
f0a979 |
if (hdev->bus == BUS_BLUETOOTH)
|
|
Takashi Iwai |
f0a979 |
device_remove_file(&hdev->dev, &dev_attr_speed);
|
|
Takashi Iwai |
f0a979 |
|
|
Takashi Iwai |
f0a979 |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
|
|
Takashi Iwai |
f0a979 |
index f8cc4bb3e3a7..d049239256a2 100644
|
|
Takashi Iwai |
f0a979 |
--- a/drivers/hid/wacom_wac.c
|
|
Takashi Iwai |
f0a979 |
+++ b/drivers/hid/wacom_wac.c
|
|
Takashi Iwai |
f0a979 |
@@ -11,6 +11,7 @@
|
|
Takashi Iwai |
f0a979 |
#include "wacom_wac.h"
|
|
Takashi Iwai |
f0a979 |
#include "wacom.h"
|
|
Takashi Iwai |
f0a979 |
#include <linux/input/mt.h>
|
|
Takashi Iwai |
f0a979 |
+#include <linux/jiffies.h>
|
|
Takashi Iwai |
f0a979 |
|
|
Takashi Iwai |
f0a979 |
/* resolution for penabled devices */
|
|
Takashi Iwai |
f0a979 |
#define WACOM_PL_RES 20
|
|
Takashi Iwai |
f0a979 |
@@ -41,6 +42,43 @@ static int wacom_numbered_button_to_key(int n);
|
|
Takashi Iwai |
f0a979 |
|
|
Takashi Iwai |
f0a979 |
static void wacom_update_led(struct wacom *wacom, int button_count, int mask,
|
|
Takashi Iwai |
f0a979 |
int group);
|
|
Takashi Iwai |
f0a979 |
+
|
|
Takashi Iwai |
f0a979 |
+static void wacom_force_proxout(struct wacom_wac *wacom_wac)
|
|
Takashi Iwai |
f0a979 |
+{
|
|
Takashi Iwai |
f0a979 |
+ struct input_dev *input = wacom_wac->pen_input;
|
|
Takashi Iwai |
f0a979 |
+
|
|
Takashi Iwai |
f0a979 |
+ wacom_wac->shared->stylus_in_proximity = 0;
|
|
Takashi Iwai |
f0a979 |
+
|
|
Takashi Iwai |
f0a979 |
+ input_report_key(input, BTN_TOUCH, 0);
|
|
Takashi Iwai |
f0a979 |
+ input_report_key(input, BTN_STYLUS, 0);
|
|
Takashi Iwai |
f0a979 |
+ input_report_key(input, BTN_STYLUS2, 0);
|
|
Takashi Iwai |
f0a979 |
+ input_report_key(input, BTN_STYLUS3, 0);
|
|
Takashi Iwai |
f0a979 |
+ input_report_key(input, wacom_wac->tool[0], 0);
|
|
Takashi Iwai |
f0a979 |
+ if (wacom_wac->serial[0]) {
|
|
Takashi Iwai |
f0a979 |
+ input_report_abs(input, ABS_MISC, 0);
|
|
Takashi Iwai |
f0a979 |
+ }
|
|
Takashi Iwai |
f0a979 |
+ input_report_abs(input, ABS_PRESSURE, 0);
|
|
Takashi Iwai |
f0a979 |
+
|
|
Takashi Iwai |
f0a979 |
+ wacom_wac->tool[0] = 0;
|
|
Takashi Iwai |
f0a979 |
+ wacom_wac->id[0] = 0;
|
|
Takashi Iwai |
f0a979 |
+ wacom_wac->serial[0] = 0;
|
|
Takashi Iwai |
f0a979 |
+
|
|
Takashi Iwai |
f0a979 |
+ input_sync(input);
|
|
Takashi Iwai |
f0a979 |
+}
|
|
Takashi Iwai |
f0a979 |
+
|
|
Takashi Iwai |
f0a979 |
+void wacom_idleprox_timeout(struct timer_list *list)
|
|
Takashi Iwai |
f0a979 |
+{
|
|
Takashi Iwai |
f0a979 |
+ struct wacom *wacom = from_timer(wacom, list, idleprox_timer);
|
|
Takashi Iwai |
f0a979 |
+ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
|
|
Takashi Iwai |
f0a979 |
+
|
|
Takashi Iwai |
f0a979 |
+ if (!wacom_wac->hid_data.sense_state) {
|
|
Takashi Iwai |
f0a979 |
+ return;
|
|
Takashi Iwai |
f0a979 |
+ }
|
|
Takashi Iwai |
f0a979 |
+
|
|
Takashi Iwai |
f0a979 |
+ hid_warn(wacom->hdev, "%s: tool appears to be hung in-prox. forcing it out.\n", __func__);
|
|
Takashi Iwai |
f0a979 |
+ wacom_force_proxout(wacom_wac);
|
|
Takashi Iwai |
f0a979 |
+}
|
|
Takashi Iwai |
f0a979 |
+
|
|
Takashi Iwai |
f0a979 |
/*
|
|
Takashi Iwai |
f0a979 |
* Percent of battery capacity for Graphire.
|
|
Takashi Iwai |
f0a979 |
* 8th value means AC online and show 100% capacity.
|
|
Takashi Iwai |
f0a979 |
@@ -2329,6 +2367,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
|
|
Takashi Iwai |
f0a979 |
value = field->logical_maximum - value;
|
|
Takashi Iwai |
f0a979 |
break;
|
|
Takashi Iwai |
f0a979 |
case HID_DG_INRANGE:
|
|
Takashi Iwai |
f0a979 |
+ mod_timer(&wacom->idleprox_timer, jiffies + msecs_to_jiffies(100));
|
|
Takashi Iwai |
f0a979 |
wacom_wac->hid_data.inrange_state = value;
|
|
Takashi Iwai |
f0a979 |
if (!(features->quirks & WACOM_QUIRK_SENSE))
|
|
Takashi Iwai |
f0a979 |
wacom_wac->hid_data.sense_state = value;
|
|
Takashi Iwai |
f0a979 |
--
|
|
Takashi Iwai |
f0a979 |
2.35.3
|
|
Takashi Iwai |
f0a979 |
|