Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH] HID: ft260: fix SMBus block read protocol handling
From: Raman Varabets @ 2026-06-10 13:41 UTC (permalink / raw)
  To: michael.zaidman
  Cc: jikos, bentiss, linux-i2c, linux-input, linux-kernel,
	Raman Varabets

For I2C_SMBUS_BLOCK_DATA reads, ft260_smbus_xfer() passed
data->block[0] + 1 as the read length. But on a block read the byte
count is supplied by the slave as the first byte of the response;
data->block[0] is not initialized by the caller, so the transfer
length was taken from stale buffer contents, and the count byte the
slave did return was stored without any validation.

Implement the SMBus 2.0 block read protocol properly: read the count
byte first with a repeated START and no STOP, validate it against
I2C_SMBUS_BLOCK_MAX (resetting the bus and returning -EPROTO on a
bogus count), then read exactly that many data bytes and finish the
transaction with STOP. This keeps the whole sequence within a single
I2C transaction:

  S Addr+Wr A Reg A Sr Addr+Rd A Count A Data... P

To support issuing the two reads as one transaction, teach
ft260_i2c_read() to honor the caller's flags instead of always
forcing a START and unconditionally appending STOP to the last
chunk: START is only emitted if requested, and STOP is appended to
the final chunk only when the caller asked for it.

Signed-off-by: Raman Varabets <kernel-linux-20260610-80b7ab08@raman.v1.sg>
---
 drivers/hid/hid-ft260.c | 45 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
index 70e2eedb4..946ed0c6f 100644
--- a/drivers/hid/hid-ft260.c
+++ b/drivers/hid/hid-ft260.c
@@ -502,15 +502,23 @@ static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,
 	struct ft260_i2c_read_request_report rep;
 	struct hid_device *hdev = dev->hdev;
 	u8 bus_busy = 0;
+	/*
+	 * STOP terminates the last chunk; clear means hold the bus so a
+	 * follow-up call continues the same I2C transaction.
+	 */
+	bool want_stop = !!(flag & FT260_FLAG_STOP);
 
 	if ((flag & FT260_FLAG_START_REPEATED) == FT260_FLAG_START_REPEATED)
 		flag = FT260_FLAG_START_REPEATED;
-	else
+	else if (flag & FT260_FLAG_START)
 		flag = FT260_FLAG_START;
+	else
+		flag = 0;	/* no fresh START - continue current transaction */
 	do {
 		if (len <= rd_data_max) {
 			rd_len = len;
-			flag |= FT260_FLAG_STOP;
+			if (want_stop)
+				flag |= FT260_FLAG_STOP;
 		} else {
 			rd_len = rd_data_max;
 		}
@@ -708,14 +716,41 @@ static int ft260_smbus_xfer(struct i2c_adapter *adapter, u16 addr, u16 flags,
 		break;
 	case I2C_SMBUS_BLOCK_DATA:
 		if (read_write == I2C_SMBUS_READ) {
+			u8 count = 0;
+
+			/*
+			 * SMBus 2.0 section 6.5.7 block read in one I2C
+			 * transaction:
+			 *
+			 *   S Addr+Wr A Reg A Sr Addr+Rd A Count A Data... P
+			 *
+			 * The count is read separately and validated
+			 * before sizing the data read so a misbehaving
+			 * slave cannot drive a write past data->block[].
+			 */
 			ret = ft260_smbus_write(dev, addr, cmd, NULL, 0,
 						FT260_FLAG_START);
 			if (ret)
 				goto smbus_exit;
 
-			ret = ft260_i2c_read(dev, addr, data->block,
-					     data->block[0] + 1,
-					     FT260_FLAG_START_STOP_REPEATED);
+			ret = ft260_i2c_read(dev, addr, &count, 1,
+					     FT260_FLAG_START_REPEATED);
+			if (ret)
+				goto smbus_exit;
+
+			if (count == 0 || count > I2C_SMBUS_BLOCK_MAX) {
+				hid_warn(hdev,
+					 "smbus block read: invalid count %u from slave 0x%02x\n",
+					 count, addr);
+				ft260_i2c_reset(hdev);
+				ret = -EPROTO;
+				goto smbus_exit;
+			}
+
+			data->block[0] = count;
+
+			ret = ft260_i2c_read(dev, addr, data->block + 1,
+					     count, FT260_FLAG_STOP);
 		} else {
 			ret = ft260_smbus_write(dev, addr, cmd, data->block,
 						data->block[0] + 1,

base-commit: ab5fce87a778cb780a05984a2ca448f2b41aafbf
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH] HID: ft260: fix SMBus block read protocol handling
From: sashiko-bot @ 2026-06-10 14:08 UTC (permalink / raw)
  To: Raman Varabets; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260610134119.3313484-1-kernel-linux-20260610-80b7ab08@raman.v1.sg>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [Critical] A Time-of-Check to Time-of-Use (TOCTOU) race condition in the I2C read timeout handling allows a malicious USB device to execute a Use-After-Free write on the kernel stack. This problem wasn't introduced by this patch, but it is a critical pre-existing flaw. `ft260_i2c_read` sets `dev->read_buf` to point to a stack variable and waits for completion. If the device delays the response causing a timeout, the function clears `dev->read_buf` to NULL and returns, popping the stack frame. Concurrently, `ft260_raw_event` checks `dev->read_buf != NULL` without locking and then performs a `memcpy`. A properly timed malicious device response can pass the NULL check before the timeout clears it, resulting in the `memcpy` writing device-controlled payload data into freed kernel stack memory, potentially hijacking control flow.
--

commit b044839cc37c642e14b8d9de071b491bae721de9
Author: Raman Varabets <kernel-linux-20260610-80b7ab08@raman.v1.sg>

HID: ft260: fix SMBus block read protocol handling

For I2C_SMBUS_BLOCK_DATA reads, ft260_smbus_xfer() passed
data->block[0] + 1 as the read length. But on a block read the byte
count is supplied by the slave as the first byte of the response;
data->block[0] is not initialized by the caller, so the transfer
length was taken from stale buffer contents, and the count byte the
slave did return was stored without any validation.

> diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
> index 70e2eedb465af..946ed0c6fc39f 100644
> --- a/drivers/hid/hid-ft260.c
> +++ b/drivers/hid/hid-ft260.c
> @@ -502,15 +502,23 @@ static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,
>  	struct ft260_i2c_read_request_report rep;
>  	struct hid_device *hdev = dev->hdev;
>  	u8 bus_busy = 0;
> +	/*
> +	 * STOP terminates the last chunk; clear means hold the bus so a
> +	 * follow-up call continues the same I2C transaction.
> +	 */
> +	bool want_stop = !!(flag & FT260_FLAG_STOP);

[Severity: Critical]
This is a pre-existing issue, but is there a TOCTOU race condition in the I2C
read timeout handling that allows a malicious USB device to execute a
use-after-free write on the kernel stack?

Looking at ft260_i2c_read(), it sets dev->read_buf to point to the provided
data pointer and waits for completion. If the device delays the response
causing a timeout, the function clears dev->read_buf to NULL and returns,
popping the stack frame:

drivers/hid/hid-ft260.c:ft260_i2c_read() {
        ...
		if (!wait_for_completion_timeout(&dev->wait, timeout)) {
			ret = -ETIMEDOUT;
			ft260_i2c_reset(hdev);
			goto ft260_i2c_read_exit;
		}
        ...
ft260_i2c_read_exit:
	dev->read_buf = NULL;
	return ret;
}

Concurrently, ft260_raw_event() checks dev->read_buf != NULL without taking
any locks and then performs a memcpy():

drivers/hid/hid-ft260.c:ft260_raw_event() {
        ...
		if ((dev->read_buf == NULL) ||
		    (xfer->length > dev->read_len - dev->read_idx)) {
        ...
		}

		memcpy(&dev->read_buf[dev->read_idx], &xfer->data,
		       xfer->length);
        ...
}

Could a properly timed malicious device response pass the NULL check before the
timeout clears it, resulting in the memcpy() writing device-controlled payload
data into freed kernel stack memory?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260610134119.3313484-1-kernel-linux-20260610-80b7ab08@raman.v1.sg?part=1

^ permalink raw reply

* [PATCH] HID: ft260: fix stack-use-after-return write in I2C read race
From: Raman Varabets @ 2026-06-10 14:29 UTC (permalink / raw)
  To: michael.zaidman
  Cc: jikos, bentiss, linux-i2c, linux-input, linux-kernel,
	Raman Varabets, stable

ft260_i2c_read() points dev->read_buf at a caller-supplied buffer
(often an on-stack variable), arms a completion and waits up to five
seconds for the device to return the data. The HID input callback
ft260_raw_event() runs in the input/IRQ path, independent of the
dev->lock mutex held by the read path, and copies the device-supplied
payload into dev->read_buf after a plain NULL check.

These two paths share read_buf, read_idx and read_len with no
serialization. If the device delays its response until the read
times out, ft260_i2c_read() resets the controller, clears read_buf
and returns, unwinding the stack frame the buffer lived in. A
response that arrives at that moment lets ft260_raw_event() pass the
NULL check and then memcpy() the device-controlled payload into the
now-freed stack location, a bounded but attacker-influenced
stack-use-after-return write triggerable by malicious or
malfunctioning hardware.

Add a dedicated spinlock that serializes every access to read_buf,
read_idx and read_len. ft260_raw_event() now holds it across the
NULL check, the memcpy and the index update, while the read path
takes it when arming and when clearing the buffer, so the teardown
can no longer slip between the check and the copy.

Fixes: 6a82582d9fa4 ("HID: ft260: add usb hid to i2c host bridge driver")
Cc: stable@vger.kernel.org
Signed-off-by: Raman Varabets <kernel-linux-20260610-80b7ab08@raman.v1.sg>
---
 drivers/hid/hid-ft260.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
index 70e2eedb4..f47945954 100644
--- a/drivers/hid/hid-ft260.c
+++ b/drivers/hid/hid-ft260.c
@@ -240,6 +240,8 @@ struct ft260_device {
 	struct mutex lock;
 	u8 write_buf[FT260_REPORT_MAX_LENGTH];
 	unsigned long need_wakeup_at;
+	/* Protects read_buf, read_idx and read_len against ft260_raw_event() */
+	spinlock_t read_lock;
 	u8 *read_buf;
 	u16 read_idx;
 	u16 read_len;
@@ -501,6 +503,7 @@ static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,
 	int timeout, ret = 0;
 	struct ft260_i2c_read_request_report rep;
 	struct hid_device *hdev = dev->hdev;
+	unsigned long irqflags;
 	u8 bus_busy = 0;
 
 	if ((flag & FT260_FLAG_START_REPEATED) == FT260_FLAG_START_REPEATED)
@@ -526,9 +529,11 @@ static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,
 
 		reinit_completion(&dev->wait);
 
+		spin_lock_irqsave(&dev->read_lock, irqflags);
 		dev->read_idx = 0;
 		dev->read_buf = data;
 		dev->read_len = rd_len;
+		spin_unlock_irqrestore(&dev->read_lock, irqflags);
 
 		ret = ft260_hid_output_report(hdev, (u8 *)&rep, sizeof(rep));
 		if (ret < 0) {
@@ -543,7 +548,9 @@ static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,
 			goto ft260_i2c_read_exit;
 		}
 
+		spin_lock_irqsave(&dev->read_lock, irqflags);
 		dev->read_buf = NULL;
+		spin_unlock_irqrestore(&dev->read_lock, irqflags);
 
 		if (flag & FT260_FLAG_STOP)
 			bus_busy = FT260_I2C_STATUS_BUS_BUSY;
@@ -562,7 +569,9 @@ static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,
 	} while (len > 0);
 
 ft260_i2c_read_exit:
+	spin_lock_irqsave(&dev->read_lock, irqflags);
 	dev->read_buf = NULL;
+	spin_unlock_irqrestore(&dev->read_lock, irqflags);
 	return ret;
 }
 
@@ -1018,6 +1027,7 @@ static int ft260_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		 "FT260 usb-i2c bridge");
 
 	mutex_init(&dev->lock);
+	spin_lock_init(&dev->read_lock);
 	init_completion(&dev->wait);
 
 	ret = ft260_xfer_status(dev, FT260_I2C_STATUS_BUS_BUSY);
@@ -1067,6 +1077,7 @@ static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,
 {
 	struct ft260_device *dev = hid_get_drvdata(hdev);
 	struct ft260_i2c_input_report *xfer = (void *)data;
+	unsigned long irqflags;
 
 	if (size < offsetof(struct ft260_i2c_input_report, data)) {
 		hid_err(hdev, "short report %d\n", size);
@@ -1075,6 +1086,8 @@ static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,
 
 	if (xfer->report >= FT260_I2C_REPORT_MIN &&
 	    xfer->report <= FT260_I2C_REPORT_MAX) {
+		bool complete_read;
+
 		ft260_dbg("i2c resp: rep %#02x len %d size %d\n",
 			  xfer->report, xfer->length, size);
 
@@ -1085,8 +1098,15 @@ static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,
 			return -1;
 		}
 
+		/*
+		 * Hold read_lock so a timed-out ft260_i2c_read() cannot
+		 * clear read_buf between the NULL check and the memcpy.
+		 */
+		spin_lock_irqsave(&dev->read_lock, irqflags);
+
 		if ((dev->read_buf == NULL) ||
 		    (xfer->length > dev->read_len - dev->read_idx)) {
+			spin_unlock_irqrestore(&dev->read_lock, irqflags);
 			hid_err(hdev, "unexpected report %#02x, length %d\n",
 				xfer->report, xfer->length);
 			return -1;
@@ -1095,8 +1115,11 @@ static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,
 		memcpy(&dev->read_buf[dev->read_idx], &xfer->data,
 		       xfer->length);
 		dev->read_idx += xfer->length;
+		complete_read = dev->read_idx == dev->read_len;
+
+		spin_unlock_irqrestore(&dev->read_lock, irqflags);
 
-		if (dev->read_idx == dev->read_len)
+		if (complete_read)
 			complete(&dev->wait);
 
 	} else {
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH] HID: ft260: fix stack-use-after-return write in I2C read race
From: sashiko-bot @ 2026-06-10 14:42 UTC (permalink / raw)
  To: Raman Varabets; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260610142952.3335586-1-kernel-linux-20260610-80b7ab08@raman.v1.sg>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] The driver calls `hid_hw_open()` and `hid_hw_start()` before fully initializing driver data and locks, allowing an early interrupt to cause a NULL pointer dereference or uninitialized spinlock access.
- [High] Calling `complete(&dev->wait)` outside the `read_lock` creates a race condition where a delayed completion signal can spuriously wake up a subsequent I2C read, resulting in the exposure of uninitialized memory.
- [High] A delayed I2C response from a timed-out read can erroneously fulfill a newly issued I2C read request, silently corrupting the read payload.
--

commit f93912f569da4f226a3bdb7379cc9b9a98ba1eb9
Author: Raman Varabets <kernel-linux-20260610-80b7ab08@raman.v1.sg>

HID: ft260: fix stack-use-after-return write in I2C read race

This commit fixes a race condition where a delayed I2C response could write
into a freed stack buffer after a timeout in ft260_i2c_read. It adds a
dedicated spinlock to serialize accesses to the read buffer, index, and length
between the read path and the raw event handler.

> diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
> index 70e2eedb465af..f479459544aee 100644
> --- a/drivers/hid/hid-ft260.c
> +++ b/drivers/hid/hid-ft260.c
[ ... ]
> @@ -543,7 +548,9 @@ static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,
>  			goto ft260_i2c_read_exit;
>  		}
>  
> +		spin_lock_irqsave(&dev->read_lock, irqflags);
>  		dev->read_buf = NULL;
> +		spin_unlock_irqrestore(&dev->read_lock, irqflags);

[Severity: High]
This is a pre-existing issue, but does the timeout path leave stale USB input
reports pending?

If an I2C read times out, ft260_i2c_read() resets the controller but does not
flush the HID/USB receive queues. When a new I2C read begins, dev->read_buf
is updated to point to the new buffer.

Could a delayed USB report containing the response for the previous timed-out
read arrive, pass the NULL check in ft260_raw_event(), and blindly copy stale
data into the new buffer? This would silently corrupt the payload and
desynchronize the bus state.

[ ... ]
> @@ -1018,6 +1027,7 @@ static int ft260_probe(struct hid_device *hdev, const struct hid_device_id *id)
>  		 "FT260 usb-i2c bridge");
>  
>  	mutex_init(&dev->lock);
> +	spin_lock_init(&dev->read_lock);
>  	init_completion(&dev->wait);
>  
>  	ret = ft260_xfer_status(dev, FT260_I2C_STATUS_BUS_BUSY);

