Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Hans de Goede and committed by
Jiri Kosina
227312b4 487b23af

+12 -3
+11 -3
drivers/hid/hid-input.c
··· 354 354 #define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */ 355 355 #define HID_BATTERY_QUIRK_IGNORE (1 << 2) /* completely ignore the battery */ 356 356 #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 */ 357 358 358 359 static const struct hid_device_id hid_battery_quirks[] = { 359 360 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, ··· 399 398 * Elan HID touchscreens seem to all report a non present battery, 400 399 * set HID_BATTERY_QUIRK_IGNORE for all Elan I2C and USB HID devices. 401 400 */ 402 - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE }, 403 - { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE }, 401 + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_DYNAMIC }, 402 + { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_DYNAMIC }, 404 403 {} 405 404 }; 406 405 ··· 457 456 int ret = 0; 458 457 459 458 switch (prop) { 460 - case POWER_SUPPLY_PROP_PRESENT: 461 459 case POWER_SUPPLY_PROP_ONLINE: 462 460 val->intval = 1; 461 + break; 462 + 463 + case POWER_SUPPLY_PROP_PRESENT: 464 + val->intval = dev->battery_present; 463 465 break; 464 466 465 467 case POWER_SUPPLY_PROP_CAPACITY: ··· 577 573 if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY) 578 574 dev->battery_avoid_query = true; 579 575 576 + dev->battery_present = (quirks & HID_BATTERY_QUIRK_DYNAMIC) ? false : true; 577 + 580 578 dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg); 581 579 if (IS_ERR(dev->battery)) { 582 580 error = PTR_ERR(dev->battery); ··· 634 628 return; 635 629 636 630 if (hidinput_update_battery_charge_status(dev, usage, value)) { 631 + dev->battery_present = true; 637 632 power_supply_changed(dev->battery); 638 633 return; 639 634 } ··· 650 643 if (dev->battery_status != HID_BATTERY_REPORTED || 651 644 capacity != dev->battery_capacity || 652 645 ktime_after(ktime_get_coarse(), dev->battery_ratelimit_time)) { 646 + dev->battery_present = true; 653 647 dev->battery_capacity = capacity; 654 648 dev->battery_status = HID_BATTERY_REPORTED; 655 649 dev->battery_ratelimit_time =
+1
include/linux/hid.h
··· 682 682 __s32 battery_charge_status; 683 683 enum hid_battery_status battery_status; 684 684 bool battery_avoid_query; 685 + bool battery_present; 685 686 ktime_t battery_ratelimit_time; 686 687 #endif 687 688