Skip to content

Commit 227312b

Browse files
Hans de GoedeJiri Kosina
authored andcommitted
HID: input: Add HID_BATTERY_QUIRK_DYNAMIC for Elan touchscreens
Elan touchscreens have a HID-battery device for the stylus which is always there even if there is no stylus. This is causing upower to report an empty battery for the stylus and some desktop-environments will show a notification about this, which is quite annoying. Because of this the HID-battery is being ignored on all Elan I2c and USB touchscreens, but this causes there to be no battery reporting for the stylus at all. This adds a new HID_BATTERY_QUIRK_DYNAMIC and uses these for the Elan touchscreens. This new quirks causes the present value of the battery to start at 0, which will make userspace ignore it and only sets present to 1 after receiving a battery input report which only happens when the stylus gets in range. Reported-by: ggrundik@gmail.com Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221118 Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent 487b23a commit 227312b

2 files changed

Lines changed: 12 additions & 3 deletions

File tree

drivers/hid/hid-input.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ static enum power_supply_property hidinput_battery_props[] = {
354354
#define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */
355355
#define HID_BATTERY_QUIRK_IGNORE (1 << 2) /* completely ignore the battery */
356356
#define HID_BATTERY_QUIRK_AVOID_QUERY (1 << 3) /* do not query the battery */
357+
#define HID_BATTERY_QUIRK_DYNAMIC (1 << 4) /* report present only after life signs */
357358

358359
static const struct hid_device_id hid_battery_quirks[] = {
359360
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
@@ -398,8 +399,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
398399
* Elan HID touchscreens seem to all report a non present battery,
399400
* set HID_BATTERY_QUIRK_IGNORE for all Elan I2C and USB HID devices.
400401
*/
401-
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE },
402-
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE },
402+
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_DYNAMIC },
403+
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_DYNAMIC },
403404
{}
404405
};
405406

@@ -456,11 +457,14 @@ static int hidinput_get_battery_property(struct power_supply *psy,
456457
int ret = 0;
457458

458459
switch (prop) {
459-
case POWER_SUPPLY_PROP_PRESENT:
460460
case POWER_SUPPLY_PROP_ONLINE:
461461
val->intval = 1;
462462
break;
463463

464+
case POWER_SUPPLY_PROP_PRESENT:
465+
val->intval = dev->battery_present;
466+
break;
467+
464468
case POWER_SUPPLY_PROP_CAPACITY:
465469
if (dev->battery_status != HID_BATTERY_REPORTED &&
466470
!dev->battery_avoid_query) {
@@ -573,6 +577,8 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
573577
if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY)
574578
dev->battery_avoid_query = true;
575579

580+
dev->battery_present = (quirks & HID_BATTERY_QUIRK_DYNAMIC) ? false : true;
581+
576582
dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
577583
if (IS_ERR(dev->battery)) {
578584
error = PTR_ERR(dev->battery);
@@ -628,6 +634,7 @@ static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
628634
return;
629635

630636
if (hidinput_update_battery_charge_status(dev, usage, value)) {
637+
dev->battery_present = true;
631638
power_supply_changed(dev->battery);
632639
return;
633640
}
@@ -643,6 +650,7 @@ static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
643650
if (dev->battery_status != HID_BATTERY_REPORTED ||
644651
capacity != dev->battery_capacity ||
645652
ktime_after(ktime_get_coarse(), dev->battery_ratelimit_time)) {
653+
dev->battery_present = true;
646654
dev->battery_capacity = capacity;
647655
dev->battery_status = HID_BATTERY_REPORTED;
648656
dev->battery_ratelimit_time =

include/linux/hid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ struct hid_device {
682682
__s32 battery_charge_status;
683683
enum hid_battery_status battery_status;
684684
bool battery_avoid_query;
685+
bool battery_present;
685686
ktime_t battery_ratelimit_time;
686687
#endif
687688

0 commit comments

Comments
 (0)