Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH v5] HID: magicmouse: add battery reporting for Magic Trackpad v1
From: Damiano Gragnaniello @ 2026-04-16 12:53 UTC (permalink / raw)
  To: jikos; +Cc: bentiss, linux-input, Damiano Gragnaniello
In-Reply-To: <20260415155548.927385-1-damianogragnaniello@gmail.com>

The Magic Trackpad v1 (A1339) reports battery level via Bluetooth using
Report ID 0x47. This patch adds support for parsing this report and
registering a power_supply interface so that userspace (upower) can
correctly display the battery percentage for this legacy device.

Signed-off-by: Damiano Gragnaniello <damianogragnaniello@gmail.com>
---
v5:
  - Rebased on current upstream hid-magicmouse.c (post-timer_container_of
    refactor). Previous versions failed to apply due to context drift.
  - Removed spurious TRACKPAD_V1_BATTERY_TIMEOUT_SEC define (unused).
  - Removed space-aligned assignments in probe() in favor of plain
    single-tab assignments to satisfy checkpatch.pl --strict.
  - Added kernel-doc comment entries for new struct fields.
  - Preserved all original driver logic and comments without modification.
v4:
  - Fixed patch formatting and spacing issues to ensure clean application.
  - Removed local path references and non-technical notes.
  - Corrected diff headers.
v3:
  - Fixed changelog language (translated from Italian to English).
  - Standardized patch naming for upstream submission.
v2:
  - Rename macros to TRACKPAD_V1_BATTERY_REPORT_ID for clarity.
  - Add clamp_val() to ensure battery capacity stays within 0-100 range.
  - Restore original driver comments.

 drivers/hid/hid-magicmouse.c | 82 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -15,6 +15,7 @@
 #include <linux/hid.h>
 #include <linux/input/mt.h>
 #include <linux/module.h>
+#include <linux/power_supply.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 
@@ -60,6 +61,7 @@
 #define MOUSE_REPORT_ID    0x29
 #define MOUSE2_REPORT_ID   0x12
 #define DOUBLE_REPORT_ID   0xf7
+#define TRACKPAD_V1_BATTERY_REPORT_ID 0x47
 #define USB_BATTERY_TIMEOUT_SEC 60
 
 /* These definitions are not precise, but they're close enough.  (Bits
@@ -124,6 +126,10 @@
  * @hdev: Pointer to the underlying HID device.
  * @work: Workqueue to handle initialization retry for quirky devices.
  * @battery_timer: Timer for obtaining battery level information.
+ * @battery: Power supply instance for Magic Trackpad v1 AA battery reporting.
+ * @battery_desc: Descriptor for the power_supply registration.
+ * @battery_name: Name buffer for the power_supply instance.
+ * @battery_capacity: Last known battery level (0-100%) for Magic Trackpad v1.
  */
 struct magicmouse_sc {
 	struct input_dev *input;
@@ -149,8 +155,46 @@
 	struct hid_device *hdev;
 	struct delayed_work work;
 	struct timer_list battery_timer;
+
+	/* Magic Trackpad v1 (AA battery) power_supply support */
+	struct power_supply *battery;
+	struct power_supply_desc battery_desc;
+	char battery_name[64];
+	int battery_capacity;
+};
+
+static const enum power_supply_property magicmouse_v1_battery_props[] = {
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_STATUS,
+};
+
+static int magicmouse_v1_battery_get_property(struct power_supply *psy,
+					   enum power_supply_property psp,
+					   union power_supply_propval *val)
+{
+	struct magicmouse_sc *msc = power_supply_get_drvdata(psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = 1;
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		val->intval = msc->battery_capacity;
+		break;
+	case POWER_SUPPLY_PROP_SCOPE:
+		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+		break;
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
 }
 
 static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -391,6 +435,19 @@
 	int x = 0, y = 0, ii, clicks = 0, npoints;
 
 	switch (data[0]) {
+	case TRACKPAD_V1_BATTERY_REPORT_ID:
+		/*
+		 * Magic Trackpad v1 (A1339, BT) sends battery level in byte 1,
+		 * already expressed as a percentage (0-100) by the firmware.
+		 * Clamp defensively and notify the power_supply framework.
+		 */
+		if (size < 2)
+			return 0;
+		if (msc->battery) {
+			msc->battery_capacity = clamp_val((int)data[1], 0, 100);
+			power_supply_changed(msc->battery);
+		}
+		return 0;
 	case TRACKPAD_REPORT_ID:
 	case TRACKPAD2_BT_REPORT_ID:
 		/* Expect four bytes of prefix, and N*9 bytes of touch data. */
@@ -890,6 +947,31 @@
 		magicmouse_fetch_battery(hdev);
 	}
 
+	/* Register power_supply for Magic Trackpad v1 (AA battery, BT only) */
+	if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD &&
+	    id->vendor == USB_VENDOR_ID_APPLE) {
+		struct power_supply_config psy_cfg = {};
+
+		psy_cfg.drv_data = msc;
+		msc->battery_capacity = 0;
+		snprintf(msc->battery_name, sizeof(msc->battery_name),
+			 "hid-magictrackpad-v1-%s", dev_name(&hdev->dev));
+
+		msc->battery_desc.name = msc->battery_name;
+		msc->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY;
+		msc->battery_desc.properties = magicmouse_v1_battery_props;
+		msc->battery_desc.num_properties = ARRAY_SIZE(magicmouse_v1_battery_props);
+		msc->battery_desc.get_property = magicmouse_v1_battery_get_property;
+
+		msc->battery = devm_power_supply_register(&hdev->dev,
+							  &msc->battery_desc,
+							  &psy_cfg);
+		if (IS_ERR(msc->battery)) {
+			hid_err(hdev, "can't register battery device\n");
+			msc->battery = NULL;
+		}
+	}
+
 	if (is_usb_magicmouse2(id->vendor, id->product) ||
 	    (is_usb_magictrackpad2(id->vendor, id->product) &&
 	     hdev->type != HID_TYPE_USBMOUSE))

^ permalink raw reply

* Re: [PATCH 01/61] Coccinelle: Prefer IS_ERR_OR_NULL over manual NULL check
From: Krzysztof Kozlowski @ 2026-04-16 12:30 UTC (permalink / raw)
  To: Philipp Hahn, amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel,
	dri-devel, gfs2, intel-gfx, intel-wired-lan, iommu, kvm,
	linux-arm-kernel, linux-block, linux-bluetooth, linux-btrfs,
	linux-cifs, linux-clk, linux-erofs, linux-ext4, linux-fsdevel,
	linux-gpio, linux-hyperv, linux-input, linux-kernel, linux-leds,
	linux-media, linux-mips, linux-mm, linux-modules, linux-mtd,
	linux-nfs, linux-omap, linux-phy, linux-pm, linux-rockchip,
	linux-s390, linux-scsi, linux-sctp, linux-security-module,
	linux-sh, linux-sound, linux-stm32, linux-trace-kernel, linux-usb,
	linux-wireless, netdev, ntfs3, samba-technical, sched-ext,
	target-devel, tipc-discussion, v9fs
  Cc: Julia Lawall, Nicolas Palix
In-Reply-To: <20260310-b4-is_err_or_null-v1-1-bd63b656022d@avm.de>

On 10/03/2026 12:48, Philipp Hahn wrote:
> Find and convert uses of IS_ERR() plus NULL check to IS_ERR_OR_NULL().
> 
> There are several cases where `!ptr && WARN_ON[_ONCE](IS_ERR(ptr))` is
> used:
> - arch/x86/kernel/callthunks.c:215 WARN_ON_ONCE
> - drivers/clk/clk.c:4561 WARN_ON_ONCE
> - drivers/interconnect/core.c:793 WARN_ON
> - drivers/reset/core.c:718 WARN_ON
> The change is not 100% semantical equivalent as the warning will now
> also happen when the pointer is NULL.
> 
> To: Julia Lawall <Julia.Lawall@inria.fr>
> To: Nicolas Palix <nicolas.palix@imag.fr>
> Cc: cocci@inria.fr
> Cc: linux-kernel@vger.kernel.org
> 
> ---
> drivers/clocksource/mips-gic-timer.c:283 looks suspicious: ret != clk,
> but Daniel Lezcano verified it as cottect.
> 
> There are some cases where the checks are part of a larger expression:
> - mm/kmemleak.c:1095
> - mm/kmemleak.c:1155
> - mm/kmemleak.c:1173
> - mm/kmemleak.c:1290
> - mm/kmemleak.c:1328
> - mm/kmemleak.c:1241
> - mm/kmemleak.c:1310
> - mm/kmemleak.c:1258
> - net/netlink/af_netlink.c:2670
> Thanks to Julia Lawall for the help to also handle them.
> 
> Signed-off-by: Philipp Hahn <phahn-oss@avm.de>
> ---
>  scripts/coccinelle/api/is_err_or_null.cocci | 125 ++++++++++++++++++++++++++++
>  1 file changed, 125 insertions(+)
> 

Neither this, nor try from 2011, nor any future try should be accepted,
because it creates impression IS_ERR_OR_NULL is somehow okay. No, it is
not okay, it is a discouraged pattern leading to less readable and
maintainable code. We should not have therefore any tools suggesting
usage of IS_ERR_OR_NULL, because people will be converting poor code
into that, instead of fixing that poor code.

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH 55/61] interconnect: Prefer IS_ERR_OR_NULL over manual NULL check
From: Krzysztof Kozlowski @ 2026-04-16 12:24 UTC (permalink / raw)
  To: Philipp Hahn, amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel,
	dri-devel, gfs2, intel-gfx, intel-wired-lan, iommu, kvm,
	linux-arm-kernel, linux-block, linux-bluetooth, linux-btrfs,
	linux-cifs, linux-clk, linux-erofs, linux-ext4, linux-fsdevel,
	linux-gpio, linux-hyperv, linux-input, linux-kernel, linux-leds,
	linux-media, linux-mips, linux-mm, linux-modules, linux-mtd,
	linux-nfs, linux-omap, linux-phy, linux-pm, linux-rockchip,
	linux-s390, linux-scsi, linux-sctp, linux-security-module,
	linux-sh, linux-sound, linux-stm32, linux-trace-kernel, linux-usb,
	linux-wireless, netdev, ntfs3, samba-technical, sched-ext,
	target-devel, tipc-discussion, v9fs
  Cc: Georgi Djakov
In-Reply-To: <20260310-b4-is_err_or_null-v1-55-bd63b656022d@avm.de>

On 10/03/2026 12:49, Philipp Hahn wrote:
> Prefer using IS_ERR_OR_NULL() over using IS_ERR() and a manual NULL
> check.
> 
> Semantich change: Previously the code only printed the warning on error,
> but not when the pointer was NULL. Now the warning is printed in both
> cases!

NAK, read the code

> 
> Change found with coccinelle.
> 
> To: Georgi Djakov <djakov@kernel.org>
> Cc: linux-pm@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Philipp Hahn <phahn-oss@avm.de>
> ---
>  drivers/interconnect/core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
> index 8569b78a18517b33abeafac091978b25cbc1acc7..22e92b30f73853d5bd2e05b4f52cb5aa22556468 100644
> --- a/drivers/interconnect/core.c
> +++ b/drivers/interconnect/core.c
> @@ -790,7 +790,7 @@ void icc_put(struct icc_path *path)
>  	size_t i;
>  	int ret;
>  
> -	if (!path || WARN_ON(IS_ERR(path)))
> +	if (WARN_ON(IS_ERR_OR_NULL(path)))

IS_ERR_OR_NULL is simply discouraged, but beside of code preference, you
just added bug here. This is clearly not equivalent and you emit warn on
perfectly valid case!

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH 2/4] HID: core: introduce hid_safe_input_report()
From: Bastien Nocera @ 2026-04-16  9:32 UTC (permalink / raw)
  To: Benjamin Tissoires, Jiri Kosina, Filipe Laíns, Ping Cheng,
	Jason Gerecke, Viresh Kumar, Johan Hovold, Alex Elder,
	Greg Kroah-Hartman, Lee Jones
  Cc: linux-input, linux-kernel, greybus-dev, linux-staging, linux-usb,
	stable
In-Reply-To: <20260415-wip-fix-core-v1-2-ed3c4c823175@kernel.org>

On Wed, 2026-04-15 at 11:38 +0200, Benjamin Tissoires wrote:
> hid_input_report() is used in too many places to have a commit that
> doesn't cross subsystem borders. Instead of changing the API,
> introduce
> a new one when things matters in the transport layers:
> - usbhid
> - i2chid
> 
> This effectively revert to the old behavior for those two transport
> layers.
> 
> Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing
> bogus memset()")
> Cc: stable@vger.kernel.org
> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
> ---
>  drivers/hid/hid-core.c             | 21 +++++++++++++++++++++
>  drivers/hid/i2c-hid/i2c-hid-core.c |  7 ++++---
>  drivers/hid/usbhid/hid-core.c      | 11 ++++++-----
>  include/linux/hid.h                |  2 ++
>  4 files changed, 33 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index a806820df7e5..cb0ad99e7a0a 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -2191,6 +2191,27 @@ int hid_input_report(struct hid_device *hid,
> enum hid_report_type type, u8 *data
>  }
>  EXPORT_SYMBOL_GPL(hid_input_report);
>  
> +/**
> + * hid_safe_input_report - report data from lower layer (usb, bt...)
> + *
> + * @hid: hid device
> + * @type: HID report type (HID_*_REPORT)
> + * @data: report contents
> + * @bufsize: allocated size of the data buffer
> + * @size: useful size of data parameter
> + * @interrupt: distinguish between interrupt and control transfers
> + *
> + * This is data entry for lower layers.

You probably want to explain why it should be used instead of
hid_input_report() in this doc blurb, and modify the hid_input_report()
docs to mention that this should be used.

Maybe hid_input_report() should also be marked as deprecated somehow,
to avoid new users?

Cheers

> + */
> +int hid_safe_input_report(struct hid_device *hid, enum
> hid_report_type type, u8 *data,
> +			  size_t bufsize, u32 size, int interrupt)
> +{
> +	return __hid_input_report(hid, type, data, bufsize, size,
> interrupt, 0,
> +				  false, /* from_bpf */
> +				  false /* lock_already_taken */);
> +}
> +EXPORT_SYMBOL_GPL(hid_safe_input_report);
> +
>  bool hid_match_one_id(const struct hid_device *hdev,
>  		      const struct hid_device_id *id)
>  {
> diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-
> hid/i2c-hid-core.c
> index 5a183af3d5c6..e0a302544cef 100644
> --- a/drivers/hid/i2c-hid/i2c-hid-core.c
> +++ b/drivers/hid/i2c-hid/i2c-hid-core.c
> @@ -574,9 +574,10 @@ static void i2c_hid_get_input(struct i2c_hid
> *ihid)
>  		if (ihid->hid->group != HID_GROUP_RMI)
>  			pm_wakeup_event(&ihid->client->dev, 0);
>  
> -		hid_input_report(ihid->hid, HID_INPUT_REPORT,
> -				ihid->inbuf + sizeof(__le16),
> -				ret_size - sizeof(__le16), 1);
> +		hid_safe_input_report(ihid->hid, HID_INPUT_REPORT,
> +				      ihid->inbuf + sizeof(__le16),
> +				      ihid->bufsize -
> sizeof(__le16),
> +				      ret_size - sizeof(__le16), 1);
>  	}
>  
>  	return;
> diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-
> core.c
> index fbbfc0f60829..5af93b9b1fb5 100644
> --- a/drivers/hid/usbhid/hid-core.c
> +++ b/drivers/hid/usbhid/hid-core.c
> @@ -283,9 +283,9 @@ static void hid_irq_in(struct urb *urb)
>  			break;
>  		usbhid_mark_busy(usbhid);
>  		if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) {
> -			hid_input_report(urb->context,
> HID_INPUT_REPORT,
> -					 urb->transfer_buffer,
> -					 urb->actual_length, 1);
> +			hid_safe_input_report(urb->context,
> HID_INPUT_REPORT,
> +					      urb->transfer_buffer,
> urb->transfer_buffer_length,
> +					      urb->actual_length,
> 1);
>  			/*
>  			 * autosuspend refused while keys are
> pressed
>  			 * because most keyboards don't wake up when
> @@ -482,9 +482,10 @@ static void hid_ctrl(struct urb *urb)
>  	switch (status) {
>  	case 0:			/* success */
>  		if (usbhid->ctrl[usbhid->ctrltail].dir ==
> USB_DIR_IN)
> -			hid_input_report(urb->context,
> +			hid_safe_input_report(urb->context,
>  				usbhid->ctrl[usbhid-
> >ctrltail].report->type,
> -				urb->transfer_buffer, urb-
> >actual_length, 0);
> +				urb->transfer_buffer, urb-
> >transfer_buffer_length,
> +				urb->actual_length, 0);
>  		break;
>  	case -ESHUTDOWN:	/* unplug */
>  		unplug = 1;
> diff --git a/include/linux/hid.h b/include/linux/hid.h
> index ac432a2ef415..bfb9859f391e 100644
> --- a/include/linux/hid.h
> +++ b/include/linux/hid.h
> @@ -1030,6 +1030,8 @@ struct hid_field *hid_find_field(struct
> hid_device *hdev, unsigned int report_ty
>  int hid_set_field(struct hid_field *, unsigned, __s32);
>  int hid_input_report(struct hid_device *hid, enum hid_report_type
> type, u8 *data, u32 size,
>  		     int interrupt);
> +int hid_safe_input_report(struct hid_device *hid, enum
> hid_report_type type, u8 *data,
> +			  size_t bufsize, u32 size, int interrupt);
>  struct hid_field *hidinput_get_led_field(struct hid_device *hid);
>  unsigned int hidinput_count_leds(struct hid_device *hid);
>  __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16
> code);

^ permalink raw reply

* [PATCH RESEND] HID: Add force feedback support for Speedlink Cougar Vibration Flightstick
From: Harald Judt @ 2026-04-16  9:20 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires; +Cc: linux-input

Hi,

I have implemented force feedback/rumble support for the Speedlink
Cougar Vibration Flightstick joystick. While I am not quite sure about
the correctness of my approach regarding the strong and weak motors, it
seems to work as expected; I ran the fftest samples and also tested it
successfully with SuperTuxKart.

Here is the code, hopefully I have set up thunderbird mail correctly to
not mangle the patch...


From 48d8512fbe49ae7b940dc5869fe50aa905d3d5fb Mon Sep 17 00:00:00 2001
From: Harald Judt <h.judt@gmx.at>
Date: Sun, 18 Jan 2026 02:47:20 +0100
Subject: [PATCH] HID: Add force feedback support for Gembird based joystick

This commit adds force feedback support for a Gembird based joystick, namely
the SpeedLink Cougar Vibration Flightstick (SL-6630), which sports vibration
motors for rumble effects. Though it is not easy to determine, it seems to have
one motor in the base and the other in the stick, both are of equal
strength. The implementation tries to take this into account for realising weak
and strong rumble effects and has been tested using fftest and SuperTuxKart.

Signed-off-by: Harald Judt <h.judt@gmx.at>
---
 drivers/hid/Kconfig           |   8 ++
 drivers/hid/Makefile          |   1 +
 drivers/hid/hid-gembird-joy.c | 178 ++++++++++++++++++++++++++++++++++
 drivers/hid/hid-ids.h         |   3 +
 drivers/hid/hid-quirks.c      |   3 +
 5 files changed, 193 insertions(+)
 create mode 100644 drivers/hid/hid-gembird-joy.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 04420a713be0..b4e2c8f67728 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -406,6 +406,14 @@ config HID_GEMBIRD
 	help
 	Support for Gembird JPD-DualForce 2.
 
+config HID_GEMBIRD_JOY_FF
+	tristate "Gembird Joysticks force feedback support"
+	depends on USB_HID
+	select INPUT_FF_MEMLESS
+	help
+	Force feedback support for Gembird (Vendor ID 0x12bd) based devices:
+	  - Speed Link Cougar Vibration Flightstick (SL-6630)
+
 config HID_GFRM
 	tristate "Google Fiber TV Box remote control support"
 	help
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 361a7daedeb8..593a429661ed 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_HID_EVISION)	+= hid-evision.o
 obj-$(CONFIG_HID_EZKEY)		+= hid-ezkey.o
 obj-$(CONFIG_HID_FT260)		+= hid-ft260.o
 obj-$(CONFIG_HID_GEMBIRD)	+= hid-gembird.o
+obj-$(CONFIG_HID_GEMBIRD_JOY_FF)	+= hid-gembird-joy.o
 obj-$(CONFIG_HID_GFRM)		+= hid-gfrm.o
 obj-$(CONFIG_HID_GLORIOUS)  += hid-glorious.o
 obj-$(CONFIG_HID_VIVALDI_COMMON) += hid-vivaldi-common.o
