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: asus: listen to the asus-wmi brightness device instead of creating one

Some ROG laptops expose multiple interfaces for controlling the
keyboard/RGB brightness. This creates a name conflict under
asus::kbd_brightness, where the second device ends up being
named asus::kbd_brightness_1 and they are both broken.

Therefore, register a listener to the asus-wmi brightness device
instead of creating a new one.

Reviewed-by: Luke D. Jones <luke@ljones.dev>
Reviewed-by: Benjamin Tissoires <bentiss@kernel.org>
Reviewed-by: Denis Benato <benato.denis96@gmail.com>
Acked-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
Link: https://patch.msgid.link/20260122075044.5070-9-lkml@antheas.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Antheas Kapenekakis and committed by
Ilpo Järvinen
b34b5945 fac55d29

+10 -55
+10 -55
drivers/hid/hid-asus.c
··· 27 27 #include <linux/hid.h> 28 28 #include <linux/module.h> 29 29 #include <linux/platform_data/x86/asus-wmi.h> 30 - #include <linux/platform_data/x86/asus-wmi-leds-ids.h> 31 30 #include <linux/input/mt.h> 32 31 #include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */ 33 32 #include <linux/power_supply.h> ··· 102 103 #define TRKID_SGN ((TRKID_MAX + 1) >> 1) 103 104 104 105 struct asus_kbd_leds { 105 - struct led_classdev cdev; 106 + struct asus_hid_listener listener; 106 107 struct hid_device *hdev; 107 108 struct work_struct work; 108 109 unsigned int brightness; ··· 494 495 spin_unlock_irqrestore(&led->lock, flags); 495 496 } 496 497 497 - static void asus_kbd_backlight_set(struct led_classdev *led_cdev, 498 - enum led_brightness brightness) 498 + static void asus_kbd_backlight_set(struct asus_hid_listener *listener, 499 + int brightness) 499 500 { 500 - struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, 501 - cdev); 501 + struct asus_kbd_leds *led = container_of(listener, struct asus_kbd_leds, 502 + listener); 502 503 unsigned long flags; 503 504 504 505 spin_lock_irqsave(&led->lock, flags); ··· 506 507 spin_unlock_irqrestore(&led->lock, flags); 507 508 508 509 asus_schedule_work(led); 509 - } 510 - 511 - static enum led_brightness asus_kbd_backlight_get(struct led_classdev *led_cdev) 512 - { 513 - struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, 514 - cdev); 515 - enum led_brightness brightness; 516 - unsigned long flags; 517 - 518 - spin_lock_irqsave(&led->lock, flags); 519 - brightness = led->brightness; 520 - spin_unlock_irqrestore(&led->lock, flags); 521 - 522 - return brightness; 523 510 } 524 511 525 512 static void asus_kbd_backlight_work(struct work_struct *work) ··· 522 537 ret = asus_kbd_set_report(led->hdev, buf, sizeof(buf)); 523 538 if (ret < 0) 524 539 hid_err(led->hdev, "Asus failed to set keyboard backlight: %d\n", ret); 525 - } 526 - 527 - /* WMI-based keyboard backlight LED control (via asus-wmi driver) takes 528 - * precedence. We only activate HID-based backlight control when the 529 - * WMI control is not available. 530 - */ 531 - static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev) 532 - { 533 - struct asus_drvdata *drvdata = hid_get_drvdata(hdev); 534 - u32 value; 535 - int ret; 536 - 537 - if (!IS_ENABLED(CONFIG_ASUS_WMI)) 538 - return false; 539 - 540 - if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD && 541 - dmi_check_system(asus_use_hid_led_dmi_ids)) { 542 - hid_info(hdev, "using HID for asus::kbd_backlight\n"); 543 - return false; 544 - } 545 - 546 - ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 547 - ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value); 548 - hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value); 549 - if (ret) 550 - return false; 551 - 552 - return !!(value & ASUS_WMI_DSTS_PRESENCE_BIT); 553 540 } 554 541 555 542 /* ··· 663 706 drvdata->kbd_backlight->removed = false; 664 707 drvdata->kbd_backlight->brightness = 0; 665 708 drvdata->kbd_backlight->hdev = hdev; 666 - drvdata->kbd_backlight->cdev.name = "asus::kbd_backlight"; 667 - drvdata->kbd_backlight->cdev.max_brightness = 3; 668 - drvdata->kbd_backlight->cdev.brightness_set = asus_kbd_backlight_set; 669 - drvdata->kbd_backlight->cdev.brightness_get = asus_kbd_backlight_get; 709 + drvdata->kbd_backlight->listener.brightness_set = asus_kbd_backlight_set; 670 710 INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_backlight_work); 671 711 spin_lock_init(&drvdata->kbd_backlight->lock); 672 712 673 - ret = devm_led_classdev_register(&hdev->dev, &drvdata->kbd_backlight->cdev); 713 + ret = asus_hid_register_listener(&drvdata->kbd_backlight->listener); 674 714 if (ret < 0) { 675 715 /* No need to have this still around */ 676 716 devm_kfree(&hdev->dev, drvdata->kbd_backlight); ··· 1056 1102 1057 1103 if (drvdata->kbd_backlight) { 1058 1104 const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, 1059 - drvdata->kbd_backlight->cdev.brightness }; 1105 + drvdata->kbd_backlight->brightness }; 1060 1106 ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); 1061 1107 if (ret < 0) { 1062 1108 hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret); ··· 1182 1228 } 1183 1229 1184 1230 if (is_vendor && (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) && 1185 - !asus_kbd_wmi_led_control_present(hdev) && 1186 1231 asus_kbd_register_leds(hdev)) 1187 1232 hid_warn(hdev, "Failed to initialize backlight.\n"); 1188 1233 ··· 1228 1275 unsigned long flags; 1229 1276 1230 1277 if (drvdata->kbd_backlight) { 1278 + asus_hid_unregister_listener(&drvdata->kbd_backlight->listener); 1279 + 1231 1280 spin_lock_irqsave(&drvdata->kbd_backlight->lock, flags); 1232 1281 drvdata->kbd_backlight->removed = true; 1233 1282 spin_unlock_irqrestore(&drvdata->kbd_backlight->lock, flags);