Re: [PATCH v2] platform/x86: asus-wmi: fix camera key led on Zenbook S14
From: Ilpo Järvinen
Date: Tue Apr 28 2026 - 04:28:12 EST
On Thu, 9 Apr 2026, José Guilherme de Castro Rodrigues wrote:
> Fix key led not turning on/off when the camera key is pressed. The
> asus_wmi_dev_is_present(ASUS_WMI_DEVID_CAMERA_LED) check fails on
> Zenbook S14, and no sysfs attribute for the camera key led is
> created.
>
> The check succeeds for ASUS_WMI_DEVID_CAMERA_LED_NEG, though,
> and when it is read, the led state is synchronized. By doing a read after
> every key press, the led is guaranteed to stay in sync with the actual
> camera state.
>
> This change is not visible to userspace, as no sysfs attribute for
> ASUS_WMI_DEVID_CAMERA_LED_NEG exists.
While I believe you are "correct" that userspace won't see a thing, is
this really correct way to implement support for this device?
I mean the camera led init in asus_wmi_led_init() is gated by
asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CAMERA_LED) but should that
be gated by either CAMERA_LED or CAMERA_LED_NEG and the related code in
*_camera_led_*() that now only uses ASUS_WMI_DEVID_CAMERA_LED
should use which ever of them is available?
> Tested on an ASUS Zenbook S14 with BIOS version UX5406SA.309.
>
> Signed-off-by: José Guilherme de Castro Rodrigues <jose.guilherme.cr.bh@xxxxxxxxx>
> ---
> Changes in v2:
> - Do not return after triggering the update.
> - Use tabs for indentation on new defines.
> ---
> drivers/platform/x86/asus-wmi.c | 19 +++++++++++++++++++
> include/linux/platform_data/x86/asus-wmi.h | 2 +-
> 2 files changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index 80144c412b90..32d0d4ce60ff 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -70,6 +70,8 @@ module_param(fnlock_default, bool, 0444);
> #define NOTIFY_KBD_TTP 0xae
> #define NOTIFY_LID_FLIP 0xfa
> #define NOTIFY_LID_FLIP_ROG 0xbd
> +#define NOTIFY_CAMERA_TOGGLE_1 0x82
> +#define NOTIFY_CAMERA_TOGGLE_2 0x85
>
> #define ASUS_WMI_FNLOCK_BIOS_DISABLED BIT(0)
>
> @@ -307,6 +309,7 @@ struct asus_wmi {
> u32 kbd_rgb_dev;
> bool kbd_rgb_state_available;
> bool oobe_state_available;
> + bool camera_neg_led_available;
>
> u8 throttle_thermal_policy_mode;
> u32 throttle_thermal_policy_dev;
> @@ -1982,6 +1985,18 @@ static int micmute_led_set(struct led_classdev *led_cdev,
> return err < 0 ? err : 0;
> }
>
> +static bool is_camera_toggle(int code)
> +{
> + return code == NOTIFY_CAMERA_TOGGLE_1 || code == NOTIFY_CAMERA_TOGGLE_2;
> +}
> +
> +static void camera_neg_led_trigger_update(struct asus_wmi *asus)
> +{
> + u32 result;
> +
> + asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_CAMERA_LED_NEG, &result);
> +}
> +
> static enum led_brightness camera_led_get(struct led_classdev *led_cdev)
> {
> struct asus_wmi *asus;
> @@ -4587,6 +4602,9 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
> if (is_display_toggle(code) && asus->driver->quirks->no_display_toggle)
> return;
>
> + if (is_camera_toggle(code) && asus->camera_neg_led_available)
> + camera_neg_led_trigger_update(asus);
> +
> if (!sparse_keymap_report_event(asus->inputdev, code,
> key_value, autorelease))
> pr_info("Unknown key code 0x%x\n", code);
> @@ -5062,6 +5080,7 @@ static int asus_wmi_add(struct platform_device *pdev)
> #endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */
>
> asus->oobe_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_OOBE);
> + asus->camera_neg_led_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CAMERA_LED_NEG);
>
> if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY))
> asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY;
> diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
> index 554f41b827e1..1a9349da6069 100644
> --- a/include/linux/platform_data/x86/asus-wmi.h
> +++ b/include/linux/platform_data/x86/asus-wmi.h
> @@ -56,7 +56,7 @@
> #define ASUS_WMI_DEVID_MICMUTE_LED 0x00040017
>
> /* Disable Camera LED */
> -#define ASUS_WMI_DEVID_CAMERA_LED_NEG 0x00060078 /* 0 = on (unused) */
> +#define ASUS_WMI_DEVID_CAMERA_LED_NEG 0x00060078 /* 0 = on */
> #define ASUS_WMI_DEVID_CAMERA_LED 0x00060079 /* 1 = on */
>
> /* Backlight and Brightness */
>
--
i.