[Severity: High]
This isn't a bug introduced by this patch, but does hid_hw_open() allow events
to trigger before the driver data and locks are fully initialized?

In ft260_probe(), hid_hw_open() is called before hid_set_drvdata() and before
spin_lock_init(&dev->read_lock). Because hid_hw_open() submits USB interrupt
IN URBs, the hardware can start sending events immediately.

If ft260_raw_event() triggers early, hid_get_drvdata() would return NULL.
Could this lead to a NULL pointer dereference when ft260_raw_event() attempts
to acquire dev->read_lock?

[ ... ]
> @@ -1095,8 +1115,11 @@ static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,
>  		memcpy(&dev->read_buf[dev->read_idx], &xfer->data,
>  		       xfer->length);
>  		dev->read_idx += xfer->length;
> +		complete_read = dev->read_idx == dev->read_len;
> +
> +		spin_unlock_irqrestore(&dev->read_lock, irqflags);
>  
> -		if (dev->read_idx == dev->read_len)
> +		if (complete_read)
>  			complete(&dev->wait);
>  
>  	} else {

[Severity: High]
This is a pre-existing issue, but does calling complete() outside the
read_lock create a race condition with the teardown path?

If an I2C read times out, ft260_i2c_read() wakes up and clears dev->read_buf.
A new I2C read request could then be issued, which calls
reinit_completion(&dev->wait).

If the softirq executing ft260_raw_event() is preempted between dropping the
lock and calling complete(&dev->wait), could it resume and signal the
completion after the new request has already reinitialized it? This would
cause the new wait to instantly succeed, returning success without writing any
data to the caller's buffer.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260610142952.3335586-1-kernel-linux-20260610-80b7ab08@raman.v1.sg?part=1

^ permalink raw reply

* [PATCH v2 00/12] HID: storing pointers in 'hid_device_id::driver_data'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)

The <linux/mod_devicetable.h> has multiple structs that follow
the pattern of having either 'driver_data' or 'driver_info'
fields which are of the 'kernel_ulong_t' type. Then how to 
interpret that field is user defined, some users will treat
the value as an actual integer, others as a valid pointer to
dereference. 

One of instances of the above is the 'hid_device_id::driver_data'
field, for the most part it is used for setting HID quirks and
treated as an integer value for storing metadata in the subsystem
drivers. But in a few instances it is used as a valid pointer to
dereference, namely in:
- hid-tmff
- wacom
 
Additionally this field can be set from the userspace via the
'hid_core::new_id_store' function - which is not memory safe and
could lead to OOB memory access in the above two cases. 

This series is addressing the issue by making the usage of the field
consistent, all drives treat the value as an integer and if the
driver has a need for dereferencing a pointer - it stores and 
index to a table of pointers. The index is bounded by a named enum
and checked at runtime at the module level to avoid developer bugs.

Furthermore a user-input sanitizer was added in the 'hid_core' module
that restricts injecting arbitrary values for 'hid_device_id::driver_data'
that are not defined and matched within the driver already.

It was found that some modules that use the field do not use a named
initializers for the field - which is inconsistent with rest of the
modules within the HID subsystem. This is also addressed in the series
as part of the pre-clean up to increase clarity in patches 1-4. 

It was found that some modules use a bit of a type-unsafe way of storing
integers in the 'void *driver_data' pointer of the 'struct hid_device'
- this required a cast during storage via 'hid_set_drvdata' and a cast
during retrieval when using 'hid_get_drvdata'. I can see why this was 
done - as we potentially save on an allocation - but really code is
more readable and better quality without resorting to this. This issue
is also addressed in this patch series in patches 5-8 as part of the
pre-clean up.

The actual implementation of the table of pointers approach 
can be found in patches 9-11. In case of wacom driver the sad thing
about it is that it requires a bit of macro magic for sanity. 

However, in doing so it was discovered that in the wacom driver
there is a 1:1 mapping between the 'driver_data' field and the 
product id - therefore patch 12 shows that the lookup can be
simplified as there is no need for using 'driver_data' at all
(it also does not require macro magic) - but it was left in a 
separate patch to show the working - happy to squash in v3 if
this would be accepted.

The change also makes the code more portable on architecture 
like CHERI [1], where a pointer is replaced with a new primitive
(called the capability) at the architecture level and is twice as
wide as the greatest representable address, ie. for 64 bit address
space capabilities are 128 bits wide (the other 64 bits are used to
store meta-data relating to the 64 bit address). So you can not store 
valid pointers inside 'unsigned long' as effectively a different set of
instructions is being generated by the compiler based on the data-type
that was used in C (ie. capabilities have their own set of load/store
that also copy over the meta-data which are orthogonal to the load/store
instructions used for plain integers that would invalidate the meta-data).
There is slightly more detail to this, but the above is enough to
explain the motivation - the proposed changes make the code a bit
better even without considering CHERI at all - as it is more readable 
and type-safe.

The series was built and tested under QEMU (boots with relevant 
configs set to Y) on arm64. Additionally the operation of the input 
sanitizer was tested via the following:

```

modprobe wacom
echo "0x0003 0x056a 0x0001 0x00000" > /sys/bus/hid/drivers/wacom/new_id

echo "0x0003 0x056a 0x0000 0x000A1" > /sys/bus/hid/drivers/wacom/new_id

echo "0x0003 0x056a 0x0000 0x000A2" > /sys/bus/hid/drivers/wacom/new_id
-sh: echo: write error: Invalid argument

modprobe wacom
echo "0x0003 0x056a 0x0001 0x00000" > /sys/bus/hid/drivers/wacom/new_id

echo "0x0003 0x056a 0x0001 0x00001" > /sys/bus/hid/drivers/wacom/new_id
-sh: echo: write error: Invalid argument
echo "0x0003 0x056a 0x0001 0x00010" > /sys/bus/hid/drivers/wacom/new_id
-sh: echo: write error: Invalid argument
```

The 'hid-tmff' and other randomly picked modules were also tested as 
above. Furthermore the './hid-wacom.sh' test was run from the user space
and all tests (except the expected to-do's) passed as required.

This series is part of a larger effort led by Uwe [2]

[1] https://cheri-alliance.org/discover-cheri/
[2] https://lore.kernel.org/all/cover.1776429984.git.u.kleine-koenig@baylibre.com/ 

---
Changes in v2:
- Patches 1-4: No change
- Patches 5-8: Additional signed-off-by as patches were applied.
- Patches 9-12: Rewritten and new.
- Link to v1: https://patch.msgid.link/20260518-mod-devicetable-hid_device_id-v1-0-a08e3989c283@thegoodpenguin.co.uk

To: Jiri Kosina <jikos@kernel.org>
To: Benjamin Tissoires <bentiss@kernel.org>
To: Ping Cheng <ping.cheng@wacom.com>
To: Jason Gerecke <jason.gerecke@wacom.com>
Cc: linux-input@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---
Pawel Zalewski (The Capable Hub) (12):
      HID: hid-input: use named initializer for 'hid_battery_quirks[]'
      HID: hid-quirks: use named initializer in 'hid_quirks[]'
      HID: hid-asus: use named initializer for 'asus_devices[]'
      HID: i2c-hid-dmi-quirks: use named initializer for 'i2c_hid_elan_flipped_quirks[]'
      HID: hid-belkin: clean up usage of 'driver_data'
      HID: hid-cypress: clean up usage of 'driver_data'
      HID: hid-gfrm: clean up usage of 'driver_data'
      HID: hid-ite: clean up usage of 'driver_data'
      HID: hid-tmff: clean up usage of 'driver_data'
      HID: wacom: cleanup usage of 'driver_data'
      HID: hid-core: sanitize user input in 'new_id_store'
      HID: wacom: do not use 'driver_data'

 drivers/hid/hid-asus.c                   |  46 ++-
 drivers/hid/hid-belkin.c                 |   5 +-
 drivers/hid/hid-core.c                   |  18 +
 drivers/hid/hid-cypress.c                |  32 +-
 drivers/hid/hid-gfrm.c                   |   8 +-
 drivers/hid/hid-input.c                  |  38 +-
 drivers/hid/hid-ite.c                    |   9 +-
 drivers/hid/hid-quirks.c                 | 578 ++++++++++++++++++++-----------
 drivers/hid/hid-tmff.c                   |  48 ++-
 drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c |   2 +-
 drivers/hid/wacom.h                      |   1 +
 drivers/hid/wacom_sys.c                  |  25 +-
 drivers/hid/wacom_wac.c                  | 194 ++++++++++-
 drivers/hid/wacom_wac.h                  |   5 +
 14 files changed, 731 insertions(+), 278 deletions(-)
---
base-commit: c1f7d1aa16a4f3b5d9476bf3716ca6bb8271c910
change-id: 20260427-mod-devicetable-hid_device_id-7f30d877387c

Best regards,
--  
Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>


^ permalink raw reply

* [PATCH v2 01/12] HID: hid-input: use named initializer for 'hid_battery_quirks[]'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

This makes the code a little bit more readable and consistent
with other drivers in the HID subsystem that assign the
'driver_data' field in the 'hid_device_id' struct explicitly.

While touching the 'hid_battery_quirks[]', align the list
terminator entry to use a space between the curly braces for
better matching the layout of the other entries.

It was confirmed that hid-input.o pre/post the patch are equal
using diffscope.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
---
 drivers/hid/hid-input.c | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index d73cfa2e73d3..50ee03508806 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -359,49 +359,51 @@ static enum power_supply_property hidinput_battery_props[] = {
 static const struct hid_device_id hid_battery_quirks[] = {
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
-	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
+	  .driver_data = HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
-	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
+	  .driver_data = HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
-	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
+	  .driver_data = HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
-			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
-	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
+		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
+	  .driver_data = HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
-	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
+	  .driver_data = HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_MAGICTRACKPAD),
-	  HID_BATTERY_QUIRK_IGNORE },
+	  .driver_data = HID_BATTERY_QUIRK_IGNORE },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
 		USB_DEVICE_ID_ELECOM_BM084),
