Thread (17 messages) flat view 17 messages, 3 authors, 2026-01-07

Re: [PATCH] HID: asus: Filter HID vendor codes and add WMI fan control support for ROG laptops

From: "Mario Limonciello (AMD) (kernel.org)" <superm1@kernel.org>
Date: 2026-01-06 16:18:55
Also in: lkml

+ Denis Benato

On 1/6/2026 8:04 AM, Ionut Nechita (Sunlight Linux) wrote:
From: Ionut Nechita <redacted>

On Asus ROG G14 and G15 laptops, several HID vendor usage codes are sent
during normal operation without a clear purpose, generating unwanted
"Unmapped Asus vendor usagepage code" warnings in dmesg.

Additionally, the Fn+F5 fan control key (code 0xae) needs to communicate
with the asus-wmi driver to toggle between fan modes, but this was not
previously handled.

Changes:
- Filter out spurious HID codes (0xea, 0xec, 0x02, 0x8a, 0x9e) for
   QUIRK_ROG_NKEY_KEYBOARD devices to prevent kernel log spam
- Add asus_wmi_send_event() function to communicate with asus-wmi driver
- Implement Fn+F5 (0xae) fan control key handler that triggers WMI events
- Replace magic number 0xff310000 with HID_UP_ASUSVENDOR constant for
   better code clarity
I feel these should be split into smaller logical patches.
quoted hunk ↗ jump to hunk
This eliminates unnecessary kernel warnings and enables proper fan control
functionality on affected Asus ROG laptops.

Tested on Asus ROG G14/G15 series laptops.

Signed-off-by: Ionut Nechita <redacted>
---
  drivers/hid/hid-asus.c                     | 48 +++++++++++++++++++++-
  include/linux/platform_data/x86/asus-wmi.h |  2 +
  2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 472bca54642b9..cd8d0e495a75a 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -26,6 +26,8 @@
  #include <linux/dmi.h>
  #include <linux/hid.h>
  #include <linux/module.h>
+
+#include <linux/acpi.h>
Shouldn't this be in alphabetical order before linux/dmi.h above?
quoted hunk ↗ jump to hunk
  #include <linux/platform_data/x86/asus-wmi.h>
  #include <linux/platform_data/x86/asus-wmi-leds-ids.h>
  #include <linux/input/mt.h>
@@ -314,10 +316,33 @@ static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size)
  	return 0;
  }
  
+/*
+ * This enables triggering events in asus-wmi
+ */
+static int asus_wmi_send_event(struct asus_drvdata *drvdat, u8 code)
+{
+	int err;
+	u32 retval;
+
+	err = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS,
+		ASUS_WMI_METHODID_NOTIF, code, &retval);
+	if (err) {
+		pr_warn("Failed to notify asus-wmi: %d\n", err);
+		return err;
+	}
+
+	if (retval != 0) {
+		pr_warn("Failed to notify asus-wmi (retval): 0x%x\n", retval);
+		return -EIO;
+	}
+
+	return 0;
+}
+
  static int asus_event(struct hid_device *hdev, struct hid_field *field,
  		      struct hid_usage *usage, __s32 value)
  {
-	if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 &&
+	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_ASUSVENDOR &&
  	    (usage->hid & HID_USAGE) != 0x00 &&
  	    (usage->hid & HID_USAGE) != 0xff && !usage->type) {
  		hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n",
@@ -330,6 +355,7 @@ static int asus_event(struct hid_device *hdev, struct hid_field *field,
  static int asus_raw_event(struct hid_device *hdev,
  		struct hid_report *report, u8 *data, int size)
  {
+	int ret;
  	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
  
  	if (drvdata->battery && data[0] == BATTERY_REPORT_ID)
@@ -348,6 +374,26 @@ static int asus_raw_event(struct hid_device *hdev,
  	if (report->id == FEATURE_KBD_LED_REPORT_ID1 || report->id == FEATURE_KBD_LED_REPORT_ID2)
  		return -1;
  	if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
+		/* Additional report filtering */
+		if (report->id == FEATURE_KBD_REPORT_ID) {
+			/* Fn+F5 "fan" symbol, trigger WMI event to toggle next mode */
+			if (data[1] == 0xae) {
As this has a meaning you've identified shouldn't it have a #define as well?
quoted hunk ↗ jump to hunk
+				ret = asus_wmi_send_event(drvdata, 0xae);
+				if (ret < 0) {
+					hid_warn(hdev, "Asus failed to trigger fan control event");
+				}
+				return -1;
+			/*
+			 * G14 and G15 send these codes on some keypresses with no
+			 * discernable reason for doing so. We'll filter them out to avoid
+			 * unmapped warning messages later
+			 */
+			} else if (data[1] == 0xea || data[1] == 0xec || data[1] == 0x02 ||
+					data[1] == 0x8a || data[1] == 0x9e) {
+				return -1;
+			}
+		}
+
  		/*
  		 * G713 and G733 send these codes on some keypresses, depending on
  		 * the key pressed it can trigger a shutdown event if not caught.
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
index 419491d4abca1..8ed6f603735d1 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -30,6 +30,8 @@
  #define ASUS_WMI_METHODID_INIT		0x54494E49 /* INITialize */
  #define ASUS_WMI_METHODID_HKEY		0x59454B48 /* Hot KEY ?? */
  
+#define ASUS_WMI_METHODID_NOTIF                0x00100021 /* Notify method ?? */
+
  #define ASUS_WMI_UNSUPPORTED_METHOD	0xFFFFFFFE
  
  /* Wireless */
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help