All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] HID: wacom: Force pen out of prox if no events have been received in a while
@ 2022-07-15 23:05 Jason Gerecke
  2022-07-21 11:50 ` Jiri Kosina
  0 siblings, 1 reply; 3+ messages in thread
From: Jason Gerecke @ 2022-07-15 23:05 UTC (permalink / raw)
  To: linux-input, Benjamin Tissoires, Jiri Kosina
  Cc: Ping Cheng, Aaron Armstrong Skomra, Joshua Dickens, Jason Gerecke

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>
---
 drivers/hid/wacom.h     |  3 +++
 drivers/hid/wacom_sys.c |  2 ++
 drivers/hid/wacom_wac.c | 39 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+)

diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
index 203d27d198b8..3f8b24a57014 100644
--- a/drivers/hid/wacom.h
+++ b/drivers/hid/wacom.h
@@ -91,6 +91,7 @@
 #include <linux/leds.h>
 #include <linux/usb/input.h>
 #include <linux/power_supply.h>
+#include <linux/timer.h>
 #include <asm/unaligned.h>
 
 /*
@@ -167,6 +168,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;
@@ -239,4 +241,5 @@ struct wacom_led *wacom_led_find(struct wacom *wacom, unsigned int group,
 struct wacom_led *wacom_led_next(struct wacom *wacom, struct wacom_led *cur);
 int wacom_equivalent_usage(int usage);
 int wacom_initialize_leds(struct wacom *wacom);
+void wacom_idleprox_timeout(struct timer_list *list);
 #endif
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 98384b911288..194a2e327591 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -2781,6 +2781,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);
+	timer_setup(&wacom->idleprox_timer, &wacom_idleprox_timeout, TIMER_DEFERRABLE);
 
 	/* ask for the report descriptor to be loaded by HID */
 	error = hid_parse(hdev);
@@ -2821,6 +2822,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);
 
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;
-- 
2.37.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] HID: wacom: Force pen out of prox if no events have been received in a while
  2022-07-15 23:05 [PATCH] HID: wacom: Force pen out of prox if no events have been received in a while Jason Gerecke
@ 2022-07-21 11:50 ` Jiri Kosina
  2023-05-16 23:20   ` Ping Cheng
  0 siblings, 1 reply; 3+ messages in thread
From: Jiri Kosina @ 2022-07-21 11:50 UTC (permalink / raw)
  To: Jason Gerecke
  Cc: linux-input, Benjamin Tissoires, Ping Cheng,
	Aaron Armstrong Skomra, Joshua Dickens, Jason Gerecke

On Fri, 15 Jul 2022, Jason Gerecke wrote:

> 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>

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH] HID: wacom: Force pen out of prox if no events have been received in a while
  2022-07-21 11:50 ` Jiri Kosina
@ 2023-05-16 23:20   ` Ping Cheng
  0 siblings, 0 replies; 3+ messages in thread
From: Ping Cheng @ 2023-05-16 23:20 UTC (permalink / raw)
  To: stable # v4 . 10

Hi Stable Team,

This patch, ID 94b179052f95c294d83e9c9c34f7833cf3cd4305, can be
applied to stable kernel 4.14 to 5.15 AS IS.

The patch has been merged to stable 6.1 and later. It fixes a missing
proximity out event issue.

Thank you for your support!
Ping

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-05-16 23:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-15 23:05 [PATCH] HID: wacom: Force pen out of prox if no events have been received in a while Jason Gerecke
2022-07-21 11:50 ` Jiri Kosina
2023-05-16 23:20   ` Ping Cheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.