diff --git a/drivers/hid/hid-gembird-joy.c b/drivers/hid/hid-gembird-joy.c
new file mode 100644
index 000000000000..5a5afa02f840
--- /dev/null
+++ b/drivers/hid/hid-gembird-joy.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  HID driver for Gembird based Joysticks
+ *
+ *  Currently supported devices:
+ *    - 12bd:a02f Speed Link Cougar Vibration Flightstick (SL-6630)
+ *
+ *  Copyright (c) 2026 Harald Judt <h.judt@gmx.at>
+ */
+
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+
+struct gembird_joy_device {
+	struct hid_report *report;
+};
+
+static int hid_gembird_joy_play(struct input_dev *dev, void *data,
+				struct ff_effect *effect)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+	struct gembird_joy_device *joy = data;
+	int strong, weak;
+
+	strong = effect->u.rumble.strong_magnitude;
+	weak = effect->u.rumble.weak_magnitude;
+
+	hid_dbg(hid, "called with 0x%04x 0x%04x\n", strong, weak);
+
+	/* Likely there are two motors, one in the base and the other in an upper
+	 * part of the stick, yet they are not different in strength, and honestly
+	 * it is hard to determine which motor is active or correlates to value 0
+	 * or 1 of the report field. However, the third value does not have any
+	 * function, thus it will always be set to 0.
+	 *
+	 * The windows drivers want to make believe the first value in the report
+	 * field should be influenced by horizontal axis movement, and the second
+	 * by vertical axis movement, but this might just be some arbitrary gimmick
+	 * of the configuration dialog, which describes the motors as left and
+	 * right.
+	 *
+	 * Ranges are the same for both motors, weak and strong (0 to 31), so scale
+	 * down the magnitudes accordingly...
+	 */
+	strong = (strong / 0xff) * 0x1f / 0xff;
+	weak = (weak / 0xff) * 0x1f / 0xff;
+
+	/* ... and to support the notions of strong vs weak rumble effects,
+	 * increase the magnitude for the strong rumble effect if it is below the
+	 * half of the maximum value, as the strong motor has the same strength as
+	 * the weak one. Likewise, decrease the magnitude for the weak effect.
+	 */
+	if (strong < 0x10 && !weak)         /* fftest effect 4 strong rumble */
+		strong *= 2;
+	else if (!strong && weak >= 0x10)   /* fftest effect 5 weak rumble */
+		weak /= 2;
+
+	/* Use unmodified values if both magnitudes have been set. */
+	joy->report->field[0]->value[0] = strong;
+	joy->report->field[0]->value[1] = weak;
+	joy->report->field[0]->value[2] = 0;
+
+	hid_dbg(hid, "running with 0x%02x, 0x%02x\n", strong, weak);
+	hid_hw_request(hid, joy->report, HID_REQ_SET_REPORT);
+
+	return 0;
+}
+
+static int gembird_joy_init(struct hid_device *hid)
+{
+	struct gembird_joy_device *joy;
+	struct hid_report *report;
+	struct hid_input *hidinput;
+	struct list_head *report_list =
+			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct list_head *report_ptr = report_list;
+	struct input_dev *dev;
+	int error;
+
+	if (list_empty(&hid->inputs)) {
+		hid_err(hid, "no inputs found\n");
+		return -ENODEV;
+	}
+	hidinput = list_first_entry(&hid->inputs, struct hid_input, list);
+	dev = hidinput->input;
+
+	if (list_empty(report_list)) {
+		hid_err(hid, "no output reports found\n");
+		return -ENODEV;
+	}
+
+	list_for_each_entry(hidinput, &hid->inputs, list) {
+		report_ptr = report_ptr->next;
+
+		if (report_ptr == report_list) {
+			hid_err(hid, "required output report is missing\n");
+			return -ENODEV;
+		}
+
+		report = list_entry(report_ptr, struct hid_report, list);
+		if (report->maxfield < 1) {
+			hid_err(hid, "no fields in the report\n");
+			return -ENODEV;
+		}
+
+		if (report->field[0]->report_count < 3) {
+			hid_err(hid, "not enough values in the field\n");
+			return -ENODEV;
+		}
+
+		joy = kzalloc(sizeof(struct gembird_joy_device), GFP_KERNEL);
+		if (!joy)
+			return -ENOMEM;
+
+		dev = hidinput->input;
+
+		set_bit(FF_RUMBLE, dev->ffbit);
+
+		error = input_ff_create_memless(dev, joy, hid_gembird_joy_play);
+		if (error) {
+			kfree(joy);
+			return error;
+		}
+
+		joy->report = report;
+		joy->report->field[0]->value[0] = 0x00;
+		joy->report->field[0]->value[1] = 0x00;
+		joy->report->field[0]->value[2] = 0x00;
+		hid_hw_request(hid, joy->report, HID_REQ_SET_REPORT);
+	}
+
+	hid_info(hid, "Force Feedback for Gembird Joystick devices by Harald Judt <h.judt@gmx.at>\n");
+
+	return 0;
+}
+
+static int gembird_joy_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		hid_err(hdev, "parse failed\n");
+		return ret;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+	if (ret) {
+		hid_err(hdev, "hw start failed\n");
+		return ret;
+	}
+
+	gembird_joy_init(hdev);
+
+	return 0;
+}
+
+static const struct hid_device_id gembird_joy_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD_JOY, USB_DEVICE_ID_GEMBIRD_JOY_SL_6630) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, gembird_joy_devices);
+
+static struct hid_driver gembird_joy_driver = {
+	.name = "gembird_joy",
+	.id_table = gembird_joy_devices,
+	.probe = gembird_joy_probe,
+};
+module_hid_driver(gembird_joy_driver);
+
+MODULE_AUTHOR("Harald Judt <h.judt@gmx.at>");
+MODULE_DESCRIPTION("Force feedback support for HID Gembird joysticks");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index c4589075a5ed..1bdd9b879152 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -528,6 +528,9 @@
 #define USB_VENDOR_ID_GEMBIRD			0x11ff
 #define USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2	0x3331
 
+#define USB_VENDOR_ID_GEMBIRD_JOY		0x12bd
+#define USB_DEVICE_ID_GEMBIRD_JOY_SL_6630	0xa02f
+
 #define USB_VENDOR_ID_GENERAL_TOUCH	0x0dfc
 #define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003
 #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS 0x0100
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 6a8a7ca3d804..835070491da7 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -444,6 +444,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
 #if IS_ENABLED(CONFIG_HID_GEMBIRD)
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD, USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2) },
 #endif
+#if IS_ENABLED(CONFIG_HID_GEMBIRD_JOY_FF)
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD_JOY, USB_DEVICE_ID_GEMBIRD_JOY_SL_6630) },
+#endif
 #if IS_ENABLED(CONFIG_HID_GFRM)
 	{ HID_BLUETOOTH_DEVICE(0x58, 0x2000) },
 	{ HID_BLUETOOTH_DEVICE(0x471, 0x2210) },
-- 
2.52.0