-	  HID_BATTERY_QUIRK_IGNORE },
+	  .driver_data = HID_BATTERY_QUIRK_IGNORE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL,
 		USB_DEVICE_ID_SYMBOL_SCANNER_3),
-	  HID_BATTERY_QUIRK_IGNORE },
+	  .driver_data = HID_BATTERY_QUIRK_IGNORE },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
 		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
-	  HID_BATTERY_QUIRK_IGNORE },
+	  .driver_data = HID_BATTERY_QUIRK_IGNORE },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
 		USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD),
-	  HID_BATTERY_QUIRK_IGNORE },
+	  .driver_data = HID_BATTERY_QUIRK_IGNORE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L),
-	  HID_BATTERY_QUIRK_AVOID_QUERY },
+	  .driver_data = HID_BATTERY_QUIRK_AVOID_QUERY },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_MW),
-	  HID_BATTERY_QUIRK_AVOID_QUERY },
+	  .driver_data = HID_BATTERY_QUIRK_AVOID_QUERY },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW),
-	  HID_BATTERY_QUIRK_AVOID_QUERY },
+	  .driver_data = HID_BATTERY_QUIRK_AVOID_QUERY },
 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM),
-	  HID_BATTERY_QUIRK_AVOID_QUERY },
+	  .driver_data = HID_BATTERY_QUIRK_AVOID_QUERY },
 	/*
 	 * Elan HID touchscreens seem to all report a non present battery,
 	 * set HID_BATTERY_QUIRK_IGNORE for all Elan I2C and USB HID devices.
 	 */
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_DYNAMIC },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_DYNAMIC },
-	{}
+	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID),
+	  .driver_data = HID_BATTERY_QUIRK_DYNAMIC },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID),
+	  .driver_data = HID_BATTERY_QUIRK_DYNAMIC },
+	{ }
 };
 
 static unsigned find_battery_quirk(struct hid_device *hdev)

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 02/12] HID: hid-quirks: use named initializer in 'hid_quirks[]'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

This makes the code a little bit more readable and consistent
with other drivers in the HID subsystem that assign the
'driver_data' field in the 'hid_device_id' struct explicitly.

While touching the 'hid_quirks[]', modify the terminator entry to use
a space between the curly braces as opposed to a 0 for consistency.

It was confirmed that hid-quirks.o pre/post the patch are equal
using diffscope.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
---
 drivers/hid/hid-quirks.c | 578 +++++++++++++++++++++++++++++++----------------
 1 file changed, 384 insertions(+), 194 deletions(-)

diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 57d8efdd9b89..71efca6a03ed 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -25,202 +25,392 @@
  */
 
 static const struct hid_device_id hid_quirks[] = {
-	{ HID_USB_DEVICE(USB_VENDOR_ID_8BITDO, USB_DEVICE_ID_8BITDO_PRO_3), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD), HID_QUIRK_BADPAD },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR), HID_QUIRK_BADPAD },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ADATA_XPG, USB_VENDOR_ID_ADATA_XPG_WL_GAMING_MOUSE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ADATA_XPG, USB_VENDOR_ID_ADATA_XPG_WL_GAMING_MOUSE_DONGLE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016), HID_QUIRK_FULLSPEED_INTERVAL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS1758), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD), HID_QUIRK_BADPAD },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_COOLER_MASTER, USB_DEVICE_ID_COOLER_MASTER_MICE_DONGLE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70R), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K95RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_M65RGB), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_GLAIVE_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_REDRAGON_SEYMUR2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER), HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_EDIFIER, USB_DEVICE_ID_EDIFIER_QR30), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH_2968), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD), HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_8BITDO, USB_DEVICE_ID_8BITDO_PRO_3),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD),
+	  .driver_data = HID_QUIRK_BADPAD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR),
+	  .driver_data = HID_QUIRK_BADPAD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ADATA_XPG, USB_VENDOR_ID_ADATA_XPG_WL_GAMING_MOUSE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ADATA_XPG, USB_VENDOR_ID_ADATA_XPG_WL_GAMING_MOUSE_DONGLE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016),
+	  .driver_data = HID_QUIRK_FULLSPEED_INTERVAL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD),
+	  .driver_data = HID_QUIRK_BADPAD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_AMI,	USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS1758),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY,	USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY,	USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD),
+	  .driver_data = HID_QUIRK_BADPAD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_COOLER_MASTER, USB_DEVICE_ID_COOLER_MASTER_MICE_DONGLE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,	USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70R),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K95RGB),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_M65RGB),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_GLAIVE_RGB),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,	USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_REDRAGON_SEYMUR2),
+	  .driver_data = HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER),
+	  .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_EDIFIER, USB_DEVICE_ID_EDIFIER_QR30),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH_2968),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_GV186),
-		HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+	  .driver_data = HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_KISHI),
-		HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL },
-	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M506), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406W), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_340), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_M508WX), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_M508X), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_T609A), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_ODDOR_HANDBRAKE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_MOUSE_0783), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE3_COVER), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD), HID_QUIRK_BADPAD },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD), HID_QUIRK_BADPAD },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN), HID_QUIRK_MULTI_INPUT},
-	{ HID_USB_DEVICE(USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK), HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL), HID_QUIRK_HIDINPUT_FORCE },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4E2A), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPAD), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPORT), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD), HID_QUIRK_BADPAD },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_PRO), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X65), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_USB_MOUSE), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS1030_TOUCH), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS817_TOUCH), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS_TS), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DELL_K12A), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DELL_K15A), HID_QUIRK_NO_INIT_REPORTS },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD), HID_QUIRK_BADPAD },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD), HID_QUIRK_NOGET },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_WP5540), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_VRS, USB_DEVICE_ID_VRS_R295), HID_QUIRK_ALWAYS_POLL },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO), HID_QUIRK_NOGET },
-
-	{ 0 }
+	  .driver_data = HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING),
+	  .driver_data = HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING),
+	  .driver_data = HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING),
+	  .driver_data = HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M506),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406W),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_340),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_M508WX),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_M508X),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_T609A),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_ODDOR_HANDBRAKE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_MOUSE_0783),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE3_COVER),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD),
+	  .driver_data = HID_QUIRK_BADPAD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD),
+	  .driver_data = HID_QUIRK_BADPAD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN),
+	  .driver_data = HID_QUIRK_MULTI_INPUT},
+	{ HID_USB_DEVICE(USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK),
+	  .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PI_ENGINEERING,
+		USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL),
+	  .driver_data = HID_QUIRK_HIDINPUT_FORCE },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4E2A),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPAD),
+	  .driver_data = HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPORT),
+	  .driver_data = HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD),
+	  .driver_data = HID_QUIRK_BADPAD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52),
+	  .driver_data = HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_2),
+	  .driver_data = HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_PRO),
+	  .driver_data = HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X65),
+	  .driver_data = HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_USB_MOUSE),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS1030_TOUCH),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS817_TOUCH),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH),
+	  .driver_data =  HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS_TS),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DELL_K12A),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DELL_K15A),
+	  .driver_data = HID_QUIRK_NO_INIT_REPORTS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD),
+	  .driver_data = HID_QUIRK_BADPAD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_WP5540),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_VRS, USB_DEVICE_ID_VRS_R295),
+	  .driver_data = HID_QUIRK_ALWAYS_POLL },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS),
+	  .driver_data = HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD),
+	  .driver_data = HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE),
+	  .driver_data = HID_QUIRK_MULTI_INPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO),
+	  .driver_data = HID_QUIRK_NOGET },
+	{ }
 };
 
 /*

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 03/12] HID: hid-asus: use named initializer for 'asus_devices[]'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

This makes the code a little bit more readable and consistent
with other drivers in the HID subsystem that assign the
'driver_data' field in the 'hid_device_id' struct explicitly.

It was confirmed that hid-asus.o pre/post the patch are equal
using diffscope.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
---
 drivers/hid/hid-asus.c | 46 ++++++++++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 3f5e96900b67..ba9a49e9c7f0 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -1476,33 +1476,41 @@ static const __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 
 static const struct hid_device_id asus_devices[] = {
 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
-		USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD), I2C_KEYBOARD_QUIRKS},
+		USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD),
+	  .driver_data = I2C_KEYBOARD_QUIRKS },
 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
-		USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD), I2C_TOUCHPAD_QUIRKS },
+		USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD),
+	  .driver_data = I2C_TOUCHPAD_QUIRKS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
-		USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1), QUIRK_USE_KBD_BACKLIGHT },
+		USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1),
+	  .driver_data = QUIRK_USE_KBD_BACKLIGHT },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
-		USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2), QUIRK_USE_KBD_BACKLIGHT },
+		USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2),
+	  .driver_data = QUIRK_USE_KBD_BACKLIGHT },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
-		USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3), QUIRK_G752_KEYBOARD },
+		USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3),
+	  .driver_data = QUIRK_G752_KEYBOARD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 		USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD),
-	  QUIRK_USE_KBD_BACKLIGHT },
+	  .driver_data = QUIRK_USE_KBD_BACKLIGHT },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 	    USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD),
-	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
+	  .driver_data = QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 	    USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2),
-	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_HID_FN_LOCK },
+	  .driver_data = QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD |
+		QUIRK_HID_FN_LOCK },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 	    USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR),
-	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
+	  .driver_data = QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 	    USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY),
-	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD},
+	  .driver_data = QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD |
+		QUIRK_ROG_ALLY_XPAD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 	    USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X),
-	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD },
+	  .driver_data = QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD |
+		QUIRK_ROG_ALLY_XPAD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 	    USB_DEVICE_ID_ASUSTEK_XGM_2022),
 	},
@@ -1511,29 +1519,31 @@ static const struct hid_device_id asus_devices[] = {
 	},
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 	    USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD),
-	  QUIRK_ROG_CLAYMORE_II_KEYBOARD },
+	  .driver_data = QUIRK_ROG_CLAYMORE_II_KEYBOARD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 		USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD),
-	  QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
+	  .driver_data = QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 		USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD),
-	  QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
+	  .driver_data = QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_ASUS_AK1D) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_ASUS_MD_5110) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
-		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD), QUIRK_T100CHI },
+		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
+	  .driver_data = QUIRK_T100CHI },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE_MEDION_E1239T),
-		QUIRK_MEDION_E1239T },
+	  .driver_data = QUIRK_MEDION_E1239T },
 	/*
 	 * Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard
 	 * part, while letting hid-multitouch.c handle the touchpad.
 	 */
 	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
 		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_Z13_FOLIO),
-	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
+	  .driver_data = QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
 	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
-		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD) },
+		USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD),
+	  .driver_data = 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, asus_devices);

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 04/12] HID: i2c-hid-dmi-quirks: use named initializer for 'i2c_hid_elan_flipped_quirks[]'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

This makes the code a little bit more readable and consistent
with other drivers in the HID subsystem that assign the
'driver_data' field in the 'hid_device_id' struct explicitly.

It was confirmed that i2c-hid-dmi-quirks.o pre/post patch are equal
using diffscope.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
---
 drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
index 210f17c3a0be..f3e3cf73641e 100644
--- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
+++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
@@ -420,7 +420,7 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
 
 static const struct hid_device_id i2c_hid_elan_flipped_quirks = {
 	HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_ELAN, 0x2dcd),
-		HID_QUIRK_X_INVERT | HID_QUIRK_Y_INVERT
+	.driver_data = HID_QUIRK_X_INVERT | HID_QUIRK_Y_INVERT,
 };
 
 /*

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 05/12] HID: hid-belkin: clean up usage of 'driver_data'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

The module is storing an integer inside the drvdata pointer, which is
confusing, lets fix this and set the whole of 'hid_device_id' struct
as the drvdata and then simply use its integer 'driver_data' field for
quirks, which shall make the code cleaner, type-safe, consistent and
more readable.

This makes the cast to (void *) during storage a bit safer (just to
suppress the const qualifier warning) and the cast to (unsigned long)
during retrieval is removed.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/hid-belkin.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c
index 75aaed35ee9f..84695115d37b 100644
--- a/drivers/hid/hid-belkin.c
+++ b/drivers/hid/hid-belkin.c
@@ -27,7 +27,8 @@ static int belkin_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
-	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+	const struct hid_device_id *id = hid_get_drvdata(hdev);
+	unsigned long quirks = id->driver_data;
 
 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER ||
 			!(quirks & BELKIN_WKBD))
@@ -48,7 +49,7 @@ static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	unsigned long quirks = id->driver_data;
 	int ret;
 
-	hid_set_drvdata(hdev, (void *)quirks);
+	hid_set_drvdata(hdev, (void *)id);
 
 	ret = hid_parse(hdev);
 	if (ret) {

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 06/12] HID: hid-cypress: clean up usage of 'driver_data'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

The module is storing an integer inside the drvdata pointer, which is
confusing - furthermore this integer is mutable. When its value is
changed it is set again using the 'hid_set_drvdata' API within
the 'cp_event' function.

Let's fix this, create and allocate the 'cp_device' struct that is then
set as the drvdata and then simply use its integer 'quirks' field for
storing the quirks, which shall make the code cleaner, type-safe,
consistent and more readable.

This makes the cast to (void *) during storage unnecessary and the cast
to (unsigned long) during retrieval is also removed.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/hid-cypress.c | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 98548201feec..f18fddc176d0 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -25,6 +25,10 @@
 
 #define VA_INVAL_LOGICAL_BOUNDARY	0x08
 
+struct cp_device {
+	unsigned long quirks;
+};
+
 /*
  * Some USB barcode readers from cypress have usage min and usage max in
  * the wrong order
@@ -70,7 +74,8 @@ static __u8 *va_logical_boundary_fixup(struct hid_device *hdev, __u8 *rdesc,
 static const __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		unsigned int *rsize)
 {
-	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+	const struct cp_device *cp_device = hid_get_drvdata(hdev);
+	unsigned long quirks = cp_device->quirks;
 
 	if (quirks & CP_RDESC_SWAPPED_MIN_MAX)
 		rdesc = cp_rdesc_fixup(hdev, rdesc, rsize);
@@ -84,7 +89,8 @@ static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
-	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+	const struct cp_device *cp_device = hid_get_drvdata(hdev);
+	unsigned long quirks = cp_device->quirks;
 
 	if (!(quirks & CP_2WHEEL_MOUSE_HACK))
 		return 0;
@@ -100,22 +106,21 @@ static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
 static int cp_event(struct hid_device *hdev, struct hid_field *field,
 		struct hid_usage *usage, __s32 value)
 {
-	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+	struct cp_device *cp_device = hid_get_drvdata(hdev);
 
 	if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
-			!usage->type || !(quirks & CP_2WHEEL_MOUSE_HACK))
+			!usage->type || !(cp_device->quirks & CP_2WHEEL_MOUSE_HACK))
 		return 0;
 
 	if (usage->hid == 0x00090005) {
 		if (value)
-			quirks |=  CP_2WHEEL_MOUSE_HACK_ON;
+			cp_device->quirks |= CP_2WHEEL_MOUSE_HACK_ON;
 		else
-			quirks &= ~CP_2WHEEL_MOUSE_HACK_ON;
-		hid_set_drvdata(hdev, (void *)quirks);
+			cp_device->quirks &= ~CP_2WHEEL_MOUSE_HACK_ON;
 		return 1;
 	}
 
-	if (usage->code == REL_WHEEL && (quirks & CP_2WHEEL_MOUSE_HACK_ON)) {
+	if (usage->code == REL_WHEEL && (cp_device->quirks & CP_2WHEEL_MOUSE_HACK_ON)) {
 		struct input_dev *input = field->hidinput->input;
 
 		input_event(input, usage->type, REL_HWHEEL, value);
@@ -127,10 +132,17 @@ static int cp_event(struct hid_device *hdev, struct hid_field *field,
 
 static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
-	unsigned long quirks = id->driver_data;
 	int ret;
+	struct cp_device *cp_device;
 
-	hid_set_drvdata(hdev, (void *)quirks);
+	cp_device = devm_kzalloc(&hdev->dev, sizeof(*cp_device), GFP_KERNEL);
+
+	if (!cp_device)
+		return -ENOMEM;
+
+	cp_device->quirks = id->driver_data;
+
+	hid_set_drvdata(hdev, cp_device);
 
 	ret = hid_parse(hdev);
 	if (ret) {

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 07/12] HID: hid-gfrm: clean up usage of 'driver_data'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

The module is storing an integer inside the drvdata pointer, which is
confusing, lets fix this and set the whole of 'hid_device_id' struct
as the drvdata and then simply use its integer 'driver_data' field for
quirks, which shall make the code cleaner, type-safe, consistent and
more readable.

This makes the cast to (void *) during storage a bit safer (just to
suppress the const qualifier warning) and the cast to (unsigned long)
during retrieval is removed.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/hid-gfrm.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-gfrm.c b/drivers/hid/hid-gfrm.c
index d2a56bf92b41..f7cc754de84e 100644
--- a/drivers/hid/hid-gfrm.c
+++ b/drivers/hid/hid-gfrm.c
@@ -28,7 +28,8 @@ static int gfrm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
-	unsigned long hdev_type = (unsigned long) hid_get_drvdata(hdev);
+	const struct hid_device_id *id = hid_get_drvdata(hdev);
+	unsigned long hdev_type = id->driver_data;
 
 	if (hdev_type == GFRM100) {
 		if (usage->hid == (HID_UP_CONSUMER | 0x4)) {
@@ -50,7 +51,8 @@ static int gfrm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 static int gfrm_raw_event(struct hid_device *hdev, struct hid_report *report,
 		u8 *data, int size)
 {
-	unsigned long hdev_type = (unsigned long) hid_get_drvdata(hdev);
+	const struct hid_device_id *id = hid_get_drvdata(hdev);
+	unsigned long hdev_type = id->driver_data;
 	int ret = 0;
 
 	if (hdev_type != GFRM100)
@@ -99,7 +101,7 @@ static int gfrm_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
 	int ret;
 
-	hid_set_drvdata(hdev, (void *) id->driver_data);
+	hid_set_drvdata(hdev, (void *)id);
 
 	ret = hid_parse(hdev);
 	if (ret)

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 08/12] HID: hid-ite: clean up usage of 'driver_data'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

The module is storing an integer inside the drvdata pointer, which is
confusing, lets fix this and set the whole of 'hid_device_id' struct
as the drvdata and then simply use its integer 'driver_data' field for
quirks, which shall make the code cleaner, type-safe, consistent and
more readable.

This makes the cast to (void *) during storage a bit safer (just to
suppress the const qualifier warning) and the cast to (unsigned long)
during retrieval is removed.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
 drivers/hid/hid-ite.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-ite.c b/drivers/hid/hid-ite.c
index 8e42780a2663..63908f24b524 100644
--- a/drivers/hid/hid-ite.c
+++ b/drivers/hid/hid-ite.c
@@ -15,7 +15,9 @@
 
 static const __u8 *ite_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize)
 {
-	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+
+	const struct hid_device_id *id = hid_get_drvdata(hdev);
+	unsigned long quirks = id->driver_data;
 
 	if (quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) {
 		/* For Acer Aspire Switch 10 SW5-012 keyboard-dock */
@@ -44,7 +46,8 @@ static int ite_input_mapping(struct hid_device *hdev,
 		int *max)
 {
 
-	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+	const struct hid_device_id *id = hid_get_drvdata(hdev);
+	unsigned long quirks = id->driver_data;
 
 	if ((quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) &&
 	    (usage->hid & HID_USAGE_PAGE) == 0x00880000) {
@@ -94,7 +97,7 @@ static int ite_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
 	int ret;
 
-	hid_set_drvdata(hdev, (void *)id->driver_data);
+	hid_set_drvdata(hdev, (void *)id);
 
 	ret = hid_open_report(hdev);
 	if (ret)

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 09/12] HID: hid-tmff: clean up usage of 'driver_data'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

This module is using the 'hid_device_id::driver_data' field
as a valid pointer to dereference. The hid subsystem supports
injecting a 'new_id' device from the command line and so it is
more convenient to have this value to be an integer - that way
userspace can select a valid pointer within the driver via an
index.

Lets make this possible by storing an index to the table of
pointers 'ff_bits_table' there as opposed to the pointer address
directly.

The retrieval is bounded at runtime by the 'ff_bits_table_index'
enum to avoid dereferencing OOB objects.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
---
 drivers/hid/hid-tmff.c | 48 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 11 deletions(-)

diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 423f395d01ac..93de756dd30e 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -34,6 +34,17 @@ static const signed short ff_joystick[] = {
 	-1
 };
 
+enum ff_bits_table_index {
+	FF_BITS_TABLE_RUMBLE,
+	FF_BITS_TABLE_JOYSTICK,
+	NUM_OF_FF_BITS_IN_TABLE
+};
+
+static const signed short *ff_bits_table[] = {
+	[FF_BITS_TABLE_RUMBLE]		= ff_rumble,
+	[FF_BITS_TABLE_JOYSTICK]	= ff_joystick
+};
+
 #ifdef CONFIG_THRUSTMASTER_FF
 
 /* Usages for thrustmaster devices I know about */
@@ -210,9 +221,18 @@ static inline int tmff_init(struct hid_device *hid, const signed short *ff_bits)
 }
 #endif
 
+static const signed short *get_ff_bits(enum ff_bits_table_index index)
+{
+	if (index >= NUM_OF_FF_BITS_IN_TABLE)
+		return NULL;
+
+	return ff_bits_table[index];
+}
+
 static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
 	int ret;
+	const signed short *ff_bits = get_ff_bits(id->driver_data);
 
 	ret = hid_parse(hdev);
 	if (ret) {
@@ -226,7 +246,13 @@ static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		goto err;
 	}
 
-	tmff_init(hdev, (void *)id->driver_data);
+	if (!ff_bits) {
+		hid_err(hdev, "no ff_bits found\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	tmff_init(hdev, ff_bits);
 
 	return 0;
 err:
@@ -235,25 +261,25 @@ static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
 static const struct hid_device_id tm_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300),
-		.driver_data = (unsigned long)ff_rumble },
+		.driver_data = FF_BITS_TABLE_RUMBLE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304),   /* FireStorm Dual Power 2 (and 3) */
-		.driver_data = (unsigned long)ff_rumble },
+		.driver_data = FF_BITS_TABLE_RUMBLE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, THRUSTMASTER_DEVICE_ID_2_IN_1_DT),   /* Dual Trigger 2-in-1 */
-		.driver_data = (unsigned long)ff_rumble },
+		.driver_data = FF_BITS_TABLE_RUMBLE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323),   /* Dual Trigger 3-in-1 (PC Mode) */
-		.driver_data = (unsigned long)ff_rumble },
+		.driver_data = FF_BITS_TABLE_RUMBLE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324),   /* Dual Trigger 3-in-1 (PS3 Mode) */
-		.driver_data = (unsigned long)ff_rumble },
+		.driver_data = FF_BITS_TABLE_RUMBLE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb605),   /* NASCAR PRO FF2 Wheel */
-		.driver_data = (unsigned long)ff_joystick },
+		.driver_data = FF_BITS_TABLE_JOYSTICK },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651),	/* FGT Rumble Force Wheel */
-		.driver_data = (unsigned long)ff_rumble },
+		.driver_data = FF_BITS_TABLE_RUMBLE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653),	/* RGT Force Feedback CLUTCH Raging Wheel */
-		.driver_data = (unsigned long)ff_joystick },
+		.driver_data = FF_BITS_TABLE_JOYSTICK },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654),	/* FGT Force Feedback Wheel */
-		.driver_data = (unsigned long)ff_joystick },
+		.driver_data = FF_BITS_TABLE_JOYSTICK },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a),	/* F430 Force Feedback Wheel */
-		.driver_data = (unsigned long)ff_joystick },
+		.driver_data = FF_BITS_TABLE_JOYSTICK },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, tm_devices);

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 10/12] HID: wacom: cleanup usage of 'driver_data'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

