aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86
diff options
context:
space:
mode:
authorLuke D. Jones <luke@ljones.dev>2022-08-26 11:22:50 +1200
committerHans de Goede <hdegoede@redhat.com>2022-08-26 11:44:29 +0200
commite305a71cea37a64c7558b8b979f6f08f657d0c3d (patch)
tree1365a5eb85df4a845feb3c29e85e6a7becf6601f /drivers/platform/x86
parentplatform/x86: asus-wmi: Support the GPU fan on TUF laptops (diff)
downloadlinux-dev-e305a71cea37a64c7558b8b979f6f08f657d0c3d.tar.xz
linux-dev-e305a71cea37a64c7558b8b979f6f08f657d0c3d.zip
platform/x86: asus-wmi: Implement TUF laptop keyboard LED modes
Adds support for changing the laptop keyboard LED mode and colour. The modes are visible effects such as static, rainbow, pulsing, colour cycles. These sysfs attributes are added to asus::kbd_backlight: - kbd_rgb_mode - kbd_rgb_mode_index Signed-off-by: Luke D. Jones <luke@ljones.dev> Link: https://lore.kernel.org/r/20220825232251.345893-2-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')
-rw-r--r--drivers/platform/x86/asus-wmi.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index eebc20c70bf7..46cd91efd693 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -239,6 +239,8 @@ struct asus_wmi {
bool dgpu_disable_available;
bool gpu_mux_mode_available;
+ bool kbd_rgb_mode_available;
+
bool throttle_thermal_policy_available;
u8 throttle_thermal_policy_mode;
@@ -722,6 +724,69 @@ static ssize_t gpu_mux_mode_store(struct device *dev,
}
static DEVICE_ATTR_RW(gpu_mux_mode);
+/* TUF Laptop Keyboard RGB Modes **********************************************/
+static ssize_t kbd_rgb_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 cmd, mode, r, g, b, speed;
+ int err;
+
+ if (sscanf(buf, "%d %d %d %d %d %d", &cmd, &mode, &r, &g, &b, &speed) != 6)
+ return -EINVAL;
+
+ cmd = !!cmd;
+
+ /* These are the known usable modes across all TUF/ROG */
+ if (mode >= 12 || mode == 9)
+ mode = 10;
+
+ switch (speed) {
+ case 0:
+ speed = 0xe1;
+ break;
+ case 1:
+ speed = 0xeb;
+ break;
+ case 2:
+ speed = 0xf5;
+ break;
+ default:
+ speed = 0xeb;
+ }
+
+ err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS, ASUS_WMI_DEVID_TUF_RGB_MODE,
+ cmd | (mode << 8) | (r << 16) | (g << 24), b | (speed << 8), NULL);
+ if (err)
+ return err;
+
+ return count;
+}
+static DEVICE_ATTR_WO(kbd_rgb_mode);
+
+static ssize_t kbd_rgb_mode_index_show(struct device *device,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sysfs_emit(buf, "%s\n", "cmd mode red green blue speed");
+}
+static DEVICE_ATTR_RO(kbd_rgb_mode_index);
+
+static struct attribute *kbd_rgb_mode_attrs[] = {
+ &dev_attr_kbd_rgb_mode.attr,
+ &dev_attr_kbd_rgb_mode_index.attr,
+ NULL,
+};
+
+static const struct attribute_group kbd_rgb_mode_group = {
+ .attrs = kbd_rgb_mode_attrs,
+};
+
+const struct attribute_group *kbd_rgb_mode_groups[] = {
+ NULL,
+ NULL,
+};
+
/* Battery ********************************************************************/
/* The battery maximum charging percentage */
@@ -1040,7 +1105,10 @@ static void asus_wmi_led_exit(struct asus_wmi *asus)
static int asus_wmi_led_init(struct asus_wmi *asus)
{
- int rv = 0, led_val;
+ int rv = 0, num_rgb_groups = 0, led_val;
+
+ if (asus->kbd_rgb_mode_available)
+ kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_mode_group;
asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
if (!asus->led_workqueue)
@@ -1068,6 +1136,9 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
asus->kbd_led.brightness_get = kbd_led_get;
asus->kbd_led.max_brightness = 3;
+ if (num_rgb_groups != 0)
+ asus->kbd_led.groups = kbd_rgb_mode_groups;
+
rv = led_classdev_register(&asus->platform_device->dev,
&asus->kbd_led);
if (rv)
@@ -3589,6 +3660,7 @@ static int asus_wmi_add(struct platform_device *pdev)
asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
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->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
err = fan_boost_mode_check_present(asus);