From: Abhijeet V <abhijeetviswa@gmail.com>
To: Corentin Chary <corentin.chary@gmail.com>,
Hans de Goede <hdegoede@redhat.com>,
Mark Gross <markgross@kernel.org>
Cc: acpi4asus-user@lists.sourceforge.net,
platform-driver-x86@vger.kernel.org,
linux-kernel@vger.kernel.org,
Abhijeet V <abhijeetviswa@gmail.com>
Subject: [PATCH 2/2] asus-wmi: Add support for keyboard rgb backlights
Date: Sat, 12 Feb 2022 01:31:22 +0530 [thread overview]
Message-ID: <20220211200122.9821-3-abhijeetviswa@gmail.com> (raw)
In-Reply-To: <20220211200122.9821-1-abhijeetviswa@gmail.com>
Uses the led multicolor classdev to change the rgb values.
The WMI function expects other settings in addition to the rgb values.
This patch assumes some defaults to get the base rgb functionality
working.
Signed-off-by: Abhijeet V <abhijeetviswa@gmail.com>
---
drivers/platform/x86/asus-wmi.c | 137 +++++++++++++++++++++
include/linux/platform_data/x86/asus-wmi.h | 2 +
2 files changed, 139 insertions(+)
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 117fbcb303d3..f8e92021399c 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -193,6 +193,12 @@ struct fan_curve_data {
u8 percents[FAN_CURVE_POINTS];
};
+struct asus_kbd_rgb {
+ u8 red;
+ u8 green;
+ u8 blue;
+};
+
struct asus_wmi {
int dsts_id;
int spec;
@@ -217,6 +223,8 @@ struct asus_wmi {
struct led_classdev_mc kbd_led_mc;
int kbd_led_wk;
struct mc_subled subled_info[ASUS_KBD_SUBLED_COUNT];
+ struct asus_kbd_rgb kbd_rgb;
+ bool kbd_rgb_available;
struct asus_rfkill wlan;
struct asus_rfkill bluetooth;
@@ -914,6 +922,114 @@ static void kbd_led_brightness_wmi_write(struct asus_wmi *asus, int value)
asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
}
+static int kbd_led_rgb_wmi_write(struct asus_wmi *asus)
+{
+ int err;
+ u32 retval;
+ u8 red;
+ u8 green;
+ u8 blue;
+ u8 speed_byte;
+ u8 mode_byte;
+ u8 speed;
+ u8 mode;
+ u8 flags;
+ u8 persistent;
+
+ speed = 0; // Sane default
+ switch (speed) {
+ case 0:
+ default:
+ speed_byte = 0xe1; // slow
+ speed = 0;
+ break;
+ case 1:
+ speed_byte = 0xeb; // medium
+ break;
+ case 2:
+ speed_byte = 0xf5; // fast
+ break;
+ }
+
+ mode = 0; // Sane default
+ switch (mode) {
+ case 0:
+ default:
+ mode_byte = 0x00; // static color
+ mode = 0;
+ break;
+ case 1:
+ mode_byte = 0x01; // breathing
+ break;
+ case 2:
+ mode_byte = 0x02; // color cycle
+ break;
+ case 3:
+ mode_byte = 0x0a; // strobing
+ break;
+ }
+
+ red = clamp_val(asus->kbd_led_mc.subled_info[0].intensity, 0, 255);
+ green = clamp_val(asus->kbd_led_mc.subled_info[1].intensity, 0, 255);
+ blue = clamp_val(asus->kbd_led_mc.subled_info[2].intensity, 0, 255);
+
+ /*
+ * 00 - Reset on boot
+ * 01 - Persist across boot
+ */
+ persistent = 1; // Sane defaults
+
+ err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS,
+ ASUS_WMI_DEVID_KBD_RGB,
+ (persistent ? 0xb4 : 0xb3) |
+ (mode_byte << 8) |
+ (red << 16) |
+ (green << 24),
+ (blue) |
+ (speed_byte << 8), &retval);
+ if (err) {
+ pr_warn("RGB keyboard device 1, write error: %d\n", err);
+ return err;
+ }
+
+ if (retval != 1) {
+ pr_warn("RGB keyboard device 1, write error (retval): %x\n",
+ retval);
+ return -EIO;
+ }
+
+ /*
+ * Enable: 02 - on boot (until module load) | 08 - awake | 20 - sleep
+ * (2a or ff to enable everything)
+ *
+ * Logically 80 would be shutdown, but no visible effects of this option
+ * were observed so far
+ */
+ flags = 0xff;
+
+ err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS,
+ ASUS_WMI_DEVID_KBD_RGB2,
+ (0xbd) |
+ (flags << 16) |
+ (persistent ? 0x0100 : 0x0000), 0, &retval);
+ if (err) {
+ pr_warn("RGB keyboard device 2, write error: %d\n", err);
+ return err;
+ }
+
+ if (retval != 1) {
+ pr_warn("RGB keyboard device 2, write error (retval): %x\n",
+ retval);
+ return -EIO;
+ }
+
+ asus->kbd_rgb.red = red;
+ asus->kbd_rgb.green = green;
+ asus->kbd_rgb.blue = blue;
+
+ return 0;
+}
+
static void kbd_led_brightness_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
@@ -928,6 +1044,18 @@ static void kbd_led_brightness_set(struct led_classdev *led_cdev,
asus = container_of(led_cdev_mc, struct asus_wmi, kbd_led_mc);
kbd_led_brightness_wmi_write(asus, value);
+
+ /* Check and set if rgb available */
+ if (!asus->kbd_rgb_available)
+ return;
+
+ if (asus->kbd_rgb.red == asus->subled_info[LED_COLOR_ID_RED].intensity &&
+ asus->kbd_rgb.green == asus->subled_info[LED_COLOR_ID_GREEN].intensity &&
+ asus->kbd_rgb.blue == asus->subled_info[LED_COLOR_ID_BLUE].intensity) {
+ return;
+ }
+
+ kbd_led_rgb_wmi_write(asus);
}
static void kbd_led_set_brightness_by_hw(struct asus_wmi *asus,
@@ -959,6 +1087,7 @@ int kbd_led_classdev_init(struct asus_wmi *asus, int brightness)
{
int rv;
+ asus->kbd_rgb_available = true;
asus->kbd_led_wk = brightness;
asus->kbd_led_mc.led_cdev.name = "asus::kbd_backlight";
asus->kbd_led_mc.led_cdev.flags = LED_BRIGHT_HW_CHANGED;
@@ -966,6 +1095,14 @@ int kbd_led_classdev_init(struct asus_wmi *asus, int brightness)
asus->kbd_led_mc.led_cdev.brightness_get = kbd_led_brightness_get;
asus->kbd_led_mc.led_cdev.max_brightness = 3;
+ asus->subled_info[0].color_index = LED_COLOR_ID_RED;
+ asus->subled_info[0].channel = 0;
+ asus->subled_info[1].color_index = LED_COLOR_ID_GREEN;
+ asus->subled_info[1].channel = 1;
+ asus->subled_info[2].color_index = LED_COLOR_ID_BLUE;
+ asus->subled_info[2].channel = 2;
+ asus->kbd_led_mc.subled_info = asus->subled_info;
+
asus->kbd_led_mc.num_colors = ASUS_KBD_SUBLED_COUNT;
rv = led_classdev_multicolor_register(&asus->platform_device->dev,
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
index a571b47ff362..a20ca3787e9f 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -59,6 +59,8 @@
#define ASUS_WMI_DEVID_LIGHTBAR 0x00050025
#define ASUS_WMI_DEVID_FAN_BOOST_MODE 0x00110018
#define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075
+#define ASUS_WMI_DEVID_KBD_RGB 0x00100056
+#define ASUS_WMI_DEVID_KBD_RGB2 0x00100057
/* Misc */
#define ASUS_WMI_DEVID_PANEL_OD 0x00050019
--
2.35.1
next prev parent reply other threads:[~2022-02-11 20:01 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-11 20:01 [PATCH 0/2] asus-wmi: Keyboard rgb led multicolor support Abhijeet V
2022-02-11 20:01 ` [PATCH 1/2] asus-wmi: Use led multicolor class for keyboard backlight Abhijeet V
2022-02-12 19:08 ` kernel test robot
2022-02-13 6:20 ` Abhijeet Viswa
2022-02-16 9:58 ` Pavel Machek
2022-02-11 20:01 ` Abhijeet V [this message]
2022-02-17 16:17 ` [PATCH 2/2] asus-wmi: Add support for keyboard rgb backlights Hans de Goede
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220211200122.9821-3-abhijeetviswa@gmail.com \
--to=abhijeetviswa@gmail.com \
--cc=acpi4asus-user@lists.sourceforge.net \
--cc=corentin.chary@gmail.com \
--cc=hdegoede@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=markgross@kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).