This module is using the 'hid_device_id::driver_data' field
as a valid pointer to dereference. The hid subsystem allows
for injecting 'new_id' device via the command line. It follows
that it is more convenient to have 'driver_data' to be an integer
to allow the userspace to select a valid pointer via an index.

Lets enable this and store an index to the table of pointers
'wacom_features_table' instead, the access to this table is
bounded and checked at runtime via the 'wacom_features_table_index'
enum to avoid OOB dereferencing of objects.

The implementation relies heavily on the preprocessor - but
given the large amount of required entries (162) this is justified,
more robust and more resilient to user error than manual input.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
---
 drivers/hid/wacom.h     | 177 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/hid/wacom_sys.c |  22 ++++--
 drivers/hid/wacom_wac.c |  25 +++++--
 3 files changed, 214 insertions(+), 10 deletions(-)

diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
index 1deacb4568cb..115d0eb23277 100644
--- a/drivers/hid/wacom.h
+++ b/drivers/hid/wacom.h
@@ -228,6 +228,182 @@ static inline u32 wacom_rescale(u32 value, u32 in_max, u32 out_max)
 
 extern const struct hid_device_id wacom_ids[];
 
+/* This table lists all unique product IDs that are matched with
+ * a corresponging wacom_features_##prod struct. So any new product
+ * should be added to this table.
+ */
+#define HID_WACOM_PRODUCT_TABLE() \
+	table_entry(0x00) \
+	table_entry(0x03) \
+	table_entry(0x10) \
+	table_entry(0x11) \
+	table_entry(0x12) \
+	table_entry(0x13) \
+	table_entry(0x14) \
+	table_entry(0x15) \
+	table_entry(0x16) \
+	table_entry(0x17) \
+	table_entry(0x18) \
+	table_entry(0x19) \
+	table_entry(0x20) \
+	table_entry(0x21) \
+	table_entry(0x22) \
+	table_entry(0x23) \
+	table_entry(0x24) \
+	table_entry(0x26) \
+	table_entry(0x27) \
+	table_entry(0x28) \
+	table_entry(0x29) \
+	table_entry(0x2A) \
+	table_entry(0x30) \
+	table_entry(0x31) \
+	table_entry(0x32) \
+	table_entry(0x33) \
+	table_entry(0x34) \
+	table_entry(0x35) \
+	table_entry(0x37) \
+	table_entry(0x38) \
+	table_entry(0x39) \
+	table_entry(0x3F) \
+	table_entry(0x41) \
+	table_entry(0x42) \
+	table_entry(0x43) \
+	table_entry(0x44) \
+	table_entry(0x45) \
+	table_entry(0x47) \
+	table_entry(0x57) \
+	table_entry(0x59) \
+	table_entry(0x5B) \
+	table_entry(0x5D) \
+	table_entry(0x5E) \
+	table_entry(0x60) \
+	table_entry(0x61) \
+	table_entry(0x62) \
+	table_entry(0x63) \
+	table_entry(0x64) \
+	table_entry(0x65) \
+	table_entry(0x69) \
+	table_entry(0x6A) \
+	table_entry(0x6B) \
+	table_entry(0x81) \
+	table_entry(0x84) \
+	table_entry(0x90) \
+	table_entry(0x93) \
+	table_entry(0x94) \
+	table_entry(0x97) \
+	table_entry(0x9A) \
+	table_entry(0x9F) \
+	table_entry(0xB0) \
+	table_entry(0xB1) \
+	table_entry(0xB2) \
+	table_entry(0xB3) \
+	table_entry(0xB4) \
+	table_entry(0xB5) \
+	table_entry(0xB7) \
+	table_entry(0xB8) \
+	table_entry(0xB9) \
+	table_entry(0xBA) \
+	table_entry(0xBB) \
+	table_entry(0xBC) \
+	table_entry(0xBD) \
+	table_entry(0xC0) \
+	table_entry(0xC2) \
+	table_entry(0xC4) \
+	table_entry(0xC5) \
+	table_entry(0xC6) \
+	table_entry(0xC7) \
+	table_entry(0xCC) \
+	table_entry(0xCE) \
+	table_entry(0xD0) \
+	table_entry(0xD1) \
+	table_entry(0xD2) \
+	table_entry(0xD3) \
+	table_entry(0xD4) \
+	table_entry(0xD5) \
+	table_entry(0xD6) \
+	table_entry(0xD7) \
+	table_entry(0xD8) \
+	table_entry(0xDA) \
+	table_entry(0xDB) \
+	table_entry(0xDD) \
+	table_entry(0xDE) \
+	table_entry(0xDF) \
+	table_entry(0xE2) \
+	table_entry(0xE3) \
+	table_entry(0xE5) \
+	table_entry(0xE6) \
+	table_entry(0xEC) \
+	table_entry(0xED) \
+	table_entry(0xEF) \
+	table_entry(0xF0) \
+	table_entry(0xF4) \
+	table_entry(0xF6) \
+	table_entry(0xF8) \
+	table_entry(0xFA) \
+	table_entry(0xFB) \
+	table_entry(0x100) \
+	table_entry(0x101) \
+	table_entry(0x10D) \
+	table_entry(0x10E) \
+	table_entry(0x10F) \
+	table_entry(0x116) \
+	table_entry(0x12C) \
+	table_entry(0x300) \
+	table_entry(0x301) \
+	table_entry(0x302) \
+	table_entry(0x303) \
+	table_entry(0x304) \
+	table_entry(0x307) \
+	table_entry(0x309) \
+	table_entry(0x30A) \
+	table_entry(0x30C) \
+	table_entry(0x30E) \
+	table_entry(0x314) \
+	table_entry(0x315) \
+	table_entry(0x317) \
+	table_entry(0x318) \
+	table_entry(0x319) \
+	table_entry(0x323) \
+	table_entry(0x325) \
+	table_entry(0x326) \
+	table_entry(0x32A) \
+	table_entry(0x32B) \
+	table_entry(0x32C) \
+	table_entry(0x32F) \
+	table_entry(0x331) \
+	table_entry(0x333) \
+	table_entry(0x335) \
+	table_entry(0x336) \
+	table_entry(0x33B) \
+	table_entry(0x33C) \
+	table_entry(0x33D) \
+	table_entry(0x33E) \
+	table_entry(0x343) \
+	table_entry(0x360) \
+	table_entry(0x361) \
+	table_entry(0x377) \
+	table_entry(0x379) \
+	table_entry(0x37A) \
+	table_entry(0x37B) \
+	table_entry(0x393) \
+	table_entry(0x3c6) \
+	table_entry(0x3c8) \
+	table_entry(0x3dd) \
+	table_entry(0x4001) \
+	table_entry(0x4004) \
+	table_entry(0x5000) \
+	table_entry(0x5002) \
+	table_entry(0x6004) \
+	table_entry(HID_ANY_ID) \
+
+enum wacom_features_table_index {
+#define table_entry(product)	\
+	WACOM_FEATURE_TABLE_##product,
+	HID_WACOM_PRODUCT_TABLE()
+	NUM_OF_WACOM_FEATURES_IN_TABLE
+#undef table_entry
+};
+
 void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
 void wacom_setup_device_quirks(struct wacom *wacom);
 int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
@@ -249,4 +425,5 @@ struct wacom_led *wacom_led_next(struct wacom *wacom, struct wacom_led *cur);
 int wacom_equivalent_usage(int usage);
 int wacom_initialize_leds(struct wacom *wacom);
 void wacom_idleprox_timeout(struct timer_list *list);
+const struct wacom_features *get_wacom_features(enum wacom_features_table_index index);
 #endif
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 2220168bf116..dd3ed1f8134b 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -2561,8 +2561,13 @@ static void wacom_wireless_work(struct work_struct *work)
 		}
 
 		/* Stylus interface */
-		wacom_wac1->features =
-			*((struct wacom_features *)id->driver_data);
+		const struct wacom_features *features = get_wacom_features(id->driver_data);
+
+		if (!features) {
+			hid_err(wacom->hdev, "could not get wacom features.\n");
+			return;
+		}
+		wacom_wac1->features = *features;
 
 		wacom_wac1->pid = wacom_wac->pid;
 		hid_hw_stop(hdev1);
@@ -2574,8 +2579,7 @@ static void wacom_wireless_work(struct work_struct *work)
 		if (wacom_wac1->features.touch_max ||
 		    (wacom_wac1->features.type >= INTUOSHT &&
 		    wacom_wac1->features.type <= BAMBOO_PT)) {
-			wacom_wac2->features =
-				*((struct wacom_features *)id->driver_data);
+			wacom_wac2->features = *features;
 			wacom_wac2->pid = wacom_wac->pid;
 			hid_hw_stop(hdev2);
 			error = wacom_parse_and_register(wacom2, true);
@@ -2845,7 +2849,15 @@ static int wacom_probe(struct hid_device *hdev,
 	wacom->hdev = hdev;
 
 	wacom_wac = &wacom->wacom_wac;
-	wacom_wac->features = *((struct wacom_features *)id->driver_data);
+
+	const struct wacom_features *id_features = get_wacom_features(id->driver_data);
+
+	if (!id_features) {
+		hid_err(wacom->hdev, "could not get wacom id_features.\n");
+		return -EINVAL;
+	}
+	wacom_wac->features = *id_features;
+
 	features = &wacom_wac->features;
 
 	if (features->check_for_hid_type && features->hid_type != hdev->type)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index da1f0ea85625..d0a864d52509 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -4945,25 +4945,40 @@ static const struct wacom_features wacom_features_HID_ANY_ID =
 static const struct wacom_features wacom_features_0x94 =
 	{ "Wacom Bootloader", .type = BOOTLOADER };
 
+static const struct wacom_features *wacom_features_table[] = {
+#define table_entry(product)				\
+	[WACOM_FEATURE_TABLE_##product] = &wacom_features_##product,
+	HID_WACOM_PRODUCT_TABLE()
+#undef table_entry
+};
+
+const struct wacom_features *get_wacom_features(enum wacom_features_table_index index)
+{
+	if (index >= NUM_OF_WACOM_FEATURES_IN_TABLE)
+		return NULL;
+
+	return wacom_features_table[index];
+}
+
 #define USB_DEVICE_WACOM(prod)						\
 	HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
-	.driver_data = (kernel_ulong_t)&wacom_features_##prod
+	.driver_data = WACOM_FEATURE_TABLE_##prod
 
 #define BT_DEVICE_WACOM(prod)						\
 	HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
-	.driver_data = (kernel_ulong_t)&wacom_features_##prod
+	.driver_data = WACOM_FEATURE_TABLE_##prod
 
 #define I2C_DEVICE_WACOM(prod)						\
 	HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
-	.driver_data = (kernel_ulong_t)&wacom_features_##prod
+	.driver_data = WACOM_FEATURE_TABLE_##prod
 
 #define PCI_DEVICE_WACOM(prod)						\
 	HID_DEVICE(BUS_PCI, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
-	.driver_data = (kernel_ulong_t)&wacom_features_##prod
+	.driver_data = WACOM_FEATURE_TABLE_##prod
 
 #define USB_DEVICE_LENOVO(prod)					\
 	HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod),			\
-	.driver_data = (kernel_ulong_t)&wacom_features_##prod
+	.driver_data = WACOM_FEATURE_TABLE_##prod
 
 const struct hid_device_id wacom_ids[] = {
 	{ USB_DEVICE_WACOM(0x00) },

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 11/12] HID: hid-core: sanitize user input in 'new_id_store'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

Only accept 'driver_data' values that match an existing 'id_table'
entry within the driver. This makes the field mandatory if the
'id_table' is defined in the HID module and disallows overriding
pre-defined values within the driver module with arbitrary entries
from the command line.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
---
 drivers/hid/hid-core.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 41a79e43c82b..e060e5ec4ea6 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2647,6 +2647,8 @@ static ssize_t new_id_store(struct device_driver *drv, const char *buf,
 		size_t count)
 {
 	struct hid_driver *hdrv = to_hid_driver(drv);
+	const struct hid_device_id *ids = hdrv->id_table;
+
 	struct hid_dynid *dynid;
 	__u32 bus, vendor, product;
 	unsigned long driver_data = 0;
@@ -2657,6 +2659,22 @@ static ssize_t new_id_store(struct device_driver *drv, const char *buf,
 	if (ret < 3)
 		return -EINVAL;
 
+	/* Only accept driver_data values that match an
+	 * existing id_table entry
+	 */
+	if (ids) {
+		ret = -EINVAL;
+		while (ids->bus) {
+			if (driver_data == ids->driver_data) {
+				ret = 0;
+				break;
+			}
+			ids++;
+		}
+		if (ret)	/* No match */
+			return ret;
+	}
+
 	dynid = kzalloc_obj(*dynid);
 	if (!dynid)
 		return -ENOMEM;

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 12/12] HID: wacom: do not use 'driver_data'
From: Pawel Zalewski (The Capable Hub) @ 2026-06-10 15:11 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, Ping Cheng, Jason Gerecke
  Cc: linux-kernel, linux-input, Pawel Zalewski (The Capable Hub)
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk>

The driver data field is used to match the product with
a 'wacom_features' struct via a remapped enum - since
we already have to look it up at runtime and validate,
we can just remove the remapping and look up the
'wacom_features' directly by the product id.

This makes the code easier to edit and maintain. It also
reduces the complexity of macro magic and keeps macros
local to the module.

Signed-off-by: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
---
 drivers/hid/wacom.h     | 178 +------------------------------------------
 drivers/hid/wacom_sys.c |   7 +-
 drivers/hid/wacom_wac.c | 197 +++++++++++++++++++++++++++++++++++++++++++-----
 drivers/hid/wacom_wac.h |   5 ++
 4 files changed, 186 insertions(+), 201 deletions(-)

diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
index 115d0eb23277..80a1a5d09e55 100644
--- a/drivers/hid/wacom.h
+++ b/drivers/hid/wacom.h
@@ -228,182 +228,6 @@ static inline u32 wacom_rescale(u32 value, u32 in_max, u32 out_max)
 
 extern const struct hid_device_id wacom_ids[];
 
-/* This table lists all unique product IDs that are matched with
- * a corresponging wacom_features_##prod struct. So any new product
- * should be added to this table.
- */
-#define HID_WACOM_PRODUCT_TABLE() \
-	table_entry(0x00) \
-	table_entry(0x03) \
-	table_entry(0x10) \
-	table_entry(0x11) \
-	table_entry(0x12) \
-	table_entry(0x13) \
-	table_entry(0x14) \
-	table_entry(0x15) \
-	table_entry(0x16) \
-	table_entry(0x17) \
-	table_entry(0x18) \
-	table_entry(0x19) \
-	table_entry(0x20) \
-	table_entry(0x21) \
-	table_entry(0x22) \
-	table_entry(0x23) \
-	table_entry(0x24) \
-	table_entry(0x26) \
-	table_entry(0x27) \
-	table_entry(0x28) \
-	table_entry(0x29) \
-	table_entry(0x2A) \
-	table_entry(0x30) \
-	table_entry(0x31) \
-	table_entry(0x32) \
-	table_entry(0x33) \
-	table_entry(0x34) \
-	table_entry(0x35) \
-	table_entry(0x37) \
-	table_entry(0x38) \
-	table_entry(0x39) \
-	table_entry(0x3F) \
-	table_entry(0x41) \
-	table_entry(0x42) \
-	table_entry(0x43) \
-	table_entry(0x44) \
-	table_entry(0x45) \
-	table_entry(0x47) \
-	table_entry(0x57) \
-	table_entry(0x59) \
-	table_entry(0x5B) \
-	table_entry(0x5D) \
-	table_entry(0x5E) \
-	table_entry(0x60) \
-	table_entry(0x61) \
-	table_entry(0x62) \
-	table_entry(0x63) \
-	table_entry(0x64) \
-	table_entry(0x65) \
-	table_entry(0x69) \
-	table_entry(0x6A) \
-	table_entry(0x6B) \
-	table_entry(0x81) \
-	table_entry(0x84) \
-	table_entry(0x90) \
-	table_entry(0x93) \
-	table_entry(0x94) \
-	table_entry(0x97) \
-	table_entry(0x9A) \
-	table_entry(0x9F) \
-	table_entry(0xB0) \
-	table_entry(0xB1) \
-	table_entry(0xB2) \
-	table_entry(0xB3) \
-	table_entry(0xB4) \
-	table_entry(0xB5) \
-	table_entry(0xB7) \
-	table_entry(0xB8) \
-	table_entry(0xB9) \
-	table_entry(0xBA) \
-	table_entry(0xBB) \
-	table_entry(0xBC) \
-	table_entry(0xBD) \
-	table_entry(0xC0) \
-	table_entry(0xC2) \
-	table_entry(0xC4) \
-	table_entry(0xC5) \
-	table_entry(0xC6) \
-	table_entry(0xC7) \
-	table_entry(0xCC) \
-	table_entry(0xCE) \
-	table_entry(0xD0) \
-	table_entry(0xD1) \
-	table_entry(0xD2) \
-	table_entry(0xD3) \
-	table_entry(0xD4) \
-	table_entry(0xD5) \
-	table_entry(0xD6) \
-	table_entry(0xD7) \
-	table_entry(0xD8) \
-	table_entry(0xDA) \
-	table_entry(0xDB) \
-	table_entry(0xDD) \
-	table_entry(0xDE) \
-	table_entry(0xDF) \
-	table_entry(0xE2) \
-	table_entry(0xE3) \
-	table_entry(0xE5) \
-	table_entry(0xE6) \
-	table_entry(0xEC) \
-	table_entry(0xED) \
-	table_entry(0xEF) \
-	table_entry(0xF0) \
-	table_entry(0xF4) \
-	table_entry(0xF6) \
-	table_entry(0xF8) \
-	table_entry(0xFA) \
-	table_entry(0xFB) \
-	table_entry(0x100) \
-	table_entry(0x101) \
-	table_entry(0x10D) \
-	table_entry(0x10E) \
-	table_entry(0x10F) \
-	table_entry(0x116) \
-	table_entry(0x12C) \
-	table_entry(0x300) \
-	table_entry(0x301) \
-	table_entry(0x302) \
-	table_entry(0x303) \
-	table_entry(0x304) \
-	table_entry(0x307) \
-	table_entry(0x309) \
-	table_entry(0x30A) \
-	table_entry(0x30C) \
-	table_entry(0x30E) \
-	table_entry(0x314) \
-	table_entry(0x315) \
-	table_entry(0x317) \
-	table_entry(0x318) \
-	table_entry(0x319) \
-	table_entry(0x323) \
-	table_entry(0x325) \
-	table_entry(0x326) \
-	table_entry(0x32A) \
-	table_entry(0x32B) \
-	table_entry(0x32C) \
-	table_entry(0x32F) \
-	table_entry(0x331) \
-	table_entry(0x333) \
-	table_entry(0x335) \
-	table_entry(0x336) \
-	table_entry(0x33B) \
-	table_entry(0x33C) \
-	table_entry(0x33D) \
-	table_entry(0x33E) \
-	table_entry(0x343) \
-	table_entry(0x360) \
-	table_entry(0x361) \
-	table_entry(0x377) \
-	table_entry(0x379) \
-	table_entry(0x37A) \
-	table_entry(0x37B) \
-	table_entry(0x393) \
-	table_entry(0x3c6) \
-	table_entry(0x3c8) \
-	table_entry(0x3dd) \
-	table_entry(0x4001) \
-	table_entry(0x4004) \
-	table_entry(0x5000) \
-	table_entry(0x5002) \
-	table_entry(0x6004) \
-	table_entry(HID_ANY_ID) \
-
-enum wacom_features_table_index {
-#define table_entry(product)	\
-	WACOM_FEATURE_TABLE_##product,
-	HID_WACOM_PRODUCT_TABLE()
-	NUM_OF_WACOM_FEATURES_IN_TABLE
-#undef table_entry
-};
-
 void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
 void wacom_setup_device_quirks(struct wacom *wacom);
 int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
@@ -425,5 +249,5 @@ struct wacom_led *wacom_led_next(struct wacom *wacom, struct wacom_led *cur);
 int wacom_equivalent_usage(int usage);
 int wacom_initialize_leds(struct wacom *wacom);
 void wacom_idleprox_timeout(struct timer_list *list);
-const struct wacom_features *get_wacom_features(enum wacom_features_table_index index);
+const struct wacom_features *get_wacom_features(u32 product);
 #endif
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index dd3ed1f8134b..1d5bdb4da29c 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -2561,7 +2561,7 @@ static void wacom_wireless_work(struct work_struct *work)
 		}
 
 		/* Stylus interface */
-		const struct wacom_features *features = get_wacom_features(id->driver_data);
+		const struct wacom_features *features = get_wacom_features(id->product);
 
 		if (!features) {
 			hid_err(wacom->hdev, "could not get wacom features.\n");
@@ -2833,9 +2833,6 @@ static int wacom_probe(struct hid_device *hdev,
 	struct wacom_features *features;
 	int error;
 
-	if (!id->driver_data)
-		return -EINVAL;
-
 	hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
 
 	/* hid-core sets this quirk for the boot interface */
@@ -2850,7 +2847,7 @@ static int wacom_probe(struct hid_device *hdev,
 
 	wacom_wac = &wacom->wacom_wac;
 
-	const struct wacom_features *id_features = get_wacom_features(id->driver_data);
+	const struct wacom_features *id_features = get_wacom_features(id->product);
 
 	if (!id_features) {
 		hid_err(wacom->hdev, "could not get wacom id_features.\n");
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index d0a864d52509..e066aa334837 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -4945,40 +4945,199 @@ static const struct wacom_features wacom_features_HID_ANY_ID =
 static const struct wacom_features wacom_features_0x94 =
 	{ "Wacom Bootloader", .type = BOOTLOADER };
 
-static const struct wacom_features *wacom_features_table[] = {
-#define table_entry(product)				\
-	[WACOM_FEATURE_TABLE_##product] = &wacom_features_##product,
-	HID_WACOM_PRODUCT_TABLE()
-#undef table_entry
+#define WACOM_FEATURE_TABLE_ENTRY(product_id)			\
+	{.product = product_id, .wacom_features_ptr = &wacom_features_##product_id}
+
+static const struct wacom_features_table_item wacom_features_table[] = {
+	WACOM_FEATURE_TABLE_ENTRY(0x00),
+	WACOM_FEATURE_TABLE_ENTRY(0x03),
+	WACOM_FEATURE_TABLE_ENTRY(0x10),
+	WACOM_FEATURE_TABLE_ENTRY(0x11),
+	WACOM_FEATURE_TABLE_ENTRY(0x12),
+	WACOM_FEATURE_TABLE_ENTRY(0x13),
+	WACOM_FEATURE_TABLE_ENTRY(0x14),
+	WACOM_FEATURE_TABLE_ENTRY(0x15),
+	WACOM_FEATURE_TABLE_ENTRY(0x16),
+	WACOM_FEATURE_TABLE_ENTRY(0x17),
+	WACOM_FEATURE_TABLE_ENTRY(0x18),
+	WACOM_FEATURE_TABLE_ENTRY(0x19),
+	WACOM_FEATURE_TABLE_ENTRY(0x20),
+	WACOM_FEATURE_TABLE_ENTRY(0x21),
+	WACOM_FEATURE_TABLE_ENTRY(0x22),
+	WACOM_FEATURE_TABLE_ENTRY(0x23),
+	WACOM_FEATURE_TABLE_ENTRY(0x24),
+	WACOM_FEATURE_TABLE_ENTRY(0x26),
+	WACOM_FEATURE_TABLE_ENTRY(0x27),
+	WACOM_FEATURE_TABLE_ENTRY(0x28),
+	WACOM_FEATURE_TABLE_ENTRY(0x29),
+	WACOM_FEATURE_TABLE_ENTRY(0x2A),
+	WACOM_FEATURE_TABLE_ENTRY(0x30),
+	WACOM_FEATURE_TABLE_ENTRY(0x31),
+	WACOM_FEATURE_TABLE_ENTRY(0x32),
+	WACOM_FEATURE_TABLE_ENTRY(0x33),
+	WACOM_FEATURE_TABLE_ENTRY(0x34),
+	WACOM_FEATURE_TABLE_ENTRY(0x35),
+	WACOM_FEATURE_TABLE_ENTRY(0x37),
+	WACOM_FEATURE_TABLE_ENTRY(0x38),
+	WACOM_FEATURE_TABLE_ENTRY(0x39),
+	WACOM_FEATURE_TABLE_ENTRY(0x3F),
+	WACOM_FEATURE_TABLE_ENTRY(0x41),
+	WACOM_FEATURE_TABLE_ENTRY(0x42),
+	WACOM_FEATURE_TABLE_ENTRY(0x43),
+	WACOM_FEATURE_TABLE_ENTRY(0x44),
+	WACOM_FEATURE_TABLE_ENTRY(0x45),
+	WACOM_FEATURE_TABLE_ENTRY(0x47),
+	WACOM_FEATURE_TABLE_ENTRY(0x57),
+	WACOM_FEATURE_TABLE_ENTRY(0x59),
+	WACOM_FEATURE_TABLE_ENTRY(0x5B),
+	WACOM_FEATURE_TABLE_ENTRY(0x5D),
+	WACOM_FEATURE_TABLE_ENTRY(0x5E),
+	WACOM_FEATURE_TABLE_ENTRY(0x60),
+	WACOM_FEATURE_TABLE_ENTRY(0x61),
+	WACOM_FEATURE_TABLE_ENTRY(0x62),
+	WACOM_FEATURE_TABLE_ENTRY(0x63),
+	WACOM_FEATURE_TABLE_ENTRY(0x64),
+	WACOM_FEATURE_TABLE_ENTRY(0x65),
+	WACOM_FEATURE_TABLE_ENTRY(0x69),
+	WACOM_FEATURE_TABLE_ENTRY(0x6A),
+	WACOM_FEATURE_TABLE_ENTRY(0x6B),
+	WACOM_FEATURE_TABLE_ENTRY(0x81),
+	WACOM_FEATURE_TABLE_ENTRY(0x84),
+	WACOM_FEATURE_TABLE_ENTRY(0x90),
+	WACOM_FEATURE_TABLE_ENTRY(0x93),
+	WACOM_FEATURE_TABLE_ENTRY(0x94),
+	WACOM_FEATURE_TABLE_ENTRY(0x97),
+	WACOM_FEATURE_TABLE_ENTRY(0x9A),
+	WACOM_FEATURE_TABLE_ENTRY(0x9F),
+	WACOM_FEATURE_TABLE_ENTRY(0xB0),
+	WACOM_FEATURE_TABLE_ENTRY(0xB1),
+	WACOM_FEATURE_TABLE_ENTRY(0xB2),
+	WACOM_FEATURE_TABLE_ENTRY(0xB3),
+	WACOM_FEATURE_TABLE_ENTRY(0xB4),
+	WACOM_FEATURE_TABLE_ENTRY(0xB5),
+	WACOM_FEATURE_TABLE_ENTRY(0xB7),
+	WACOM_FEATURE_TABLE_ENTRY(0xB8),
+	WACOM_FEATURE_TABLE_ENTRY(0xB9),
+	WACOM_FEATURE_TABLE_ENTRY(0xBA),
+	WACOM_FEATURE_TABLE_ENTRY(0xBB),
+	WACOM_FEATURE_TABLE_ENTRY(0xBC),
+	WACOM_FEATURE_TABLE_ENTRY(0xBD),
+	WACOM_FEATURE_TABLE_ENTRY(0xC0),
+	WACOM_FEATURE_TABLE_ENTRY(0xC2),
+	WACOM_FEATURE_TABLE_ENTRY(0xC4),
+	WACOM_FEATURE_TABLE_ENTRY(0xC5),
+	WACOM_FEATURE_TABLE_ENTRY(0xC6),
+	WACOM_FEATURE_TABLE_ENTRY(0xC7),
+	WACOM_FEATURE_TABLE_ENTRY(0xCC),
+	WACOM_FEATURE_TABLE_ENTRY(0xCE),
+	WACOM_FEATURE_TABLE_ENTRY(0xD0),
+	WACOM_FEATURE_TABLE_ENTRY(0xD1),
+	WACOM_FEATURE_TABLE_ENTRY(0xD2),
+	WACOM_FEATURE_TABLE_ENTRY(0xD3),
+	WACOM_FEATURE_TABLE_ENTRY(0xD4),
+	WACOM_FEATURE_TABLE_ENTRY(0xD5),
+	WACOM_FEATURE_TABLE_ENTRY(0xD6),
+	WACOM_FEATURE_TABLE_ENTRY(0xD7),
+	WACOM_FEATURE_TABLE_ENTRY(0xD8),
+	WACOM_FEATURE_TABLE_ENTRY(0xDA),
+	WACOM_FEATURE_TABLE_ENTRY(0xDB),
+	WACOM_FEATURE_TABLE_ENTRY(0xDD),
+	WACOM_FEATURE_TABLE_ENTRY(0xDE),
+	WACOM_FEATURE_TABLE_ENTRY(0xDF),
+	WACOM_FEATURE_TABLE_ENTRY(0xE2),
+	WACOM_FEATURE_TABLE_ENTRY(0xE3),
+	WACOM_FEATURE_TABLE_ENTRY(0xE5),
+	WACOM_FEATURE_TABLE_ENTRY(0xE6),
+	WACOM_FEATURE_TABLE_ENTRY(0xEC),
+	WACOM_FEATURE_TABLE_ENTRY(0xED),
+	WACOM_FEATURE_TABLE_ENTRY(0xEF),
+	WACOM_FEATURE_TABLE_ENTRY(0xF0),
+	WACOM_FEATURE_TABLE_ENTRY(0xF4),
+	WACOM_FEATURE_TABLE_ENTRY(0xF6),
+	WACOM_FEATURE_TABLE_ENTRY(0xF8),
+	WACOM_FEATURE_TABLE_ENTRY(0xFA),
+	WACOM_FEATURE_TABLE_ENTRY(0xFB),
+	WACOM_FEATURE_TABLE_ENTRY(0x100),
+	WACOM_FEATURE_TABLE_ENTRY(0x101),
+	WACOM_FEATURE_TABLE_ENTRY(0x10D),
+	WACOM_FEATURE_TABLE_ENTRY(0x10E),
+	WACOM_FEATURE_TABLE_ENTRY(0x10F),
+	WACOM_FEATURE_TABLE_ENTRY(0x116),
+	WACOM_FEATURE_TABLE_ENTRY(0x12C),
+	WACOM_FEATURE_TABLE_ENTRY(0x300),
+	WACOM_FEATURE_TABLE_ENTRY(0x301),
+	WACOM_FEATURE_TABLE_ENTRY(0x302),
+	WACOM_FEATURE_TABLE_ENTRY(0x303),
+	WACOM_FEATURE_TABLE_ENTRY(0x304),
+	WACOM_FEATURE_TABLE_ENTRY(0x307),
+	WACOM_FEATURE_TABLE_ENTRY(0x309),
+	WACOM_FEATURE_TABLE_ENTRY(0x30A),
+	WACOM_FEATURE_TABLE_ENTRY(0x30C),
+	WACOM_FEATURE_TABLE_ENTRY(0x30E),
+	WACOM_FEATURE_TABLE_ENTRY(0x314),
+	WACOM_FEATURE_TABLE_ENTRY(0x315),
+	WACOM_FEATURE_TABLE_ENTRY(0x317),
+	WACOM_FEATURE_TABLE_ENTRY(0x318),
+	WACOM_FEATURE_TABLE_ENTRY(0x319),
+	WACOM_FEATURE_TABLE_ENTRY(0x323),
+	WACOM_FEATURE_TABLE_ENTRY(0x325),
+	WACOM_FEATURE_TABLE_ENTRY(0x326),
+	WACOM_FEATURE_TABLE_ENTRY(0x32A),
+	WACOM_FEATURE_TABLE_ENTRY(0x32B),
+	WACOM_FEATURE_TABLE_ENTRY(0x32C),
+	WACOM_FEATURE_TABLE_ENTRY(0x32F),
+	WACOM_FEATURE_TABLE_ENTRY(0x331),
+	WACOM_FEATURE_TABLE_ENTRY(0x333),
+	WACOM_FEATURE_TABLE_ENTRY(0x335),
+	WACOM_FEATURE_TABLE_ENTRY(0x336),
+	WACOM_FEATURE_TABLE_ENTRY(0x33B),
+	WACOM_FEATURE_TABLE_ENTRY(0x33C),
+	WACOM_FEATURE_TABLE_ENTRY(0x33D),
+	WACOM_FEATURE_TABLE_ENTRY(0x33E),
+	WACOM_FEATURE_TABLE_ENTRY(0x343),
+	WACOM_FEATURE_TABLE_ENTRY(0x360),
+	WACOM_FEATURE_TABLE_ENTRY(0x361),
+	WACOM_FEATURE_TABLE_ENTRY(0x377),
+	WACOM_FEATURE_TABLE_ENTRY(0x379),
+	WACOM_FEATURE_TABLE_ENTRY(0x37A),
+	WACOM_FEATURE_TABLE_ENTRY(0x37B),
+	WACOM_FEATURE_TABLE_ENTRY(0x393),
+	WACOM_FEATURE_TABLE_ENTRY(0x3c6),
+	WACOM_FEATURE_TABLE_ENTRY(0x3c8),
+	WACOM_FEATURE_TABLE_ENTRY(0x3dd),
+	WACOM_FEATURE_TABLE_ENTRY(0x4001),
+	WACOM_FEATURE_TABLE_ENTRY(0x4004),
+	WACOM_FEATURE_TABLE_ENTRY(0x5000),
+	WACOM_FEATURE_TABLE_ENTRY(0x5002),
+	WACOM_FEATURE_TABLE_ENTRY(0x6004),
+	WACOM_FEATURE_TABLE_ENTRY(HID_ANY_ID),
 };
 
-const struct wacom_features *get_wacom_features(enum wacom_features_table_index index)
+const struct wacom_features *get_wacom_features(u32 product)
 {
-	if (index >= NUM_OF_WACOM_FEATURES_IN_TABLE)
-		return NULL;
+	int i;
 
-	return wacom_features_table[index];
+	for (i = 0; i < ARRAY_SIZE(wacom_features_table); i++)
+		if (wacom_features_table[i].product == product)
+			return wacom_features_table[i].wacom_features_ptr;
+
+	return NULL;
 }
 
 #define USB_DEVICE_WACOM(prod)						\
-	HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
-	.driver_data = WACOM_FEATURE_TABLE_##prod
+	HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod)
 
 #define BT_DEVICE_WACOM(prod)						\
-	HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
-	.driver_data = WACOM_FEATURE_TABLE_##prod
+	HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod)
 
 #define I2C_DEVICE_WACOM(prod)						\
-	HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
-	.driver_data = WACOM_FEATURE_TABLE_##prod
+	HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod)
 
 #define PCI_DEVICE_WACOM(prod)						\
-	HID_DEVICE(BUS_PCI, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
-	.driver_data = WACOM_FEATURE_TABLE_##prod
+	HID_DEVICE(BUS_PCI, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod)
 
 #define USB_DEVICE_LENOVO(prod)					\
-	HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod),			\
-	.driver_data = WACOM_FEATURE_TABLE_##prod
+	HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod)
 
 const struct hid_device_id wacom_ids[] = {
 	{ USB_DEVICE_WACOM(0x00) },
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 126bec6e5c0c..ecb85c459d9a 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -279,6 +279,11 @@ struct wacom_features {
 	int hid_type;
 };
 
+struct wacom_features_table_item {
+	u32 product;
+	const struct wacom_features *wacom_features_ptr;
+};
+
 struct wacom_shared {
 	bool stylus_in_proximity;
 	bool touch_down;

-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v2 11/12] HID: hid-core: sanitize user input in 'new_id_store'
From: sashiko-bot @ 2026-06-10 15:32 UTC (permalink / raw)
  Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260610-mod-devicetable-hid_device_id-v2-11-a1d7473ccd9c@thegoodpenguin.co.uk>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Restricting `driver_data` to strictly match an existing `id_table` entry breaks backward compatibility and defeats the purpose of the `new_id` interface.
--

commit 613c086c5db811baec4d7b28a4e3757a62048b24
Author: Pawel Zalewski (The Capable Hub) <pzalewski@thegoodpenguin.co.uk>
Subject: HID: hid-core: sanitize user input in 'new_id_store'

This commit modifies the new_id sysfs interface for HID drivers. It adds a
check to ensure that any provided driver_data value strictly matches an
existing entry within the driver's id_table, preventing arbitrary values
from being passed.

> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index 41a79e43c82b3..e060e5ec4ea62 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -2647,6 +2647,8 @@ static ssize_t new_id_store(struct device_driver *drv, const char *buf,
>  		size_t count)
>  {
>  	struct hid_driver *hdrv = to_hid_driver(drv);
> +	const struct hid_device_id *ids = hdrv->id_table;
> +
>  	struct hid_dynid *dynid;
>  	__u32 bus, vendor, product;
>  	unsigned long driver_data = 0;
> @@ -2657,6 +2659,22 @@ static ssize_t new_id_store(struct device_driver *drv, const char *buf,
>  	if (ret < 3)
>  		return -EINVAL;
>  
> +	/* Only accept driver_data values that match an
> +	 * existing id_table entry
> +	 */
> +	if (ids) {
> +		ret = -EINVAL;
> +		while (ids->bus) {
> +			if (driver_data == ids->driver_data) {
> +				ret = 0;
> +				break;
> +			}
> +			ids++;
> +		}
> +		if (ret)	/* No match */
> +			return ret;
> +	}
> +

[Severity: High]
Does this change break backward compatibility and the intended purpose of the
new_id interface?

Previously, users could write just the bus, vendor, and product to new_id,
leaving driver_data to default to 0. With this patch, if a driver's id_table
only contains entries with non-zero driver_data (such as quirk bitmasks in
hid-apple), wouldn't the sysfs write now fail with -EINVAL?

Additionally, does this prevent developers from testing unsupported hardware
by passing custom quirk bitmasks (or passing 0 to test without quirks) via
the driver_data field?

>  	dynid = kzalloc_obj(*dynid);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260610-mod-devicetable-hid_device_id-v2-0-a1d7473ccd9c@thegoodpenguin.co.uk?part=11

^ permalink raw reply

* Re: [PATCH v14 0/2] Firmware Support for USB-HID Devices and CP2112
From: Jiri Kosina @ 2026-06-10 15:35 UTC (permalink / raw)
  To: Danny Kaehn
  Cc: Benjamin Tissoires, Andy Shevchenko, Andi Shyti, Conor Dooley,
	linux-input, Dmitry Torokhov, Ethan Twardy, linux-i2c,
	linux-kernel, Leo Huang, Arun D Patil, Willie Thai, Ting-Kai Chen,
	Bartosz Golaszewski
In-Reply-To: <20260520-cp2112-dt-v14-0-b1b4b6734b6f@plexus.com>

On Wed, 20 May 2026, Danny Kaehn wrote:

> This patchset allows USB-HID devices to have Firmware bindings through sharing
> the USB fwnode with the HID driver, and adds such a binding and driver
> implementation for the CP2112 USB to SMBus Bridge (which necessitated the
> USB-HID change). This change allows a CP2112 permanently attached in hardware to
> be described in DT and ACPI and interoperate with other drivers.

Applied to hid.git#for-7.2/cp2112, thanks.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply

* [PATCH v2 0/7] HID: iio: basic clean up for usage_id
From: Sanjay Chitroda @ 2026-06-10 15:37 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko
  Cc: linux-input, linux-iio, linux-kernel, Sanjay Chitroda,
	Maxwell Doose

Hi all,

This series updates all HID IIO drivers to use 'u32' instead of
bare 'unsigned' for the usage_id parameter.

This matches expected callback API type and improves code clarity,
as HID usage IDs are defined as 32-bit values.

No functional changes are introduced.

Testing:
  - Compiled with W=1 for each patch in the series

---
Changes in v2:
- rectify commit message with input from Jonathan
- added reviewed by tag in all change of series
- Link to v1: https://patch.msgid.link/20260606-6-june-hid-iio-correct-usage-id-v1-0-dd4a6820b674@gmail.com

---
Sanjay Chitroda (7):
      iio: gyro: hid-sensor-gyro-3d: use u32 instead of unsigned
      iio: accel: hid-sensor-accel-3d: use u32 instead of unsigned
      iio: light: hid-sensor-als: use u32 instead of unsigned
      iio: light: hid-sensor-prox: use u32 instead of unsigned
      iio: orientation: hid-sensor-incl-3d: use u32 instead of unsigned
      iio: orientation: hid-sensor-rotation: use u32 instead of unsigned
      iio: pressure: hid-sensor-press: use u32 instead of unsigned

 drivers/iio/accel/hid-sensor-accel-3d.c       | 6 +++---
 drivers/iio/gyro/hid-sensor-gyro-3d.c         | 6 +++---
 drivers/iio/light/hid-sensor-als.c            | 6 +++---
 drivers/iio/light/hid-sensor-prox.c           | 4 ++--
 drivers/iio/orientation/hid-sensor-incl-3d.c  | 6 +++---
 drivers/iio/orientation/hid-sensor-rotation.c | 6 +++---
 drivers/iio/pressure/hid-sensor-press.c       | 6 +++---
 7 files changed, 20 insertions(+), 20 deletions(-)
---
base-commit: ae696dfa47c30016cd429b9db5e70b259b8f509e
change-id: 20260606-6-june-hid-iio-correct-usage-id-57ce92cb102b

Best regards,
--  
Sanjay Chitroda <sanjayembeddedse@gmail.com>


^ permalink raw reply

* [PATCH v2 1/7] iio: gyro: hid-sensor-gyro-3d: use u32 instead of unsigned
From: Sanjay Chitroda @ 2026-06-10 15:37 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko
  Cc: linux-input, linux-iio, linux-kernel, Sanjay Chitroda,
	Maxwell Doose
In-Reply-To: <20260610-6-june-hid-iio-correct-usage-id-v2-0-c3c5f0720493@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

Prefer 'u32' instead of bare 'unsigned' for usage_id variable.
This matches expected callback API type and improves code clarity.

No functional change.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Reviewed-by: Maxwell Doose <m32285159@gmail.com>
---
 drivers/iio/gyro/hid-sensor-gyro-3d.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index e48c25c87b6d..bbca2111e79b 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -177,7 +177,7 @@ static const struct iio_info gyro_3d_info = {
 
 /* Callback handler to send event after all samples are received and captured */
 static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				void *priv)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(priv);
@@ -199,7 +199,7 @@ static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
 
 /* Capture samples in local storage */
 static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				size_t raw_len, char *raw_data,
 				void *priv)
 {
@@ -234,7 +234,7 @@ static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
 static int gyro_3d_parse_report(struct platform_device *pdev,
 				struct hid_sensor_hub_device *hsdev,
 				struct iio_chan_spec *channels,
-				unsigned usage_id,
+				u32 usage_id,
 				struct gyro_3d_state *st)
 {
 	int ret;

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 2/7] iio: accel: hid-sensor-accel-3d: use u32 instead of unsigned
From: Sanjay Chitroda @ 2026-06-10 15:37 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko
  Cc: linux-input, linux-iio, linux-kernel, Sanjay Chitroda,
	Maxwell Doose
In-Reply-To: <20260610-6-june-hid-iio-correct-usage-id-v2-0-c3c5f0720493@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

Prefer 'u32' instead of bare 'unsigned' for usage_id variable.
This matches expected callback API type and improves code clarity.

No functional change.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Reviewed-by: Maxwell Doose <m32285159@gmail.com>
---
 drivers/iio/accel/hid-sensor-accel-3d.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index 2bf05ab5235e..42c4259bf209 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -223,7 +223,7 @@ static void hid_sensor_push_data(struct iio_dev *indio_dev, void *data,
 
 /* Callback handler to send event after all samples are received and captured */
 static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				void *priv)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(priv);
@@ -247,7 +247,7 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
 
 /* Capture samples in local storage */
 static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				size_t raw_len, char *raw_data,
 				void *priv)
 {
@@ -283,7 +283,7 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
 static int accel_3d_parse_report(struct platform_device *pdev,
 				struct hid_sensor_hub_device *hsdev,
 				struct iio_chan_spec *channels,
-				unsigned usage_id,
+				u32 usage_id,
 				struct accel_3d_state *st)
 {
 	int ret;

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 3/7] iio: light: hid-sensor-als: use u32 instead of unsigned
From: Sanjay Chitroda @ 2026-06-10 15:37 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko
  Cc: linux-input, linux-iio, linux-kernel, Sanjay Chitroda,
	Maxwell Doose
In-Reply-To: <20260610-6-june-hid-iio-correct-usage-id-v2-0-c3c5f0720493@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

Prefer 'u32' instead of bare 'unsigned' for usage_id variable.
This matches expected callback API type and improves code clarity.

No functional change.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Reviewed-by: Maxwell Doose <m32285159@gmail.com>
---
 drivers/iio/light/hid-sensor-als.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index d72e260b8266..ae2fda8dc500 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -241,7 +241,7 @@ static const struct iio_info als_info = {
 
 /* Callback handler to send event after all samples are received and captured */
 static int als_proc_event(struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				void *priv)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(priv);
@@ -263,7 +263,7 @@ static int als_proc_event(struct hid_sensor_hub_device *hsdev,
 
 /* Capture samples in local storage */
 static int als_capture_sample(struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				size_t raw_len, char *raw_data,
 				void *priv)
 {
@@ -305,7 +305,7 @@ static int als_capture_sample(struct hid_sensor_hub_device *hsdev,
 /* Parse report which is specific to an usage id*/
 static int als_parse_report(struct platform_device *pdev,
 				struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				struct als_state *st)
 {
 	struct iio_chan_spec *channels;

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 4/7] iio: light: hid-sensor-prox: use u32 instead of unsigned
From: Sanjay Chitroda @ 2026-06-10 15:37 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko
  Cc: linux-input, linux-iio, linux-kernel, Sanjay Chitroda,
	Maxwell Doose
In-Reply-To: <20260610-6-june-hid-iio-correct-usage-id-v2-0-c3c5f0720493@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

Prefer 'u32' instead of bare 'unsigned' for usage_id variable.
This matches expected callback API type and improves code clarity.

No functional change.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Reviewed-by: Maxwell Doose <m32285159@gmail.com>
---
 drivers/iio/light/hid-sensor-prox.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
index edc9274a2c07..9059f00f0ced 100644
--- a/drivers/iio/light/hid-sensor-prox.c
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -166,7 +166,7 @@ static const struct iio_info prox_info = {
 
 /* Callback handler to send event after all samples are received and captured */
 static int prox_proc_event(struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				void *priv)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(priv);
@@ -183,7 +183,7 @@ static int prox_proc_event(struct hid_sensor_hub_device *hsdev,
 
 /* Capture samples in local storage */
 static int prox_capture_sample(struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				size_t raw_len, char *raw_data,
 				void *priv)
 {

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 5/7] iio: orientation: hid-sensor-incl-3d: use u32 instead of unsigned
From: Sanjay Chitroda @ 2026-06-10 15:37 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko
  Cc: linux-input, linux-iio, linux-kernel, Sanjay Chitroda,
	Maxwell Doose
In-Reply-To: <20260610-6-june-hid-iio-correct-usage-id-v2-0-c3c5f0720493@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

Prefer 'u32' instead of bare 'unsigned' for usage_id variable.
This matches expected callback API type and improves code clarity.

No functional change.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Reviewed-by: Maxwell Doose <m32285159@gmail.com>
---
 drivers/iio/orientation/hid-sensor-incl-3d.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c
index 4e23a598a3fb..c7fbff498be7 100644
--- a/drivers/iio/orientation/hid-sensor-incl-3d.c
+++ b/drivers/iio/orientation/hid-sensor-incl-3d.c
@@ -189,7 +189,7 @@ static const struct iio_info incl_3d_info = {
 
 /* Callback handler to send event after all samples are received and captured */
 static int incl_3d_proc_event(struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				void *priv)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(priv);
@@ -212,7 +212,7 @@ static int incl_3d_proc_event(struct hid_sensor_hub_device *hsdev,
 
 /* Capture samples in local storage */
 static int incl_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
-				unsigned usage_id,
+				u32 usage_id,
 				size_t raw_len, char *raw_data,
 				void *priv)
 {
@@ -247,7 +247,7 @@ static int incl_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
 static int incl_3d_parse_report(struct platform_device *pdev,
 				struct hid_sensor_hub_device *hsdev,
 				struct iio_chan_spec *channels,
-				unsigned usage_id,
+				u32 usage_id,
 				struct incl_3d_state *st)
 {
 	int ret;

-- 
2.34.1


^ permalink raw reply related


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