* [PATCH v2] platform/x86: asus-wmi: fix camera key led on Zenbook S14
@ 2026-04-09 23:45 José Guilherme de Castro Rodrigues
2026-04-28 8:22 ` Ilpo Järvinen
0 siblings, 1 reply; 3+ messages in thread
From: José Guilherme de Castro Rodrigues @ 2026-04-09 23:45 UTC (permalink / raw)
To: Corentin Chary, Luke D. Jones, Denis Benato, Hans de Goede,
Ilpo Järvinen
Cc: José Guilherme de Castro Rodrigues, platform-driver-x86,
linux-kernel
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.
Tested on an ASUS Zenbook S14 with BIOS version UX5406SA.309.
Signed-off-by: José Guilherme de Castro Rodrigues <jose.guilherme.cr.bh@gmail.com>
---
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 */
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2] platform/x86: asus-wmi: fix camera key led on Zenbook S14
2026-04-09 23:45 [PATCH v2] platform/x86: asus-wmi: fix camera key led on Zenbook S14 José Guilherme de Castro Rodrigues
@ 2026-04-28 8:22 ` Ilpo Järvinen
2026-04-28 23:20 ` José Guilherme de Castro Rodrigues
0 siblings, 1 reply; 3+ messages in thread
From: Ilpo Järvinen @ 2026-04-28 8:22 UTC (permalink / raw)
To: José Guilherme de Castro Rodrigues
Cc: Corentin Chary, Luke D. Jones, Denis Benato, Hans de Goede,
platform-driver-x86, LKML
[-- Attachment #1: Type: text/plain, Size: 4447 bytes --]
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@gmail.com>
> ---
> 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.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2] platform/x86: asus-wmi: fix camera key led on Zenbook S14
2026-04-28 8:22 ` Ilpo Järvinen
@ 2026-04-28 23:20 ` José Guilherme de Castro Rodrigues
0 siblings, 0 replies; 3+ messages in thread
From: José Guilherme de Castro Rodrigues @ 2026-04-28 23:20 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: Corentin Chary, Luke D. Jones, Denis Benato, Hans de Goede,
platform-driver-x86, LKML
Thanks for the comment, Ilpo.
On Tue, Apr 28, 2026 at 11:22:20AM +0300, Ilpo Järvinen wrote:
> While I believe you are "correct" that userspace won't see a thing, is
> this really correct way to implement support for this device?
At first, I created another sysfs attribute that basically duplicated
the logic that is used for the "asus::camera" attribute, with the
exception being the value that was written to it, of course. I noticed,
however, that calling asus_wmi_set_devstate() had not effect on the LED
state. The LED only toggled when I read the attribute, which then called
asus_wmi_get_devstate().
I don't know if this is a quirk for this device, or if all devices that
expose ASUS_WMI_DEVID_CAMERA_LED_NEG behave the same, but the LED is not
toggled until I call asus_wmi_get_devstate() - be it when detecting a
key press (hardware change) or after the sysfs attribute is written to
(software change).
Since in this case the LED state would not change after a write to the
sysfs attribute, I went in the "do not make it visible to userspace at
all" direction.
> 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?
Yes, I think what you said makes sense as it would give userspace access
to the resource without creating a new attribute.
In this case, I feel like a good option would be to gate the camera led
initialization by both IDs, and assume that the write and read works as
they probably should for CAMERA_LED_NEG. Then, somehow add a quirk for
this specific device that performs a read when the key is pressed, and
right after the sysfs attribute is written to. If we can confirm that
this behavior is expected when writing to CAMERA_LED_NEG, it might not
need to be a quirk. Unfortunately, I am not able to try this on other
devices.
What do you think about it?
Best regards,
José Rodrigues
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-04-28 23:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-09 23:45 [PATCH v2] platform/x86: asus-wmi: fix camera key led on Zenbook S14 José Guilherme de Castro Rodrigues
2026-04-28 8:22 ` Ilpo Järvinen
2026-04-28 23:20 ` José Guilherme de Castro Rodrigues
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox