diff options
author | Luke D. Jones <luke@ljones.dev> | 2022-08-26 11:22:51 +1200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2022-08-26 11:48:06 +0200 |
commit | 61f64515299e5f4885093656087ec1c0df8109c5 (patch) | |
tree | cdccc7184bfb7f2ec9534630776845f4e7eac977 /drivers/platform/x86/asus-wmi.c | |
parent | e305a71cea37a64c7558b8b979f6f08f657d0c3d (diff) | |
download | lwn-61f64515299e5f4885093656087ec1c0df8109c5.tar.gz lwn-61f64515299e5f4885093656087ec1c0df8109c5.zip |
platform/x86: asus-wmi: Implement TUF laptop keyboard power states
Adds support for setting various power states of TUF keyboards.
These states are combinations of:
- boot, set if a boot animation is shown on keyboard
- awake, set if the keyboard LEDs are visible while laptop is on
- sleep, set if an animation is displayed while the laptop is suspended
- keyboard (unknown effect)
Adds two sysfs attributes to asus::kbd_backlight:
- kbd_rgb_state
- kbd_rgb_state_index
Signed-off-by: Luke D. Jones <luke@ljones.dev>
Link: https://lore.kernel.org/r/20220825232251.345893-3-luke@ljones.dev
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'drivers/platform/x86/asus-wmi.c')
-rw-r--r-- | drivers/platform/x86/asus-wmi.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 46cd91efd693..bb430260653e 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -240,6 +240,7 @@ struct asus_wmi { bool gpu_mux_mode_available; bool kbd_rgb_mode_available; + bool kbd_rgb_state_available; bool throttle_thermal_policy_available; u8 throttle_thermal_policy_mode; @@ -782,9 +783,62 @@ static const struct attribute_group kbd_rgb_mode_group = { .attrs = kbd_rgb_mode_attrs, }; +/* TUF Laptop Keyboard RGB State **********************************************/ +static ssize_t kbd_rgb_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u32 flags, cmd, boot, awake, sleep, keyboard; + int err; + + if (sscanf(buf, "%d %d %d %d %d", &cmd, &boot, &awake, &sleep, &keyboard) != 5) + return -EINVAL; + + if (cmd) + cmd = BIT(2); + + flags = 0; + if (boot) + flags |= BIT(1); + if (awake) + flags |= BIT(3); + if (sleep) + flags |= BIT(5); + if (keyboard) + flags |= BIT(7); + + /* 0xbd is the required default arg0 for the method. Nothing happens otherwise */ + err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS, + ASUS_WMI_DEVID_TUF_RGB_STATE, 0xbd | cmd << 8 | (flags << 16), 0, NULL); + if (err) + return err; + + return count; +} +static DEVICE_ATTR_WO(kbd_rgb_state); + +static ssize_t kbd_rgb_state_index_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%s\n", "cmd boot awake sleep keyboard"); +} +static DEVICE_ATTR_RO(kbd_rgb_state_index); + +static struct attribute *kbd_rgb_state_attrs[] = { + &dev_attr_kbd_rgb_state.attr, + &dev_attr_kbd_rgb_state_index.attr, + NULL, +}; + +static const struct attribute_group kbd_rgb_state_group = { + .attrs = kbd_rgb_state_attrs, +}; + const struct attribute_group *kbd_rgb_mode_groups[] = { NULL, NULL, + NULL, }; /* Battery ********************************************************************/ @@ -1109,6 +1163,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus) if (asus->kbd_rgb_mode_available) kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_mode_group; + if (asus->kbd_rgb_state_available) + kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_state_group; asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); if (!asus->led_workqueue) @@ -3661,6 +3717,7 @@ static int asus_wmi_add(struct platform_device *pdev) asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU); asus->gpu_mux_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX); asus->kbd_rgb_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE); + asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE); asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD); err = fan_boost_mode_check_present(asus); |