-- 
`Experience is the best teacher.'

PGP Key ID: 4FFFAB21B8580ABD
Fingerprint: E073 6DD8 FF40 9CF2 0665 11D4 4FFF AB21 B858 0ABD

^ permalink raw reply related

* Re: [PATCH v3 1/4] dt-bindings: input: adc-keys: allow all input properties
From: Rob Herring (Arm) @ 2026-04-15 22:19 UTC (permalink / raw)
  To: Nicolas Frattaroli
  Cc: Heiko Stuebner, kernel, Krzysztof Kozlowski, linux-kernel,
	linux-rockchip, linux-input, devicetree, Dmitry Torokhov,
	Conor Dooley, Alexandre Belloni, linux-arm-kernel,
	Krzysztof Kozlowski
In-Reply-To: <20260408-rock4d-audio-v3-1-49e43c3c2a68@collabora.com>


On Wed, 08 Apr 2026 19:49:39 +0200, Nicolas Frattaroli wrote:
> adc-keys, unlike gpio-keys, does not allow linux,input-type as a valid
> property. This makes it impossible to model devices that have ADC inputs
> that should generate switch events.
> 
> Replace "additionalProperties" with "unevaluatedProperties", so that any
> of the properties in the referenced input.yaml schema can be used.
> Consequently, throw out the explicit mention of "linux,code" and extend
> the example to verify.
> 
> Suggested-by: Krzysztof Kozlowski <krzk@kernel.org>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> ---
>  Documentation/devicetree/bindings/input/adc-keys.yaml | 17 ++++++++++++-----
>  1 file changed, 12 insertions(+), 5 deletions(-)
> 

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply

* [PATCH v4] HID: magicmouse: add battery reporting for Magic Trackpad v1
From: Damiano Gragnaniello @ 2026-04-15 21:53 UTC (permalink / raw)
  To: jikos; +Cc: bentiss, linux-input, Damiano Gragnaniello
In-Reply-To: <20260415155548.927385-1-damianogragnaniello@gmail.com>

The Magic Trackpad v1 (A1339) reports battery level via Bluetooth using
Report ID 0x47. This patch adds support for parsing this report and
registering a power_supply interface so that userspace (upower) can
correctly display the battery percentage for this legacy device.

Signed-off-by: Damiano Gragnaniello <damianogragnaniello@gmail.com>
---
v4:
  - Fixed patch formatting and spacing issues to ensure clean application.
  - Removed local path references and non-technical notes.
  - Corrected diff headers.
v3:
  - Fixed changelog language (translated from Italian to English).
  - Standardized patch naming for upstream submission.
v2:
  - Rename macros to TRACKPAD_V1_BATTERY_REPORT_ID for clarity.
  - Add clamp_val() to ensure battery capacity stays within 0-100 range.
  - Restore original driver comments.

 drivers/hid/hid-magicmouse.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 79a60c6..82b3c1d 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -62,6 +62,8 @@
 #define TRACKPAD_REPORT_ID 0x28
 #define TRACKPAD2_USB_REPORT_ID 0x02
 #define TRACKPAD2_BT_REPORT_ID 0x31
+#define TRACKPAD_V1_BATTERY_REPORT_ID 0x47
+#define TRACKPAD_V1_BATTERY_TIMEOUT_SEC 60
 #define MOUSE_REPORT_ID    0x29
 #define MOUSE2_REPORT_ID   0x12
 #define DOUBLE_REPORT_ID   0xf7
@@ -156,6 +158,44 @@ struct magicmouse_sc {
 	struct hid_device *hdev;
 	struct delayed_work work;
 	struct timer_list battery_timer;
+
+	/* Magic Trackpad v1 battery support */
+	struct power_supply *battery;
+	struct power_supply_desc battery_desc;
+	char battery_name[64];
+	int battery_capacity;
+};
+
+static const enum power_supply_property magicmouse_v1_battery_props[] = {
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_STATUS,
+};
+
+static int magicmouse_v1_battery_get_property(struct power_supply *psy,
+					   enum power_supply_property psp,
+					   union power_supply_propval *val)
+{
+	struct magicmouse_sc *msc = power_supply_get_drvdata(psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = 1;
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		val->intval = msc->battery_capacity;
+		break;
+	case POWER_SUPPLY_PROP_SCOPE:
+		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+		break;
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
 }
 
 static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -434,6 +474,16 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 
 	switch (data[0]) {
+	case TRACKPAD_V1_BATTERY_REPORT_ID:
+		if (size < 2)
+			return 0;
+		if (msc->battery) {
+			msc->battery_capacity = clamp_val((int)data[1], 0, 100);
+			power_supply_changed(msc->battery);
+		}
+		return 0;
 	case TRACKPAD_REPORT_ID:
 	case TRACKPAD2_BT_REPORT_ID:
 		/* Expect four bytes of prefix, and N*9 bytes of touch data. */
@@ -939,6 +989,32 @@ static int magicmouse_probe(struct hid_device *hdev,
 		magicmouse_fetch_battery(hdev);
 	}
 
+	if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD &&
+	    id->vendor == USB_VENDOR_ID_APPLE) {
+		struct power_supply_config psy_cfg = {};
+
+		psy_cfg.drv_data = msc;
+		msc->battery_capacity = 0;
+		snprintf(msc->battery_name, sizeof(msc->battery_name),
+			 "hid-magictrackpad-v1-%s", dev_name(&hdev->dev));
+
+		msc->battery_desc.name           = msc->battery_name;
+		msc->battery_desc.type           = POWER_SUPPLY_TYPE_BATTERY;
+		msc->battery_desc.properties     = magicmouse_v1_battery_props;
+		msc->battery_desc.num_properties = ARRAY_SIZE(magicmouse_v1_battery_props);
+		msc->battery_desc.get_property   = magicmouse_v1_battery_get_property;
+
+		msc->battery = devm_power_supply_register(&hdev->dev,
+							  &msc->battery_desc,
+							  &psy_cfg);
+		if (IS_ERR(msc->battery)) {
+			hid_err(hdev, "can't register battery device\n");
+			msc->battery = NULL;
+		}
+	}
+
 	return 0;
 }

^ permalink raw reply related

* Re: [PATCH v4] dt-bindings: input: touchscreen: ti,tsc2005: Add wakeup-source
From: Rob Herring (Arm) @ 2026-04-15 21:34 UTC (permalink / raw)
  To: phucduc.bui
  Cc: tglx, linux-input, krzk, dmitry.torokhov, linux-kernel, conor+dt,
	conor, devicetree, mingo, krzk+dt, marex
In-Reply-To: <20260403040714.106093-1-phucduc.bui@gmail.com>


On Fri, 03 Apr 2026 11:07:14 +0700, phucduc.bui@gmail.com wrote:
> From: bui duc phuc <phucduc.bui@gmail.com>
> 
> Document the "wakeup-source" property for the ti,tsc2005 touchscreen
> controllers to allow the device to wake the system from suspend.
> 
> Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
> ---
> 
> changes:
> v4: Drop redundant "type: boolean" for wakeup-source to use the core
>     definition from dt-schema (as suggested by Rob Herring).
> v3: Remove blank lines (suggested by Conor).
> v2: Revise the commit content and remove patch1 related to I2C and SPI
> wakeup handling
>  .../devicetree/bindings/input/touchscreen/ti,tsc2005.yaml     | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply

* [PATCH v3] HID: magicmouse: add battery reporting for Magic Trackpad v1
From: Damiano Gragnaniello @ 2026-04-15 21:31 UTC (permalink / raw)
  To: jikos; +Cc: bentiss, linux-input, Damiano Gragnaniello
In-Reply-To: <20260415155548.927385-1-damianogragnaniello@gmail.com>

The Magic Trackpad v1 (A1339) reports battery level via Bluetooth using
Report ID 0x47. This patch adds support for parsing this report and 
registering a power_supply interface so that userspace (upower) can 
correctly display the battery percentage.

Signed-off-by: Damiano Gragnaniello <damianogragnaniello@gmail.com>
---
v3:
  - Fixed changelog language (translated from Italian to English).
  - Standardized patch naming and formatting for upstream submission.
  - Ensured UTF-8 encoding and fixed minor alignment issues.

v2:
  - Rename macros to TRACKPAD_V1_BATTERY_REPORT_ID for clarity.
  - Add clamp_val() to ensure battery capacity stays within 0-100 range.
  - Restore original driver comments in the source file.
  - Optimize code alignment according to kernel coding style guidelines.

 drivers/hid/hid-magicmouse.c | 56 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 79a60c6..82b3c1d 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -62,6 +62,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
 #define TRACKPAD_REPORT_ID 0x28
 #define TRACKPAD2_USB_REPORT_ID 0x02
 #define TRACKPAD2_BT_REPORT_ID 0x31
+#define TRACKPAD_V1_BATTERY_REPORT_ID 0x47
+#define TRACKPAD_V1_BATTERY_TIMEOUT_SEC 60
 
 #define MOUSE_REPORT_ID    0x29
 #define MOUSE2_REPORT_ID   0x12
@@ -156,6 +158,12 @@ struct magicmouse_sc {
 	struct delayed_work work;
 	struct timer_list battery_timer;
 
+	/* Magic Trackpad v1 battery support */
+	struct power_supply *battery;
+	struct power_supply_desc battery_desc;
+	char battery_name[64];
+	int battery_capacity;
+};
+
+static const enum power_supply_property magicmouse_v1_battery_props[] = {
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_STATUS,
+};
+
+static int magicmouse_v1_battery_get_property(struct power_supply *psy,
+					   enum power_supply_property psp,
+					   union power_supply_propval *val)
+{
+	struct magicmouse_sc *msc = power_supply_get_drvdata(psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = 1;
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		val->intval = msc->battery_capacity;
+		break;
+	case POWER_SUPPLY_PROP_SCOPE:
+		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+		break;
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int magicmouse_firm_touch(struct magicmouse_sc *msc)
 {
@@ -434,6 +442,16 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 
 	switch (data[0]) {
+	case TRACKPAD_V1_BATTERY_REPORT_ID:
+		if (size < 2)
+			return 0;
+		if (msc->battery) {
+			msc->battery_capacity = clamp_val((int)data[1], 0, 100);
+			power_supply_changed(msc->battery);
+		}
+		return 0;
 	case TRACKPAD_REPORT_ID:
 	case TRACKPAD2_BT_REPORT_ID:
 		/* Expect four bytes of prefix, and N*9 bytes of touch data. */
@@ -939,6 +957,32 @@ static int magicmouse_probe(struct hid_device *hdev,
 		magicmouse_fetch_battery(hdev);
 	}
 
+	if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD &&
+	    id->vendor == USB_VENDOR_ID_APPLE) {
+		struct power_supply_config psy_cfg = {};
+
+		psy_cfg.drv_data = msc;
+		msc->battery_capacity = 0;
+		snprintf(msc->battery_name, sizeof(msc->battery_name),
+			 "hid-magictrackpad-v1-%s", dev_name(&hdev->dev));
+
+		msc->battery_desc.name           = msc->battery_name;
+		msc->battery_desc.type           = POWER_SUPPLY_TYPE_BATTERY;
+		msc->battery_desc.properties     = magicmouse_v1_battery_props;
+		msc->battery_desc.num_properties = ARRAY_SIZE(magicmouse_v1_battery_props);
+		msc->battery_desc.get_property   = magicmouse_v1_battery_get_property;
+
+		msc->battery = devm_power_supply_register(&hdev->dev,
+							  &msc->battery_desc,
+							  &psy_cfg);
+		if (IS_ERR(msc->battery)) {
+			hid_err(hdev, "can't register battery device\n");
+			msc->battery = NULL;
+		}
+	}
+
 	return 0;
 }
-- 
2.34.1

^ permalink raw reply related

* [PATCH v2] HID: magicmouse: add battery reporting for Magic Trackpad v1
From: Damiano Gragnaniello @ 2026-04-15 20:41 UTC (permalink / raw)
  To: jikos; +Cc: linux-input, Damiano Gragnaniello
In-Reply-To: <20260415155548.927385-1-damianogragnaniello@gmail.com>

---
 .../hid-magicmouse.c                          | 462 ++++--------------
 1 file changed, 101 insertions(+), 361 deletions(-)

diff --git a/hid-magictrackpad-v1-battery-main/hid-magictrackpad-v1-battery/hid-magicmouse.c b/hid-magictrackpad-v1-battery-main/hid-magictrackpad-v1-battery/hid-magicmouse.c
index 79a60c6..652760a 100644
--- a/hid-magictrackpad-v1-battery-main/hid-magictrackpad-v1-battery/hid-magicmouse.c
+++ b/hid-magictrackpad-v1-battery-main/hid-magictrackpad-v1-battery/hid-magicmouse.c
@@ -1,12 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
- *   Apple "Magic" Wireless Mouse driver
+ * Apple "Magic" Wireless Mouse driver
  *
- *   Copyright (c) 2010 Michael Poole <mdpoole@troilus.org>
- *   Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com>
- */
-
-/*
+ * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org>
+ * Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com>
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -64,25 +61,16 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
 #define TRACKPAD_V1_BATTERY_REPORT_ID 0x47
 #define USB_BATTERY_TIMEOUT_SEC 60
 
-/* These definitions are not precise, but they're close enough.  (Bits
- * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
- * to be some kind of bit mask -- 0x20 may be a near-field reading,
- * and 0x40 is actual contact, and 0x10 may be a start/stop or change
- * indication.)
- */
 #define TOUCH_STATE_MASK  0xf0
 #define TOUCH_STATE_NONE  0x00
 #define TOUCH_STATE_START 0x30
 #define TOUCH_STATE_DRAG  0x40
 
-/* Number of high-resolution events for each low-resolution detent. */
 #define SCROLL_HR_STEPS 10
 #define SCROLL_HR_MULT (120 / SCROLL_HR_STEPS)
 #define SCROLL_HR_THRESHOLD 90 /* units */
 #define SCROLL_ACCEL_DEFAULT 7
 
-/* Touch surface information. Dimension is in hundredths of a mm, min and max
- * are in units. */
 #define MOUSE_DIMENSION_X (float)9056
 #define MOUSE_MIN_X -1100
 #define MOUSE_MAX_X 1258
@@ -114,23 +102,6 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
 #define TRACKPAD2_RES_Y \
 	((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100))
 
-/**
- * struct magicmouse_sc - Tracks Magic Mouse-specific data.
- * @input: Input device through which we report events.
- * @quirks: Currently unused.
- * @ntouches: Number of touches in most recent touch report.
- * @scroll_accel: Number of consecutive scroll motions.
- * @scroll_jiffies: Time of last scroll motion.
- * @touches: Most recent data for a touch, indexed by tracking ID.
- * @tracking_ids: Mapping of current touch input data to @touches.
- * @hdev: Pointer to the underlying HID device.
- * @work: Workqueue to handle initialization retry for quirky devices.
- * @battery_timer: Timer for obtaining battery level information.
- * @battery: Power supply instance for Magic Trackpad v1 AA battery reporting.
- * @battery_desc: Descriptor for the power_supply registration.
- * @battery_name: Name buffer for the power_supply instance.
- * @battery_capacity: Last known battery level (0-100%) for Magic Trackpad v1.
- */
 struct magicmouse_sc {
 	struct input_dev *input;
 	unsigned long quirks;
@@ -156,11 +127,11 @@ struct magicmouse_sc {
 	struct delayed_work work;
 	struct timer_list battery_timer;
 
-	/* Magic Trackpad v1 (AA battery) power_supply support */
-	struct power_supply		*battery;
-	struct power_supply_desc	 battery_desc;
-	char				 battery_name[64];
-	int				 battery_capacity;
+	/* Magic Trackpad v1 battery support */
+	struct power_supply *battery;
+	struct power_supply_desc battery_desc;
+	char battery_name[64];
+	int battery_capacity;
 };
 
 static const enum power_supply_property magicmouse_v1_battery_props[] = {
@@ -171,8 +142,8 @@ static const enum power_supply_property magicmouse_v1_battery_props[] = {
 };
 
 static int magicmouse_v1_battery_get_property(struct power_supply *psy,
-					       enum power_supply_property psp,
-					       union power_supply_propval *val)
+					   enum power_supply_property psp,
+					   union power_supply_propval *val)
 {
 	struct magicmouse_sc *msc = power_supply_get_drvdata(psy);
 
@@ -200,13 +171,9 @@ static int magicmouse_firm_touch(struct magicmouse_sc *msc)
 	int touch = -1;
 	int ii;
 
-	/* If there is only one "firm" touch, set touch to its
-	 * tracking ID.
-	 */
 	for (ii = 0; ii < msc->ntouches; ii++) {
 		int idx = msc->tracking_ids[ii];
 		if (msc->touches[idx].size < 8) {
-			/* Ignore this touch. */
 		} else if (touch >= 0) {
 			touch = -1;
 			break;
@@ -214,7 +181,6 @@ static int magicmouse_firm_touch(struct magicmouse_sc *msc)
 			touch = idx;
 		}
 	}
-
 	return touch;
 }
 
@@ -226,13 +192,7 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
 
 	if (emulate_3button) {
 		int id;
-
-		/* If some button was pressed before, keep it held
-		 * down.  Otherwise, if there's exactly one firm
-		 * touch, use that to override the mouse's guess.
-		 */
 		if (state == 0) {
-			/* The button was released. */
 		} else if (last_state != 0) {
 			state = last_state;
 		} else if ((id = magicmouse_firm_touch(msc)) >= 0) {
@@ -243,8 +203,7 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
 				state = 2;
 			else
 				state = 4;
-		} /* else: we keep the mouse's guess */
-
+		}
 		input_report_key(msc->input, BTN_MIDDLE, state & 4);
 	}
 
@@ -274,8 +233,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
 		state = tdata[7] & TOUCH_STATE_MASK;
 		down = state != TOUCH_STATE_NONE;
 	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
-		   input->id.product ==
-			   USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
+		   input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		id = tdata[8] & 0xf;
 		x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
 		y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
@@ -298,30 +256,21 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
 		down = state != TOUCH_STATE_NONE;
 	}
 
-	/* Store tracking ID and other fields. */
 	msc->tracking_ids[raw_id] = id;
 	msc->touches[id].x = x;
 	msc->touches[id].y = y;
 	msc->touches[id].size = size;
 
-	/* If requested, emulate a scroll wheel by detecting small
-	 * vertical touch motions.
-	 */
 	if (emulate_scroll_wheel &&
 	    input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
 	    input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		unsigned long now = jiffies;
 		int step_x = msc->touches[id].scroll_x - x;
 		int step_y = msc->touches[id].scroll_y - y;
-		int step_hr =
-			max_t(int,
-			      ((64 - (int)scroll_speed) * msc->scroll_accel) /
-					SCROLL_HR_STEPS,
-			      1);
+		int step_hr = max_t(int, ((64 - (int)scroll_speed) * msc->scroll_accel) / SCROLL_HR_STEPS, 1);
 		int step_x_hr = msc->touches[id].scroll_x_hr - x;
 		int step_y_hr = msc->touches[id].scroll_y_hr - y;
 
-		/* Calculate and apply the scroll motion. */
 		switch (state) {
 		case TOUCH_STATE_START:
 			msc->touches[id].scroll_x = x;
@@ -330,65 +279,43 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
 			msc->touches[id].scroll_y_hr = y;
 			msc->touches[id].scroll_x_active = false;
 			msc->touches[id].scroll_y_active = false;
-
-			/* Reset acceleration after half a second. */
-			if (scroll_acceleration && time_before(now,
-						msc->scroll_jiffies + HZ / 2))
-				msc->scroll_accel = max_t(int,
-						msc->scroll_accel - 1, 1);
+			if (scroll_acceleration && time_before(now, msc->scroll_jiffies + HZ / 2))
+				msc->scroll_accel = max_t(int, msc->scroll_accel - 1, 1);
 			else
 				msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
-
 			break;
 		case TOUCH_STATE_DRAG:
 			step_x /= (64 - (int)scroll_speed) * msc->scroll_accel;
 			if (step_x != 0) {
-				msc->touches[id].scroll_x -= step_x *
-					(64 - scroll_speed) * msc->scroll_accel;
+				msc->touches[id].scroll_x -= step_x * (64 - scroll_speed) * msc->scroll_accel;
 				msc->scroll_jiffies = now;
 				input_report_rel(input, REL_HWHEEL, -step_x);
 			}
-
 			step_y /= (64 - (int)scroll_speed) * msc->scroll_accel;
 			if (step_y != 0) {
-				msc->touches[id].scroll_y -= step_y *
-					(64 - scroll_speed) * msc->scroll_accel;
+				msc->touches[id].scroll_y -= step_y * (64 - scroll_speed) * msc->scroll_accel;
 				msc->scroll_jiffies = now;
 				input_report_rel(input, REL_WHEEL, step_y);
 			}
-
-			if (!msc->touches[id].scroll_x_active &&
-			    abs(step_x_hr) > SCROLL_HR_THRESHOLD) {
+			if (!msc->touches[id].scroll_x_active && abs(step_x_hr) > SCROLL_HR_THRESHOLD) {
 				msc->touches[id].scroll_x_active = true;
 				msc->touches[id].scroll_x_hr = x;
 				step_x_hr = 0;
 			}
-
 			step_x_hr /= step_hr;
-			if (step_x_hr != 0 &&
-			    msc->touches[id].scroll_x_active) {
-				msc->touches[id].scroll_x_hr -= step_x_hr *
-					step_hr;
-				input_report_rel(input,
-						 REL_HWHEEL_HI_RES,
-						 -step_x_hr * SCROLL_HR_MULT);
+			if (step_x_hr != 0 && msc->touches[id].scroll_x_active) {
+				msc->touches[id].scroll_x_hr -= step_x_hr * step_hr;
+				input_report_rel(input, REL_HWHEEL_HI_RES, -step_x_hr * SCROLL_HR_MULT);
 			}
-
-			if (!msc->touches[id].scroll_y_active &&
-			    abs(step_y_hr) > SCROLL_HR_THRESHOLD) {
+			if (!msc->touches[id].scroll_y_active && abs(step_y_hr) > SCROLL_HR_THRESHOLD) {
 				msc->touches[id].scroll_y_active = true;
 				msc->touches[id].scroll_y_hr = y;
 				step_y_hr = 0;
 			}
-
 			step_y_hr /= step_hr;
-			if (step_y_hr != 0 &&
-			    msc->touches[id].scroll_y_active) {
-				msc->touches[id].scroll_y_hr -= step_y_hr *
-					step_hr;
-				input_report_rel(input,
-						 REL_WHEEL_HI_RES,
-						 step_y_hr * SCROLL_HR_MULT);
+			if (step_y_hr != 0 && msc->touches[id].scroll_y_active) {
+				msc->touches[id].scroll_y_hr -= step_y_hr * step_hr;
+				input_report_rel(input, REL_WHEEL_HI_RES, step_y_hr * SCROLL_HR_MULT);
 			}
 			break;
 		}
@@ -400,7 +327,6 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
 	input_mt_slot(input, id);
 	input_mt_report_slot_state(input, MT_TOOL_FINGER, down);
 
-	/* Generate the input events for this touch. */
 	if (down) {
 		input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2);
 		input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2);
@@ -409,8 +335,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
 		input_report_abs(input, ABS_MT_POSITION_Y, y);
 
 		if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
-		    input->id.product ==
-			    USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC)
+		    input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC)
 			input_report_abs(input, ABS_MT_PRESSURE, pressure);
 
 		if (report_undeciphered) {
@@ -418,10 +343,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
 			    input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
 			    input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC)
 				input_event(input, EV_MSC, MSC_RAW, tdata[7]);
-			else if (input->id.product !=
-					 USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
-				 input->id.product !=
-					 USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC)
+			else if (input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
+				 input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC)
 				input_event(input, EV_MSC, MSC_RAW, tdata[8]);
 		}
 	}
@@ -436,11 +359,6 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 
 	switch (data[0]) {
 	case TRACKPAD_V1_BATTERY_REPORT_ID:
-		/*
-		 * Magic Trackpad v1 (AA battery, 0x030e) sends battery level
-		 * in byte 1, already expressed as a percentage (0-100).
-		 * Clamp defensively and notify the power_supply framework.
-		 */
 		if (size < 2)
 			return 0;
 		if (msc->battery) {
@@ -450,106 +368,64 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 		return 0;
 	case TRACKPAD_REPORT_ID:
 	case TRACKPAD2_BT_REPORT_ID:
-		/* Expect four bytes of prefix, and N*9 bytes of touch data. */
 		if (size < 4 || ((size - 4) % 9) != 0)
 			return 0;
 		npoints = (size - 4) / 9;
 		if (npoints > 15) {
-			hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n",
-					size);
+			hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n", size);
 			return 0;
 		}
 		msc->ntouches = 0;
 		for (ii = 0; ii < npoints; ii++)
 			magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
-
 		clicks = data[1];
-
-		/* The following bits provide a device specific timestamp. They
-		 * are unused here.
-		 *
-		 * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10;
-		 */
 		break;
 	case TRACKPAD2_USB_REPORT_ID:
-		/* Expect twelve bytes of prefix and N*9 bytes of touch data. */
 		if (size < 12 || ((size - 12) % 9) != 0)
 			return 0;
 		npoints = (size - 12) / 9;
 		if (npoints > 15) {
-			hid_warn(hdev, "invalid size value (%d) for TRACKPAD2_USB_REPORT_ID\n",
-					size);
+			hid_warn(hdev, "invalid size value (%d) for TRACKPAD2_USB_REPORT_ID\n", size);
 			return 0;
 		}
 		msc->ntouches = 0;
 		for (ii = 0; ii < npoints; ii++)
 			magicmouse_emit_touch(msc, ii, data + ii * 9 + 12);
-
 		clicks = data[1];
 		break;
 	case MOUSE_REPORT_ID:
-		/* Expect six bytes of prefix, and N*8 bytes of touch data. */
 		if (size < 6 || ((size - 6) % 8) != 0)
 			return 0;
 		npoints = (size - 6) / 8;
 		if (npoints > 15) {
-			hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n",
-					size);
+			hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n", size);
 			return 0;
 		}
 		msc->ntouches = 0;
 		for (ii = 0; ii < npoints; ii++)
 			magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
-
-		/* When emulating three-button mode, it is important
-		 * to have the current touch information before
-		 * generating a click event.
-		 */
 		x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22;
 		y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22;
 		clicks = data[3];
-
-		/* The following bits provide a device specific timestamp. They
-		 * are unused here.
-		 *
-		 * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10;
-		 */
 		break;
 	case MOUSE2_REPORT_ID:
-		/* Size is either 8 or (14 + 8 * N) */
 		if (size != 8 && (size < 14 || (size - 14) % 8 != 0))
 			return 0;
 		npoints = (size - 14) / 8;
 		if (npoints > 15) {
-			hid_warn(hdev, "invalid size value (%d) for MOUSE2_REPORT_ID\n",
-					size);
+			hid_warn(hdev, "invalid size value (%d) for MOUSE2_REPORT_ID\n", size);
 			return 0;
 		}
 		msc->ntouches = 0;
 		for (ii = 0; ii < npoints; ii++)
 			magicmouse_emit_touch(msc, ii, data + ii * 8 + 14);
-
-		/* When emulating three-button mode, it is important
-		 * to have the current touch information before
-		 * generating a click event.
-		 */
 		x = (int)((data[3] << 24) | (data[2] << 16)) >> 16;
 		y = (int)((data[5] << 24) | (data[4] << 16)) >> 16;
 		clicks = data[1];
-
-		/* The following bits provide a device specific timestamp. They
-		 * are unused here.
-		 *
-		 * ts = data[11] >> 6 | data[12] << 2 | data[13] << 10;
-		 */
 		break;
 	case DOUBLE_REPORT_ID:
-		/* Sometimes the trackpad sends two touch reports in one
-		 * packet.
-		 */
 		magicmouse_raw_event(hdev, report, data + 2, data[1]);
-		magicmouse_raw_event(hdev, report, data + 2 + data[1],
-			size - 2 - data[1]);
+		magicmouse_raw_event(hdev, report, data + 2 + data[1], size - 2 - data[1]);
 		return 0;
 	default:
 		return 0;
@@ -562,8 +438,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 		input_report_rel(input, REL_X, x);
 		input_report_rel(input, REL_Y, y);
 	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
-		   input->id.product ==
-			   USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
+		   input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		input_mt_sync_frame(input);
 		input_report_key(input, BTN_MOUSE, clicks & 1);
 	} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
@@ -582,12 +457,6 @@ static int magicmouse_event(struct hid_device *hdev, struct hid_field *field,
 	if ((msc->input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
 	     msc->input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC) &&
 	    field->report->id == MOUSE2_REPORT_ID) {
-		/*
-		 * magic_mouse_raw_event has done all the work. Skip hidinput.
-		 *
-		 * Specifically, hidinput may modify BTN_LEFT and BTN_RIGHT,
-		 * breaking emulate_3button.
-		 */
 		return 1;
 	}
 	return 0;
@@ -618,25 +487,15 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
 			__set_bit(REL_HWHEEL_HI_RES, input->relbit);
 		}
 	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
-		   input->id.product ==
-			   USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
-		/* If the trackpad has been connected to a Mac, the name is
-		 * automatically personalized, e.g., "José Expósito's Trackpad".
-		 * When connected through Bluetooth, the personalized name is
-		 * reported, however, when connected through USB the generic
-		 * name is reported.
-		 * Set the device name to ensure the same driver settings get
-		 * loaded, whether connected through bluetooth or USB.
-		 */
+		   input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		if (hdev->vendor == BT_VENDOR_ID_APPLE) {
 			if (input->id.version == TRACKPAD2_2021_BT_VERSION)
 				input->name = "Apple Inc. Magic Trackpad 2021";
-			else if (input->id.version == TRACKPAD_2024_BT_VERSION) {
+			else if (input->id.version == TRACKPAD_2024_BT_VERSION)
 				input->name = "Apple Inc. Magic Trackpad USB-C";
-			} else {
+			else
 				input->name = "Apple Inc. Magic Trackpad";
-			}
-		} else { /* USB_VENDOR_ID_APPLE */
+		} else {
 			input->name = hdev->name;
 		}
 
@@ -648,14 +507,8 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
 		__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
 		__set_bit(BTN_TOOL_FINGER, input->keybit);
 
-		mt_flags = INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED |
-				INPUT_MT_TRACK;
+		mt_flags = INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK;
 	} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
-		/* input->keybit is initialized with incorrect button info
-		 * for Magic Trackpad. There really is only one physical
-		 * button (BTN_LEFT == BTN_MOUSE). Make sure we don't
-		 * advertise buttons that don't exist...
-		 */
 		__clear_bit(BTN_RIGHT, input->keybit);
 		__clear_bit(BTN_MIDDLE, input->keybit);
 		__set_bit(BTN_MOUSE, input->keybit);
@@ -669,72 +522,45 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
 		__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
 	}
 
-
 	__set_bit(EV_ABS, input->evbit);
 
 	error = input_mt_init_slots(input, 16, mt_flags);
 	if (error)
 		return error;
-	input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
-			     4, 0);
-	input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2,
-			     4, 0);
-
-	/* Note: Touch Y position from the device is inverted relative
-	 * to how pointer motion is reported (and relative to how USB
-	 * HID recommends the coordinates work).  This driver keeps
-	 * the origin at the same position, and just uses the additive
-	 * inverse of the reported Y.
-	 */
+	input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, 4, 0);
+	input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2, 4, 0);
+
 	if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
 	    input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
 	    input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC) {
 		input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
-		input_set_abs_params(input, ABS_MT_POSITION_X,
-				     MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
-		input_set_abs_params(input, ABS_MT_POSITION_Y,
-				     MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
-
-		input_abs_set_res(input, ABS_MT_POSITION_X,
-				  MOUSE_RES_X);
-		input_abs_set_res(input, ABS_MT_POSITION_Y,
-				  MOUSE_RES_Y);
+		input_set_abs_params(input, ABS_MT_POSITION_X, MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
+		input_set_abs_params(input, ABS_MT_POSITION_Y, MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
+		input_abs_set_res(input, ABS_MT_POSITION_X, MOUSE_RES_X);
+		input_abs_set_res(input, ABS_MT_POSITION_Y, MOUSE_RES_Y);
 	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
-		   input->id.product ==
-			   USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
+		   input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		input_set_abs_params(input, ABS_MT_PRESSURE, 0, 253, 0, 0);
 		input_set_abs_params(input, ABS_PRESSURE, 0, 253, 0, 0);
 		input_set_abs_params(input, ABS_MT_ORIENTATION, -3, 4, 0, 0);
-		input_set_abs_params(input, ABS_X, TRACKPAD2_MIN_X,
-				     TRACKPAD2_MAX_X, 0, 0);
-		input_set_abs_params(input, ABS_Y, TRACKPAD2_MIN_Y,
-				     TRACKPAD2_MAX_Y, 0, 0);
-		input_set_abs_params(input, ABS_MT_POSITION_X,
-				     TRACKPAD2_MIN_X, TRACKPAD2_MAX_X, 0, 0);
-		input_set_abs_params(input, ABS_MT_POSITION_Y,
-				     TRACKPAD2_MIN_Y, TRACKPAD2_MAX_Y, 0, 0);
-
+		input_set_abs_params(input, ABS_X, TRACKPAD2_MIN_X, TRACKPAD2_MAX_X, 0, 0);
+		input_set_abs_params(input, ABS_Y, TRACKPAD2_MIN_Y, TRACKPAD2_MAX_Y, 0, 0);
+		input_set_abs_params(input, ABS_MT_POSITION_X, TRACKPAD2_MIN_X, TRACKPAD2_MAX_X, 0, 0);
+		input_set_abs_params(input, ABS_MT_POSITION_Y, TRACKPAD2_MIN_Y, TRACKPAD2_MAX_Y, 0, 0);
 		input_abs_set_res(input, ABS_X, TRACKPAD2_RES_X);
 		input_abs_set_res(input, ABS_Y, TRACKPAD2_RES_Y);
 		input_abs_set_res(input, ABS_MT_POSITION_X, TRACKPAD2_RES_X);
 		input_abs_set_res(input, ABS_MT_POSITION_Y, TRACKPAD2_RES_Y);
 	} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
 		input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
-		input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
-				     TRACKPAD_MAX_X, 4, 0);
-		input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
-				     TRACKPAD_MAX_Y, 4, 0);
-		input_set_abs_params(input, ABS_MT_POSITION_X,
-				     TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
-		input_set_abs_params(input, ABS_MT_POSITION_Y,
-				     TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
-
+		input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
+		input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
+		input_set_abs_params(input, ABS_MT_POSITION_X, TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
+		input_set_abs_params(input, ABS_MT_POSITION_Y, TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
 		input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
 		input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
-		input_abs_set_res(input, ABS_MT_POSITION_X,
-				  TRACKPAD_RES_X);
-		input_abs_set_res(input, ABS_MT_POSITION_Y,
-				  TRACKPAD_RES_Y);
+		input_abs_set_res(input, ABS_MT_POSITION_X, TRACKPAD_RES_X);
+		input_abs_set_res(input, ABS_MT_POSITION_Y, TRACKPAD_RES_Y);
 	}
 
 	input_set_events_per_packet(input, 60);
@@ -746,10 +572,6 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
 		__set_bit(MSC_RAW, input->mscbit);
 	}
 
-	/*
-	 * hid-input may mark device as using autorepeat, but neither
-	 * the trackpad, nor the mouse actually want it.
-	 */
 	__clear_bit(EV_REP, input->evbit);
 
 	return 0;
@@ -764,11 +586,9 @@ static int magicmouse_input_mapping(struct hid_device *hdev,
 	if (!msc->input)
 		msc->input = hi->input;
 
-	/* Magic Trackpad does not give relative data after switching to MT */
 	if ((hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD ||
 	     hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
-	     hi->input->id.product ==
-		     USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
+	     hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
 	    field->flags & HID_MAIN_ITEM_RELATIVE)
 		return -1;
 
@@ -777,7 +597,6 @@ static int magicmouse_input_mapping(struct hid_device *hdev,
 
 static int magicmouse_input_configured(struct hid_device *hdev,
 		struct hid_input *hi)
-
 {
 	struct magicmouse_sc *msc = hid_get_drvdata(hdev);
 	int ret;
@@ -790,7 +609,6 @@ static int magicmouse_input_configured(struct hid_device *hdev,
 	ret = magicmouse_setup_input(msc->input, hdev);
 	if (ret) {
 		hid_err(hdev, "magicmouse setup input failed (%d)\n", ret);
-		/* clean msc->input to notify probe() of the failure */
 		msc->input = NULL;
 		return ret;
 	}
@@ -817,7 +635,7 @@ static int magicmouse_enable_multitouch(struct hid_device *hdev)
 			feature_size = sizeof(feature_mt_trackpad2_bt);
 			feature = feature_mt_trackpad2_bt;
 			break;
-		default: /* USB_VENDOR_ID_APPLE */
+		default:
 			feature_size = sizeof(feature_mt_trackpad2_usb);
 			feature = feature_mt_trackpad2_usb;
 		}
@@ -886,9 +704,6 @@ static int magicmouse_fetch_battery(struct hid_device *hdev)
 	if (!report || report->maxfield < 1)
 		return -1;
 
-	if (hdev->battery_capacity == hdev->battery_max)
-		return -1;
-
 	hid_hw_request(hdev, report, HID_REQ_GET_REPORT);
 	return 0;
 #else
@@ -898,13 +713,11 @@ static int magicmouse_fetch_battery(struct hid_device *hdev)
 
 static void magicmouse_battery_timer_tick(struct timer_list *t)
 {
-	struct magicmouse_sc *msc = timer_container_of(msc, t, battery_timer);
+	struct magicmouse_sc *msc = from_timer(msc, t, battery_timer);
 	struct hid_device *hdev = msc->hdev;
 
-	if (magicmouse_fetch_battery(hdev) == 0) {
-		mod_timer(&msc->battery_timer,
-			  jiffies + secs_to_jiffies(USB_BATTERY_TIMEOUT_SEC));
-	}
+	magicmouse_fetch_battery(hdev);
+	mod_timer(&msc->battery_timer, jiffies + USB_BATTERY_TIMEOUT_SEC * HZ);
 }
 
 static int magicmouse_probe(struct hid_device *hdev,
@@ -920,11 +733,9 @@ static int magicmouse_probe(struct hid_device *hdev,
 		return -ENOMEM;
 	}
 
-	msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
 	msc->hdev = hdev;
-	INIT_DEFERRABLE_WORK(&msc->work, magicmouse_enable_mt_work);
+	INIT_DEFERRED_WORK(&msc->work, magicmouse_enable_mt_work);
 
-	msc->quirks = id->driver_data;
 	hid_set_drvdata(hdev, msc);
 
 	ret = hid_parse(hdev);
@@ -939,19 +750,11 @@ static int magicmouse_probe(struct hid_device *hdev,
 		return ret;
 	}
 
-	if (is_usb_magicmouse2(id->vendor, id->product) ||
-	    is_usb_magictrackpad2(id->vendor, id->product)) {
-		timer_setup(&msc->battery_timer, magicmouse_battery_timer_tick, 0);
-		mod_timer(&msc->battery_timer,
-			  jiffies + secs_to_jiffies(USB_BATTERY_TIMEOUT_SEC));
-		magicmouse_fetch_battery(hdev);
-	}
-
-	/* Register power_supply for Magic Trackpad v1 (AA battery, BT only) */
 	if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD &&
 	    id->vendor == USB_VENDOR_ID_APPLE) {
 		struct power_supply_config psy_cfg = {};
 
+		psy_cfg.drv_data = msc;
 		msc->battery_capacity = 0;
 		snprintf(msc->battery_name, sizeof(msc->battery_name),
 			 "hid-magictrackpad-v1-%s", dev_name(&hdev->dev));
@@ -959,95 +762,63 @@ static int magicmouse_probe(struct hid_device *hdev,
 		msc->battery_desc.name           = msc->battery_name;
 		msc->battery_desc.type           = POWER_SUPPLY_TYPE_BATTERY;
 		msc->battery_desc.properties     = magicmouse_v1_battery_props;
-		msc->battery_desc.num_properties =
-			ARRAY_SIZE(magicmouse_v1_battery_props);
-		msc->battery_desc.get_property   =
-			magicmouse_v1_battery_get_property;
-
-		psy_cfg.drv_data = msc;
+		msc->battery_desc.num_properties = ARRAY_SIZE(magicmouse_v1_battery_props);
+		msc->battery_desc.get_property   = magicmouse_v1_battery_get_property;
 
 		msc->battery = devm_power_supply_register(&hdev->dev,
 							  &msc->battery_desc,
 							  &psy_cfg);
 		if (IS_ERR(msc->battery)) {
-			ret = PTR_ERR(msc->battery);
-			hid_err(hdev,
-				"unable to register trackpad v1 battery: %d\n",
-				ret);
+			hid_err(hdev, "can't register battery device\n");
 			msc->battery = NULL;
-			/* Non-fatal: continue without battery reporting */
 		}
 	}
 
-	if (is_usb_magicmouse2(id->vendor, id->product) ||
-	    (is_usb_magictrackpad2(id->vendor, id->product) &&
-	     hdev->type != HID_TYPE_USBMOUSE))
-		return 0;
-
 	if (!msc->input) {
 		hid_err(hdev, "magicmouse input not registered\n");
-		ret = -ENOMEM;
+		ret = -ENODEV;
 		goto err_stop_hw;
 	}
 
-	switch (id->product) {
-	case USB_DEVICE_ID_APPLE_MAGICMOUSE:
-		report = hid_register_report(hdev, HID_INPUT_REPORT, MOUSE_REPORT_ID, 0);
-		break;
-	case USB_DEVICE_ID_APPLE_MAGICMOUSE2:
-	case USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC:
-		report = hid_register_report(hdev, HID_INPUT_REPORT, MOUSE2_REPORT_ID, 0);
-		break;
-	case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2:
-	case USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC:
-		switch (id->vendor) {
-		case BT_VENDOR_ID_APPLE:
-			report = hid_register_report(hdev, HID_INPUT_REPORT,
-				TRACKPAD2_BT_REPORT_ID, 0);
-			break;
-		default:
-			report = hid_register_report(hdev, HID_INPUT_REPORT,
-				TRACKPAD2_USB_REPORT_ID, 0);
+	if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
+	    id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC ||
+	    id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+	    id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
+		if (is_usb_magicmouse2(id->vendor, id->product) ||
+		    is_usb_magictrackpad2(id->vendor, id->product)) {
+			timer_setup(&msc->battery_timer, magicmouse_battery_timer_tick, 0);
+			mod_timer(&msc->battery_timer, jiffies + USB_BATTERY_TIMEOUT_SEC * HZ);
 		}
-		break;
-	default: /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
-		report = hid_register_report(hdev, HID_INPUT_REPORT,
-			TRACKPAD_REPORT_ID, 0);
-		report = hid_register_report(hdev, HID_INPUT_REPORT,
-			DOUBLE_REPORT_ID, 0);
+		magicmouse_fetch_battery(hdev);
 	}
 
-	if (!report) {
-		hid_err(hdev, "unable to register touch report\n");
-		ret = -ENOMEM;
-		goto err_stop_hw;
+	if (id->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
+	    id->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
+		report = hid_register_report(hdev, HID_INPUT_REPORT, MOUSE_REPORT_ID);
+		if (!report) {
+			ret = -ENOMEM;
+			goto err_stop_hw;
+		}
+
+		report = hid_register_report(hdev, HID_INPUT_REPORT, DOUBLE_REPORT_ID);
+		if (!report) {
+			ret = -ENOMEM;
+			goto err_stop_hw;
+		}
 	}
-	report->size = 6;
-
-	/*
-	 * Some devices repond with 'invalid report id' when feature
-	 * report switching it into multitouch mode is sent to it.
-	 *
-	 * This results in -EIO from the _raw low-level transport callback,
-	 * but there seems to be no other way of switching the mode.
-	 * Thus the super-ugly hacky success check below.
-	 */
+
 	ret = magicmouse_enable_multitouch(hdev);
 	if (ret != -EIO && ret < 0) {
 		hid_err(hdev, "unable to request touch data (%d)\n", ret);
 		goto err_stop_hw;
 	}
-	if (ret == -EIO && (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
-			    id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC)) {
-		schedule_delayed_work(&msc->work, msecs_to_jiffies(500));
+	if (ret == -EIO && id->vendor == BT_VENDOR_ID_APPLE) {
+		schedule_deferred_work(&msc->work, HZ * 2);
 	}
 
 	return 0;
-err_stop_hw:
-	if (is_usb_magicmouse2(id->vendor, id->product) ||
-	    is_usb_magictrackpad2(id->vendor, id->product))
-		timer_delete_sync(&msc->battery_timer);
 
+err_stop_hw:
 	hid_hw_stop(hdev);
 	return ret;
 }
@@ -1057,45 +828,16 @@ static void magicmouse_remove(struct hid_device *hdev)
 	struct magicmouse_sc *msc = hid_get_drvdata(hdev);
 
 	if (msc) {
-		cancel_delayed_work_sync(&msc->work);
-		if (is_usb_magicmouse2(hdev->vendor, hdev->product) ||
-		    is_usb_magictrackpad2(hdev->vendor, hdev->product))
-			timer_delete_sync(&msc->battery_timer);
+		cancel_delayed_work_sync(&msc->work.work);
+		if (msc->battery_timer.function)
+			del_timer_sync(&msc->battery_timer);
 	}
 
 	hid_hw_stop(hdev);
 }
 
-static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
-					   unsigned int *rsize)
-{
-	/*
-	 * Change the usage from:
-	 *   0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1)  0
-	 *   0x09, 0x0b,       // Usage (Vendor Usage 0x0b)           3
-	 * To:
-	 *   0x05, 0x01,       // Usage Page (Generic Desktop)        0
-	 *   0x09, 0x02,       // Usage (Mouse)                       2
-	 */
-	if ((is_usb_magicmouse2(hdev->vendor, hdev->product) ||
-	     is_usb_magictrackpad2(hdev->vendor, hdev->product)) &&
-	    *rsize >= 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) {
-		hid_info(hdev,
-			 "fixing up magicmouse battery report descriptor\n");
-		*rsize = *rsize - 1;
-		rdesc = rdesc + 1;
-
-		rdesc[0] = 0x05;
-		rdesc[1] = 0x01;
-		rdesc[2] = 0x09;
-		rdesc[3] = 0x02;
-	}
-
-	return rdesc;
-}
-
-static const struct hid_device_id magic_mice[] = {
-	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+static const struct hid_device_id magicmouse_devices[] = {
+	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
 	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_MAGICMOUSE2), .driver_data = 0 },
@@ -1117,14 +859,13 @@ static const struct hid_device_id magic_mice[] = {
 		USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 },
 	{ }
 };
-MODULE_DEVICE_TABLE(hid, magic_mice);
+MODULE_DEVICE_TABLE(hid, magicmouse_devices);
 
 static struct hid_driver magicmouse_driver = {
 	.name = "magicmouse",
-	.id_table = magic_mice,
+	.id_table = magicmouse_devices,
 	.probe = magicmouse_probe,
 	.remove = magicmouse_remove,
-	.report_fixup = magicmouse_report_fixup,
 	.raw_event = magicmouse_raw_event,
 	.event = magicmouse_event,
 	.input_mapping = magicmouse_input_mapping,
@@ -1132,5 +873,4 @@ static struct hid_driver magicmouse_driver = {
 };
 module_hid_driver(magicmouse_driver);
 
-MODULE_DESCRIPTION("Apple \"Magic\" Wireless Mouse driver");
 MODULE_LICENSE("GPL");
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH] HID: quirks: update hid-sony supported devices
From: kernel test robot @ 2026-04-15 16:56 UTC (permalink / raw)
  To: Rosalie Wanders, Jiri Kosina, Benjamin Tissoires
  Cc: llvm, oe-kbuild-all, Rosalie Wanders, linux-input, linux-kernel
In-Reply-To: <20260407144247.368567-2-rosalie@mailbox.org>

Hi Rosalie,

kernel test robot noticed the following build errors:

[auto build test ERROR on v7.0]
[also build test ERROR on linus/master]
[cannot apply to hid/for-next next-20260414]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Rosalie-Wanders/HID-quirks-update-hid-sony-supported-devices/20260415-021759
base:   v7.0
patch link:    https://lore.kernel.org/r/20260407144247.368567-2-rosalie%40mailbox.org
patch subject: [PATCH] HID: quirks: update hid-sony supported devices
config: loongarch-allmodconfig (https://download.01.org/0day-ci/archive/20260416/202604160057.euPpXOLj-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260416/202604160057.euPpXOLj-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604160057.euPpXOLj-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/hid/hid-quirks.c:698:19: error: use of undeclared identifier 'USB_VENDOR_ID_HARMONIX'
     698 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS) },
         |                          ^
>> drivers/hid/hid-quirks.c:698:43: error: use of undeclared identifier 'USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS'
     698 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS) },
         |                                                  ^
   drivers/hid/hid-quirks.c:699:19: error: use of undeclared identifier 'USB_VENDOR_ID_HARMONIX'
     699 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_GUITAR) },
         |                          ^
>> drivers/hid/hid-quirks.c:699:43: error: use of undeclared identifier 'USB_DEVICE_ID_HARMONIX_WII_RB1_GUITAR'
     699 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_GUITAR) },
         |                                                  ^
   drivers/hid/hid-quirks.c:700:19: error: use of undeclared identifier 'USB_VENDOR_ID_HARMONIX'
     700 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_DRUMS) },
         |                          ^
>> drivers/hid/hid-quirks.c:700:43: error: use of undeclared identifier 'USB_DEVICE_ID_HARMONIX_WII_RB2_DRUMS'
     700 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_DRUMS) },
         |                                                  ^
   drivers/hid/hid-quirks.c:701:19: error: use of undeclared identifier 'USB_VENDOR_ID_HARMONIX'
     701 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_GUITAR) },
         |                          ^
>> drivers/hid/hid-quirks.c:701:43: error: use of undeclared identifier 'USB_DEVICE_ID_HARMONIX_WII_RB2_GUITAR'
     701 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_GUITAR) },
         |                                                  ^
   drivers/hid/hid-quirks.c:702:19: error: use of undeclared identifier 'USB_VENDOR_ID_HARMONIX'
     702 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_KEYBOARD) },
         |                          ^
>> drivers/hid/hid-quirks.c:702:43: error: use of undeclared identifier 'USB_DEVICE_ID_HARMONIX_WII_RB3_KEYBOARD'
     702 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_KEYBOARD) },
         |                                                  ^
   drivers/hid/hid-quirks.c:703:19: error: use of undeclared identifier 'USB_VENDOR_ID_HARMONIX'
     703 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_DRUMS_MODE) },
         |                          ^
>> drivers/hid/hid-quirks.c:703:43: error: use of undeclared identifier 'USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_DRUMS_MODE'
     703 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_DRUMS_MODE) },
         |                                                  ^
   drivers/hid/hid-quirks.c:704:19: error: use of undeclared identifier 'USB_VENDOR_ID_HARMONIX'
     704 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_KEYBOARD_MODE) },
         |                          ^
>> drivers/hid/hid-quirks.c:704:43: error: use of undeclared identifier 'USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_KEYBOARD_MODE'
     704 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_KEYBOARD_MODE) },
         |                                                  ^
   drivers/hid/hid-quirks.c:705:19: error: use of undeclared identifier 'USB_VENDOR_ID_HARMONIX'
     705 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_MUSTANG_MODE) },
         |                          ^
>> drivers/hid/hid-quirks.c:705:43: error: use of undeclared identifier 'USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_MUSTANG_MODE'
     705 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_MUSTANG_MODE) },
         |                                                  ^
   drivers/hid/hid-quirks.c:706:19: error: use of undeclared identifier 'USB_VENDOR_ID_HARMONIX'
     706 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_SQUIRE_MODE) },
         |                          ^
>> drivers/hid/hid-quirks.c:706:43: error: use of undeclared identifier 'USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_SQUIRE_MODE'
     706 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_SQUIRE_MODE) },
         |                                                  ^
   drivers/hid/hid-quirks.c:707:19: error: use of undeclared identifier 'USB_VENDOR_ID_HARMONIX'
     707 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MUSTANG_GUITAR) },
         |                          ^
   fatal error: too many errors emitted, stopping now [-ferror-limit=]
   20 errors generated.


vim +/USB_VENDOR_ID_HARMONIX +698 drivers/hid/hid-quirks.c

   223	
   224	/*
   225	 * A list of devices for which there is a specialized driver on HID bus.
   226	 *
   227	 * Please note that for multitouch devices (driven by hid-multitouch driver),
   228	 * there is a proper autodetection and autoloading in place (based on presence
   229	 * of HID_DG_CONTACTID), so those devices don't need to be added to this list,
   230	 * as we are doing the right thing in hid_scan_usage().
   231	 *
   232	 * Autodetection for (USB) HID sensor hubs exists too. If a collection of type
   233	 * physical is found inside a usage page of type sensor, hid-sensor-hub will be
   234	 * used as a driver. See hid_scan_report().
   235	 */
   236	static const struct hid_device_id hid_have_special_driver[] = {
   237	#if IS_ENABLED(CONFIG_APPLEDISPLAY)
   238		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9218) },
   239		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9219) },
   240		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x921c) },
   241		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x921d) },
   242		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9222) },
   243		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9226) },
   244		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9236) },
   245	#endif
   246	#if IS_ENABLED(CONFIG_HID_A4TECH)
   247		{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
   248		{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
   249		{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
   250		{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_NB_95) },
   251	#endif
   252	#if IS_ENABLED(CONFIG_HID_ACCUTOUCH)
   253		{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) },
   254	#endif
   255	#if IS_ENABLED(CONFIG_HID_ACRUX)
   256		{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
   257		{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0xf705) },
   258	#endif
   259	#if IS_ENABLED(CONFIG_HID_ALPS)
   260		{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
   261	#endif
   262	#if IS_ENABLED(CONFIG_HID_APPLE)
   263		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
   264		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
   265		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
   266		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
   267		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) },
   268		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) },
   269		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) },
   270		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) },
   271		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) },
   272		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
   273		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
   274		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
   275		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) },
   276		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) },
   277		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) },
   278		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) },
   279		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) },
   280		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) },
   281		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) },
   282		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) },
   283		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) },
   284		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) },
   285		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) },
   286		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) },
   287		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) },
   288		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) },
   289		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) },
   290		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
   291		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
   292		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
   293		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
   294		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
   295		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
   296		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) },
   297		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) },
   298		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) },
   299		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) },
   300		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) },
   301		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) },
   302		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
   303		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
   304		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
   305		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI) },
   306		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO) },
   307		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS) },
   308		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI) },
   309		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO) },
   310		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS) },
   311		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) },
   312		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) },
   313		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) },
   314		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) },
   315		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) },
   316		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) },
   317		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) },
   318		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) },
   319		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) },
   320		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) },
   321		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) },
   322		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) },
   323		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) },
   324		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) },
   325		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) },
   326		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) },
   327		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) },
   328		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) },
   329		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) },
   330		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) },
   331		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) },
   332		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT) },
   333		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) },
   334		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) },
   335		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223) },
   336		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) },
   337		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) },
   338		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
   339		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
   340		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
   341		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) },
   342		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) },
   343		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS) },
   344		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015) },
   345		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
   346		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
   347		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021) },
   348		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021) },
   349	#endif
   350	#if IS_ENABLED(CONFIG_HID_APPLEIR)
   351		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
   352		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
   353		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
   354		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
   355		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
   356	#endif
   357	#if IS_ENABLED(CONFIG_HID_APPLETB_BL)
   358		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) },
   359	#endif
   360	#if IS_ENABLED(CONFIG_HID_APPLETB_KBD)
   361		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) },
   362	#endif
   363	#if IS_ENABLED(CONFIG_HID_ASUS)
   364		{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD) },
   365		{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) },
   366		{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) },
   367		{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2) },
   368		{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3) },
   369		{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) },
   370		{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_ASUS_MD_5110) },
   371		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD) },
   372	#endif
   373	#if IS_ENABLED(CONFIG_HID_AUREAL)
   374		{ HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) },
   375	#endif
   376	#if IS_ENABLED(CONFIG_HID_BELKIN)
   377		{ HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
   378		{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
   379	#endif
   380	#if IS_ENABLED(CONFIG_HID_BETOP_FF)
   381		{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) },
   382		{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185PC, 0x5506) },
   383		{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2PC, 0x1850) },
   384		{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2BFM, 0x5500) },
   385	#endif
   386	#if IS_ENABLED(CONFIG_HID_CHERRY)
   387		{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
   388		{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
   389	#endif
   390	#if IS_ENABLED(CONFIG_HID_CHICONY)
   391		{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
   392		{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
   393		{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_ASUS_AK1D) },
   394		{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) },
   395	#endif
   396	#if IS_ENABLED(CONFIG_HID_CMEDIA)
   397		{ HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM6533) },
   398	#endif
   399	#if IS_ENABLED(CONFIG_HID_CORSAIR)
   400		{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) },
   401		{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_GLAIVE_RGB) },
   402		{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
   403	#endif
   404	#if IS_ENABLED(CONFIG_HID_CP2112)
   405		{ HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) },
   406	#endif
   407	#if IS_ENABLED(CONFIG_HID_CYPRESS)
   408		{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
   409		{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
   410		{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
   411		{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4) },
   412		{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
   413	#endif
   414	#if IS_ENABLED(CONFIG_HID_DRAGONRISE)
   415		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
   416		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
   417	#endif
   418	#if IS_ENABLED(CONFIG_HID_ELAN)
   419		{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_HP_X2_10_COVER) },
   420	#endif
   421	#if IS_ENABLED(CONFIG_HID_ELECOM)
   422		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
   423		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
   424		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC) },
   425		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) },
   426		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
   427		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC) },
   428		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C) },
   429		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
   430		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
   431		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
   432		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT2DRBK) },
   433		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) },
   434		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) },
   435		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) },
   436		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C) },
   437		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK) },
   438		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AB) },
   439	#endif
   440	#if IS_ENABLED(CONFIG_HID_ELO)
   441		{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) },
   442		{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) },
   443	#endif
   444	#if IS_ENABLED(CONFIG_HID_EMS_FF)
   445		{ HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
   446	#endif
   447	#if IS_ENABLED(CONFIG_HID_EZKEY)
   448		{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
   449	#endif
   450	#if IS_ENABLED(CONFIG_HID_GEMBIRD)
   451		{ HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD, USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2) },
   452	#endif
   453	#if IS_ENABLED(CONFIG_HID_GFRM)
   454		{ HID_BLUETOOTH_DEVICE(0x58, 0x2000) },
   455		{ HID_BLUETOOTH_DEVICE(0x471, 0x2210) },
   456	#endif
   457	#if IS_ENABLED(CONFIG_HID_GREENASIA)
   458		{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
   459	#endif
   460	#if IS_ENABLED(CONFIG_HID_GT683R)
   461		{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
   462	#endif
   463	#if IS_ENABLED(CONFIG_HID_GYRATION)
   464		{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
   465		{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
   466		{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
   467	#endif
   468	#if IS_ENABLED(CONFIG_HID_HOLTEK)
   469		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
   470		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
   471		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
   472		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
   473		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) },
   474		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
   475		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
   476		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2) },
   477	#endif
   478	#if IS_ENABLED(CONFIG_HID_ICADE)
   479		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
   480	#endif
   481	#if IS_ENABLED(CONFIG_HID_JABRA)
   482		{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, HID_ANY_ID) },
   483	#endif
   484	#if IS_ENABLED(CONFIG_HID_KENSINGTON)
   485		{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
   486	#endif
   487	#if IS_ENABLED(CONFIG_HID_KEYTOUCH)
   488		{ HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
   489	#endif
   490	#if IS_ENABLED(CONFIG_HID_KYE)
   491		{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
   492		{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_MANTICORE) },
   493		{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GX_IMPERATOR) },
   494		{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
   495	#endif
   496	#if IS_ENABLED(CONFIG_HID_LCPOWER)
   497		{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000) },
   498	#endif
   499	#if IS_ENABLED(CONFIG_HID_LENOVO)
   500		{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
   501		{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
   502		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
   503		{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) },
   504	#endif
   505	#if IS_ENABLED(CONFIG_HID_LOGITECH)
   506		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
   507		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
   508		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) },
   509		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
   510		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) },
   511		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
   512		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
   513		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DUAL_ACTION) },
   514		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
   515		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
   516		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
   517		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
   518		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) },
   519		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
   520		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FG) },
   521		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG) },
   522		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
   523		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) },
   524		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
   525		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
   526		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL) },
   527		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) },
   528		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) },
   529		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
   530		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) },
   531		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
   532		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
   533		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
   534		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
   535	#endif
   536	#if IS_ENABLED(CONFIG_HID_LOGITECH_HIDPP)
   537		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) },
   538	#endif
   539	#if IS_ENABLED(CONFIG_HID_MAGICMOUSE)
   540		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
   541		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
   542	#endif
   543	#if IS_ENABLED(CONFIG_HID_MAYFLASH)
   544		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3) },
   545		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) },
   546		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) },
   547		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) },
   548		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3) },
   549	#endif
   550	#if IS_ENABLED(CONFIG_HID_MICROSOFT)
   551		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) },
   552		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD) },
   553		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
   554		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
   555		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) },
   556		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE7K) },
   557		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
   558		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
   559		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
   560		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
   561		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
   562		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K) },
   563		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600) },
   564		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1) },
   565		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) },
   566		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
   567	#endif
   568	#if IS_ENABLED(CONFIG_HID_MONTEREY)
   569		{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
   570	#endif
   571	#if IS_ENABLED(CONFIG_HID_MULTITOUCH)
   572		{ HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MELFAS_MT) },
   573	#endif
   574	#if IS_ENABLED(CONFIG_HID_WIIMOTE)
   575		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
   576		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
   577	#endif
   578	#if IS_ENABLED(CONFIG_HID_NTI)
   579		{ HID_USB_DEVICE(USB_VENDOR_ID_NTI, USB_DEVICE_ID_USB_SUN) },
   580	#endif
   581	#if IS_ENABLED(CONFIG_HID_NTRIG)
   582		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
   583		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },
   584		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) },
   585		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3) },
   586		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4) },
   587		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5) },
   588		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6) },
   589		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7) },
   590		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8) },
   591		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9) },
   592		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10) },
   593		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11) },
   594		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12) },
   595		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13) },
   596		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14) },
   597		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15) },
   598		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) },
   599		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) },
   600		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
   601	#endif
   602	#if IS_ENABLED(CONFIG_HID_ORTEK)
   603		{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
   604		{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
   605		{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S) },
   606		{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
   607	#endif
   608	#if IS_ENABLED(CONFIG_HID_PANTHERLORD)
   609		{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
   610		{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
   611		{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
   612		{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
   613	#endif
   614	#if IS_ENABLED(CONFIG_HID_PENMOUNT)
   615		{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) },
   616	#endif
   617	#if IS_ENABLED(CONFIG_HID_PETALYNX)
   618		{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
   619	#endif
   620	#if IS_ENABLED(CONFIG_HID_PICOLCD)
   621		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
   622		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
   623	#endif
   624	#if IS_ENABLED(CONFIG_HID_PLANTRONICS)
   625		{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
   626	#endif
   627	#if IS_ENABLED(CONFIG_HID_PLAYSTATION)
   628		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
   629		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
   630		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2) },
   631		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2) },
   632		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) },
   633		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER) },
   634		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER) },
   635		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) },
   636		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) },
   637	#endif
   638	#if IS_ENABLED(CONFIG_HID_PRIMAX)
   639		{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
   640	#endif
   641	#if IS_ENABLED(CONFIG_HID_PRODIKEYS)
   642		{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
   643	#endif
   644	#if IS_ENABLED(CONFIG_HID_RETRODE)
   645		{ HID_USB_DEVICE(USB_VENDOR_ID_FUTURE_TECHNOLOGY, USB_DEVICE_ID_RETRODE2) },
   646	#endif
   647	#if IS_ENABLED(CONFIG_HID_RMI)
   648		{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) },
   649		{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },
   650		{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_REZEL) },
   651	#endif
   652	#if IS_ENABLED(CONFIG_HID_ROCCAT)
   653		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
   654		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
   655		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKUFX) },
   656		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
   657		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
   658		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) },
   659		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE_OPTICAL) },
   660		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEXTD) },
   661		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
   662		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
   663		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
   664		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
   665		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK) },
   666		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_GLOW) },
   667		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO) },
   668		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
   669	#endif
   670	#if IS_ENABLED(CONFIG_HID_SAITEK)
   671		{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
   672		{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD) },
   673		{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7) },
   674		{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT9) },
   675		{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) },
   676		{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5) },
   677		{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) },
   678		{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_MMO7) },
   679	#endif
   680	#if IS_ENABLED(CONFIG_HID_SAMSUNG)
   681		{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
   682		{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
   683	#endif
   684	#if IS_ENABLED(CONFIG_HID_SMARTJOYPLUS)
   685		{ HID_USB_DEVICE(USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII) },
   686		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
   687		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) },
   688		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
   689		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
   690		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
   691		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
   692	#endif
   693	#if IS_ENABLED(CONFIG_HID_SONY)
   694		{ HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS4_GIBSON_SG) },
   695		{ HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS4_GIBSON_SG_DONGLE) },
   696		{ HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS5_GIBSON_SG) },
   697		{ HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS5_GIBSON_SG_DONGLE) },
 > 698		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS) },
 > 699		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_GUITAR) },
 > 700		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_DRUMS) },
 > 701		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_GUITAR) },
 > 702		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_KEYBOARD) },
 > 703		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_DRUMS_MODE) },
 > 704		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_KEYBOARD_MODE) },
 > 705		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_MUSTANG_MODE) },
 > 706		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_SQUIRE_MODE) },
   707		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MUSTANG_GUITAR) },
   708		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_SQUIRE_GUITAR) },
   709		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
   710		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_PS4_STRATOCASTER) },
   711		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_JAGUAR) },
   712		{ HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_RIFFMASTER) },
   713		{ HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS5_RIFFMASTER) },
   714		{ HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_GUITAR_DONGLE) },
   715		{ HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_PS4_GHLIVE_DONGLE) },
   716		{ HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER) },
   717		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE) },
   718		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE) },
   719		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) },
   720		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
   721		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) },
   722		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) },
   723		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
   724		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
   725		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
   726		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
   727		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
   728		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
   729		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
   730		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
   731		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE) },
   732		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_DJH_TURNTABLE) },
   733		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GH_DRUMS) },
   734		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GH_GUITAR) },
   735		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_KEYBOARD) },
   736		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_DRUMS_MODE) },
   737		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_KEYBOARD_MODE) },
   738		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_MUSTANG_MODE) },
   739		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_SQUIRE_MODE) },
   740		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MUSTANG_GUITAR) },
   741		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_SQUIRE_GUITAR) },
   742		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB_DRUMS) },
   743		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB_GUITAR) },
   744	#endif
   745	#if IS_ENABLED(CONFIG_HID_SPEEDLINK)
   746		{ HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
   747	#endif
   748	#if IS_ENABLED(CONFIG_HID_STEELSERIES)
   749		{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) },
   750		{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_1) },
   751		{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_9) },
   752	#endif
   753	#if IS_ENABLED(CONFIG_HID_SUNPLUS)
   754		{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
   755	#endif
   756	#if IS_ENABLED(CONFIG_HID_THRUSTMASTER)
   757		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
   758		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
   759		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
   760		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
   761		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb605) },
   762		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
   763		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
   764		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
   765		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
   766		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65d) },
   767	#endif
   768	#if IS_ENABLED(CONFIG_HID_TIVO)
   769		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
   770		{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
   771		{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) },
   772	#endif
   773	#if IS_ENABLED(CONFIG_HID_TOPSEED)
   774		{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
   775		{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
   776		{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
   777		{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
   778		{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
   779	#endif
   780	#if IS_ENABLED(CONFIG_HID_TWINHAN)
   781		{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
   782	#endif
   783	#if IS_ENABLED(CONFIG_HID_UDRAW_PS3)
   784		{ HID_USB_DEVICE(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW) },
   785	#endif
   786	#if IS_ENABLED(CONFIG_HID_XINMO)
   787		{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
   788		{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
   789	#endif
   790	#if IS_ENABLED(CONFIG_HID_ZEROPLUS)
   791		{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
   792		{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
   793	#endif
   794	#if IS_ENABLED(CONFIG_HID_ZYDACRON)
   795		{ HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
   796	#endif
   797		{ }
   798	};
   799	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH] HID: quirks: update hid-sony supported devices
From: kernel test robot @ 2026-04-15 16:01 UTC (permalink / raw)
  To: Rosalie Wanders, Jiri Kosina, Benjamin Tissoires
  Cc: oe-kbuild-all, Rosalie Wanders, linux-input, linux-kernel
In-Reply-To: <20260407144247.368567-2-rosalie@mailbox.org>

Hi Rosalie,

kernel test robot noticed the following build errors:

[auto build test ERROR on v7.0]
[also build test ERROR on linus/master]
[cannot apply to hid/for-next next-20260414]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Rosalie-Wanders/HID-quirks-update-hid-sony-supported-devices/20260415-021759
base:   v7.0
patch link:    https://lore.kernel.org/r/20260407144247.368567-2-rosalie%40mailbox.org
patch subject: [PATCH] HID: quirks: update hid-sony supported devices
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20260415/202604152332.KsvO9aH8-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260415/202604152332.KsvO9aH8-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604152332.KsvO9aH8-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/hid/hid-quirks.c:15:
>> drivers/hid/hid-quirks.c:698:26: error: 'USB_VENDOR_ID_HARMONIX' undeclared here (not in a function); did you mean 'USB_VENDOR_ID_HANVON'?
     698 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS) },
         |                          ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:36: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                    ^~~
>> drivers/hid/hid-quirks.c:698:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS' undeclared here (not in a function)
     698 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:699:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB1_GUITAR' undeclared here (not in a function)
     699 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_GUITAR) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:700:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB2_DRUMS' undeclared here (not in a function)
     700 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_DRUMS) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:701:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB2_GUITAR' undeclared here (not in a function)
     701 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_GUITAR) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:702:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB3_KEYBOARD' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD'?
     702 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_KEYBOARD) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:703:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_DRUMS_MODE' undeclared here (not in a function)
     703 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_DRUMS_MODE) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:704:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_KEYBOARD_MODE' undeclared here (not in a function)
     704 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_KEYBOARD_MODE) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:705:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_MUSTANG_MODE' undeclared here (not in a function)
     705 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_MUSTANG_MODE) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:706:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_SQUIRE_MODE' undeclared here (not in a function)
     706 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_SQUIRE_MODE) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:707:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB3_MUSTANG_GUITAR' undeclared here (not in a function)
     707 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MUSTANG_GUITAR) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:708:50: error: 'USB_DEVICE_ID_HARMONIX_WII_RB3_SQUIRE_GUITAR' undeclared here (not in a function)
     708 |         { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_SQUIRE_GUITAR) },
         |                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:731:53: error: 'USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE_DONGLE'?
     731 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:732:53: error: 'USB_DEVICE_ID_SONY_PS3_DJH_TURNTABLE' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3_GUITAR_DONGLE'?
     732 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_DJH_TURNTABLE) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:733:53: error: 'USB_DEVICE_ID_SONY_PS3_GH_DRUMS' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3_BDREMOTE'?
     733 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GH_DRUMS) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:734:53: error: 'USB_DEVICE_ID_SONY_PS3_GH_GUITAR' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3_BDREMOTE'?
     734 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GH_GUITAR) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:735:53: error: 'USB_DEVICE_ID_SONY_PS3_RB3_KEYBOARD' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3_BDREMOTE'?
     735 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_KEYBOARD) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:736:53: error: 'USB_DEVICE_ID_SONY_PS3_RB3_MPA_DRUMS_MODE' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3_BDREMOTE'?
     736 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_DRUMS_MODE) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:737:53: error: 'USB_DEVICE_ID_SONY_PS3_RB3_MPA_KEYBOARD_MODE' undeclared here (not in a function)
     737 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_KEYBOARD_MODE) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
>> drivers/hid/hid-quirks.c:738:53: error: 'USB_DEVICE_ID_SONY_PS3_RB3_MPA_MUSTANG_MODE' undeclared here (not in a function)
     738 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_MUSTANG_MODE) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
   drivers/hid/hid-quirks.c:739:53: error: 'USB_DEVICE_ID_SONY_PS3_RB3_MPA_SQUIRE_MODE' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3_BDREMOTE'?
     739 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_SQUIRE_MODE) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
   drivers/hid/hid-quirks.c:740:53: error: 'USB_DEVICE_ID_SONY_PS3_RB3_MUSTANG_GUITAR' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3_GUITAR_DONGLE'?
     740 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MUSTANG_GUITAR) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
   drivers/hid/hid-quirks.c:741:53: error: 'USB_DEVICE_ID_SONY_PS3_RB3_SQUIRE_GUITAR' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3_BDREMOTE'?
     741 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_SQUIRE_GUITAR) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
   drivers/hid/hid-quirks.c:742:53: error: 'USB_DEVICE_ID_SONY_PS3_RB_DRUMS' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3_BDREMOTE'?
     742 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB_DRUMS) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~
   drivers/hid/hid-quirks.c:743:53: error: 'USB_DEVICE_ID_SONY_PS3_RB_GUITAR' undeclared here (not in a function); did you mean 'USB_DEVICE_ID_SONY_PS3_BDREMOTE'?
     743 |         { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB_GUITAR) },
         |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/hid.h:785:54: note: in definition of macro 'HID_USB_DEVICE'
     785 |         .bus = BUS_USB, .vendor = (ven), .product = (prod)
         |                                                      ^~~~


vim +698 drivers/hid/hid-quirks.c

   223	
   224	/*
   225	 * A list of devices for which there is a specialized driver on HID bus.
   226	 *
   227	 * Please note that for multitouch devices (driven by hid-multitouch driver),
   228	 * there is a proper autodetection and autoloading in place (based on presence
   229	 * of HID_DG_CONTACTID), so those devices don't need to be added to this list,
   230	 * as we are doing the right thing in hid_scan_usage().
   231	 *
   232	 * Autodetection for (USB) HID sensor hubs exists too. If a collection of type
   233	 * physical is found inside a usage page of type sensor, hid-sensor-hub will be
   234	 * used as a driver. See hid_scan_report().
   235	 */
   236	static const struct hid_device_id hid_have_special_driver[] = {
   237	#if IS_ENABLED(CONFIG_APPLEDISPLAY)
   238		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9218) },
   239		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9219) },
   240		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x921c) },
   241		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x921d) },
   242		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9222) },
   243		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9226) },
   244		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9236) },
   245	#endif
   246	#if IS_ENABLED(CONFIG_HID_A4TECH)
   247		{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
   248		{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
   249		{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
   250		{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_NB_95) },
   251	#endif
   252	#if IS_ENABLED(CONFIG_HID_ACCUTOUCH)
   253		{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) },
   254	#endif
   255	#if IS_ENABLED(CONFIG_HID_ACRUX)
   256		{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
   257		{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0xf705) },
   258	#endif
   259	#if IS_ENABLED(CONFIG_HID_ALPS)
   260		{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
   261	#endif
   262	#if IS_ENABLED(CONFIG_HID_APPLE)
   263		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
   264		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
   265		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
   266		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
   267		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) },
   268		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) },
   269		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) },
   270		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) },
   271		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) },
   272		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
   273		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
   274		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
   275		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) },
   276		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) },
   277		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) },
   278		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) },
   279		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) },
   280		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) },
   281		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) },
   282		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) },
   283		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) },
   284		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) },
   285		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) },
   286		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) },
   287		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) },
   288		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) },
   289		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) },
   290		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
   291		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
   292		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
   293		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
   294		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
   295		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
   296		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) },
   297		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) },
   298		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) },
   299		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) },
   300		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) },
   301		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) },
   302		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
   303		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
   304		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
   305		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI) },
   306		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO) },
   307		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS) },
   308		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI) },
   309		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO) },
   310		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS) },
   311		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) },
   312		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) },
   313		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) },
   314		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) },
   315		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) },
   316		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) },
   317		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) },
   318		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) },
   319		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) },
   320		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) },
   321		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) },
   322		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) },
   323		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) },
   324		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) },
   325		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) },
   326		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) },
   327		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) },
   328		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) },
   329		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K) },
   330		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132) },
   331		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680) },
   332		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT) },
   333		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213) },
   334		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K) },
   335		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223) },
   336		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K) },
   337		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F) },
   338		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
   339		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
   340		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
   341		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) },
   342		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) },
   343		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS) },
   344		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015) },
   345		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
   346		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
   347		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021) },
   348		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021) },
   349	#endif
   350	#if IS_ENABLED(CONFIG_HID_APPLEIR)
   351		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
   352		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
   353		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
   354		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
   355		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
   356	#endif
   357	#if IS_ENABLED(CONFIG_HID_APPLETB_BL)
   358		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) },
   359	#endif
   360	#if IS_ENABLED(CONFIG_HID_APPLETB_KBD)
   361		{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY) },
   362	#endif
   363	#if IS_ENABLED(CONFIG_HID_ASUS)
   364		{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD) },
   365		{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) },
   366		{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) },
   367		{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2) },
   368		{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3) },
   369		{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) },
   370		{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_ASUS_MD_5110) },
   371		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD) },
   372	#endif
   373	#if IS_ENABLED(CONFIG_HID_AUREAL)
   374		{ HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) },
   375	#endif
   376	#if IS_ENABLED(CONFIG_HID_BELKIN)
   377		{ HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
   378		{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
   379	#endif
   380	#if IS_ENABLED(CONFIG_HID_BETOP_FF)
   381		{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) },
   382		{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185PC, 0x5506) },
   383		{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2PC, 0x1850) },
   384		{ HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185V2BFM, 0x5500) },
   385	#endif
   386	#if IS_ENABLED(CONFIG_HID_CHERRY)
   387		{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
   388		{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
   389	#endif
   390	#if IS_ENABLED(CONFIG_HID_CHICONY)
   391		{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
   392		{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
   393		{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_ASUS_AK1D) },
   394		{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) },
   395	#endif
   396	#if IS_ENABLED(CONFIG_HID_CMEDIA)
   397		{ HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM6533) },
   398	#endif
   399	#if IS_ENABLED(CONFIG_HID_CORSAIR)
   400		{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) },
   401		{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_GLAIVE_RGB) },
   402		{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
   403	#endif
   404	#if IS_ENABLED(CONFIG_HID_CP2112)
   405		{ HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) },
   406	#endif
   407	#if IS_ENABLED(CONFIG_HID_CYPRESS)
   408		{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
   409		{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
   410		{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
   411		{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4) },
   412		{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
   413	#endif
   414	#if IS_ENABLED(CONFIG_HID_DRAGONRISE)
   415		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
   416		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
   417	#endif
   418	#if IS_ENABLED(CONFIG_HID_ELAN)
   419		{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_HP_X2_10_COVER) },
   420	#endif
   421	#if IS_ENABLED(CONFIG_HID_ELECOM)
   422		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
   423		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
   424		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC) },
   425		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) },
   426		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
   427		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC) },
   428		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C) },
   429		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
   430		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
   431		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
   432		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT2DRBK) },
   433		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) },
   434		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) },
   435		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) },
   436		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C) },
   437		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK) },
   438		{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AB) },
   439	#endif
   440	#if IS_ENABLED(CONFIG_HID_ELO)
   441		{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) },
   442		{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) },
   443	#endif
   444	#if IS_ENABLED(CONFIG_HID_EMS_FF)
   445		{ HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
   446	#endif
   447	#if IS_ENABLED(CONFIG_HID_EZKEY)
   448		{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
   449	#endif
   450	#if IS_ENABLED(CONFIG_HID_GEMBIRD)
   451		{ HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD, USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2) },
   452	#endif
   453	#if IS_ENABLED(CONFIG_HID_GFRM)
   454		{ HID_BLUETOOTH_DEVICE(0x58, 0x2000) },
   455		{ HID_BLUETOOTH_DEVICE(0x471, 0x2210) },
   456	#endif
   457	#if IS_ENABLED(CONFIG_HID_GREENASIA)
   458		{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
   459	#endif
   460	#if IS_ENABLED(CONFIG_HID_GT683R)
   461		{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
   462	#endif
   463	#if IS_ENABLED(CONFIG_HID_GYRATION)
   464		{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
   465		{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
   466		{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
   467	#endif
   468	#if IS_ENABLED(CONFIG_HID_HOLTEK)
   469		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
   470		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
   471		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
   472		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
   473		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) },
   474		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
   475		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
   476		{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2) },
   477	#endif
   478	#if IS_ENABLED(CONFIG_HID_ICADE)
   479		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
   480	#endif
   481	#if IS_ENABLED(CONFIG_HID_JABRA)
   482		{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, HID_ANY_ID) },
   483	#endif
   484	#if IS_ENABLED(CONFIG_HID_KENSINGTON)
   485		{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
   486	#endif
   487	#if IS_ENABLED(CONFIG_HID_KEYTOUCH)
   488		{ HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
   489	#endif
   490	#if IS_ENABLED(CONFIG_HID_KYE)
   491		{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
   492		{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_MANTICORE) },
   493		{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GX_IMPERATOR) },
   494		{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
   495	#endif
   496	#if IS_ENABLED(CONFIG_HID_LCPOWER)
   497		{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000) },
   498	#endif
   499	#if IS_ENABLED(CONFIG_HID_LENOVO)
   500		{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
   501		{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
   502		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
   503		{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) },
   504	#endif
   505	#if IS_ENABLED(CONFIG_HID_LOGITECH)
   506		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
   507		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
   508		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) },
   509		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
   510		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) },
   511		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
   512		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
   513		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DUAL_ACTION) },
   514		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
   515		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
   516		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
   517		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
   518		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) },
   519		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
   520		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FG) },
   521		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG) },
   522		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
   523		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) },
   524		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
   525		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
   526		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL) },
   527		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) },
   528		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) },
   529		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
   530		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) },
   531		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
   532		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
   533		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
   534		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
   535	#endif
   536	#if IS_ENABLED(CONFIG_HID_LOGITECH_HIDPP)
   537		{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) },
   538	#endif
   539	#if IS_ENABLED(CONFIG_HID_MAGICMOUSE)
   540		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
   541		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
   542	#endif
   543	#if IS_ENABLED(CONFIG_HID_MAYFLASH)
   544		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3) },
   545		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) },
   546		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) },
   547		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) },
   548		{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3) },
   549	#endif
   550	#if IS_ENABLED(CONFIG_HID_MICROSOFT)
   551		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) },
   552		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD) },
   553		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
   554		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
   555		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) },
   556		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE7K) },
   557		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
   558		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
   559		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
   560		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
   561		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
   562		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K) },
   563		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600) },
   564		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1) },
   565		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) },
   566		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
   567	#endif
   568	#if IS_ENABLED(CONFIG_HID_MONTEREY)
   569		{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
   570	#endif
   571	#if IS_ENABLED(CONFIG_HID_MULTITOUCH)
   572		{ HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MELFAS_MT) },
   573	#endif
   574	#if IS_ENABLED(CONFIG_HID_WIIMOTE)
   575		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
   576		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
   577	#endif
   578	#if IS_ENABLED(CONFIG_HID_NTI)
   579		{ HID_USB_DEVICE(USB_VENDOR_ID_NTI, USB_DEVICE_ID_USB_SUN) },
   580	#endif
   581	#if IS_ENABLED(CONFIG_HID_NTRIG)
   582		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
   583		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },
   584		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) },
   585		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3) },
   586		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4) },
   587		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5) },
   588		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6) },
   589		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7) },
   590		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8) },
   591		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9) },
   592		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10) },
   593		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11) },
   594		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12) },
   595		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13) },
   596		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14) },
   597		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15) },
   598		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) },
   599		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) },
   600		{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
   601	#endif
   602	#if IS_ENABLED(CONFIG_HID_ORTEK)
   603		{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
   604		{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
   605		{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S) },
   606		{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
   607	#endif
   608	#if IS_ENABLED(CONFIG_HID_PANTHERLORD)
   609		{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
   610		{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
   611		{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
   612		{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
   613	#endif
   614	#if IS_ENABLED(CONFIG_HID_PENMOUNT)
   615		{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) },
   616	#endif
   617	#if IS_ENABLED(CONFIG_HID_PETALYNX)
   618		{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
   619	#endif
   620	#if IS_ENABLED(CONFIG_HID_PICOLCD)
   621		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
   622		{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
   623	#endif
   624	#if IS_ENABLED(CONFIG_HID_PLANTRONICS)
   625		{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
   626	#endif
   627	#if IS_ENABLED(CONFIG_HID_PLAYSTATION)
   628		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
   629		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
   630		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2) },
   631		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2) },
   632		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) },
   633		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER) },
   634		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER) },
   635		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) },
   636		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) },
   637	#endif
   638	#if IS_ENABLED(CONFIG_HID_PRIMAX)
   639		{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
   640	#endif
   641	#if IS_ENABLED(CONFIG_HID_PRODIKEYS)
   642		{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
   643	#endif
   644	#if IS_ENABLED(CONFIG_HID_RETRODE)
   645		{ HID_USB_DEVICE(USB_VENDOR_ID_FUTURE_TECHNOLOGY, USB_DEVICE_ID_RETRODE2) },
   646	#endif
   647	#if IS_ENABLED(CONFIG_HID_RMI)
   648		{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) },
   649		{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14) },
   650		{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_REZEL) },
   651	#endif
   652	#if IS_ENABLED(CONFIG_HID_ROCCAT)
   653		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
   654		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
   655		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKUFX) },
   656		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
   657		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
   658		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) },
   659		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE_OPTICAL) },
   660		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEXTD) },
   661		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
   662		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
   663		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
   664		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
   665		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK) },
   666		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_GLOW) },
   667		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO) },
   668		{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
   669	#endif
   670	#if IS_ENABLED(CONFIG_HID_SAITEK)
   671		{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
   672		{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD) },
   673		{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7) },
   674		{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT9) },
   675		{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) },
   676		{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5) },
   677		{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) },
   678		{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_MMO7) },
   679	#endif
   680	#if IS_ENABLED(CONFIG_HID_SAMSUNG)
   681		{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
   682		{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
   683	#endif
   684	#if IS_ENABLED(CONFIG_HID_SMARTJOYPLUS)
   685		{ HID_USB_DEVICE(USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII) },
   686		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
   687		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) },
   688		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
   689		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
   690		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
   691		{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
   692	#endif
   693	#if IS_ENABLED(CONFIG_HID_SONY)
   694		{ HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS4_GIBSON_SG) },
   695		{ HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS4_GIBSON_SG_DONGLE) },
   696		{ HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS5_GIBSON_SG) },
   697		{ HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS5_GIBSON_SG_DONGLE) },
 > 698		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS) },
 > 699		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_GUITAR) },
 > 700		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_DRUMS) },
 > 701		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_GUITAR) },
 > 702		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_KEYBOARD) },
 > 703		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_DRUMS_MODE) },
 > 704		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_KEYBOARD_MODE) },
 > 705		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_MUSTANG_MODE) },
 > 706		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_SQUIRE_MODE) },
 > 707		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MUSTANG_GUITAR) },
 > 708		{ HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_SQUIRE_GUITAR) },
   709		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
   710		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_PS4_STRATOCASTER) },
   711		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_JAGUAR) },
   712		{ HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_RIFFMASTER) },
   713		{ HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS5_RIFFMASTER) },
   714		{ HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_GUITAR_DONGLE) },
   715		{ HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_PS4_GHLIVE_DONGLE) },
   716		{ HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER) },
   717		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE) },
   718		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE) },
   719		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) },
   720		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
   721		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) },
   722		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) },
   723		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
   724		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
   725		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
   726		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
   727		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
   728		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
   729		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
   730		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
 > 731		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE) },
 > 732		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_DJH_TURNTABLE) },
 > 733		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GH_DRUMS) },
 > 734		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GH_GUITAR) },
 > 735		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_KEYBOARD) },
 > 736		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_DRUMS_MODE) },
 > 737		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_KEYBOARD_MODE) },
 > 738		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_MUSTANG_MODE) },
 > 739		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_SQUIRE_MODE) },
 > 740		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MUSTANG_GUITAR) },
 > 741		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_SQUIRE_GUITAR) },
 > 742		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB_DRUMS) },
 > 743		{ HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB_GUITAR) },
   744	#endif
   745	#if IS_ENABLED(CONFIG_HID_SPEEDLINK)
   746		{ HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
   747	#endif
   748	#if IS_ENABLED(CONFIG_HID_STEELSERIES)
   749		{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) },
   750		{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_1) },
   751		{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_ARCTIS_9) },
   752	#endif
   753	#if IS_ENABLED(CONFIG_HID_SUNPLUS)
   754		{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
   755	#endif
   756	#if IS_ENABLED(CONFIG_HID_THRUSTMASTER)
   757		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
   758		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
   759		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
   760		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
   761		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb605) },
   762		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
   763		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
   764		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
   765		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
   766		{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65d) },
   767	#endif
   768	#if IS_ENABLED(CONFIG_HID_TIVO)
   769		{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
   770		{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
   771		{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) },
   772	#endif
   773	#if IS_ENABLED(CONFIG_HID_TOPSEED)
   774		{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
   775		{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) },
   776		{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
   777		{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
   778		{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
   779	#endif
   780	#if IS_ENABLED(CONFIG_HID_TWINHAN)
   781		{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
   782	#endif
   783	#if IS_ENABLED(CONFIG_HID_UDRAW_PS3)
   784		{ HID_USB_DEVICE(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW) },
   785	#endif
   786	#if IS_ENABLED(CONFIG_HID_XINMO)
   787		{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
   788		{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
   789	#endif
   790	#if IS_ENABLED(CONFIG_HID_ZEROPLUS)
   791		{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
   792		{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
   793	#endif
   794	#if IS_ENABLED(CONFIG_HID_ZYDACRON)
   795		{ HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
   796	#endif
   797		{ }
   798	};
   799	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH] HID: magicmouse: add battery reporting for Magic Trackpad v1
From: Damiano Gragnaniello @ 2026-04-15 15:55 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires
  Cc: linux-input, linux-kernel, Damiano Gragnaniello, Jiri Kosina,
	Benjamin Tissoires

The Magic Trackpad v1 (USB_DEVICE_ID_APPLE_MAGICTRACKPAD, 0x030e)
connects over Bluetooth and uses two AA batteries. When the device
sends Report ID 0x47, byte 1 carries the battery level as a
percentage (0-100) already expressed in firmware units.

This patch:
  - Registers a power_supply instance via devm_power_supply_register()
    during probe() for the v1 trackpad only (BT, vendor 0x05ac).
  - Parses Report ID 0x47 in magicmouse_raw_event() and calls
    power_supply_changed() to propagate the value to userspace.
  - Exposes PRESENT, CAPACITY, SCOPE and STATUS properties, consistent
    with how hid-sony and hid-logitech-hidpp expose battery data.
  - Registration failure is treated as non-fatal so the input device
    continues to work even if power_supply cannot be allocated.

Tested on Linux Mint / kernel 6.17 with an Apple Magic Trackpad A1339
(first generation, AA cells, firmware 0x0291).

Note: Technical analysis and initial boilerplate structure were assisted by 
Claude (Anthropic AI). The logic has been manually verified against hardware 
descriptors (rdesc) and tested on physical A1339 hardware.

Cc: Jiri Kosina <jikos@kernel.org>
Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Damiano Gragnaniello <damianogragnaniello@gmail.com>
---
--- /home/claude/hid-patch/hid-magicmouse.c.orig	2026-04-15 13:34:50.358612695 +0000
+++ /home/claude/hid-patch/hid-magicmouse.c	2026-04-15 13:35:39.402309524 +0000
@@ -15,6 +15,7 @@
 #include <linux/hid.h>
 #include <linux/input/mt.h>
 #include <linux/module.h>
+#include <linux/power_supply.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 
@@ -60,6 +61,7 @@
 #define MOUSE_REPORT_ID    0x29
 #define MOUSE2_REPORT_ID   0x12
 #define DOUBLE_REPORT_ID   0xf7
+#define TRACKPAD_V1_BATTERY_REPORT_ID 0x47
 #define USB_BATTERY_TIMEOUT_SEC 60
 
 /* These definitions are not precise, but they're close enough.  (Bits
@@ -124,6 +126,10 @@
  * @hdev: Pointer to the underlying HID device.
  * @work: Workqueue to handle initialization retry for quirky devices.
  * @battery_timer: Timer for obtaining battery level information.
+ * @battery: Power supply instance for Magic Trackpad v1 AA battery reporting.
+ * @battery_desc: Descriptor for the power_supply registration.
+ * @battery_name: Name buffer for the power_supply instance.
+ * @battery_capacity: Last known battery level (0-100%) for Magic Trackpad v1.
  */
 struct magicmouse_sc {
 	struct input_dev *input;
@@ -149,8 +155,46 @@
 	struct hid_device *hdev;
 	struct delayed_work work;
 	struct timer_list battery_timer;
+
+	/* Magic Trackpad v1 (AA battery) power_supply support */
+	struct power_supply		*battery;
+	struct power_supply_desc	 battery_desc;
+	char				 battery_name[64];
+	int				 battery_capacity;
+};
+
+static const enum power_supply_property magicmouse_v1_battery_props[] = {
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_STATUS,
 };
 
+static int magicmouse_v1_battery_get_property(struct power_supply *psy,
+					       enum power_supply_property psp,
+					       union power_supply_propval *val)
+{
+	struct magicmouse_sc *msc = power_supply_get_drvdata(psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = 1;
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		val->intval = msc->battery_capacity;
+		break;
+	case POWER_SUPPLY_PROP_SCOPE:
+		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+		break;
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int magicmouse_firm_touch(struct magicmouse_sc *msc)
 {
 	int touch = -1;
@@ -391,6 +435,19 @@
 	int x = 0, y = 0, ii, clicks = 0, npoints;
 
 	switch (data[0]) {
+	case TRACKPAD_V1_BATTERY_REPORT_ID:
+		/*
+		 * Magic Trackpad v1 (AA battery, 0x030e) sends battery level
+		 * in byte 1, already expressed as a percentage (0-100).
+		 * Clamp defensively and notify the power_supply framework.
+		 */
+		if (size < 2)
+			return 0;
+		if (msc->battery) {
+			msc->battery_capacity = clamp_val((int)data[1], 0, 100);
+			power_supply_changed(msc->battery);
+		}
+		return 0;
 	case TRACKPAD_REPORT_ID:
 	case TRACKPAD2_BT_REPORT_ID:
 		/* Expect four bytes of prefix, and N*9 bytes of touch data. */
@@ -890,6 +947,38 @@
 		magicmouse_fetch_battery(hdev);
 	}
 
+	/* Register power_supply for Magic Trackpad v1 (AA battery, BT only) */
+	if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD &&
+	    id->vendor == USB_VENDOR_ID_APPLE) {
+		struct power_supply_config psy_cfg = {};
+
+		msc->battery_capacity = 0;
+		snprintf(msc->battery_name, sizeof(msc->battery_name),
+			 "hid-magictrackpad-v1-%s", dev_name(&hdev->dev));
+
+		msc->battery_desc.name           = msc->battery_name;
+		msc->battery_desc.type           = POWER_SUPPLY_TYPE_BATTERY;
+		msc->battery_desc.properties     = magicmouse_v1_battery_props;
+		msc->battery_desc.num_properties =
+			ARRAY_SIZE(magicmouse_v1_battery_props);
+		msc->battery_desc.get_property   =
+			magicmouse_v1_battery_get_property;
+
+		psy_cfg.drv_data = msc;
+
+		msc->battery = devm_power_supply_register(&hdev->dev,
+							  &msc->battery_desc,
+							  &psy_cfg);
+		if (IS_ERR(msc->battery)) {
+			ret = PTR_ERR(msc->battery);
+			hid_err(hdev,
+				"unable to register trackpad v1 battery: %d\n",
+				ret);
+			msc->battery = NULL;
+			/* Non-fatal: continue without battery reporting */
+		}
+	}
+
 	if (is_usb_magicmouse2(id->vendor, id->product) ||
 	    (is_usb_magictrackpad2(id->vendor, id->product) &&
 	     hdev->type != HID_TYPE_USBMOUSE))

^ permalink raw reply

* Re: [PATCH 1/1] HID: magicmouse: Prevent out-of-bounds (OOB) read during DOUBLE_REPORT_ID
From: Günther Noack @ 2026-04-15 13:30 UTC (permalink / raw)
  To: Lee Jones; +Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <20260414143238.1177080-1-lee@kernel.org>

Hello Lee!

On Tue, Apr 14, 2026 at 03:32:38PM +0100, Lee Jones wrote:
> It is currently possible for a malicious or misconfigured USB device to
> cause an out-of-bounds (OOB) read when submitting reports using
> DOUBLE_REPORT_ID by specifying a large report length and providing a
> smaller one.
> 
> Let's prevent that by comparing the specified report length with the
> actual size of the data read in from userspace.  If the actual data
> length ends up being smaller than specified, we'll politely warn the
> user and prevent any further processing.
> 
> Signed-off-by: Lee Jones <lee@kernel.org>
> ---
>  drivers/hid/hid-magicmouse.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
> index 91f621ceb924..5f44129e6dcc 100644
> --- a/drivers/hid/hid-magicmouse.c
> +++ b/drivers/hid/hid-magicmouse.c
> @@ -490,6 +490,14 @@ static int magicmouse_raw_event(struct hid_device *hdev,
>  		/* Sometimes the trackpad sends two touch reports in one
>  		 * packet.
>  		 */
> +
> +		if (size < data[1] + 2) {
> +			hid_warn(hdev,
> +				 "received report length (%d) was smaller than specified (%d)",
> +				 size, data[1] + 2);
> +			return 0;
> +		}
> +
>  		magicmouse_raw_event(hdev, report, data + 2, data[1]);
>  		magicmouse_raw_event(hdev, report, data + 2 + data[1],
>  			size - 2 - data[1]);
> -- 
> 2.54.0.rc0.605.g598a273b03-goog

I am afraid this still looks buggy to me.

With your check, size can still be *equal* to data[1] + 2.  In that case, the
second recursive call becomes

  magicmouse_raw_event(hdev, report, data + size, 0);

so this points just after the original "data" buffer with zero size.

But the magicmouse_raw_event() function accesses data[0] directly at the
beginning.  It assumes that size is >= 1, but it does not check that before that
first access.

—Günther

^ permalink raw reply

* [PATCH] HID: mcp2221: Fix heap buffer overflow in mcp2221_raw_event()
From: Benoit Sevens @ 2026-04-15 11:47 UTC (permalink / raw)
  To: Rishi Gupta, Jiri Kosina, Benjamin Tissoires
  Cc: linux-i2c, linux-input, linux-kernel, Benoît Sevens

From: Benoît Sevens <bsevens@google.com>

A heap buffer overflow can occur in the mcp2221_raw_event() function
when handling I2C read responses. The driver failed to check if the
total incoming data length fits within the originally allocated buffer
`mcp->rxbuf`.

Fix this by introducing `rxbuf_len` to `struct mcp2221` to keep track
of the allocated buffer size. Initialize it in `mcp_i2c_smbus_read()`
and `mcp_smbus_xfer()`, and ensure the copied data length combined with
the current index does not exceed this length in `mcp2221_raw_event()`.

Signed-off-by: Benoît Sevens <bsevens@google.com>
---
 drivers/hid/hid-mcp2221.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
index ef3b5c77c38e..744561e65079 100644
--- a/drivers/hid/hid-mcp2221.c
+++ b/drivers/hid/hid-mcp2221.c
@@ -119,6 +119,7 @@ struct mcp2221 {
 	struct completion wait_in_report;
 	struct delayed_work init_work;
 	u8 *rxbuf;
+	int rxbuf_len;
 	u8 txbuf[64];
 	int rxbuf_idx;
 	int status;
@@ -323,12 +324,14 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp,
 		mcp->txbuf[3] = (u8)(msg->addr << 1);
 		total_len = msg->len;
 		mcp->rxbuf = msg->buf;
+		mcp->rxbuf_len = msg->len;
 	} else {
 		mcp->txbuf[1] = smbus_len;
 		mcp->txbuf[2] = 0;
 		mcp->txbuf[3] = (u8)(smbus_addr << 1);
 		total_len = smbus_len;
 		mcp->rxbuf = smbus_buf;
+		mcp->rxbuf_len = smbus_len;
 	}
 
 	ret = mcp_send_data_req_status(mcp, mcp->txbuf, 4);
@@ -538,6 +541,7 @@ static int mcp_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
 
 			mcp->rxbuf_idx = 0;
 			mcp->rxbuf = data->block;
+			mcp->rxbuf_len = sizeof(data->block);
 			mcp->txbuf[0] = MCP2221_I2C_GET_DATA;
 			ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
 			if (ret)
@@ -561,6 +565,7 @@ static int mcp_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
 
 			mcp->rxbuf_idx = 0;
 			mcp->rxbuf = data->block;
+			mcp->rxbuf_len = sizeof(data->block);
 			mcp->txbuf[0] = MCP2221_I2C_GET_DATA;
 			ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
 			if (ret)
@@ -908,7 +913,9 @@ static int mcp2221_raw_event(struct hid_device *hdev,
 			}
 			if (data[2] == MCP2221_I2C_READ_COMPL ||
 			    data[2] == MCP2221_I2C_READ_PARTIAL) {
-				if (!mcp->rxbuf || mcp->rxbuf_idx < 0 || data[3] > 60) {
+				if (!mcp->rxbuf || mcp->rxbuf_idx < 0 ||
+				    data[3] > 60 ||
+				    mcp->rxbuf_idx + data[3] > mcp->rxbuf_len) {
 					mcp->status = -EINVAL;
 					break;
 				}
-- 
2.54.0.rc0.605.g598a273b03-goog


^ permalink raw reply related

* [PATCH 4/4] HID: wacom: use __free(kfree) to clean up temporary buffers
From: Benjamin Tissoires @ 2026-04-15  9:38 UTC (permalink / raw)
  To: Jiri Kosina, Filipe Laíns, Bastien Nocera, Ping Cheng,
	Jason Gerecke, Viresh Kumar, Johan Hovold, Alex Elder,
	Greg Kroah-Hartman, Lee Jones
  Cc: linux-input, linux-kernel, greybus-dev, linux-staging, linux-usb,
	Benjamin Tissoires
In-Reply-To: <20260415-wip-fix-core-v1-0-ed3c4c823175@kernel.org>

This simplifies error handling and protects against memory leaks.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/wacom_sys.c | 40 +++++++++++++---------------------------
 1 file changed, 13 insertions(+), 27 deletions(-)

diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index a32320b351e3..adb31f54e524 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -70,11 +70,10 @@ static void wacom_wac_queue_flush(struct hid_device *hdev,
 {
 	while (!kfifo_is_empty(fifo)) {
 		int size = kfifo_peek_len(fifo);
-		u8 *buf;
 		unsigned int count;
 		int err;
 
-		buf = kzalloc(size, GFP_KERNEL);
+		u8 *buf __free(kfree) = kzalloc(size, GFP_KERNEL);
 		if (!buf) {
 			kfifo_skip(fifo);
 			continue;
@@ -87,7 +86,6 @@ static void wacom_wac_queue_flush(struct hid_device *hdev,
 			// to flush seems reasonable enough, however.
 			hid_warn(hdev, "%s: removed fifo entry with unexpected size\n",
 				 __func__);
-			kfree(buf);
 			continue;
 		}
 		err = hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, size, false);
@@ -95,8 +93,6 @@ static void wacom_wac_queue_flush(struct hid_device *hdev,
 			hid_warn(hdev, "%s: unable to flush event due to error %d\n",
 				 __func__, err);
 		}
-
-		kfree(buf);
 	}
 }
 
@@ -311,7 +307,6 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 	struct wacom_features *features = &wacom->wacom_wac.features;
 	struct hid_data *hid_data = &wacom->wacom_wac.hid_data;
 	unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
-	u8 *data;
 	int ret;
 	u32 n;
 
@@ -325,10 +320,11 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 		/* leave touch_max as is if predefined */
 		if (!features->touch_max) {
 			/* read manually */
-			n = hid_report_len(field->report);
-			data = hid_alloc_report_buf(field->report, GFP_KERNEL);
+			u8 *data __free(kfree) = hid_alloc_report_buf(field->report, GFP_KERNEL);
+
 			if (!data)
 				break;
+			n = hid_report_len(field->report);
 			data[0] = field->report->id;
 			ret = wacom_get_report(hdev, HID_FEATURE_REPORT,
 					       data, n, WAC_CMD_RETRIES);
@@ -344,7 +340,6 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 					 "defaulting to %d\n",
 					  features->touch_max);
 			}
-			kfree(data);
 		}
 		break;
 	case HID_DG_INPUTMODE:
@@ -386,10 +381,11 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 	case WACOM_HID_WD_OFFSETRIGHT:
 	case WACOM_HID_WD_OFFSETBOTTOM:
 		/* read manually */
-		n = hid_report_len(field->report);
-		data = hid_alloc_report_buf(field->report, GFP_KERNEL);
+		u8 *data __free(kfree) = hid_alloc_report_buf(field->report, GFP_KERNEL);
+
 		if (!data)
 			break;
+		n = hid_report_len(field->report);
 		data[0] = field->report->id;
 		ret = wacom_get_report(hdev, HID_FEATURE_REPORT,
 					data, n, WAC_CMD_RETRIES);
@@ -400,7 +396,6 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 			hid_warn(hdev, "%s: could not retrieve sensor offsets\n",
 				 __func__);
 		}
-		kfree(data);
 		break;
 	}
 }
@@ -581,7 +576,6 @@ static int wacom_hid_set_device_mode(struct hid_device *hdev)
 static int wacom_set_device_mode(struct hid_device *hdev,
 				 struct wacom_wac *wacom_wac)
 {
-	u8 *rep_data;
 	struct hid_report *r;
 	struct hid_report_enum *re;
 	u32 length;
@@ -595,7 +589,7 @@ static int wacom_set_device_mode(struct hid_device *hdev,
 	if (!r)
 		return -EINVAL;
 
-	rep_data = hid_alloc_report_buf(r, GFP_KERNEL);
+	u8 *rep_data __free(kfree) = hid_alloc_report_buf(r, GFP_KERNEL);
 	if (!rep_data)
 		return -ENOMEM;
 
@@ -614,8 +608,6 @@ static int wacom_set_device_mode(struct hid_device *hdev,
 		 rep_data[1] != wacom_wac->mode_report &&
 		 limit++ < WAC_MSG_RETRIES);
 
-	kfree(rep_data);
-
 	return error < 0 ? error : 0;
 }
 
@@ -921,7 +913,6 @@ static int wacom_add_shared_data(struct hid_device *hdev)
 
 static int wacom_led_control(struct wacom *wacom)
 {
-	unsigned char *buf;
 	int retval;
 	unsigned char report_id = WAC_CMD_LED_CONTROL;
 	int buf_size = 9;
@@ -940,7 +931,8 @@ static int wacom_led_control(struct wacom *wacom)
 		report_id = WAC_CMD_WL_INTUOSP2;
 		buf_size = 51;
 	}
-	buf = kzalloc(buf_size, GFP_KERNEL);
+
+	unsigned char *buf __free(kfree) = kzalloc(buf_size, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
@@ -996,7 +988,6 @@ static int wacom_led_control(struct wacom *wacom)
 
 	retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, buf_size,
 				  WAC_CMD_RETRIES);
-	kfree(buf);
 
 	return retval;
 }
@@ -1004,11 +995,10 @@ static int wacom_led_control(struct wacom *wacom)
 static int wacom_led_putimage(struct wacom *wacom, int button_id, u8 xfer_id,
 		const unsigned len, const void *img)
 {
-	unsigned char *buf;
 	int i, retval;
 	const unsigned chunk_len = len / 4; /* 4 chunks are needed to be sent */
 
-	buf = kzalloc(chunk_len + 3 , GFP_KERNEL);
+	unsigned char *buf __free(kfree) = kzalloc(chunk_len + 3, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
@@ -1018,7 +1008,7 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, u8 xfer_id,
 	retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, 2,
 				  WAC_CMD_RETRIES);
 	if (retval < 0)
-		goto out;
+		return retval;
 
 	buf[0] = xfer_id;
 	buf[1] = button_id & 0x07;
@@ -1038,8 +1028,6 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, u8 xfer_id,
 	wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, 2,
 			 WAC_CMD_RETRIES);
 
-out:
-	kfree(buf);
 	return retval;
 }
 
@@ -1948,10 +1936,9 @@ static int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial,
 static int wacom_cmd_unpair_remote(struct wacom *wacom, unsigned char selector)
 {
 	const size_t buf_size = 2;
-	unsigned char *buf;
 	int retval;
 
-	buf = kzalloc(buf_size, GFP_KERNEL);
+	unsigned char *buf __free(kfree) = kzalloc(buf_size, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
@@ -1960,7 +1947,6 @@ static int wacom_cmd_unpair_remote(struct wacom *wacom, unsigned char selector)
 
 	retval = wacom_set_report(wacom->hdev, HID_OUTPUT_REPORT, buf,
 				  buf_size, WAC_CMD_RETRIES);
-	kfree(buf);
 
 	return retval;
 }

-- 
2.53.0


^ permalink raw reply related

* [PATCH 3/4] HID: multitouch: use __free(kfree) to clean up temporary buffers
From: Benjamin Tissoires @ 2026-04-15  9:38 UTC (permalink / raw)
  To: Jiri Kosina, Filipe Laíns, Bastien Nocera, Ping Cheng,
	Jason Gerecke, Viresh Kumar, Johan Hovold, Alex Elder,
	Greg Kroah-Hartman, Lee Jones
  Cc: linux-input, linux-kernel, greybus-dev, linux-staging, linux-usb,
	Benjamin Tissoires
In-Reply-To: <20260415-wip-fix-core-v1-0-ed3c4c823175@kernel.org>

This simplifies error handling and protects against memory leaks.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/hid-multitouch.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index eeab0b6e32cc..b19463e545d6 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -507,7 +507,6 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
 {
 	int ret;
 	u32 size = hid_report_len(report);
-	u8 *buf;
 
 	/*
 	 * Do not fetch the feature report if the device has been explicitly
@@ -516,7 +515,7 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
 	if (hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)
 		return;
 
-	buf = hid_alloc_report_buf(report, GFP_KERNEL);
+	u8 *buf __free(kfree) = hid_alloc_report_buf(report, GFP_KERNEL);
 	if (!buf)
 		return;
 
@@ -529,7 +528,7 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
 		/* The report ID in the request and the response should match */
 		if (report->id != buf[0]) {
 			hid_err(hdev, "Returned feature report did not match the request\n");
-			goto free;
+			return;
 		}
 
 		ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf,
@@ -537,9 +536,6 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
 		if (ret)
 			dev_warn(&hdev->dev, "failed to report feature\n");
 	}
-
-free:
-	kfree(buf);
 }
 
 static void mt_feature_mapping(struct hid_device *hdev,
@@ -1658,7 +1654,6 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,
 	struct mt_class *cls = &td->mtclass;
 	struct hid_report *report = field->report;
 	unsigned int index = usage->usage_index;
-	char *buf;
 	u32 report_len;
 	int max;
 
@@ -1673,17 +1668,18 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,
 			return false;
 
 		if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) {
-			report_len = hid_report_len(report);
-			buf = hid_alloc_report_buf(report, GFP_KERNEL);
+			char *buf __free(kfree) = hid_alloc_report_buf(report, GFP_KERNEL);
+
 			if (!buf) {
 				hid_err(hdev,
 					"failed to allocate buffer for report\n");
 				return false;
 			}
+
+			report_len = hid_report_len(report);
 			hid_hw_raw_request(hdev, report->id, buf, report_len,
 					   HID_FEATURE_REPORT,
 					   HID_REQ_GET_REPORT);
-			kfree(buf);
 		}
 
 		field->value[index] = td->inputmode_value;

-- 
2.53.0


^ permalink raw reply related

* [PATCH 2/4] HID: core: introduce hid_safe_input_report()
From: Benjamin Tissoires @ 2026-04-15  9:38 UTC (permalink / raw)
  To: Jiri Kosina, Filipe Laíns, Bastien Nocera, Ping Cheng,
	Jason Gerecke, Viresh Kumar, Johan Hovold, Alex Elder,
	Greg Kroah-Hartman, Lee Jones
  Cc: linux-input, linux-kernel, greybus-dev, linux-staging, linux-usb,
	Benjamin Tissoires, stable
In-Reply-To: <20260415-wip-fix-core-v1-0-ed3c4c823175@kernel.org>

hid_input_report() is used in too many places to have a commit that
doesn't cross subsystem borders. Instead of changing the API, introduce
a new one when things matters in the transport layers:
- usbhid
- i2chid

This effectively revert to the old behavior for those two transport
layers.

Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()")
Cc: stable@vger.kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/hid-core.c             | 21 +++++++++++++++++++++
 drivers/hid/i2c-hid/i2c-hid-core.c |  7 ++++---
 drivers/hid/usbhid/hid-core.c      | 11 ++++++-----
 include/linux/hid.h                |  2 ++
 4 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index a806820df7e5..cb0ad99e7a0a 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2191,6 +2191,27 @@ int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data
 }
 EXPORT_SYMBOL_GPL(hid_input_report);
 
+/**
+ * hid_safe_input_report - report data from lower layer (usb, bt...)
+ *
+ * @hid: hid device
+ * @type: HID report type (HID_*_REPORT)
+ * @data: report contents
+ * @bufsize: allocated size of the data buffer
+ * @size: useful size of data parameter
+ * @interrupt: distinguish between interrupt and control transfers
+ *
+ * This is data entry for lower layers.
+ */
+int hid_safe_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data,
+			  size_t bufsize, u32 size, int interrupt)
+{
+	return __hid_input_report(hid, type, data, bufsize, size, interrupt, 0,
+				  false, /* from_bpf */
+				  false /* lock_already_taken */);
+}
+EXPORT_SYMBOL_GPL(hid_safe_input_report);
+
 bool hid_match_one_id(const struct hid_device *hdev,
 		      const struct hid_device_id *id)
 {
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 5a183af3d5c6..e0a302544cef 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -574,9 +574,10 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
 		if (ihid->hid->group != HID_GROUP_RMI)
 			pm_wakeup_event(&ihid->client->dev, 0);
 
-		hid_input_report(ihid->hid, HID_INPUT_REPORT,
-				ihid->inbuf + sizeof(__le16),
-				ret_size - sizeof(__le16), 1);
+		hid_safe_input_report(ihid->hid, HID_INPUT_REPORT,
+				      ihid->inbuf + sizeof(__le16),
+				      ihid->bufsize - sizeof(__le16),
+				      ret_size - sizeof(__le16), 1);
 	}
 
 	return;
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index fbbfc0f60829..5af93b9b1fb5 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -283,9 +283,9 @@ static void hid_irq_in(struct urb *urb)
 			break;
 		usbhid_mark_busy(usbhid);
 		if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) {
-			hid_input_report(urb->context, HID_INPUT_REPORT,
-					 urb->transfer_buffer,
-					 urb->actual_length, 1);
+			hid_safe_input_report(urb->context, HID_INPUT_REPORT,
+					      urb->transfer_buffer, urb->transfer_buffer_length,
+					      urb->actual_length, 1);
 			/*
 			 * autosuspend refused while keys are pressed
 			 * because most keyboards don't wake up when
@@ -482,9 +482,10 @@ static void hid_ctrl(struct urb *urb)
 	switch (status) {
 	case 0:			/* success */
 		if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
-			hid_input_report(urb->context,
+			hid_safe_input_report(urb->context,
 				usbhid->ctrl[usbhid->ctrltail].report->type,
-				urb->transfer_buffer, urb->actual_length, 0);
+				urb->transfer_buffer, urb->transfer_buffer_length,
+				urb->actual_length, 0);
 		break;
 	case -ESHUTDOWN:	/* unplug */
 		unplug = 1;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index ac432a2ef415..bfb9859f391e 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1030,6 +1030,8 @@ struct hid_field *hid_find_field(struct hid_device *hdev, unsigned int report_ty
 int hid_set_field(struct hid_field *, unsigned, __s32);
 int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
 		     int interrupt);
+int hid_safe_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data,
+			  size_t bufsize, u32 size, int interrupt);
 struct hid_field *hidinput_get_led_field(struct hid_device *hid);
 unsigned int hidinput_count_leds(struct hid_device *hid);
 __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code);

-- 
2.53.0


^ permalink raw reply related

* [PATCH 1/4] HID: pass the buffer size to hid_report_raw_event
From: Benjamin Tissoires @ 2026-04-15  9:38 UTC (permalink / raw)
  To: Jiri Kosina, Filipe Laíns, Bastien Nocera, Ping Cheng,
	Jason Gerecke, Viresh Kumar, Johan Hovold, Alex Elder,
	Greg Kroah-Hartman, Lee Jones
  Cc: linux-input, linux-kernel, greybus-dev, linux-staging, linux-usb,
	Benjamin Tissoires, stable
In-Reply-To: <20260415-wip-fix-core-v1-0-ed3c4c823175@kernel.org>

commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing
bogus memset()") enforced the provided data to be at least the size of
the declared buffer in the report descriptor to prevent a buffer
overflow. However, we can try to be smarter by providing both the buffer
size and the data size, meaning that hid_report_raw_event() can make
better decision whether we should plaining reject the buffer (buffer
overflow attempt) or if we can safely memset it to 0 and pass it to the
rest of the stack.

Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()")
Cc: stable@vger.kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/bpf/hid_bpf_dispatch.c |  6 ++++--
 drivers/hid/hid-core.c             | 42 +++++++++++++++++++++++++-------------
 drivers/hid/hid-gfrm.c             |  4 ++--
 drivers/hid/hid-logitech-hidpp.c   |  2 +-
 drivers/hid/hid-multitouch.c       |  2 +-
 drivers/hid/hid-primax.c           |  2 +-
 drivers/hid/hid-vivaldi-common.c   |  2 +-
 drivers/hid/wacom_sys.c            |  6 +++---
 drivers/staging/greybus/hid.c      |  2 +-
 include/linux/hid.h                |  4 ++--
 include/linux/hid_bpf.h            | 14 ++++++++-----
 11 files changed, 53 insertions(+), 33 deletions(-)

diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 50c7b45c59e3..d0130658091b 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -24,7 +24,8 @@ EXPORT_SYMBOL(hid_ops);
 
 u8 *
 dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type, u8 *data,
-			      u32 *size, int interrupt, u64 source, bool from_bpf)
+			      size_t *buf_size, u32 *size, int interrupt, u64 source,
+			      bool from_bpf)
 {
 	struct hid_bpf_ctx_kern ctx_kern = {
 		.ctx = {
@@ -74,6 +75,7 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type
 		*size = ret;
 	}
 
+	*buf_size = ctx_kern.ctx.allocated_size;
 	return ctx_kern.data;
 }
 EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event);
@@ -505,7 +507,7 @@ __hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *b
 	if (ret)
 		return ret;
 
-	return hid_ops->hid_input_report(ctx->hid, type, buf, size, 0, (u64)(long)ctx, true,
+	return hid_ops->hid_input_report(ctx->hid, type, buf, size, size, 0, (u64)(long)ctx, true,
 					 lock_already_taken);
 }
 
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 61afec5915ec..a806820df7e5 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2033,24 +2033,32 @@ int __hid_request(struct hid_device *hid, struct hid_report *report,
 }
 EXPORT_SYMBOL_GPL(__hid_request);
 
-int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
-			 int interrupt)
+int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *data,
+			 size_t bufsize, u32 size, int interrupt)
 {
 	struct hid_report_enum *report_enum = hid->report_enum + type;
 	struct hid_report *report;
 	struct hid_driver *hdrv;
 	int max_buffer_size = HID_MAX_BUFFER_SIZE;
 	u32 rsize, csize = size;
+	size_t bsize = bufsize;
 	u8 *cdata = data;
 	int ret = 0;
 
 	report = hid_get_report(report_enum, data);
 	if (!report)
-		goto out;
+		return 0;
+
+	if (unlikely(bsize < csize)) {
+		hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs %ld)\n",
+				     report->id, csize, bsize);
+		return -EINVAL;
+	}
 
 	if (report_enum->numbered) {
 		cdata++;
 		csize--;
+		bsize--;
 	}
 
 	rsize = hid_compute_report_size(report);
@@ -2063,11 +2071,16 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
 	else if (rsize > max_buffer_size)
 		rsize = max_buffer_size;
 
+	if (bsize < rsize) {
+		hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %ld)\n",
+				     report->id, rsize, bsize);
+		return -EINVAL;
+	}
+
 	if (csize < rsize) {
-		hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n",
-				     report->id, rsize, csize);
-		ret = -EINVAL;
-		goto out;
+		dbg_hid("report %d is too short, (%d < %d)\n", report->id,
+			csize, rsize);
+		memset(cdata + csize, 0, rsize - csize);
 	}
 
 	if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
@@ -2075,7 +2088,7 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
 	if (hid->claimed & HID_CLAIMED_HIDRAW) {
 		ret = hidraw_report_event(hid, data, size);
 		if (ret)
-			goto out;
+			return ret;
 	}
 
 	if (hid->claimed != HID_CLAIMED_HIDRAW && report->maxfield) {
@@ -2087,15 +2100,15 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_report_event(hid, report);
-out:
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hid_report_raw_event);
 
 
 static int __hid_input_report(struct hid_device *hid, enum hid_report_type type,
-			      u8 *data, u32 size, int interrupt, u64 source, bool from_bpf,
-			      bool lock_already_taken)
+			      u8 *data, size_t bufsize, u32 size, int interrupt, u64 source,
+			      bool from_bpf, bool lock_already_taken)
 {
 	struct hid_report_enum *report_enum;
 	struct hid_driver *hdrv;
@@ -2120,7 +2133,8 @@ static int __hid_input_report(struct hid_device *hid, enum hid_report_type type,
 	report_enum = hid->report_enum + type;
 	hdrv = hid->driver;
 
-	data = dispatch_hid_bpf_device_event(hid, type, data, &size, interrupt, source, from_bpf);
+	data = dispatch_hid_bpf_device_event(hid, type, data, &bufsize, &size, interrupt,
+					     source, from_bpf);
 	if (IS_ERR(data)) {
 		ret = PTR_ERR(data);
 		goto unlock;
@@ -2149,7 +2163,7 @@ static int __hid_input_report(struct hid_device *hid, enum hid_report_type type,
 			goto unlock;
 	}
 
-	ret = hid_report_raw_event(hid, type, data, size, interrupt);
+	ret = hid_report_raw_event(hid, type, data, bufsize, size, interrupt);
 
 unlock:
 	if (!lock_already_taken)
@@ -2171,7 +2185,7 @@ static int __hid_input_report(struct hid_device *hid, enum hid_report_type type,
 int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
 		     int interrupt)
 {
-	return __hid_input_report(hid, type, data, size, interrupt, 0,
+	return __hid_input_report(hid, type, data, size, size, interrupt, 0,
 				  false, /* from_bpf */
 				  false /* lock_already_taken */);
 }
diff --git a/drivers/hid/hid-gfrm.c b/drivers/hid/hid-gfrm.c
index 699186ff2349..d2a56bf92b41 100644
--- a/drivers/hid/hid-gfrm.c
+++ b/drivers/hid/hid-gfrm.c
@@ -66,7 +66,7 @@ static int gfrm_raw_event(struct hid_device *hdev, struct hid_report *report,
 	switch (data[1]) {
 	case GFRM100_SEARCH_KEY_DOWN:
 		ret = hid_report_raw_event(hdev, HID_INPUT_REPORT, search_key_dn,
-					   sizeof(search_key_dn), 1);
+					   sizeof(search_key_dn), sizeof(search_key_dn), 1);
 		break;
 
 	case GFRM100_SEARCH_KEY_AUDIO_DATA:
@@ -74,7 +74,7 @@ static int gfrm_raw_event(struct hid_device *hdev, struct hid_report *report,
 
 	case GFRM100_SEARCH_KEY_UP:
 		ret = hid_report_raw_event(hdev, HID_INPUT_REPORT, search_key_up,
-					   sizeof(search_key_up), 1);
+					   sizeof(search_key_up), sizeof(search_key_up), 1);
 		break;
 
 	default:
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index b1330d23bd2d..b3ff9265377b 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -3673,7 +3673,7 @@ static int hidpp10_consumer_keys_raw_event(struct hidpp_device *hidpp,
 	memcpy(&consumer_report[1], &data[3], 4);
 	/* We are called from atomic context */
 	hid_report_raw_event(hidpp->hid_dev, HID_INPUT_REPORT,
-			     consumer_report, 5, 1);
+			     consumer_report, sizeof(consumer_report), 5, 1);
 
 	return 1;
 }
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index e82a3c4e5b44..eeab0b6e32cc 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -533,7 +533,7 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
 		}
 
 		ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf,
-					   size, 0);
+					   size, size, 0);
 		if (ret)
 			dev_warn(&hdev->dev, "failed to report feature\n");
 	}
diff --git a/drivers/hid/hid-primax.c b/drivers/hid/hid-primax.c
index e44d79dff8de..8db054280afb 100644
--- a/drivers/hid/hid-primax.c
+++ b/drivers/hid/hid-primax.c
@@ -44,7 +44,7 @@ static int px_raw_event(struct hid_device *hid, struct hid_report *report,
 			data[0] |= (1 << (data[idx] - 0xE0));
 			data[idx] = 0;
 		}
-		hid_report_raw_event(hid, HID_INPUT_REPORT, data, size, 0);
+		hid_report_raw_event(hid, HID_INPUT_REPORT, data, size, size, 0);
 		return 1;
 
 	default:	/* unknown report */
diff --git a/drivers/hid/hid-vivaldi-common.c b/drivers/hid/hid-vivaldi-common.c
index bf734055d4b6..b12bb5cc091a 100644
--- a/drivers/hid/hid-vivaldi-common.c
+++ b/drivers/hid/hid-vivaldi-common.c
@@ -85,7 +85,7 @@ void vivaldi_feature_mapping(struct hid_device *hdev,
 	}
 
 	ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, report_data,
-				   report_len, 0);
+				   report_len, report_len, 0);
 	if (ret) {
 		dev_warn(&hdev->dev, "failed to report feature %d\n",
 			 field->report->id);
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 0d1c6d90fe21..a32320b351e3 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -90,7 +90,7 @@ static void wacom_wac_queue_flush(struct hid_device *hdev,
 			kfree(buf);
 			continue;
 		}
-		err = hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, false);
+		err = hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, size, false);
 		if (err) {
 			hid_warn(hdev, "%s: unable to flush event due to error %d\n",
 				 __func__, err);
@@ -334,7 +334,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 					       data, n, WAC_CMD_RETRIES);
 			if (ret == n && features->type == HID_GENERIC) {
 				ret = hid_report_raw_event(hdev,
-					HID_FEATURE_REPORT, data, n, 0);
+					HID_FEATURE_REPORT, data, n, n, 0);
 			} else if (ret == 2 && features->type != HID_GENERIC) {
 				features->touch_max = data[1];
 			} else {
@@ -395,7 +395,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
 					data, n, WAC_CMD_RETRIES);
 		if (ret == n) {
 			ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT,
-						   data, n, 0);
+						   data, n, n, 0);
 		} else {
 			hid_warn(hdev, "%s: could not retrieve sensor offsets\n",
 				 __func__);
diff --git a/drivers/staging/greybus/hid.c b/drivers/staging/greybus/hid.c
index 1f58c907c036..37e8605c6767 100644
--- a/drivers/staging/greybus/hid.c
+++ b/drivers/staging/greybus/hid.c
@@ -201,7 +201,7 @@ static void gb_hid_init_report(struct gb_hid *ghid, struct hid_report *report)
 	 * we just need to setup the input fields, so using
 	 * hid_report_raw_event is safe.
 	 */
-	hid_report_raw_event(ghid->hid, report->type, ghid->inbuf, size, 1);
+	hid_report_raw_event(ghid->hid, report->type, ghid->inbuf, ghib->bufsize, size, 1);
 }
 
 static void gb_hid_init_reports(struct gb_hid *ghid)
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 442a80d79e89..ac432a2ef415 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1298,8 +1298,8 @@ static inline u32 hid_report_len(struct hid_report *report)
 	return DIV_ROUND_UP(report->size, 8) + (report->id > 0);
 }
 
-int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
-			 int interrupt);
+int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *data,
+			 size_t bufsize, u32 size, int interrupt);
 
 /* HID quirks API */
 unsigned long hid_lookup_quirk(const struct hid_device *hdev);
diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h
index a2e47dbcf82c..19fffa4574a4 100644
--- a/include/linux/hid_bpf.h
+++ b/include/linux/hid_bpf.h
@@ -72,8 +72,8 @@ struct hid_ops {
 	int (*hid_hw_output_report)(struct hid_device *hdev, __u8 *buf, size_t len,
 				    u64 source, bool from_bpf);
 	int (*hid_input_report)(struct hid_device *hid, enum hid_report_type type,
-				u8 *data, u32 size, int interrupt, u64 source, bool from_bpf,
-				bool lock_already_taken);
+				u8 *data, size_t bufsize, u32 size, int interrupt, u64 source,
+				bool from_bpf, bool lock_already_taken);
 	struct module *owner;
 	const struct bus_type *bus_type;
 };
@@ -200,7 +200,8 @@ struct hid_bpf {
 
 #ifdef CONFIG_HID_BPF
 u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type, u8 *data,
-				  u32 *size, int interrupt, u64 source, bool from_bpf);
+				  size_t *buf_size, u32 *size, int interrupt, u64 source,
+				  bool from_bpf);
 int dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
 				  unsigned char reportnum, __u8 *buf,
 				  u32 size, enum hid_report_type rtype,
@@ -215,8 +216,11 @@ int hid_bpf_device_init(struct hid_device *hid);
 const u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, const u8 *rdesc, unsigned int *size);
 #else /* CONFIG_HID_BPF */
 static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_type type,
-						u8 *data, u32 *size, int interrupt,
-						u64 source, bool from_bpf) { return data; }
+						u8 *data, size_t *buf_size, u32 *size,
+						int interrupt, u64 source, bool from_bpf)
+{
+	return data;
+}
 static inline int dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
 						unsigned char reportnum, u8 *buf,
 						u32 size, enum hid_report_type rtype,

-- 
2.53.0


^ permalink raw reply related

* [PATCH 0/4] HID: Proper fix for OOM in hid-core
From: Benjamin Tissoires @ 2026-04-15  9:38 UTC (permalink / raw)
  To: Jiri Kosina, Filipe Laíns, Bastien Nocera, Ping Cheng,
	Jason Gerecke, Viresh Kumar, Johan Hovold, Alex Elder,
	Greg Kroah-Hartman, Lee Jones
  Cc: linux-input, linux-kernel, greybus-dev, linux-staging, linux-usb,
	Benjamin Tissoires, stable

Commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing
bogus memset()") enforced the provided data to be at least the size of
the declared buffer in the report descriptor to prevent a buffer
overflow.

We only had corner cases of malicious devices exposing the OOM because
in most cases, the buffer provided by the transport layer needs to be
allocated at probe time and is large enough to handle all the possible
reports.

However, the patch from above, which enforces the spec a little bit more
introduced both regressions for devices not following the spec (not
necesserally malicious), but also a stream of errors for those devices.

Let's revert to the old behavior by giving more information to HID core
to be able to decide whether it can or not memset the rest of the buffer
to 0 and continue the processing.

Note that the first commit makes an API change, but the callers are
relatively limited, so it should be fine on its own. The second patch
can't really make the same kind of API change because we have too many
callers in various subsystems. We can switch them one by one to the safe
approach when needed.

The last 2 patches are small cleanups I initially put together with the
2 first patches, but they can be applied on their own and don't need to
be pulled in stable like the first 2.

Cheers,
Benjamin

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
Benjamin Tissoires (4):
      HID: pass the buffer size to hid_report_raw_event
      HID: core: introduce hid_safe_input_report()
      HID: multitouch: use __free(kfree) to clean up temporary buffers
      HID: wacom: use __free(kfree) to clean up temporary buffers

 drivers/hid/bpf/hid_bpf_dispatch.c |  6 ++--
 drivers/hid/hid-core.c             | 63 +++++++++++++++++++++++++++++---------
 drivers/hid/hid-gfrm.c             |  4 +--
 drivers/hid/hid-logitech-hidpp.c   |  2 +-
 drivers/hid/hid-multitouch.c       | 18 +++++------
 drivers/hid/hid-primax.c           |  2 +-
 drivers/hid/hid-vivaldi-common.c   |  2 +-
 drivers/hid/i2c-hid/i2c-hid-core.c |  7 +++--
 drivers/hid/usbhid/hid-core.c      | 11 ++++---
 drivers/hid/wacom_sys.c            | 46 ++++++++++------------------
 drivers/staging/greybus/hid.c      |  2 +-
 include/linux/hid.h                |  6 ++--
 include/linux/hid_bpf.h            | 14 ++++++---
 13 files changed, 105 insertions(+), 78 deletions(-)
---
base-commit: 7df6572f1cb381d6b89ceed58e3b076c233c2cd0
change-id: 20260415-wip-fix-core-7d85c8516ed0

Best regards,
-- 
Benjamin Tissoires <bentiss@kernel.org>


^ permalink raw reply

* Re: [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137)
From: Thorsten Leemhuis @ 2026-04-15  9:10 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Jiri Kosina, denis.benato, linux-kernel, linux-input, honjow,
	Anj D, Linus Torvalds, Linux kernel regressions list
In-Reply-To: <ad9IhFBm85HmoxB2@beelink>

On 4/15/26 10:23, Benjamin Tissoires wrote:
> On Apr 14 2026, Thorsten Leemhuis wrote:
>> On 4/8/26 17:41, Benjamin Tissoires wrote:

Thx for the reply.

> [...]
>>> We can tell people to upgrade to the latest firmware
>> Well, that should not be required by users when it comes to regressions
>> -- unless maybe no other way to fix a severe issue can be found. Is that
>> the case here?
> Sigh. The fix that was introduced in the previous release cycle was a
> "security" one. [...]

Yeah, I figured and should have made this more obvious in my reply
(sorry), but it's hard to distinguish "this is a fix for something that
is unlikely to happen" and is fine to be reverted again temporarily in
case of regressions from those where that's not a good idea. And I
wanted to know which of it it was, but clearly did so poorly. Sorry!
>> How far is a proper fix away? And will that be GPD Win specific, or fix
> Should be out today or tomorrow, [...]

Great, thx!

Ciao, Thorsten

^ permalink raw reply

* Re: [PATCH v3 09/11] dt-bindings: input: Document hid-over-spi DT schema
From: Benjamin Tissoires @ 2026-04-15  8:41 UTC (permalink / raw)
  To: Rob Herring, Dmitry Torokhov
  Cc: Conor Dooley, Jingyuan Liang, Jiri Kosina, Jonathan Corbet,
	Mark Brown, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Krzysztof Kozlowski, Conor Dooley, linux-input, linux-doc,
	linux-kernel, linux-spi, linux-trace-kernel, devicetree, hbarnor,
	tfiga, Dmitry Antipov, Jarrett Schultz
In-Reply-To: <20260413223439.GA3647847-robh@kernel.org>

On Apr 13 2026, Rob Herring wrote:
> On Fri, Apr 10, 2026 at 06:35:00PM +0100, Conor Dooley wrote:
> > On Thu, Apr 09, 2026 at 10:16:46AM -0700, Dmitry Torokhov wrote:
> > > On Thu, Apr 09, 2026 at 05:02:11PM +0100, Conor Dooley wrote:
> > > > On Thu, Apr 02, 2026 at 01:59:46AM +0000, Jingyuan Liang wrote:
> > > > > Documentation describes the required and optional properties for
> > > > > implementing Device Tree for a Microsoft G6 Touch Digitizer that
> > > > > supports HID over SPI Protocol 1.0 specification.
> > > > > 
> > > > > The properties are common to HID over SPI.
> > > > > 
> > > > > Signed-off-by: Dmitry Antipov <dmanti@microsoft.com>
> > > > > Signed-off-by: Jarrett Schultz <jaschultz@microsoft.com>
> > > > > Signed-off-by: Jingyuan Liang <jingyliang@chromium.org>
> > > > > ---
> > > > >  .../devicetree/bindings/input/hid-over-spi.yaml    | 126 +++++++++++++++++++++
> > > > >  1 file changed, 126 insertions(+)
> > > > > 
> > > > > diff --git a/Documentation/devicetree/bindings/input/hid-over-spi.yaml b/Documentation/devicetree/bindings/input/hid-over-spi.yaml
> > > > > new file mode 100644
> > > > > index 000000000000..d1b0a2e26c32
> > > > > --- /dev/null
> > > > > +++ b/Documentation/devicetree/bindings/input/hid-over-spi.yaml
> > > > > @@ -0,0 +1,126 @@
> > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > +%YAML 1.2
> > > > > +---
> > > > > +$id: http://devicetree.org/schemas/input/hid-over-spi.yaml#
> > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > +
> > > > > +title: HID over SPI Devices
> > > > > +
> > > > > +maintainers:
> > > > > +  - Benjamin Tissoires <benjamin.tissoires@redhat.com>
> > > > > +  - Jiri Kosina <jkosina@suse.cz>
> > > > 
> > > > Why them and not you, the developers of the series?
> > > > 
> > > > > +
> > > > > +description: |+
> > > > > +  HID over SPI provides support for various Human Interface Devices over the
> > > > > +  SPI bus. These devices can be for example touchpads, keyboards, touch screens
> > > > > +  or sensors.
> > > > > +
> > > > > +  The specification has been written by Microsoft and is currently available
> > > > > +  here: https://www.microsoft.com/en-us/download/details.aspx?id=103325
> > > > > +
> > > > > +  If this binding is used, the kernel module spi-hid will handle the
> > > > > +  communication with the device and the generic hid core layer will handle the
> > > > > +  protocol.
> > > > 
> > > > This is not relevant to the binding, please remove it.
> > > > 
> > > > > +
> > > > > +allOf:
> > > > > +  - $ref: /schemas/input/touchscreen/touchscreen.yaml#
> > > > > +
> > > > > +properties:
> > > > > +  compatible:
> > > > > +    oneOf:
> > > > > +      - items:
> > > > > +          - enum:
> > > > > +              - microsoft,g6-touch-digitizer
> > > > > +          - const: hid-over-spi
> > > > > +      - description: Just "hid-over-spi" alone is allowed, but not recommended.
> > > > > +        const: hid-over-spi
> > > > 
> > > > Why is it allowed but not recommended? Seems to me like we should
> > > > require device-specific compatibles.
> > > 
> > > Why would we want to change the driver code to add a new compatible each
> > > time a vendor decides to create a chip that is fully hid-spi-protocol
> > > compliant? Or is the plan to still allow "hid-over-spi" fallback but
> > > require device-specific compatible that will be ignored unless there is
> > > device-specific quirk needed?
> 
> The plan is the latter case (the 1st entry up above). The comment is 
> remove the 2nd entry (with 'Just "hid-over-spi" alone is allowed, but 
> not recommended.').
> 
> > This has nothing to do with the driver, just the oddity of having a
> > comment saying that not having a device specific compatible was
> > permitted by not recommended in a binding. Requiring device-specific
> > compatibles is the norm after all and a comment like this makes draws
> > more attention to the fact that this is abnormal. Regardless of what the
> > driver does, device-specific compatibles should be required.
> > 
> > > > > +
> > > > > +  reg:
> > > > > +    maxItems: 1
> > > > > +
> > > > > +  interrupts:
> > > > > +    maxItems: 1
> > > > > +
> > > > > +  reset-gpios:
> > > > > +    maxItems: 1
> > > > > +    description:
> > > > > +      GPIO specifier for the digitizer's reset pin (active low). The line must
> > > > > +      be flagged with GPIO_ACTIVE_LOW.
> > > > > +
> > > > > +  vdd-supply:
> > > > > +    description:
> > > > > +      Regulator for the VDD supply voltage.
> > > > > +
> > > > > +  input-report-header-address:
> > > > > +    $ref: /schemas/types.yaml#/definitions/uint32
> > > > > +    minimum: 0
> > > > > +    maximum: 0xffffff
> > > > > +    description:
> > > > > +      A value to be included in the Read Approval packet, listing an address of
> > > > > +      the input report header to be put on the SPI bus. This address has 24
> > > > > +      bits.
> > > > > +
> > > > > +  input-report-body-address:
> > > > > +    $ref: /schemas/types.yaml#/definitions/uint32
> > > > > +    minimum: 0
> > > > > +    maximum: 0xffffff
> > > > > +    description:
> > > > > +      A value to be included in the Read Approval packet, listing an address of
> > > > > +      the input report body to be put on the SPI bus. This address has 24 bits.
> > > > > +
> > > > > +  output-report-address:
> > > > > +    $ref: /schemas/types.yaml#/definitions/uint32
> > > > > +    minimum: 0
> > > > > +    maximum: 0xffffff
> > > > > +    description:
> > > > > +      A value to be included in the Output Report sent by the host, listing an
> > > > > +      address where the output report on the SPI bus is to be written to. This
> > > > > +      address has 24 bits.
> > > > > +
> > > > > +  read-opcode:
> > > > > +    $ref: /schemas/types.yaml#/definitions/uint8
> > > > > +    description:
> > > > > +      Value to be used in Read Approval packets. 1 byte.
> > > > > +
> > > > > +  write-opcode:
> > > > > +    $ref: /schemas/types.yaml#/definitions/uint8
> > > > > +    description:
> > > > > +      Value to be used in Write Approval packets. 1 byte.
> > > > 
> > > > Why can none of these things be determined from the device's compatible?
> > > > On the surface, they like the kinds of things that could/should be.
> > > 
> > > Why would we want to keep tables of these values in the kernel and again
> > > have to update the driver for each new chip?
> > 
> > That's pretty normal though innit? It's what match data does.
> > If someone wants to have properties that communicate data that
> > can be determined from the compatible, they need to provide
> > justification why it is being done.
> 
> IIRC, it was explained in prior versions the spec itself says these 
> values vary by device. If we expect variation, then I think these 
> properties are fine. But please capture the reasoning for them in this 
> patch or we will just keep asking the same questions over and over. 
> 

Dmitry, FWIW, we roughly had the exact same of argument with Rob with
i2c-hid :)

It took me a while, but I finally understood the rationale and agreed to
it (using the i2c-hid examples):

Most i2c-hid devices are following the spec and rely purely on ACPI and
the DT declaration of i2c-hid -> they are working fine and we don't need
anything else for them. They declare their compatible and the i2c-hid
compatible, and they work great.

But some devices need a reset line. But the i2c-hid spec doesn't mention
a reset line at all. And some other devices need a reset line with a
different timing. etc... Relying purely on the i2c-hid driver means that
the driver needs to now the platform the device is on and the exact
device we have in front of us. i2c-hid provide a VID/PID through the
protocol, but we are still lacking information: in some cases, the
timing of the reset line for the same device differs depending on the
platform they run.

Having a device specific compatible means that we can make use of it
before we load i2c-hid. This is why we have i2c-hid-core and module
specifics on the side. Those extra module can do all the oddities they
want, like having 2 or 3 reset lines, but in the end they are using the
core i2c-hid once they are set up.

Think of it as a way to quirk the device upfront without polluting the
i2c-hid processing.

That allowed us to clean up the i2c-hid code by removing the non
standard regulators, reset lines, quirks that are device specific and
keep it closer to the spec.

Cheers,
Benjamin

^ permalink raw reply

* Re: [PATCH] HID: core: downgrade short report warning to debug level
From: Benjamin Tissoires @ 2026-04-15  8:24 UTC (permalink / raw)
  To: Oleksandr Natalenko
  Cc: linux-input, Anj Duvnjak, benjamin.tissoires, lee, jikos
In-Reply-To: <5062517.GXAFRqVoOG@natalenko.name>

On Apr 14 2026, Oleksandr Natalenko wrote:
> Hello.
> 
> Thank you for the submission. Please see comments inline.
> 
> On úterý 14. dubna 2026 23:41:43, středoevropský letní čas Anj Duvnjak wrote:
> > Commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus
> > memset()") replaced the silent memset() with hid_warn_ratelimited(), which
> > causes dmesg flooding on devices that legitimately send short reports,
> > such as the APC UPS (051D:0002).
> > 
> > Downgrade to dbg_hid() to restore the previous behaviour of only
> > reporting under HID_DEBUG, while preserving the security fix of
> > removing the bogus memset().
> > 
> > Reported-by: Anj Duvnjak <avian@extremenerds.net>
> > Closes: https://lore.kernel.org/linux-input/MW5PR84MB135613E7947113897DD9FDA4C7272@MW5PR84MB1356.NAMPRD84.PROD.OUTLOOK.COM/
> > Reported-by: Oleksandr Natalenko <oleksandr@natalenko.name>
> > Closes: https://lore.kernel.org/linux-input/6256259.lOV4Wx5bFT@natalenko.name/
> 
> I think these Closes: should be Link: instead. And probably Fixes: should be added as follows:
> 
> Fixes: 0a3fe972a7cb14 ("HID: core: Mitigate potential OOB by removing bogus memset()")
> 
> > Signed-off-by: Anj Duvnjak <avian@extremenerds.net>
> > ---
> >  drivers/hid/hid-core.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> > index 833df14ef68f..de8a179347ec 100644
> > --- a/drivers/hid/hid-core.c
> > +++ b/drivers/hid/hid-core.c
> > @@ -2057,8 +2057,8 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
> >  		rsize = max_buffer_size;
> >  
> >  	if (csize < rsize) {
> > -		hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n",
> > -				     report->id, rsize, csize);
> > +		dbg_hid("Event data for report %d was too short (%d vs %d)\n",
> > +			report->id, rsize, csize);
> 
> Ratelimiting is good to keep, IMO. There's a separate macro for that, hid_dbg_ratelimited(), which is surprisingly not used anywhere at the moment as far as I can grep, but it should do the job.

Thanks for the bug and the review.

However, I've got a proper fix which restores the original behavior
while still preventing the OOWM write. It should be out today or
tomorrow.

Cheers,
Benjamin

> 
> >  		ret = -EINVAL;
> >  		goto out;
> >  	}
> > 
> 
> 
> -- 
> Oleksandr Natalenko, MSE



^ permalink raw reply

* Re: [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137)
From: Benjamin Tissoires @ 2026-04-15  8:23 UTC (permalink / raw)
  To: Thorsten Leemhuis
  Cc: Jiri Kosina, denis.benato, linux-kernel, linux-input, honjow,
	Anj D, Linus Torvalds, Linux kernel regressions list
In-Reply-To: <652713b8-aa98-4ca7-8cd4-8f7ad6cff77f@leemhuis.info>

On Apr 14 2026, Thorsten Leemhuis wrote:
> On 4/8/26 17:41, Benjamin Tissoires wrote:
> > Definitely not a big fan of that new quirk. The issue is that current
> > hid-core fix is too restrictive because it doesn't have enough
> > information, like the actual allocated buffer size.
> > 
> > On Apr 08 2026, Zhouwang Huang wrote:
> >> Commit 9e2a17d2e808 ("HID: gpd: fix report descriptor on GPD Win
> >> handheld (2f24:0137)") used report_fixup to shrink Report Count from
> >> 63 to 11 so that short reports from firmware <= 1.09 would not be
> >> rejected by hid_report_raw_event().
> >>
> >> However, firmware 1.10 fixed the report length and now sends the full
> >> 63 bytes.  Because report_fixup already shrank the descriptor,
> >> usbhid allocates a 12-byte URB buffer — far too small for the 64-byte
> >> transfer — causing continuous -EOVERFLOW on every interrupt-in URB.
> >> The HID report descriptor and bcdDevice are identical across firmware
> >> versions, so report_fixup cannot conditionally apply.
> > 
> > OK, so if a firmware already fixed the bug, I'll drop 9e2a17d2e808 from
> > for-next and not include it in the final 7.0 PR I'll need to send.
> 
> Well, that meanwhile dropped commit 9e2a17d2e808 ("HID: gpd: fix report
> descriptor on GPD Win handheld (2f24:0137)") was supposed to fix a
> regression honjow (now CCed) reported on 2026-03-23:
> https://bugzilla.kernel.org/show_bug.cgi?id=221271
> https://lore.kernel.org/all/20260324013847.68024-1-honjow311@gmail.com/
> 
> So it is still unfixed as of now, I assume?

correct. But the HW is faulty and a new firmware version works, so it's
not like there is no options. But...

> 
> Side note: was honjow even notified about dropping the commit?

Not sure we replied to the original thread. That's an omission from us,
but OTH, the "fix" was only in linux-next, never in a realease kernel,
so it was just a delay introduced.

> 
> > We can tell people to upgrade to the latest firmware
> 
> Well, that should not be required by users when it comes to regressions
> -- unless maybe no other way to fix a severe issue can be found. Is that
> the case here?

Sigh. The fix that was introduced in the previous release cycle was a
"security" one. Which explained it had a fast path in being merged into
the kernel and into stable. I hate those but there was something
fundamentally wrong in the hid core code. We already got numerous
reports that the fix is not breaking other devices but is way too
verbose, so a proper fix is on its way, as soon as I managed to properly
test it on my machine.

> 
> > while I work on a proper fix.
> 
> How far is a proper fix away? And will that be GPD Win specific, or fix

Should be out today or tomorrow, depending if my machine still randomly
freeze because of the latest 7.0-rc bugs

GPD specific -> no, it's basically restoring the old behaviour where we
authorize shorter reports, but only if the provided buffer is big
enough. This is is the case when we are dealing with an actual call from
a transport layer like USB or I2C, but not from uhid.

> issues with other issues, too. Because Anj D (now CCed) recently
> reported a flooded dmesg caused by 0a3fe972a7cb ("HID: core: Mitigate
> potential OOB by removing bogus memset()") with a APC UPS (USB VID/PID
> 051D:0002):
> https://lore.kernel.org/all/MW5PR84MB135613E7947113897DD9FDA4C7272@MW5PR84MB1356.NAMPRD84.PROD.OUTLOOK.COM/
> 
> That's with 6.19.12, as the commit was recently backported to 6.18.y and
> 6.19.y.

Yes, again, please redirect your wrath to the persons who decided that
this kind of bugs (that we admitedly have to fix) are security in some
cases :) 

But yeah, security bugs are an annoyance for anybody, and we are far
from seeing the end of it.

Cheers,
Benjamin

^ permalink raw reply

* Re: [PATCH v2] HID: core: downgrade short report warning to debug level
From: Oleksandr Natalenko @ 2026-04-15  7:42 UTC (permalink / raw)
  To: linux-input, benjamin.tissoires; +Cc: lee, jikos, Anj Duvnjak
In-Reply-To: <20260414230017.30217-1-avian@extremenerds.net>

[-- Attachment #1: Type: text/plain, Size: 2054 bytes --]

On středa 15. dubna 2026 1:00:17, středoevropský letní čas Anj Duvnjak wrote:
> Commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus
> memset()") replaced the silent memset() with hid_warn_ratelimited(), which
> causes dmesg flooding on devices that legitimately send short reports,
> such as the APC UPS (051D:0002).
> 
> Downgrade to hid_dbg_ratelimited() to restore the previous behaviour of
> only reporting under HID_DEBUG, while preserving the security fix of
> removing the bogus memset() and keeping rate limiting in place.
> 
> Fixes: 0a3fe972a7cb14 ("HID: core: Mitigate potential OOB by removing bogus memset()")
> Reported-by: Anj Duvnjak <avian@extremenerds.net>
> Link: https://lore.kernel.org/linux-input/MW5PR84MB135613E7947113897DD9FDA4C7272@MW5PR84MB1356.NAMPRD84.PROD.OUTLOOK.COM/
> Reported-by: Oleksandr Natalenko <oleksandr@natalenko.name>
> Link: https://lore.kernel.org/linux-input/6256259.lOV4Wx5bFT@natalenko.name/
> Signed-off-by: Anj Duvnjak <avian@extremenerds.net>
> ---
>  drivers/hid/hid-core.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index 833df14ef68f..f30091509517 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -2057,8 +2057,8 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
>  		rsize = max_buffer_size;
>  
>  	if (csize < rsize) {
> -		hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n",
> -				     report->id, rsize, csize);
> +		hid_dbg_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n",
> +				    report->id, rsize, csize);
>  		ret = -EINVAL;
>  		goto out;
>  	}
> 

LGTM, although I'm not sure what plans do maintainers have on this. Replacing hid_warn_ratelimited() with hid_dbg_ratelimited() works for me personally, so given that,

Reviewed-by: Oleksandr Natalenko <oleksandr@natalenko.name>

Thank you.

-- 
Oleksandr Natalenko, MSE

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox