Re: [PATCH] platform/x86: asus-armoury: fix mini-LED mode get/set on MODE2 devices

From: Denis Benato

Date: Fri Jun 12 2026 - 08:03:56 EST


This has no business being here. I used *.patch to send and missed this. Apologies!

On 6/12/26 13:56, Denis Benato wrote:
> From: Ahmed Yaseen <yaseen@xxxxxxxxx>
>
> The mini-LED current_value attribute does not work on devices that use
> ASUS_WMI_DEVID_MINI_LED_MODE2 (2024 and newer models).
>
> Reading is broken: mini_led_mode_current_value_show() fetches the mode
> from the device but then decodes a literal 0 instead of the value it
> just read:
>
> mode = FIELD_GET(ASUS_MINI_LED_MODE_MASK, 0);
>
> So mode is always 0, and the attribute always reports the same thing
> regardless of the real hardware state.
>
> Writing is broken too. The number a user writes is an index; the value
> the firmware actually wants is looked up from that index in
> mini_led_mode_map[]. mini_led_mode_current_value_store() skips that
> lookup and passes the raw index straight to armoury_attr_uint_store().
> On 2024 devices the firmware numbers its modes differently from the
> index, so some writes are rejected with -EINVAL and the rest send the
> wrong mode to the hardware.
>
> Fix both paths: decode the value actually read from the device when
> reading, and look up the firmware value before sending it when
> writing. Older (MODE1) devices were unaffected because there the index
> and the firmware value are the same.
>
> Fixes: f99eb098090e ("platform/x86: asus-armoury: move existing tunings to asus-armoury module")
> Signed-off-by: Ahmed Yaseen <yaseen@xxxxxxxxx>
> ---
> drivers/platform/x86/asus-armoury.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c
> index 5b0987ccc270..495dc1e31d40 100644
> --- a/drivers/platform/x86/asus-armoury.c
> +++ b/drivers/platform/x86/asus-armoury.c
> @@ -370,7 +370,7 @@ static ssize_t mini_led_mode_current_value_show(struct kobject *kobj,
> if (err)
> return err;
>
> - mode = FIELD_GET(ASUS_MINI_LED_MODE_MASK, 0);
> + mode = FIELD_GET(ASUS_MINI_LED_MODE_MASK, mode);
>
> for (i = 0; i < mini_led_mode_map_size; i++)
> if (mode == mini_led_mode_map[i])
> @@ -386,6 +386,7 @@ static ssize_t mini_led_mode_current_value_store(struct kobject *kobj,
> {
> u32 *mini_led_mode_map;
> size_t mini_led_mode_map_size;
> + char mapped_value[12];
> u32 mode;
> int err;
>
> @@ -414,9 +415,16 @@ static ssize_t mini_led_mode_current_value_store(struct kobject *kobj,
> return -ENODEV;
> }
>
> - return armoury_attr_uint_store(kobj, attr, buf, count,
> - 0, mini_led_mode_map[mode],
> - NULL, asus_armoury.mini_led_dev_id);
> + /*
> + * armoury_attr_uint_store() parses and sends the value from the
> + * passed buffer; hand it the mapped firmware value so the device
> + * receives the translated mode instead of the raw index.
> + */
> + snprintf(mapped_value, sizeof(mapped_value), "%u", mini_led_mode_map[mode]);
> +
> + return armoury_attr_uint_store(kobj, attr, mapped_value, count, 0,
> + mini_led_mode_map[mode], NULL,
> + asus_armoury.mini_led_dev_id);
> }
>
> static ssize_t mini_led_mode_possible_values_show(struct kobject *kobj,