Linux Input/HID development
 help / color / mirror / Atom feed
From: Uddhav Swami <uddhavswami@gmail.com>
To: linux-input@vger.kernel.org
Cc: Uddhav Swami <uddhavswami@gmail.com>,
	jikos@kernel.org, bentiss@kernel.org
Subject: [PATCH v4] HID: chuyuen: add driver for vendor-specific brightness keys
Date: Mon, 17 Aug 2026 00:33:19 -0700	[thread overview]
Message-ID: <20260817073319.33200-1-uddhavswami@gmail.com> (raw)
In-Reply-To: <20260715055951.15144-1-uddhavswami@gmail.com>

The Gigabyte Aero 15 XB keyboard (Chu Yuen Enterprise Co., Ltd,
USB ID 1044:7a3f) sends brightness up/down keypresses as vendor-defined
HID reports (Usage Page 0xFF02, Report ID 4) rather than standard HID
Consumer Control usages, causing KEY_BRIGHTNESSUP and KEY_BRIGHTNESSDOWN
to never reach the input subsystem.

Add a minimal HID driver that intercepts Report ID 4 and maps values
0x7D and 0x7E to KEY_BRIGHTNESSDOWN and KEY_BRIGHTNESSUP respectively.

Tested on: Gigabyte Aero 15 XB (USB ID 1044:7a3f)

Signed-off-by: Uddhav Swami <uddhavswami@gmail.com>
---
v4:
- Rename driver from hid-gigabyte to hid-chuyuen (and Kconfig symbol
  HID_GIGABYTE_AERO to HID_CHUYUEN, module name to hid_chuyuen) to
  follow the hid-<vendor> naming convention, since Chu Yuen Enterprise
  is the actual USB vendor, not Gigabyte. (Jiri)
v3:
- Fix a NULL pointer dereference: hi->report can be NULL for some
  hid_input instances. Iterate hi->reports via list_for_each_entry()
  on hidinput_list to find report ID 0x04 before setting capabilities.
- Rename local variable ret to error in probe for clarity.
v2:
- Fix a use-after-free: check HID_CLAIMED_INPUT after hid_hw_start()
  to catch a failed input_register_device().

 drivers/hid/Kconfig       |  10 +++
 drivers/hid/Makefile      |   1 +
 drivers/hid/hid-chuyuen.c | 145 ++++++++++++++++++++++++++++++++++++++
 drivers/hid/hid-ids.h     |   3 +
 4 files changed, 159 insertions(+)
 create mode 100644 drivers/hid/hid-chuyuen.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 03f36899e458..6647434d5adf 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -243,6 +243,16 @@ config HID_CHICONY
 	help
 	Support for Chicony Tactical pad and special keys on Chicony keyboards.
 
+config HID_CHUYUEN
+	tristate "Chu Yuen Aero laptop vendor-specific keys"
+	depends on USB_HID
+	help
+	  Support for vendor-specific keyboard keys on Chu Yuen keyboards
+	  found in Gigabyte Aero laptops.
+
+	  Currently the following device is known to be supported:
+	   - Gigabyte Aero 15 XB
+
 config HID_CORSAIR
 	tristate "Corsair devices"
 	depends on USB_HID && LEDS_CLASS
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 23e6e3dd0c56..7f7503261b4f 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_HID_BETOP_FF)	+= hid-betopff.o
 obj-$(CONFIG_HID_BIGBEN_FF)	+= hid-bigbenff.o
 obj-$(CONFIG_HID_CHERRY)	+= hid-cherry.o
 obj-$(CONFIG_HID_CHICONY)	+= hid-chicony.o
+obj-$(CONFIG_HID_CHUYUEN)	+= hid-chuyuen.o
 obj-$(CONFIG_HID_CMEDIA)	+= hid-cmedia.o
 obj-$(CONFIG_HID_CORSAIR)	+= hid-corsair.o hid-corsair-void.o
 obj-$(CONFIG_HID_COUGAR)	+= hid-cougar.o
