[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1326eb84-e952-43f5-b505-99b9a784c593@gmail.com>
Date: Wed, 26 Nov 2025 21:19:21 +0100
From: Denis Benato <benato.denis96@...il.com>
To: Antheas Kapenekakis <lkml@...heas.dev>,
platform-driver-x86@...r.kernel.org, linux-input@...r.kernel.org
Cc: linux-kernel@...r.kernel.org, Jiri Kosina <jikos@...nel.org>,
Benjamin Tissoires <bentiss@...nel.org>,
Corentin Chary <corentin.chary@...il.com>, "Luke D . Jones"
<luke@...nes.dev>, Hans de Goede <hansg@...nel.org>,
Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
Subject: Re: [PATCH v10 08/11] HID: asus: listen to the asus-wmi brightness
device instead of creating one
On 11/22/25 12:00, Antheas Kapenekakis wrote:
> 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: Denis Benato <benato.denis96@...il.com>
> Reviewed-by: Luke D. Jones <luke@...nes.dev>
> Signed-off-by: Antheas Kapenekakis <lkml@...heas.dev>
> ---
> drivers/hid/hid-asus.c | 65 +++++++-----------------------------------
> 1 file changed, 10 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
> index 461b0f8efdfb..475e34187326 100644
> --- a/drivers/hid/hid-asus.c
> +++ b/drivers/hid/hid-asus.c
> @@ -27,7 +27,6 @@
> #include <linux/hid.h>
> #include <linux/module.h>
> #include <linux/platform_data/x86/asus-wmi.h>
> -#include <linux/platform_data/x86/asus-wmi-leds-ids.h>
> #include <linux/input/mt.h>
> #include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */
> #include <linux/power_supply.h>
> @@ -103,7 +102,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
> #define TRKID_SGN ((TRKID_MAX + 1) >> 1)
>
> struct asus_kbd_leds {
> - struct led_classdev cdev;
> + struct asus_hid_listener listener;
> struct hid_device *hdev;
> struct work_struct work;
> unsigned int brightness;
> @@ -493,11 +492,11 @@ static void asus_schedule_work(struct asus_kbd_leds *led)
> spin_unlock_irqrestore(&led->lock, flags);
> }
>
> -static void asus_kbd_backlight_set(struct led_classdev *led_cdev,
> - enum led_brightness brightness)
> +static void asus_kbd_backlight_set(struct asus_hid_listener *listener,
> + int brightness)
> {
> - struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds,
> - cdev);
> + struct asus_kbd_leds *led = container_of(listener, struct asus_kbd_leds,
> + listener);
> unsigned long flags;
>
> spin_lock_irqsave(&led->lock, flags);
> @@ -507,20 +506,6 @@ static void asus_kbd_backlight_set(struct led_classdev *led_cdev,
> asus_schedule_work(led);
> }
>
> -static enum led_brightness asus_kbd_backlight_get(struct led_classdev *led_cdev)
> -{
> - struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds,
> - cdev);
> - enum led_brightness brightness;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&led->lock, flags);
> - brightness = led->brightness;
> - spin_unlock_irqrestore(&led->lock, flags);
> -
> - return brightness;
> -}
> -
> static void asus_kbd_backlight_work(struct work_struct *work)
> {
> struct asus_kbd_leds *led = container_of(work, struct asus_kbd_leds, work);
> @@ -537,34 +522,6 @@ static void asus_kbd_backlight_work(struct work_struct *work)
> hid_err(led->hdev, "Asus failed to set keyboard backlight: %d\n", ret);
> }
>
> -/* WMI-based keyboard backlight LED control (via asus-wmi driver) takes
> - * precedence. We only activate HID-based backlight control when the
> - * WMI control is not available.
> - */
> -static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
> -{
> - struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
> - u32 value;
> - int ret;
> -
> - if (!IS_ENABLED(CONFIG_ASUS_WMI))
> - return false;
> -
> - if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
> - dmi_check_system(asus_use_hid_led_dmi_ids)) {
> - hid_info(hdev, "using HID for asus::kbd_backlight\n");
> - return false;
> - }
> -
> - ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
> - ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
> - hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
> - if (ret)
> - return false;
> -
> - return !!(value & ASUS_WMI_DSTS_PRESENCE_BIT);
> -}
> -
> /*
> * We don't care about any other part of the string except the version section.
> * Example strings: FGA80100.RC72LA.312_T01, FGA80100.RC71LS.318_T01
> @@ -709,14 +666,11 @@ static int asus_kbd_register_leds(struct hid_device *hdev)
> drvdata->kbd_backlight->removed = false;
> drvdata->kbd_backlight->brightness = 0;
> drvdata->kbd_backlight->hdev = hdev;
> - drvdata->kbd_backlight->cdev.name = "asus::kbd_backlight";
> - drvdata->kbd_backlight->cdev.max_brightness = 3;
> - drvdata->kbd_backlight->cdev.brightness_set = asus_kbd_backlight_set;
> - drvdata->kbd_backlight->cdev.brightness_get = asus_kbd_backlight_get;
> + drvdata->kbd_backlight->listener.brightness_set = asus_kbd_backlight_set;
> INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_backlight_work);
> spin_lock_init(&drvdata->kbd_backlight->lock);
>
> - ret = devm_led_classdev_register(&hdev->dev, &drvdata->kbd_backlight->cdev);
> + ret = asus_hid_register_listener(&drvdata->kbd_backlight->listener);
> if (ret < 0) {
> /* No need to have this still around */
> devm_kfree(&hdev->dev, drvdata->kbd_backlight);
> @@ -1105,7 +1059,7 @@ static int __maybe_unused asus_resume(struct hid_device *hdev) {
>
> if (drvdata->kbd_backlight) {
> const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4,
> - drvdata->kbd_backlight->cdev.brightness };
> + drvdata->kbd_backlight->brightness };
> ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
> if (ret < 0) {
> hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret);
> @@ -1231,7 +1185,6 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
> }
>
> if (is_vendor && (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) &&
> - !asus_kbd_wmi_led_control_present(hdev) &&
> asus_kbd_register_leds(hdev))
> hid_warn(hdev, "Failed to initialize backlight.\n");
>
> @@ -1278,6 +1231,8 @@ static void asus_remove(struct hid_device *hdev)
> unsigned long flags;
>
> if (drvdata->kbd_backlight) {
> + asus_hid_unregister_listener(&drvdata->kbd_backlight->listener);
> +
> spin_lock_irqsave(&drvdata->kbd_backlight->lock, flags);
> drvdata->kbd_backlight->removed = true;
> spin_unlock_irqrestore(&drvdata->kbd_backlight->lock, flags);
Powered by blists - more mailing lists