From fd2a9b29dc9c4c35def91d5d1c5b470843539de6 Mon Sep 17 00:00:00 2001 From: Tatsunosuke Tobita Date: Wed, 15 Nov 2023 08:57:29 +0900 Subject: HID: wacom: Remove AES power_supply after extended inactivity Even if a user does not use their AES pen for an extended period, the battery power supply attributes continue to exist. This results in the desktop showing battery status for a pen that is no longer in use and which may in fact be in a different state (e.g. the user may be charging the pen). To avoid confusion and ensure userspace has an accurate view of the battery state, this patch automatically removes the power_supply after 30 minutes of inactivity. Signed-off-by: Tatsunosuke Tobita Reviewed-by: Jason Gerecke Reviewed-by: Aaron Skomra Reviewed-by: Josh Dickens Link: https://lore.kernel.org/r/20231114235729.6867-1-tatsunosuke.wacom@gmail.com Signed-off-by: Benjamin Tissoires --- drivers/hid/wacom.h | 1 + drivers/hid/wacom_sys.c | 8 ++++++++ drivers/hid/wacom_wac.c | 12 +++++++++++- drivers/hid/wacom_wac.h | 1 + 4 files changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 166a76c9bcad..77c5fb26cd14 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -164,6 +164,7 @@ struct wacom { struct work_struct battery_work; struct work_struct remote_work; struct delayed_work init_work; + struct delayed_work aes_battery_work; struct wacom_remote *remote; struct work_struct mode_change_work; struct timer_list idleprox_timer; diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 3f704b8072e8..b613f11ed949 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1813,6 +1813,13 @@ static void wacom_destroy_battery(struct wacom *wacom) } } +static void wacom_aes_battery_handler(struct work_struct *work) +{ + struct wacom *wacom = container_of(work, struct wacom, aes_battery_work.work); + + wacom_destroy_battery(wacom); +} + static ssize_t wacom_show_speed(struct device *dev, struct device_attribute *attr, char *buf) @@ -2794,6 +2801,7 @@ static int wacom_probe(struct hid_device *hdev, mutex_init(&wacom->lock); INIT_DELAYED_WORK(&wacom->init_work, wacom_init_work); + INIT_DELAYED_WORK(&wacom->aes_battery_work, wacom_aes_battery_handler); INIT_WORK(&wacom->wireless_work, wacom_wireless_work); INIT_WORK(&wacom->battery_work, wacom_battery_work); INIT_WORK(&wacom->remote_work, wacom_remote_work); diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 471db78dbbf0..c205198ded11 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2528,11 +2528,12 @@ static void wacom_wac_pen_report(struct hid_device *hdev, struct input_dev *input = wacom_wac->pen_input; bool range = wacom_wac->hid_data.inrange_state; bool sense = wacom_wac->hid_data.sense_state; + bool entering_range = !wacom_wac->tool[0] && range; if (wacom_wac->is_invalid_bt_frame) return; - if (!wacom_wac->tool[0] && range) { /* first in range */ + if (entering_range) { /* first in range */ /* Going into range select tool */ if (wacom_wac->hid_data.invert_state) wacom_wac->tool[0] = BTN_TOOL_RUBBER; @@ -2583,6 +2584,15 @@ static void wacom_wac_pen_report(struct hid_device *hdev, input_sync(input); } + /* Handle AES battery timeout behavior */ + if (wacom_wac->features.quirks & WACOM_QUIRK_AESPEN) { + if (entering_range) + cancel_delayed_work(&wacom->aes_battery_work); + if (!sense) + schedule_delayed_work(&wacom->aes_battery_work, + msecs_to_jiffies(WACOM_AES_BATTERY_TIMEOUT)); + } + if (!sense) { wacom_wac->tool[0] = 0; wacom_wac->id[0] = 0; diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 57e185f18d53..e63b1e806e34 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -14,6 +14,7 @@ #define WACOM_MAX_REMOTES 5 #define WACOM_STATUS_UNKNOWN 255 #define WACOM_REMOTE_BATTERY_TIMEOUT 21000000000ll +#define WACOM_AES_BATTERY_TIMEOUT 1800000 /* packet length for individual models */ #define WACOM_PKGLEN_BBFUN 9 -- cgit v1.2.3