diff --git a/drivers/hid/hid-chuyuen.c b/drivers/hid/hid-chuyuen.c
new file mode 100644
index 000000000000..9bc0ab509083
--- /dev/null
+++ b/drivers/hid/hid-chuyuen.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  HID driver for Chu Yuen Enterprise keyboards, as found on Gigabyte
+ *  Aero laptops, with vendor-specific brightness keys.
+ *
+ *  The keyboard sends brightness up/down presses as a vendor-defined usage page
+ *  report instead of standard HID Consumer Control usages.
+ *
+ *  This driver intercepts them and emits the correct KEY_BRIGHTNESSUP /
+ *  KEY_BRIGHTNESSDOWN events.
+ *
+ *  Currently supported devices are:
+ *	Gigabyte Aero 15 XB
+ *
+ *  Copyright (c) 2026 Uddhav Swami <uddhavswami@gmail.com>
+ *
+ *  This module based on hid-asus by
+ *  Copyright (c) 2016 Yusuke Fujimaki <usk.fujimaki@gmail.com>
+ *  Copyright (c) 2016 Brendan McGrath <redmcg@redmandi.dyndns.org>
+ *  Copyright (c) 2016 Victor Vlasenko <victor.vlasenko@sysgears.com>
+ *  Copyright (c) 2016 Frederik Wenigwieser <frederik.wenigwieser@gmail.com>
+ */
+
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/input.h>
+
+#include "hid-ids.h"
+
+MODULE_AUTHOR("Uddhav Swami <uddhavswami@gmail.com>");
+MODULE_DESCRIPTION("HID driver for Chu Yuen Aero keyboards");
+
+#define CHUYUEN_AERO_REPORT_ID 0x04
+#define CHUYUEN_AERO_BRIGHTNESS_DOWN 0x7D
+#define CHUYUEN_AERO_BRIGHTNESS_UP 0x7E
+
+struct chuyuen_drvdata {
+	struct input_dev *input;
+};
+
+static int chuyuen_aero_raw_event(struct hid_device *hdev,
+				   struct hid_report *report, u8 *data,
+				   int size)
+{
+	struct chuyuen_drvdata *drvdata = hid_get_drvdata(hdev);
+
+	if (!drvdata->input)
+		return 0;
+
+	if (report->id != CHUYUEN_AERO_REPORT_ID || size < 4)
+		return 0;
+
+	switch (data[3]) {
+	case CHUYUEN_AERO_BRIGHTNESS_DOWN:
+		input_report_key(drvdata->input, KEY_BRIGHTNESSDOWN, 1);
+		input_sync(drvdata->input);
+		input_report_key(drvdata->input, KEY_BRIGHTNESSDOWN, 0);
+		input_sync(drvdata->input);
+		return 1;
+	case CHUYUEN_AERO_BRIGHTNESS_UP:
+		input_report_key(drvdata->input, KEY_BRIGHTNESSUP, 1);
+		input_sync(drvdata->input);
+		input_report_key(drvdata->input, KEY_BRIGHTNESSUP, 0);
+		input_sync(drvdata->input);
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static int chuyuen_aero_input_configured(struct hid_device *hdev,
+					  struct hid_input *hi)
+{
+	struct chuyuen_drvdata *drvdata = hid_get_drvdata(hdev);
+	struct hid_report *report;
+	bool has_report = false;
+
+	list_for_each_entry(report, &hi->reports, hidinput_list) {
+		if (report->id == CHUYUEN_AERO_REPORT_ID) {
+			has_report = true;
+			break;
+		}
+	}
+
+	if (!has_report)
+		return 0;
+
+	input_set_capability(hi->input, EV_KEY, KEY_BRIGHTNESSUP);
+	input_set_capability(hi->input, EV_KEY, KEY_BRIGHTNESSDOWN);
+
+	drvdata->input = hi->input;
+
+	return 0;
+}
+
+static int chuyuen_aero_probe(struct hid_device *hdev,
+			       const struct hid_device_id *id)
+{
+	struct chuyuen_drvdata *drvdata;
+	int error;
+
+	drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	hid_set_drvdata(hdev, drvdata);
+
+	error = hid_parse(hdev);
+	if (error) {
+		hid_err(hdev, "chuyuen_aero: parse failed: %d\n", error);
+		return error;
+	}
+
+	error = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+	if (error) {
+		hid_err(hdev, "chuyuen_aero: hw start failed: %d\n", error);
+		return error;
+	}
+
+	if (!(hdev->claimed & HID_CLAIMED_INPUT)) {
+		hid_err(hdev, "chuyuen_aero: no input device claimed\n");
+		hid_hw_stop(hdev);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static const struct hid_device_id chuyuen_aero_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHU_YUEN,
+			 USB_DEVICE_ID_CHU_YUEN_AERO_KBD) },
+	{}
+};
+MODULE_DEVICE_TABLE(hid, chuyuen_aero_devices);
+
+static struct hid_driver chuyuen_aero_driver = {
+	.name = "hid_chuyuen",
+	.id_table = chuyuen_aero_devices,
+	.probe = chuyuen_aero_probe,
+	.raw_event = chuyuen_aero_raw_event,
+	.input_configured = chuyuen_aero_input_configured,
+};
+module_hid_driver(chuyuen_aero_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index b70f719b3b07..b6bca8d8d94d 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -330,6 +330,9 @@
 #define USB_VENDOR_ID_CHUNGHWAT		0x2247
 #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH	0x0001
 
+#define USB_VENDOR_ID_CHU_YUEN			0x1044
+#define USB_DEVICE_ID_CHU_YUEN_AERO_KBD		0x7a3f
+
 #define USB_VENDOR_ID_CIDC		0x1677
 
 #define I2C_VENDOR_ID_CIRQUE           0x0488
-- 
2.55.0


  parent reply	other threads:[~2026-08-17  7:33 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-15  0:44 [PATCH] HID: add driver for Gigabyte Aero vendor-specific brightness keys Uddhav Swami
2026-07-15  1:08 ` sashiko-bot
2026-07-15  4:15 ` [PATCH v2] " Uddhav Swami
2026-07-15  4:27   ` sashiko-bot
2026-07-15  5:59 ` [PATCH v3] " Uddhav Swami
2026-08-05  7:18   ` Uddhav Swami
2026-08-17  7:33   ` Uddhav Swami [this message]
2026-08-17  7:49   ` Uddhav Swami

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=20260817073319.33200-1-uddhavswami@gmail.com \
    --to=uddhavswami@gmail.com \
    --cc=bentiss@kernel.org \
    --cc=jikos@kernel.org \
    --cc=linux-input@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