* [PATCH WIP v3 06/11] Input: stmfts - use client to make future code cleaner
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>
From: Petr Hodina <petr.hodina@protonmail.com>
Make code cleaner, compiler will optimize it away anyway.
Preparation for FTM5 support, where more steps are needed.
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index a90528b76f52b..5f7de5e687da2 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -763,9 +763,10 @@ static int stmfts_runtime_suspend(struct device *dev)
static int stmfts_runtime_resume(struct device *dev)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
+ struct i2c_client *client = sdata->client;
int ret;
- ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_OUT);
+ ret = i2c_smbus_write_byte(client, STMFTS_SLEEP_OUT);
if (ret)
dev_err(dev, "failed to resume device: %d\n", ret);
--
2.53.0
^ permalink raw reply related
* [PATCH WIP v3 05/11] Input: stmfts - disable regulators when power on fails
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>
From: David Heidelberg <david@ixit.cz>
We must power off regulators after failing at power on phase.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 71d9b747ccfc5..a90528b76f52b 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -557,7 +557,7 @@ static int stmfts_power_on(struct stmfts_data *sdata)
err = stmfts_read_system_info(sdata);
if (err)
- return err;
+ goto power_off;
enable_irq(sdata->client->irq);
@@ -565,11 +565,11 @@ static int stmfts_power_on(struct stmfts_data *sdata)
err = stmfts_command(sdata, STMFTS_SYSTEM_RESET);
if (err)
- return err;
+ goto power_off;
err = stmfts_command(sdata, STMFTS_SLEEP_OUT);
if (err)
- return err;
+ goto power_off;
/* optional tuning */
err = stmfts_command(sdata, STMFTS_MS_CX_TUNING);
@@ -585,7 +585,7 @@ static int stmfts_power_on(struct stmfts_data *sdata)
err = stmfts_command(sdata, STMFTS_FULL_FORCE_CALIBRATION);
if (err)
- return err;
+ goto power_off;
/*
* At this point no one is using the touchscreen
@@ -594,6 +594,11 @@ static int stmfts_power_on(struct stmfts_data *sdata)
(void) i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
return 0;
+
+power_off:
+ regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
+ sdata->supplies);
+ return err;
}
static void stmfts_power_off(void *data)
--
2.53.0
^ permalink raw reply related
* [PATCH WIP v3 04/11] Input: stmfts - abstract reading information from the firmware
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>
From: David Heidelberg <david@ixit.cz>
Improves readability and makes splitting power on function in following
commit easier.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index ff884e04ad4c8..71d9b747ccfc5 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -518,22 +518,11 @@ static struct attribute *stmfts_sysfs_attrs[] = {
};
ATTRIBUTE_GROUPS(stmfts_sysfs);
-static int stmfts_power_on(struct stmfts_data *sdata)
+static int stmfts_read_system_info(struct stmfts_data *sdata)
{
int err;
u8 reg[8];
- err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
- sdata->supplies);
- if (err)
- return err;
-
- /*
- * The datasheet does not specify the power on time, but considering
- * that the reset time is < 10ms, I sleep 20ms to be sure
- */
- msleep(20);
-
err = i2c_smbus_read_i2c_block_data(sdata->client, STMFTS_READ_INFO,
sizeof(reg), reg);
if (err < 0)
@@ -547,6 +536,29 @@ static int stmfts_power_on(struct stmfts_data *sdata)
sdata->config_id = reg[4];
sdata->config_ver = reg[5];
+ return 0;
+}
+
+static int stmfts_power_on(struct stmfts_data *sdata)
+{
+ int err;
+
+ err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
+ sdata->supplies);
+ if (err)
+ return err;
+
+ /*
+ * The datasheet does not specify the power on time, but considering
+ * that the reset time is < 10ms, I sleep 20ms to be sure
+ */
+ msleep(20);
+
+
+ err = stmfts_read_system_info(sdata);
+ if (err)
+ return err;
+
enable_irq(sdata->client->irq);
msleep(50);
--
2.53.0
^ permalink raw reply related
* [PATCH WIP v3 03/11] Input: stmfts - Switch to devm_regulator_bulk_get_const
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>
From: David Heidelberg <david@ixit.cz>
Switch to devm_regulator_bulk_get_const() to stop setting the supplies
list in probe(), and move the regulator_bulk_data struct in static const.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 7b1e975a85668..ff884e04ad4c8 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -69,9 +69,9 @@
#define STMFTS_MAX_FINGERS 10
#define STMFTS_DEV_NAME "stmfts"
-enum stmfts_regulators {
- STMFTS_REGULATOR_VDD,
- STMFTS_REGULATOR_AVDD,
+static const struct regulator_bulk_data stmfts_supplies[] = {
+ { .supply = "vdd" },
+ { .supply = "avdd" },
};
struct stmfts_data {
@@ -82,7 +82,7 @@ struct stmfts_data {
struct touchscreen_properties prop;
- struct regulator_bulk_data regulators[2];
+ struct regulator_bulk_data *supplies;
/*
* Presence of ledvdd will be used also to check
@@ -523,8 +523,8 @@ static int stmfts_power_on(struct stmfts_data *sdata)
int err;
u8 reg[8];
- err = regulator_bulk_enable(ARRAY_SIZE(sdata->regulators),
- sdata->regulators);
+ err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
+ sdata->supplies);
if (err)
return err;
@@ -589,8 +589,8 @@ static void stmfts_power_off(void *data)
struct stmfts_data *sdata = data;
disable_irq(sdata->client->irq);
- regulator_bulk_disable(ARRAY_SIZE(sdata->regulators),
- sdata->regulators);
+ regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
+ sdata->supplies);
}
static int stmfts_enable_led(struct stmfts_data *sdata)
@@ -638,11 +638,10 @@ static int stmfts_probe(struct i2c_client *client)
mutex_init(&sdata->mutex);
init_completion(&sdata->cmd_done);
- sdata->regulators[STMFTS_REGULATOR_VDD].supply = "vdd";
- sdata->regulators[STMFTS_REGULATOR_AVDD].supply = "avdd";
- err = devm_regulator_bulk_get(dev,
- ARRAY_SIZE(sdata->regulators),
- sdata->regulators);
+ err = devm_regulator_bulk_get_const(dev,
+ ARRAY_SIZE(stmfts_supplies),
+ stmfts_supplies,
+ &sdata->supplies);
if (err)
return err;
--
2.53.0
^ permalink raw reply related
* [PATCH WIP v3 02/11] Input: stmfts - Use dev struct directly
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>
From: David Heidelberg <david@ixit.cz>
Makes the code better readable and noticably shorter.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index def6bd0c8e059..7b1e975a85668 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -619,6 +619,7 @@ static int stmfts_enable_led(struct stmfts_data *sdata)
static int stmfts_probe(struct i2c_client *client)
{
+ struct device *dev = &client->dev;
int err;
struct stmfts_data *sdata;
@@ -627,7 +628,7 @@ static int stmfts_probe(struct i2c_client *client)
I2C_FUNC_SMBUS_I2C_BLOCK))
return -ENODEV;
- sdata = devm_kzalloc(&client->dev, sizeof(*sdata), GFP_KERNEL);
+ sdata = devm_kzalloc(dev, sizeof(*sdata), GFP_KERNEL);
if (!sdata)
return -ENOMEM;
@@ -639,13 +640,13 @@ static int stmfts_probe(struct i2c_client *client)
sdata->regulators[STMFTS_REGULATOR_VDD].supply = "vdd";
sdata->regulators[STMFTS_REGULATOR_AVDD].supply = "avdd";
- err = devm_regulator_bulk_get(&client->dev,
+ err = devm_regulator_bulk_get(dev,
ARRAY_SIZE(sdata->regulators),
sdata->regulators);
if (err)
return err;
- sdata->input = devm_input_allocate_device(&client->dev);
+ sdata->input = devm_input_allocate_device(dev);
if (!sdata->input)
return -ENOMEM;
@@ -664,7 +665,7 @@ static int stmfts_probe(struct i2c_client *client)
input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
input_set_abs_params(sdata->input, ABS_DISTANCE, 0, 255, 0, 0);
- sdata->use_key = device_property_read_bool(&client->dev,
+ sdata->use_key = device_property_read_bool(dev,
"touch-key-connected");
if (sdata->use_key) {
input_set_capability(sdata->input, EV_KEY, KEY_MENU);
@@ -685,20 +686,20 @@ static int stmfts_probe(struct i2c_client *client)
* interrupts. To be on the safe side it's better to not enable
* the interrupts during their request.
*/
- err = devm_request_threaded_irq(&client->dev, client->irq,
+ err = devm_request_threaded_irq(dev, client->irq,
NULL, stmfts_irq_handler,
IRQF_ONESHOT | IRQF_NO_AUTOEN,
"stmfts_irq", sdata);
if (err)
return err;
- dev_dbg(&client->dev, "initializing ST-Microelectronics FTS...\n");
+ dev_dbg(dev, "initializing ST-Microelectronics FTS...\n");
err = stmfts_power_on(sdata);
if (err)
return err;
- err = devm_add_action_or_reset(&client->dev, stmfts_power_off, sdata);
+ err = devm_add_action_or_reset(dev, stmfts_power_off, sdata);
if (err)
return err;
@@ -715,13 +716,13 @@ static int stmfts_probe(struct i2c_client *client)
* without LEDs. The ledvdd regulator pointer will be
* used as a flag.
*/
- dev_warn(&client->dev, "unable to use touchkey leds\n");
+ dev_warn(dev, "unable to use touchkey leds\n");
sdata->ledvdd = NULL;
}
}
- pm_runtime_enable(&client->dev);
- device_enable_async_suspend(&client->dev);
+ pm_runtime_enable(dev);
+ device_enable_async_suspend(dev);
return 0;
}
--
2.53.0
^ permalink raw reply related
* [PATCH WIP v3 01/11] Input: stmfts - Fix the MODULE_LICENSE() string
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260403-stmfts5-v3-0-5da768cfd201@ixit.cz>
From: David Heidelberg <david@ixit.cz>
Replace the bogus "GPL v2" with "GPL" as MODULE_LICNSE() string. The
value does not declare the module's exact license, but only lets the
module loader test whether the module is Free Software or not.
See commit bf7fbeeae6db ("module: Cure the MODULE_LICENSE "GPL" vs.
"GPL v2" bogosity") in the details of the issue. The fix is to use
"GPL" for all modules under any variant of the GPL.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 8af87d0b6eb64..def6bd0c8e059 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -807,4 +807,4 @@ module_i2c_driver(stmfts_driver);
MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>");
MODULE_DESCRIPTION("STMicroelectronics FTS Touch Screen");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related
* [PATCH WIP v3 00/11] Input: support for STM FTS5
From: David Heidelberg via B4 Relay @ 2026-04-03 17:08 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
Used on various phones. Minimal basic support.
Includes device-tree enabling touchscreen on Pixel 3.
Sending as WIP, as not all comments we're addressed, but please feel
free to apply any patch which does look ready for inclusion.
What is missing:
- switching between AP and SLPI mode (to be able to wake up phone by touch)
- firmware loading
- anything above basic touch
Signed-off-by: David Heidelberg <david@ixit.cz>
---
TODO for v4:
- wrap everything below enabling the supplies into stmfts_configure()
to avoid bunch of gotos to power off on error? (Dmitry T.)
- finish chip specific ops and potentinally remove is_fts5. (Dmitry T.)
Changes in v3:
- s/touchscreen_pins/touchscreen_irq_n. (Konrad)
- Use interrupts-extended. (Konrad)
- Fixed rebase conflict against 8665ceb926ec ("Input: stmfts - use guard notation when acquiring mutex")
- Rename switch-gpios to mode-switch-gpios.
- Do not define properties in if:then: branches. (Krzysztof)
- Link to v2: https://lore.kernel.org/r/20260315-stmfts5-v2-0-70bc83ee9591@ixit.cz
Changes in v2:
- Fix typo in the binding s/switch-gpio/switch-gpios/.
- Deduplacate allOf. (Rob yamllint)
- Add missing S-off-by. (Dmitry B.)
- Dropped irq-gpios as it's not needed. (Konrad)
- Correct x and y touchscreen area size. (Konrad)
- Correct reset introduction commit description. (Krzysztof)
- Partially implemented chip specific ops. (Dmitry T.)
- Separeted license naming cleanup into separate commit (Dmitry T.)
- Link to v1: https://lore.kernel.org/r/20260301-stmfts5-v1-0-22c458b9ac68@ixit.cz
---
David Heidelberg (7):
Input: stmfts - Fix the MODULE_LICENSE() string
Input: stmfts - Use dev struct directly
Input: stmfts - Switch to devm_regulator_bulk_get_const
Input: stmfts - abstract reading information from the firmware
Input: stmfts - disable regulators when power on fails
dt-bindings: input: touchscreen: st,stmfts: Introduce reset GPIO
dt-bindings: input: touchscreen: st,stmfts: Introduce STM FTS5
Petr Hodina (4):
Input: stmfts - use client to make future code cleaner
Input: stmfts - add optional reset GPIO support
Input: stmfts - support FTS5
arm64: dts: qcom: sdm845-google: Add STM FTS touchscreen support
.../bindings/input/touchscreen/st,stmfts.yaml | 19 +-
.../arm64/boot/dts/qcom/sdm845-google-blueline.dts | 19 +-
arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi | 2 +-
drivers/input/touchscreen/stmfts.c | 594 +++++++++++++++++++--
4 files changed, 574 insertions(+), 60 deletions(-)
---
base-commit: cc13002a9f984d37906e9476f3e532a8cdd126f5
change-id: 20260214-stmfts5-b47311fbd732
Best regards,
--
David Heidelberg <david@ixit.cz>
^ permalink raw reply
* Re: [PATCH] HID: multitouch: Fix Yoga Book 9 14IAH10 touchscreen misclassification
From: Benjamin Tissoires @ 2026-04-03 16:51 UTC (permalink / raw)
To: Dave Carey; +Cc: Benjamin Tissoires, jikos, linux-input, linux-kernel
In-Reply-To: <CALPvROSB4y0UsPvF5-ZS=_rGmj1NgM6QvBAbHO13bkgpAwQSyA@mail.gmail.com>
Hi Dave,
[not sure why your message doesn't appear on lore, so using the
@redhat.com email.]
On Fri, Apr 3, 2026 at 5:17 PM Dave Carey <carvsdriver@gmail.com> wrote:
>
> Benjamin - thanks for the response, I'll admit that I'm not the smartest person in the room here.
I wouldn't say that. Given the research you showed in the repo below,
you are definitely smart :)
> My approach was trivially simple, it works in Windows flawlessly so I knew there had to be a way to make it work in Linux.
OK, so that's a hint we are not doing something correctly.
> I essentially ran USB log captures in Windows, then banged my face against the keyboard on the linux side until I could figure out what was going on there and implement the same behavior with the firmware. All of my research is in my repo here ...
>
> https://bitbucket.org/carvsdriver/lenovoyoga9ibook/src/main/README_Touch.md
Could you add a hid-recorder output when doing a simple touch on one
of the 2 panels? (pip3 install hid-tools).
I'm curious to understand the touchpad emulation part. As I read it,
does the device emit the event on both the touchscreen and the
emulated one simultaneously?
I guess you don't happen to have a compatible stylus? It would be
interesting to look at the events from a pen to understand the button
logic.
>
> Happy to get your input and take a swing at implementing this differently.
It looks like there are multiple problems with the touchscreens, and I
need the big picture. The nice thing is you already wrote a HID-BPF
program for it, so why not contribute it upstream to udev-hid-bpf.
I'll eventually push it into the kernel as well and that would help
people who did not updated their kernel yet.
Cheers,
Benjamin
>
> -Dave
>
> On Fri, Apr 3, 2026 at 9:03 AM Benjamin Tissoires <bentiss@kernel.org> wrote:
>>
>> Hi Dave,
>>
>> On Apr 02 2026, Dave Carey wrote:
>> > The Lenovo Yoga Book 9 14IAH10 (83KJ) uses a composite USB HID device
>> > (17EF:6161) where three descriptor quirks combine to cause hid-multitouch
>> > to incorrectly set INPUT_PROP_BUTTONPAD on both touchscreen nodes, making
>> > libinput treat them as indirect clickpads rather than direct touchscreens.
>> >
>> > Quirk 1: The HID_DG_TOUCHSCREEN application collection contains
>> > HID_UP_BUTTON usages (stylus barrel buttons). The generic heuristic in
>> > mt_touch_input_mapping() treats any touchscreen-with-buttons as a
>> > touchpad, setting INPUT_MT_POINTER.
>> >
>> > Quirk 2: A HID_DG_TOUCHPAD collection ("Emulated Touchpad") sets
>> > INPUT_MT_POINTER unconditionally in mt_allocate_application().
>> >
>> > Quirk 3: The HID_DG_BUTTONTYPE feature report (0x51) returns
>> > MT_BUTTONTYPE_CLICKPAD, directly setting td->is_buttonpad = true.
>> >
>> > These combine to produce INPUT_PROP_BUTTONPAD on the touchscreen input
>> > nodes. libinput treats the devices as indirect clickpads and suppresses
>> > direct touch events, leaving the touchscreens non-functional under
>> > KDE/Wayland.
>>
>> This looks like a completely borked report descriptor. Out of curiosity,
>> do you know if there is a specific Windows driver for it or if it's
>> using the plain generic driver there.
>>
>> The reasoning is that if it's using the generic win driver, we are
>> probably doing something wrong, and we need to fix it in a more generic
>> way.
>>
>> >
>> > Additionally, the firmware resets if any USB control request is received
>> > during the CDC ACM initialization window. The existing GET_REPORT call
>> > in mt_check_input_mode() during probe triggers this reset.
>>
>> Ouch, even better :(
>>
>> >
>> > Fix by extending MT_QUIRK_YOGABOOK9I (already defined for the earlier
>> > Yoga Book 9i) to guard all three BUTTONPAD heuristics and skip the
>> > HID_DG_BUTTONTYPE GET_REPORT during probe for this device.
>>
>> Really not a big fan of the approach taken here: We are sprinkling the
>> code with special quirks for one particular device and that makes
>> everything worse.
>>
>> I would much prefer a report descriptor fixup where:
>> - we drop the HID_UP_BUTTON
>> - we drop the HID_DG_TOUCHPAD collection entirely
>> - we drop the HID_DG_BUTTONTYPE feature entirely
>> - we drop the Win8 blob feature as well to prevent queries during
>> initialization.
>>
>> For ease of development I would recomend working with a separate HID-BPF
>> program instead of a in-kernel fix, but we already have a .report_fixup
>> here, so I wouldn't mind having the fix here as well.
>>
>> Cheers,
>> Benjamin
>>
>> >
>> > Signed-off-by: Dave Carey <carvsdriver@gmail.com>
>> > Tested-by: Dave Carey <carvsdriver@gmail.com>
>> > ---
>> > drivers/hid/hid-multitouch.c | 34 +++++++++++++++++++++++++++-------
>> > 1 file changed, 27 insertions(+), 7 deletions(-)
>> >
>> > diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
>> > index e82a3c4e5..1bef32b1d 100644
>> > --- a/drivers/hid/hid-multitouch.c
>> > +++ b/drivers/hid/hid-multitouch.c
>> > @@ -549,7 +549,14 @@ static void mt_feature_mapping(struct hid_device *hdev,
>> >
>> > switch (usage->hid) {
>> > case HID_DG_CONTACTMAX:
>> > - mt_get_feature(hdev, field->report);
>> > + /*
>> > + * Yoga Book 9: skip GET_REPORT during probe; the firmware
>> > + * resets if it receives any control request before the init
>> > + * Output report is sent (within ~1.18s of USB enumeration).
>> > + * Logical maximum from the descriptor is used as the fallback.
>> > + */
>> > + if (!(td->mtclass.quirks & MT_QUIRK_YOGABOOK9I))
>> > + mt_get_feature(hdev, field->report);
>> >
>> > td->maxcontacts = field->value[0];
>> > if (!td->maxcontacts &&
>> > @@ -566,6 +573,10 @@ static void mt_feature_mapping(struct hid_device *hdev,
>> > break;
>> > }
>> >
>> > + /* Yoga Book 9 reports Clickpad but is a direct touchscreen */
>> > + if (td->mtclass.quirks & MT_QUIRK_YOGABOOK9I)
>> > + break;
>> > +
>> > mt_get_feature(hdev, field->report);
>> > switch (field->value[usage->usage_index]) {
>> > case MT_BUTTONTYPE_CLICKPAD:
>> > @@ -579,7 +590,9 @@ static void mt_feature_mapping(struct hid_device *hdev,
>> > break;
>> > case 0xff0000c5:
>> > /* Retrieve the Win8 blob once to enable some devices */
>> > - if (usage->usage_index == 0)
>> > + /* Yoga Book 9: skip; firmware resets before init if queried */
>> > + if (usage->usage_index == 0 &&
>> > + !(td->mtclass.quirks & MT_QUIRK_YOGABOOK9I))
>> > mt_get_feature(hdev, field->report);
>> > break;
>> > }
>> > @@ -644,8 +657,11 @@ static struct mt_application *mt_allocate_application(struct mt_device *td,
>> >
>> > /*
>> > * Model touchscreens providing buttons as touchpads.
>> > + * Yoga Book 9 has an emulated touchpad but its touch surfaces
>> > + * are direct screens, not indirect pointers.
>> > */
>> > - if (application == HID_DG_TOUCHPAD) {
>> > + if (application == HID_DG_TOUCHPAD &&
>> > + !(td->mtclass.quirks & MT_QUIRK_YOGABOOK9I)) {
>> > mt_application->mt_flags |= INPUT_MT_POINTER;
>> > td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
>> > }
>> > @@ -802,11 +818,15 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
>> >
>> > /*
>> > * Model touchscreens providing buttons as touchpads.
>> > + * Skip for Yoga Book 9 which has stylus buttons inside
>> > + * touchscreen collections, not physical touchpad buttons.
>> > */
>> > if (field->application == HID_DG_TOUCHSCREEN &&
>> > (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
>> > - app->mt_flags |= INPUT_MT_POINTER;
>> > - td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
>> > + if (!(app->quirks & MT_QUIRK_YOGABOOK9I)) {
>> > + app->mt_flags |= INPUT_MT_POINTER;
>> > + td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
>> > + }
>> > }
>> >
>> > /* count the buttons on touchpads */
>> > @@ -1420,7 +1440,6 @@ static int mt_touch_input_configured(struct hid_device *hdev,
>> > */
>> > if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR)
>> > app->mt_flags |= INPUT_MT_DIRECT;
>> > -
>> > if (cls->is_indirect)
>> > app->mt_flags |= INPUT_MT_POINTER;
>> >
>> > @@ -1432,7 +1451,8 @@ static int mt_touch_input_configured(struct hid_device *hdev,
>> >
>> > /* check for clickpads */
>> > if ((app->mt_flags & INPUT_MT_POINTER) &&
>> > - (app->buttons_count == 1))
>> > + (app->buttons_count == 1) &&
>> > + !(app->quirks & MT_QUIRK_YOGABOOK9I))
>> > td->is_buttonpad = true;
>> >
>> > if (td->is_buttonpad)
>> > --
>> > 2.53.0
>> >
>> >
^ permalink raw reply
* [PATCH] HID: apple: Add Niz keyboard dongle to non-apple keyboards list
From: utzcoz @ 2026-04-03 16:18 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires; +Cc: linux-input, linux-kernel, utzcoz
Niz X99 uses a 2.4GHz wireless dongle (Milsky LL Dongle) that
reports Apple's vendor and product IDs (05ac:0220), causing
hid-apple to apply Apple function key translation. Since the
dongle has no Apple Fn key, F1-F12 become unreachable when fnmode
defaults to media-first behavior.
Add the Milsky LL Dongle to the non_apple_keyboards list so that
fnmode=3 (auto) correctly resolves to fnmode=2, making F1-F12 work
as standard function keys.
Signed-off-by: utzcoz <utzcoz@gmail.com>
---
drivers/hid/hid-apple.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index fc5897a6bb53..c29834cfa468 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -368,6 +368,7 @@ static const struct apple_non_apple_keyboard non_apple_keyboards[] = {
{ "TH87" }, /* EPOMAKER TH87 BT mode */
{ "HFD Epomaker TH87" }, /* EPOMAKER TH87 USB mode */
{ "2.4G Wireless Receiver" }, /* EPOMAKER TH87 dongle */
+ { "Milsky LL Dongle" }, /* Niz keyboard dongle */
};
static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
--
2.51.0
^ permalink raw reply related
* Re: [PATCH 8/8] bpf: Add fix for Trust Philips SPK6327 (145f:024b) modifier keys
From: Benjamin Tissoires @ 2026-04-03 16:17 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, linux-kernel, muhammed Rishal
In-Reply-To: <20260403-wip-sync-udev-hid-bpf-2026-04-v1-8-978cedb9a074@kernel.org>
Of course, you hit send and you realize the commit message is missing
the 'HID:' marker. Sorry Jiri.
Also, this commit should probably be tagged with:
From: muhammed Rishal <muhammedrishal7777777@gmail.com>
Sorry, again.
Muhammed, FYI, there is nothing to be done on your side (just in case
you wonder why you receive this email). It's the normal process to merge
testing HID-BPF programs into stable.
Cheers,
Benjamin
On Apr 03 2026, Benjamin Tissoires wrote:
> The Trust Philips SPK6327 keyboard (USB ID 145f:024b) has a broken HID
> descriptor on interface 1. Byte 101 is 0x00 (Input Array) but should be
> 0x02 (Input Variable), causing LCtrl, LAlt, Super, RAlt, RCtrl and
> RShift to all report as LShift on Linux.
>
> This BPF fix patches byte 101 at runtime fixing all affected modifier
> keys.
>
> Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/234
> Signed-off-by: muhammed Rishal <muhammedrishal7777777@gmail.com>
> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
> ---
> drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c | 49 ++++++++++++++++++++++
> 1 file changed, 49 insertions(+)
>
> diff --git a/drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c b/drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c
> new file mode 100644
> index 000000000000..bc7ff27eac9f
> --- /dev/null
> +++ b/drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c
> @@ -0,0 +1,49 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/* Fix for Trust Philips SPK6327 (145f:024b)
> + * Modifier keys report as Array (0x00) instead of Variable (0x02)
> + * causing LCtrl, LAlt, Super etc. to all act as LShift
> + */
> +#include "vmlinux.h"
> +#include "hid_bpf.h"
> +#include "hid_bpf_helpers.h"
> +#include <bpf/bpf_tracing.h>
> +
> +#define VID_TRUST 0x145F
> +#define PID_SPK6327 0x024B
> +
> +HID_BPF_CONFIG(
> + HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, VID_TRUST, PID_SPK6327)
> +);
> +
> +SEC(HID_BPF_RDESC_FIXUP)
> +int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx)
> +{
> + __u8 *data = hid_bpf_get_data(hctx, 0, 4096);
> +
> + if (!data)
> + return 0;
> +
> + /* Fix modifier keys: Input Array (0x00) -> Input Variable (0x02) */
> + if (data[101] == 0x00)
> + data[101] = 0x02;
> +
> + return 0;
> +}
> +
> +HID_BPF_OPS(trust_spk6327) = {
> + .hid_rdesc_fixup = (void *)hid_fix_rdesc,
> +};
> +
> +SEC("syscall")
> +int probe(struct hid_bpf_probe_args *ctx)
> +{
> + /* Only apply to interface 1 (169 bytes) not interface 0 (62 bytes) */
> + if (ctx->rdesc_size == 169)
> + ctx->retval = 0;
> + else
> + ctx->retval = -EINVAL;
> +
> + return 0;
> +}
> +
> +char _license[] SEC("license") = "GPL";
>
> --
> 2.53.0
>
>
^ permalink raw reply
* [PATCH 8/8] bpf: Add fix for Trust Philips SPK6327 (145f:024b) modifier keys
From: Benjamin Tissoires @ 2026-04-03 16:12 UTC (permalink / raw)
To: Jiri Kosina
Cc: linux-input, linux-kernel, Benjamin Tissoires, muhammed Rishal
In-Reply-To: <20260403-wip-sync-udev-hid-bpf-2026-04-v1-0-978cedb9a074@kernel.org>
The Trust Philips SPK6327 keyboard (USB ID 145f:024b) has a broken HID
descriptor on interface 1. Byte 101 is 0x00 (Input Array) but should be
0x02 (Input Variable), causing LCtrl, LAlt, Super, RAlt, RCtrl and
RShift to all report as LShift on Linux.
This BPF fix patches byte 101 at runtime fixing all affected modifier
keys.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/234
Signed-off-by: muhammed Rishal <muhammedrishal7777777@gmail.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c | 49 ++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c b/drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c
new file mode 100644
index 000000000000..bc7ff27eac9f
--- /dev/null
+++ b/drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Fix for Trust Philips SPK6327 (145f:024b)
+ * Modifier keys report as Array (0x00) instead of Variable (0x02)
+ * causing LCtrl, LAlt, Super etc. to all act as LShift
+ */
+#include "vmlinux.h"
+#include "hid_bpf.h"
+#include "hid_bpf_helpers.h"
+#include <bpf/bpf_tracing.h>
+
+#define VID_TRUST 0x145F
+#define PID_SPK6327 0x024B
+
+HID_BPF_CONFIG(
+ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, VID_TRUST, PID_SPK6327)
+);
+
+SEC(HID_BPF_RDESC_FIXUP)
+int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx)
+{
+ __u8 *data = hid_bpf_get_data(hctx, 0, 4096);
+
+ if (!data)
+ return 0;
+
+ /* Fix modifier keys: Input Array (0x00) -> Input Variable (0x02) */
+ if (data[101] == 0x00)
+ data[101] = 0x02;
+
+ return 0;
+}
+
+HID_BPF_OPS(trust_spk6327) = {
+ .hid_rdesc_fixup = (void *)hid_fix_rdesc,
+};
+
+SEC("syscall")
+int probe(struct hid_bpf_probe_args *ctx)
+{
+ /* Only apply to interface 1 (169 bytes) not interface 0 (62 bytes) */
+ if (ctx->rdesc_size == 169)
+ ctx->retval = 0;
+ else
+ ctx->retval = -EINVAL;
+
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";
--
2.53.0
^ permalink raw reply related
* [PATCH 7/8] HID: bpf: Add support for the Huion KeyDial K20 over bluetooth
From: Benjamin Tissoires @ 2026-04-03 16:12 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, linux-kernel, Benjamin Tissoires, Peter Hutterer
In-Reply-To: <20260403-wip-sync-udev-hid-bpf-2026-04-v1-0-978cedb9a074@kernel.org>
When connected over bluetooth this device is just different enough that
forcing it into the same source file as the USB connection doesn't gain
us much benefit. So let's duplicate this.
Code and tests originally produced by Claude code.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/work_items/69
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/201
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
.../bpf/progs/Huion__KeydialK20-Bluetooth.bpf.c | 492 +++++++++++++++++++++
1 file changed, 492 insertions(+)
diff --git a/drivers/hid/bpf/progs/Huion__KeydialK20-Bluetooth.bpf.c b/drivers/hid/bpf/progs/Huion__KeydialK20-Bluetooth.bpf.c
new file mode 100644
index 000000000000..d0769e990039
--- /dev/null
+++ b/drivers/hid/bpf/progs/Huion__KeydialK20-Bluetooth.bpf.c
@@ -0,0 +1,492 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2024 Red Hat, Inc
+ */
+
+#include "vmlinux.h"
+#include "hid_bpf.h"
+#include "hid_bpf_helpers.h"
+#include "hid_report_helpers.h"
+#include <bpf/bpf_tracing.h>
+
+#define VID_HUION 0x256C
+#define PID_KEYDIAL_K20_BLUETOOTH 0x8251
+
+HID_BPF_CONFIG(
+ HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_GENERIC, VID_HUION, PID_KEYDIAL_K20_BLUETOOTH),
+);
+
+/* This is the same device as in 0010-Huion__KeydialK20 but connected via Bluetooth.
+ * It does not need (to support?) switching to a vendor mode so we just modify the
+ * existing mode.
+ *
+ * By default it exports two hidraw nodes, only the second one sends events.
+ *
+ * This is the first hidraw node which we disable:
+ *
+ * # Keydial mini-050
+ * # Report descriptor length: 114 bytes
+ * # Bytes // Field Name Offset
+ * # ----------------------------------------------------------------------------------
+ * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 0
+ * # 🭬 0x09, 0x0e, // Usage (System Multi-Axis Controller) 2
+ * # 0xa1, 0x01, // Collection (Application) 4
+ * # ┅ 0x85, 0x03, // Report ID (3) 6
+ * # 🮥 0x05, 0x0d, // Usage Page (Digitizers) 8
+ * # 0x75, 0x08, // Report Size (8) 10
+ * # 0x95, 0x01, // Report Count (1) 12
+ * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 14
+ * # 🭬 0x09, 0x21, // Usage (Puck) 16
+ * # 0xa1, 0x02, // Collection (Logical) 18
+ * # 0x15, 0x00, // Logical Minimum (0) 20
+ * # 0x25, 0x01, // Logical Maximum (1) 22
+ * # 0x75, 0x01, // Report Size (1) 24
+ * # 0x95, 0x01, // Report Count (1) 26
+ * # 0xa1, 0x00, // Collection (Physical) 28
+ * # 🮥 0x05, 0x09, // Usage Page (Button) 30
+ * # 🭬 0x09, 0x01, // Usage (Button 1) 32
+ * # ┇ 0x81, 0x02, // Input (Data,Var,Abs) 34
+ * # 🮥 0x05, 0x0d, // Usage Page (Digitizers) 36
+ * # 🭬 0x09, 0x33, // Usage (Touch) 38
+ * # ┇ 0x81, 0x02, // Input (Data,Var,Abs) 40
+ * # 0x95, 0x06, // Report Count (6) 42
+ * # ┇ 0x81, 0x03, // Input (Cnst,Var,Abs) 44
+ * # 0xa1, 0x02, // Collection (Logical) 46
+ * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 48
+ * # 🭬 0x09, 0x37, // Usage (Dial) 50
+ * # 0x16, 0x00, 0x80, // Logical Minimum (32768) 52
+ * # 0x26, 0xff, 0x7f, // Logical Maximum (32767) 55
+ * # 0x75, 0x10, // Report Size (16) 58
+ * # 0x95, 0x01, // Report Count (1) 60
+ * # ┇ 0x81, 0x06, // Input (Data,Var,Rel) 62
+ * # 0x35, 0x00, // Physical Minimum (0) 64
+ * # 0x46, 0x10, 0x0e, // Physical Maximum (3600) 66
+ * # 0x15, 0x00, // Logical Minimum (0) 69
+ * # 0x26, 0x10, 0x0e, // Logical Maximum (3600) 71
+ * # 🭬 0x09, 0x48, // Usage (Resolution Multiplier) 74
+ * # ║ 0xb1, 0x02, // Feature (Data,Var,Abs) 76
+ * # 0x45, 0x00, // Physical Maximum (0) 78
+ * # 0xc0, // End Collection 80
+ * # 0x75, 0x08, // Report Size (8) 81
+ * # 0x95, 0x01, // Report Count (1) 83
+ * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 85
+ * # 0x75, 0x08, // Report Size (8) 87
+ * # 0x95, 0x01, // Report Count (1) 89
+ * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 91
+ * # 0x75, 0x08, // Report Size (8) 93
+ * # 0x95, 0x01, // Report Count (1) 95
+ * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 97
+ * # 0x75, 0x08, // Report Size (8) 99
+ * # 0x95, 0x01, // Report Count (1) 101
+ * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 103
+ * # 0x75, 0x08, // Report Size (8) 105
+ * # 0x95, 0x01, // Report Count (1) 107
+ * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 109
+ * # 0xc0, // End Collection 111
+ * # 0xc0, // End Collection 112
+ * # 0xc0, // End Collection 113
+ * R: 114 05 01 09 0e a1 01 85 03 05 0d 75 08 95 01 81 01 09 21 a1 02 15 00 25 01 75 01 95 01 a1 00 05 09 09 01 81 02 05 0d 09 33 81 02 95 06 81 03 a1 02 05 01 09 37 16 00 80 26 ff 7f 75 10 95 01 81 06 35 00 46 10 0e 15 00 26 10 0e 09 48 b1 02 45 00 c0 75 08 95 01 81 01 75 08 95 01 81 01 75 08 95 01 81 01 75 08 95 01 81 01 75 08 95 01 81 01 c0 c0 c0
+ * N: Keydial mini-050
+ * I: 5 256c 8251
+ *
+ * The second hidraw node is what sends events:
+ *
+ * # Keydial mini-050
+ * # Report descriptor length: 160 bytes
+ * # Bytes // Field Name Offset
+ * # ----------------------------------------------------------------------------------
+ * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 0
+ * # 🭬 0x09, 0x06, // Usage (Keyboard) 2
+ * # 0xa1, 0x01, // Collection (Application) 4
+ * # ┅ 0x85, 0x01, // Report ID (1) 6
+ * # 🮥 0x05, 0x07, // Usage Page (Keyboard/Keypad) 8
+ * # 🭬 0x19, 0xe0, // Usage Minimum (224) 10
+ * # 🭬 0x29, 0xe7, // Usage Maximum (231) 12
+ * # 0x15, 0x00, // Logical Minimum (0) 14
+ * # 0x25, 0x01, // Logical Maximum (1) 16
+ * # 0x75, 0x01, // Report Size (1) 18
+ * # 0x95, 0x08, // Report Count (8) 20
+ * # ┇ 0x81, 0x02, // Input (Data,Var,Abs) 22
+ * # 0x95, 0x01, // Report Count (1) 24
+ * # 0x75, 0x08, // Report Size (8) 26
+ * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 28
+ * # 0x95, 0x05, // Report Count (5) 30
+ * # 0x75, 0x01, // Report Size (1) 32
+ * # 🮥 0x05, 0x08, // Usage Page (LED) 34
+ * # 🭬 0x19, 0x01, // Usage Minimum (1) 36
+ * # 🭬 0x29, 0x05, // Usage Maximum (5) 38
+ * # ┊ 0x91, 0x02, // Output (Data,Var,Abs) 40
+ * # 0x95, 0x01, // Report Count (1) 42
+ * # 0x75, 0x03, // Report Size (3) 44
+ * # ┊ 0x91, 0x01, // Output (Cnst,Arr,Abs) 46
+ * # 0x95, 0x06, // Report Count (6) 48
+ * # 0x75, 0x08, // Report Size (8) 50
+ * # 0x15, 0x00, // Logical Minimum (0) 52
+ * # 0x25, 0xf1, // Logical Maximum (241) 54
+ * # 🮥 0x05, 0x07, // Usage Page (Keyboard/Keypad) 56
+ * # 🭬 0x19, 0x00, // Usage Minimum (0) 58
+ * # 🭬 0x29, 0xf1, // Usage Maximum (241) 60
+ * # ┇ 0x81, 0x00, // Input (Data,Arr,Abs) 62
+ * # 0xc0, // End Collection 64
+ * # 🮥 0x05, 0x0c, // Usage Page (Consumer) 65
+ * # 🭬 0x09, 0x01, // Usage (Consumer Control) 67
+ * # 0xa1, 0x01, // Collection (Application) 69
+ * # ┅ 0x85, 0x02, // Report ID (2) 71
+ * # 🮥 0x05, 0x0c, // Usage Page (Consumer) 73
+ * # 🭬 0x19, 0x00, // Usage Minimum (0) 75
+ * # 🭬 0x2a, 0x80, 0x03, // Usage Maximum (896) 77
+ * # 0x15, 0x00, // Logical Minimum (0) 80
+ * # 0x26, 0x80, 0x03, // Logical Maximum (896) 82
+ * # 0x75, 0x10, // Report Size (16) 85
+ * # 0x95, 0x01, // Report Count (1) 87
+ * # ┇ 0x81, 0x00, // Input (Data,Arr,Abs) 89
+ * # 0xc0, // End Collection 91
+ * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 92
+ * # 🭬 0x09, 0x02, // Usage (Mouse) 94
+ * # 0xa1, 0x01, // Collection (Application) 96
+ * # 🭬 0x09, 0x01, // Usage (Pointer) 98
+ * # ┅ 0x85, 0x05, // Report ID (5) 100
+ * # 0xa1, 0x00, // Collection (Physical) 102
+ * # 🮥 0x05, 0x09, // Usage Page (Button) 104
+ * # 🭬 0x19, 0x01, // Usage Minimum (1) 106
+ * # 🭬 0x29, 0x05, // Usage Maximum (5) 108
+ * # 0x15, 0x00, // Logical Minimum (0) 110
+ * # 0x25, 0x01, // Logical Maximum (1) 112
+ * # 0x95, 0x05, // Report Count (5) 114
+ * # 0x75, 0x01, // Report Size (1) 116
+ * # ┇ 0x81, 0x02, // Input (Data,Var,Abs) 118
+ * # 0x95, 0x01, // Report Count (1) 120
+ * # 0x75, 0x03, // Report Size (3) 122
+ * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 124
+ * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 126
+ * # 🭬 0x09, 0x30, // Usage (X) 128
+ * # 🭬 0x09, 0x31, // Usage (Y) 130
+ * # 0x16, 0x01, 0x80, // Logical Minimum (32769) 132
+ * # 0x26, 0xff, 0x7f, // Logical Maximum (32767) 135
+ * # 0x75, 0x10, // Report Size (16) 138
+ * # 0x95, 0x02, // Report Count (2) 140
+ * # ┇ 0x81, 0x06, // Input (Data,Var,Rel) 142
+ * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 144
+ * # 🭬 0x09, 0x38, // Usage (Wheel) 146
+ * # 0x15, 0x81, // Logical Minimum (129) 148
+ * # 0x25, 0x7f, // Logical Maximum (127) 150
+ * # 0x95, 0x01, // Report Count (1) 152
+ * # 0x75, 0x08, // Report Size (8) 154
+ * # ┇ 0x81, 0x06, // Input (Data,Var,Rel) 156
+ * # 0xc0, // End Collection 158
+ * # 0xc0, // End Collection 159
+ * R: 160 05 01 09 06 a1 01 85 01 05 07 19 e0 29 e7 15 00 25 01 75 01 95 08 81 02 95 01 75 08 81 01 95 05 75 01 05 08 19 01 29 05 91 02 95 01 75 03 91 01 95 06 75 08 15 00 25 f1 05 07 19 00 29 f1 81 00 c0 05 0c 09 01 a1 01 85 02 05 0c 19 00 2a 80 03 15 00 26 80 03 75 10 95 01 81 00 c0 05 01 09 02 a1 01 09 01 85 05 a1 00 05 09 19 01 29 05 15 00 25 01 95 05 75 01 81 02 95 01 75 03 81 01 05 01 09 30 09 31 16 01 80 26 ff 7f 75 10 95 02 81 06 05 01 09 38 15 81 25 7f 95 01 75 08 81 06 c0 c0
+ * N: Keydial mini-050
+ * I: 5 256c 8251
+ * # Report descriptor:
+ * # ------- Input Report -------
+ * # ░ Report ID: 1
+ * # ░ | Report size: 72 bits
+ * # ░ Bit: 8 Usage: 0007/00e0: Keyboard/Keypad / Keyboard LeftControl Logical Range: 0..=1
+ * # ░ Bit: 9 Usage: 0007/00e1: Keyboard/Keypad / Keyboard LeftShift Logical Range: 0..=1
+ * # ░ Bit: 10 Usage: 0007/00e2: Keyboard/Keypad / Keyboard LeftAlt Logical Range: 0..=1
+ * # ░ Bit: 11 Usage: 0007/00e3: Keyboard/Keypad / Keyboard Left GUI Logical Range: 0..=1
+ * # ░ Bit: 12 Usage: 0007/00e4: Keyboard/Keypad / Keyboard RightControl Logical Range: 0..=1
+ * # ░ Bit: 13 Usage: 0007/00e5: Keyboard/Keypad / Keyboard RightShift Logical Range: 0..=1
+ * # ░ Bit: 14 Usage: 0007/00e6: Keyboard/Keypad / Keyboard RightAlt Logical Range: 0..=1
+ * # ░ Bit: 15 Usage: 0007/00e7: Keyboard/Keypad / Keyboard Right GUI Logical Range: 0..=1
+ * # ░ Bits: 16..=23 ######### Padding
+ * # ░ Bits: 24..=71 Usages: Logical Range: 0..=241
+ * # ░ 0007/0000: <unknown>
+ * # ░ 0007/0001: Keyboard/Keypad / ErrorRollOver
+ * # ░ 0007/0002: Keyboard/Keypad / POSTFail
+ * # ░ 0007/0003: Keyboard/Keypad / ErrorUndefined
+ * # ░ 0007/0004: Keyboard/Keypad / Keyboard A
+ * # ░ ... use --full to see all usages
+ * # ------- Input Report -------
+ * # ▒ Report ID: 2
+ * # ▒ | Report size: 24 bits
+ * # ▒ Bits: 8..=23 Usages: Logical Range: 0..=896
+ * # ▒ 000c/0000: <unknown>
+ * # ▒ 000c/0001: Consumer / Consumer Control
+ * # ▒ 000c/0002: Consumer / Numeric Key Pad
+ * # ▒ 000c/0003: Consumer / Programmable Buttons
+ * # ▒ 000c/0004: Consumer / Microphone
+ * # ▒ ... use --full to see all usages
+ * # ------- Input Report -------
+ * # ▞ Report ID: 5
+ * # ▞ | Report size: 56 bits
+ * # ▞ Bit: 8 Usage: 0009/0001: Button / Button 1 Logical Range: 0..=1
+ * # ▞ Bit: 9 Usage: 0009/0002: Button / Button 2 Logical Range: 0..=1
+ * # ▞ Bit: 10 Usage: 0009/0003: Button / Button 3 Logical Range: 0..=1
+ * # ▞ Bit: 11 Usage: 0009/0004: Button / Button 4 Logical Range: 0..=1
+ * # ▞ Bit: 12 Usage: 0009/0005: Button / Button 5 Logical Range: 0..=1
+ * # ▞ Bits: 13..=15 ######### Padding
+ * # ▞ Bits: 16..=31 Usage: 0001/0030: Generic Desktop / X Logical Range: 32769..=32767
+ * # ▞ Bits: 32..=47 Usage: 0001/0031: Generic Desktop / Y Logical Range: 32769..=32767
+ * # ▞ Bits: 48..=55 Usage: 0001/0038: Generic Desktop / Wheel Logical Range: 129..=127
+ * # ------- Output Report -------
+ * # ░ Report ID: 1
+ * # ░ | Report size: 16 bits
+ * # ░ Bit: 8 Usage: 0008/0001: LED / Num Lock Logical Range: 0..=1
+ * # ░ Bit: 9 Usage: 0008/0002: LED / Caps Lock Logical Range: 0..=1
+ * # ░ Bit: 10 Usage: 0008/0003: LED / Scroll Lock Logical Range: 0..=1
+ * # ░ Bit: 11 Usage: 0008/0004: LED / Compose Logical Range: 0..=1
+ * # ░ Bit: 12 Usage: 0008/0005: LED / Kana Logical Range: 0..=1
+ * # ░ Bits: 13..=15 ######### Padding
+ * ##############################################################################
+ * # Event nodes:
+ * # - /dev/input/event12: "Keydial mini-050 Keyboard"
+ * # - /dev/input/event14: "Keydial mini-050 Mouse"
+ * ##############################################################################
+ * # Recorded events below in format:
+ * # E: <seconds>.<microseconds> <length-in-bytes> [bytes ...]
+ * #
+ *
+ * - Report ID 1 sends keyboard shortcuts when pressing the buttons, e.g.
+ *
+ * # ░ Report ID: 1 /
+ * # ░ Keyboard LeftControl: 0 |Keyboard LeftShift: 0 |Keyboard LeftAlt: 0 |Keyboard Left GUI: 0 |Keyboard RightControl: 0 |Keyboard RightShift: 0 |Keyboard RightAlt: 0 |Keyboard Right GUI: 0 |<8 bits padding> |0007/0000: 0| Keyboard K: 14| 0007/0000: 0| 0007/0000: 0| 0007/0000: 0| 0007/0000: 0
+ * E: 000000.000292 9 01 00 00 00 0e 00 00 00 00
+ *
+ * - Report ID 2 sends the button inside the wheel/dial thing
+ * # ▒ Report ID: 2 /
+ * # ▒ Play/Pause: 205
+ * E: 000134.347845 3 02 cd 00
+ * # ▒ Report ID: 2 /
+ * # ▒ 000c/0000: 0
+ * E: 000134.444965 3 02 00 00
+ *
+ * - Report ID 5 sends the wheel relative events (always a double-event with the second as zero)
+ * # ▞ Report ID: 5 /
+ * # ▞ Button 1: 0 |Button 2: 0 |Button 3: 0 |Button 4: 0 |Button 5: 0 |<3 bits padding> |X: 0 |Y: 0 |Wheel: 255
+ * E: 000064.859915 7 05 00 00 00 00 00 ff
+ * # ▞ Report ID: 5 /
+ * # ▞ Button 1: 0 |Button 2: 0 |Button 3: 0 |Button 4: 0 |Button 5: 0 |<3 bits padding> |X: 0 |Y: 0 |Wheel: 0
+ * E: 000064.882009 7 05 00 00 00 00 00 00
+ */
+
+#define BT_PAD_REPORT_DESCRIPTOR_LENGTH 160
+#define BT_PUCK_REPORT_DESCRIPTOR_LENGTH 114 // This one doesn't send events
+#define BT_PAD_KBD_REPORT_ID 1
+#define BT_PAD_CC_REPORT_ID 2
+#define BT_PAD_MOUSE_REPORT_ID 5
+#define BT_PAD_KBD_REPORT_LENGTH 9
+#define BT_PAD_CC_REPORT_LENGTH 3
+#define BT_PAD_MOUSE_REPORT_LENGTH 7
+#define OUR_REPORT_ID 11 /* "randomly" picked report ID for our reports */
+
+__u32 last_button_state = 0;
+
+static const __u8 disabled_rdesc_puck[] = {
+ FixedSizeVendorReport(BT_PUCK_REPORT_DESCRIPTOR_LENGTH)
+};
+
+static const __u8 fixed_rdesc_pad[] = {
+ UsagePage_GenericDesktop
+ Usage_GD_Keypad
+ CollectionApplication(
+ // Byte 0
+ ReportId(OUR_REPORT_ID)
+ UsagePage_Digitizers
+ Usage_Dig_TabletFunctionKeys
+ CollectionPhysical(
+ // Byte 1 is a button so we look like a tablet
+ Usage_Dig_BarrelSwitch // BTN_STYLUS, needed so we get to be a tablet pad
+ ReportCount(1)
+ ReportSize(1)
+ Input(Var|Abs)
+ ReportCount(7) // Padding
+ Input(Const)
+ // Bytes 2/3 - x/y just exist so we get to be a tablet pad
+ UsagePage_GenericDesktop
+ Usage_GD_X
+ Usage_GD_Y
+ LogicalMinimum_i8(0x0)
+ LogicalMaximum_i8(0x1)
+ ReportCount(2)
+ ReportSize(8)
+ Input(Var|Abs)
+ // Bytes 4-7 are the button state for 19 buttons + pad out to u32
+ // We send the first 10 buttons as buttons 1-10 which is BTN_0 -> BTN_9
+ UsagePage_Button
+ UsageMinimum_i8(1)
+ UsageMaximum_i8(10)
+ LogicalMinimum_i8(0x0)
+ LogicalMaximum_i8(0x1)
+ ReportCount(10)
+ ReportSize(1)
+ Input(Var|Abs)
+ // We send the other 9 buttons as buttons 0x31 and above -> BTN_A - BTN_TL2
+ UsageMinimum_i8(0x31)
+ UsageMaximum_i8(0x3a)
+ ReportCount(9)
+ ReportSize(1)
+ Input(Var|Abs)
+ ReportCount(13)
+ ReportSize(1)
+ Input(Const) // padding
+ // Byte 8 is the wheel
+ UsagePage_GenericDesktop
+ Usage_GD_Wheel
+ LogicalMinimum_i8(-1)
+ LogicalMaximum_i8(1)
+ ReportCount(1)
+ ReportSize(8)
+ Input(Var|Rel)
+ )
+ // Make sure we match our original report length
+ FixedSizeVendorReport(BT_PAD_KBD_REPORT_LENGTH)
+ )
+};
+
+SEC(HID_BPF_RDESC_FIXUP)
+int BPF_PROG(k20_bt_fix_rdesc, struct hid_bpf_ctx *hctx)
+{
+ __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, HID_MAX_DESCRIPTOR_SIZE /* size */);
+ __s32 rdesc_size = hctx->size;
+
+ if (!data)
+ return 0; /* EPERM check */
+
+ if (rdesc_size == BT_PAD_REPORT_DESCRIPTOR_LENGTH) {
+ __builtin_memcpy(data, fixed_rdesc_pad, sizeof(fixed_rdesc_pad));
+ return sizeof(fixed_rdesc_pad);
+ }
+ if (rdesc_size == BT_PUCK_REPORT_DESCRIPTOR_LENGTH) {
+ // This hidraw node doesn't send anything and can be ignored
+ __builtin_memcpy(data, disabled_rdesc_puck, sizeof(disabled_rdesc_puck));
+ return sizeof(disabled_rdesc_puck);
+ }
+
+ return 0;
+}
+
+SEC(HID_BPF_DEVICE_EVENT)
+int BPF_PROG(k20_bt_fix_events, struct hid_bpf_ctx *hctx)
+{
+ __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 12 /* size */);
+ struct pad_report {
+ __u8 report_id;
+ __u8 btn_stylus:1;
+ __u8 pad:7;
+ __u8 x;
+ __u8 y;
+ __u32 buttons;
+ __u8 wheel;
+ } __packed * pad_report = (struct pad_report *)data;
+
+ if (!data)
+ return 0; /* EPERM check */
+
+ /* Report ID 1 - Keyboard events (button presses) */
+ if (data[0] == BT_PAD_KBD_REPORT_ID) {
+ const __u8 button_mapping[] = {
+ 0x0e, /* Button 1: K */
+ 0x0a, /* Button 2: G */
+ 0x0f, /* Button 3: L */
+ 0x4c, /* Button 4: Delete */
+ 0x0c, /* Button 5: I */
+ 0x07, /* Button 6: D */
+ 0x05, /* Button 7: B */
+ 0x08, /* Button 8: E */
+ 0x16, /* Button 9: S */
+ 0x1d, /* Button 10: Z */
+ 0x06, /* Button 11: C */
+ 0x19, /* Button 12: V */
+ 0xff, /* Button 13: LeftControl */
+ 0xff, /* Button 14: LeftAlt */
+ 0xff, /* Button 15: LeftShift */
+ 0x28, /* Button 16: Return Enter */
+ 0x2c, /* Button 17: Spacebar */
+ 0x11, /* Button 18: N */
+ };
+
+ __u8 modifiers = data[1];
+ __u32 buttons = 0;
+
+ if (modifiers & 0x01) { /* Control */
+ buttons |= BIT(12);
+ }
+ if (modifiers & 0x02) { /* Shift */
+ buttons |= BIT(14);
+ }
+ if (modifiers & 0x04) { /* Alt */
+ buttons |= BIT(13);
+ }
+
+ for (int i = 4; i < BT_PAD_KBD_REPORT_LENGTH; i++) {
+ if (!data[i])
+ break;
+
+ for (size_t b = 0; b < ARRAY_SIZE(button_mapping); b++) {
+ if (data[i] != 0xff && data[i] == button_mapping[b]) {
+ buttons |= BIT(b);
+ break;
+ }
+ }
+ }
+
+ last_button_state = buttons;
+
+ pad_report->report_id = OUR_REPORT_ID;
+ pad_report->btn_stylus = 0;
+ pad_report->x = 0;
+ pad_report->y = 0;
+ pad_report->buttons = buttons;
+ pad_report->wheel = 0;
+
+ return sizeof(struct pad_report);
+ }
+
+ /* Report ID 2 - Consumer control events (the button inside the wheel) */
+ if (data[0] == BT_PAD_CC_REPORT_ID) {
+ const __u8 PlayPause = 0xcd;
+
+ if (data[1] == PlayPause)
+ last_button_state |= BIT(18);
+ else
+ last_button_state &= ~BIT(18);
+
+ pad_report->report_id = OUR_REPORT_ID;
+ pad_report->btn_stylus = 0;
+ pad_report->x = 0;
+ pad_report->y = 0;
+ pad_report->buttons = last_button_state;
+ pad_report->wheel = 0;
+
+ return sizeof(struct pad_report);
+ }
+
+ /* Report ID 5 - Mouse events (wheel rotation) */
+ if (data[0] == BT_PAD_MOUSE_REPORT_ID) {
+ __u8 wheel_delta = data[6];
+
+ pad_report->report_id = OUR_REPORT_ID;
+ pad_report->btn_stylus = 0;
+ pad_report->x = 0;
+ pad_report->y = 0;
+ pad_report->buttons = last_button_state;
+ pad_report->wheel = wheel_delta;
+
+ return sizeof(struct pad_report);
+ }
+
+ return 0;
+}
+
+HID_BPF_OPS(keydial_k20_bluetooth) = {
+ .hid_device_event = (void *)k20_bt_fix_events,
+ .hid_rdesc_fixup = (void *)k20_bt_fix_rdesc,
+};
+
+SEC("syscall")
+int probe(struct hid_bpf_probe_args *ctx)
+{
+ switch (ctx->rdesc_size) {
+ case BT_PAD_REPORT_DESCRIPTOR_LENGTH:
+ case BT_PUCK_REPORT_DESCRIPTOR_LENGTH:
+ ctx->retval = 0;
+ break;
+ default:
+ ctx->retval = -EINVAL;
+ }
+
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";
--
2.53.0
^ permalink raw reply related
* [PATCH 6/8] HID: bpf: add a BPF to get the touchpad type
From: Benjamin Tissoires @ 2026-04-03 16:12 UTC (permalink / raw)
To: Jiri Kosina
Cc: linux-input, linux-kernel, Benjamin Tissoires, Benjamin Tissoires
In-Reply-To: <20260403-wip-sync-udev-hid-bpf-2026-04-v1-0-978cedb9a074@kernel.org>
Currently the kernel is scheduled to do this call by itself, but it
requires a kernel v6.18 at least to have the INPUT_PROP set. For older
kernels, we can try to query the property from a HID-BPF probe, and set
a udev property based on that. This way we can provide the information
to old kernels without modifying them.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/220
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
drivers/hid/bpf/progs/Generic__touchpad.bpf.c | 90 +++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/drivers/hid/bpf/progs/Generic__touchpad.bpf.c b/drivers/hid/bpf/progs/Generic__touchpad.bpf.c
new file mode 100644
index 000000000000..b9f2cac91724
--- /dev/null
+++ b/drivers/hid/bpf/progs/Generic__touchpad.bpf.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2025 Benjamin Tissoires
+ */
+
+#include "vmlinux.h"
+#include "hid_bpf.h"
+#include "hid_bpf_helpers.h"
+#include "hid_report_helpers.h"
+#include "hid_usages.h"
+#include <bpf/bpf_tracing.h>
+
+HID_BPF_CONFIG(
+ HID_DEVICE(BUS_ANY, HID_GROUP_MULTITOUCH_WIN_8, HID_VID_ANY, HID_PID_ANY),
+);
+
+EXPORT_UDEV_PROP(HID_DIGITIZER_PAD_TYPE, 32);
+
+__u8 hw_req_buf[1024];
+
+/* to be filled by udev-hid-bpf */
+struct hid_rdesc_descriptor HID_REPORT_DESCRIPTOR;
+
+SEC("syscall")
+int probe(struct hid_bpf_probe_args *ctx)
+{
+ struct hid_rdesc_report *pad_type_feature = NULL;
+ struct hid_rdesc_field *pad_type = NULL;
+ struct hid_rdesc_report *feature;
+ struct hid_bpf_ctx *hid_ctx;
+ char *pad_type_str = "";
+ int ret;
+
+ hid_bpf_for_each_feature_report(&HID_REPORT_DESCRIPTOR, feature) {
+ struct hid_rdesc_field *field;
+
+ hid_bpf_for_each_field(feature, field) {
+ if (field->usage_page == HidUsagePage_Digitizers &&
+ field->usage_id == HidUsage_Dig_PadType) {
+ pad_type = field;
+ pad_type_feature = feature;
+ break;
+ }
+ }
+ if (pad_type)
+ break;
+ }
+
+ if (!pad_type || !pad_type_feature) {
+ ctx->retval = -EINVAL;
+ return 0;
+ }
+
+ hid_ctx = hid_bpf_allocate_context(ctx->hid);
+
+ if (!hid_ctx)
+ return -1; /* EPERM check */
+
+ hw_req_buf[0] = pad_type_feature->report_id;
+
+ ret = hid_bpf_hw_request(hid_ctx, hw_req_buf, sizeof(hw_req_buf),
+ HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
+ hid_bpf_release_context(hid_ctx);
+
+ if (ret < 0) {
+ ctx->retval = ret;
+ return 0;
+ }
+
+ ctx->retval = 0;
+
+ switch (EXTRACT_BITS(hw_req_buf, pad_type)) {
+ case 0:
+ pad_type_str = "Clickpad";
+ break;
+ case 1:
+ pad_type_str = "Pressurepad";
+ break;
+ case 2:
+ pad_type_str = "Discrete";
+ break;
+ default:
+ pad_type_str = "Unknown";
+ }
+
+ UDEV_PROP_SPRINTF(HID_DIGITIZER_PAD_TYPE, "%s", pad_type_str);
+
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";
--
2.53.0
^ permalink raw reply related
* [PATCH 5/8] hid: bpf: hid_bpf_helpers: add helper for having read/write udev properties
From: Benjamin Tissoires @ 2026-04-03 16:12 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, linux-kernel, Benjamin Tissoires
In-Reply-To: <20260403-wip-sync-udev-hid-bpf-2026-04-v1-0-978cedb9a074@kernel.org>
We want udev-hid-bpf to be able to set udev properties by printing them
out after the BPF object has been loaded. This allows to make a query to
the device, and set a udev prop based on the answer.
Because the way udev works, the properties are cleared on bind/unbind,
and we need a way to store them. After several attempts to keep the
property alive without re-running the udev-hid-bpf tool to communicate
with the device, it came out that HID-BPF maps are pinned in the bpffs
and we can then query them.
So the following would export a UDEV property in the bpffs:
EXPORT_UDEV_PROP(HID_FOO, 32);
SEC("syscall")
int probe(struct hid_bpf_probe_args *ctx)
{
const char *foo = "foo";
UDEV_PROP_SPRINTF(HID_FOO, "%s", foo);
return 0;
}
Then, we can debug it with a simple cat:
sudo cat /sys/fs/bpf/hid/.../UDEV_PROP_HID_FOO
0: {['f','o','o',],}
This way, the property is always accessible without talking to the
device
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/220
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
drivers/hid/bpf/progs/hid_bpf_helpers.h | 38 +++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/hid/bpf/progs/hid_bpf_helpers.h b/drivers/hid/bpf/progs/hid_bpf_helpers.h
index c67facdefff3..0fd8e7d90742 100644
--- a/drivers/hid/bpf/progs/hid_bpf_helpers.h
+++ b/drivers/hid/bpf/progs/hid_bpf_helpers.h
@@ -340,6 +340,44 @@ DEFINE_GUARD(bpf_spin, struct bpf_spin_lock, bpf_spin_lock, bpf_spin_unlock);
#define hid_bpf_cpu_to_be32(x) bpf_htonl(x)
#define hid_bpf_cpu_to_be64(x) bpf_cpu_to_be64(x)
+/*
+ * The following macros are helpers for exporting udev properties:
+ *
+ * EXPORT_UDEV_PROP(name, len) generates:
+ * - a map with a single element UDEV_PROP_##name, of size len
+ * - a const global declaration of that len: SIZEOF_##name
+ *
+ * udev_prop_ptr(name) retrieves the data pointer behind the map.
+ *
+ * UDEV_PROP_SPRINTF(name, fmt, ...) writes data into the udev property.
+ *
+ * Can be used as such:
+ * EXPORT_UDEV_PROP(HID_FOO, 32);
+ *
+ * SEC("syscall")
+ * int probe(struct hid_bpf_probe_args *ctx)
+ * {
+ * const char *foo = "foo";
+ * UDEV_PROP_SPRINTF(HID_FOO, "%s", foo);
+ *
+ * return 0;
+ * }
+ */
+#define EXPORT_UDEV_PROP(name, len) \
+ const __u32 SIZEOF_##name = len; \
+ struct COMBINE(udev_prop, __LINE__) { \
+ __uint(type, BPF_MAP_TYPE_ARRAY); \
+ __uint(max_entries, 1); \
+ __type(key, __u32); \
+ __type(value, __u8[len]); \
+ } UDEV_PROP_##name SEC(".maps");
+
+#define udev_prop_ptr(name) \
+ bpf_map_lookup_elem(&UDEV_PROP_##name, &(__u32){0})
+
+#define UDEV_PROP_SPRINTF(name, fmt, ...) \
+ BPF_SNPRINTF(udev_prop_ptr(name), SIZEOF_##name, fmt, ##__VA_ARGS__)
+
static inline __maybe_unused __u16 field_start_byte(struct hid_rdesc_field *field)
{
return field->bits_start / 8;
--
2.53.0
^ permalink raw reply related
* [PATCH 4/8] HID: bpf: handle injected report descriptor in HID-BPF
From: Benjamin Tissoires @ 2026-04-03 16:12 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, linux-kernel, Benjamin Tissoires
In-Reply-To: <20260403-wip-sync-udev-hid-bpf-2026-04-v1-0-978cedb9a074@kernel.org>
udev-hid-bpf is now capable of injecting the parsed report descriptor in
the program. Provide the macros required for it.
Sync up from udev-hid-bpf commits:
bpf: inject the parsed report descriptor in HID_REPORT_DESCRIPTOR
hid_bpf_helpers: provide iterator macros for walking the HID report descriptor
hid_bpf_helpers: Add extract_bits function
bpf: add hid_usages.h
bpf: move the report descriptor structs into their own header
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/221
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/228
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
drivers/hid/bpf/progs/hid_bpf_helpers.h | 136 +
.../hid/bpf/progs/hid_report_descriptor_helpers.h | 80 +
drivers/hid/bpf/progs/hid_usages.h | 2810 ++++++++++++++++++++
3 files changed, 3026 insertions(+)
diff --git a/drivers/hid/bpf/progs/hid_bpf_helpers.h b/drivers/hid/bpf/progs/hid_bpf_helpers.h
index f9071444c938..c67facdefff3 100644
--- a/drivers/hid/bpf/progs/hid_bpf_helpers.h
+++ b/drivers/hid/bpf/progs/hid_bpf_helpers.h
@@ -9,6 +9,16 @@
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>
#include <linux/errno.h>
+#include "hid_report_descriptor_helpers.h"
+
+/* Compiler attributes */
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+#ifndef __maybe_unused
+#define __maybe_unused __attribute__((__unused__))
+#endif
extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx,
unsigned int offset,
@@ -330,4 +340,130 @@ DEFINE_GUARD(bpf_spin, struct bpf_spin_lock, bpf_spin_lock, bpf_spin_unlock);
#define hid_bpf_cpu_to_be32(x) bpf_htonl(x)
#define hid_bpf_cpu_to_be64(x) bpf_cpu_to_be64(x)
+static inline __maybe_unused __u16 field_start_byte(struct hid_rdesc_field *field)
+{
+ return field->bits_start / 8;
+}
+
+static inline __maybe_unused __u16 field_end_byte(struct hid_rdesc_field *field)
+{
+ if (!field->bits_end)
+ return 0;
+
+ return (__u16)(field->bits_end - 1) / 8;
+}
+
+static __maybe_unused __u32 extract_bits(__u8 *buffer, const size_t size, struct hid_rdesc_field *field)
+{
+ __s32 nbits = field->bits_end - field->bits_start;
+ __u32 start = field_start_byte(field);
+ __u32 end = field_end_byte(field);
+ __u8 base_shift = field->bits_start % 8;
+
+ if (nbits <= 0 || nbits > 32 || start >= size || end >= size)
+ return 0;
+
+ /* Fast path for byte-aligned standard-sized reads */
+ if (base_shift == 0) {
+ /* 8-bit aligned read */
+ if (nbits == 8 && start < size)
+ return buffer[start];
+
+ /* 16-bit aligned read - use separate variables for verifier */
+ if (nbits == 16) {
+ __u32 off0 = start;
+ __u32 off1 = start + 1;
+
+ if (off0 < size && off1 < size) {
+ return buffer[off0] |
+ ((__u32)buffer[off1] << 8);
+ }
+ }
+
+ /* 32-bit aligned read - use separate variables for verifier */
+ if (nbits == 32) {
+ __u32 off0 = start;
+ __u32 off1 = start + 1;
+ __u32 off2 = start + 2;
+ __u32 off3 = start + 3;
+
+ if (off0 < size && off1 < size &&
+ off2 < size && off3 < size) {
+ return buffer[off0] |
+ ((__u32)buffer[off1] << 8) |
+ ((__u32)buffer[off2] << 16) |
+ ((__u32)buffer[off3] << 24);
+ }
+ }
+ }
+
+ /* General case: bit manipulation for unaligned or non-standard sizes */
+ int mask = 0xffffffff >> (32 - nbits);
+ __u64 value = 0;
+ __u32 i;
+
+ bpf_for (i, start, end + 1) {
+ value |= (__u64)buffer[i] << ((i - start) * 8);
+ }
+
+ return (value >> base_shift) & mask;
+}
+
+#define EXTRACT_BITS(buffer, field) extract_bits(buffer, sizeof(buffer), field)
+
+/* Base macro for iterating over HID arrays with bounds checking.
+ * Follows the bpf_for pattern from libbpf.
+ */
+#define __hid_bpf_for_each_array(array, num_elements, max_elements, var) \
+ for ( \
+ /* initialize and define destructor */ \
+ struct bpf_iter_num ___it __attribute__((aligned(8), \
+ cleanup(bpf_iter_num_destroy))), \
+ /* ___p pointer is necessary to call bpf_iter_num_new() *once* */ \
+ *___p __attribute__((unused)) = ( \
+ /* always initialize iterator; if bounds fail, iterate 0 times */ \
+ bpf_iter_num_new(&___it, 0, \
+ (num_elements) > (max_elements) ? \
+ 0 : (num_elements)), \
+ /* workaround for Clang bug */ \
+ (void)bpf_iter_num_destroy, (void *)0); \
+ ({ \
+ /* iteration step */ \
+ int *___t = bpf_iter_num_next(&___it); \
+ int ___i; \
+ /* termination and bounds check, assign var */ \
+ (___t && (___i = *___t, ___i >= 0 && ___i < (num_elements)) && \
+ ((num_elements) <= (max_elements)) && \
+ (var = &(array)[___i], 1)); \
+ }); \
+ )
+
+/* Iterate over input reports in a descriptor */
+#define hid_bpf_for_each_input_report(descriptor, report_var) \
+ __hid_bpf_for_each_array((descriptor)->input_reports, \
+ (descriptor)->num_input_reports, \
+ HID_MAX_REPORTS, report_var)
+
+/* Iterate over feature reports in a descriptor */
+#define hid_bpf_for_each_feature_report(descriptor, report_var) \
+ __hid_bpf_for_each_array((descriptor)->feature_reports, \
+ (descriptor)->num_feature_reports, \
+ HID_MAX_REPORTS, report_var)
+
+/* Iterate over output reports in a descriptor */
+#define hid_bpf_for_each_output_report(descriptor, report_var) \
+ __hid_bpf_for_each_array((descriptor)->output_reports, \
+ (descriptor)->num_output_reports, \
+ HID_MAX_REPORTS, report_var)
+
+/* Iterate over fields in a report */
+#define hid_bpf_for_each_field(report, field_var) \
+ __hid_bpf_for_each_array((report)->fields, (report)->num_fields, \
+ HID_MAX_FIELDS, field_var)
+
+/* Iterate over collections in a field */
+#define hid_bpf_for_each_collection(field, collection_var) \
+ __hid_bpf_for_each_array((field)->collections, (field)->num_collections, \
+ HID_MAX_COLLECTIONS, collection_var)
+
#endif /* __HID_BPF_HELPERS_H */
diff --git a/drivers/hid/bpf/progs/hid_report_descriptor_helpers.h b/drivers/hid/bpf/progs/hid_report_descriptor_helpers.h
new file mode 100644
index 000000000000..2aed5c0a6ad4
--- /dev/null
+++ b/drivers/hid/bpf/progs/hid_report_descriptor_helpers.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2022 Benjamin Tissoires
+ */
+
+#ifndef __HID_REPORT_DESCRIPTOR_HELPERS_H
+#define __HID_REPORT_DESCRIPTOR_HELPERS_H
+
+#include "vmlinux.h"
+
+/* Compiler attributes */
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+#ifndef __maybe_unused
+#define __maybe_unused __attribute__((__unused__))
+#endif
+
+/* Report Descriptor Structures */
+#define HID_MAX_COLLECTIONS 32
+#define HID_MAX_FIELDS 64
+#define HID_MAX_REPORTS 16
+
+enum hid_rdesc_field_type {
+ HID_FIELD_VARIABLE = 0,
+ HID_FIELD_ARRAY = 1,
+ HID_FIELD_CONSTANT = 2,
+};
+
+struct hid_rdesc_collection {
+ __u16 usage_page;
+ __u16 usage_id;
+ __u8 collection_type;
+} __packed;
+
+struct hid_rdesc_field {
+ __u8 field_type; /* enum hid_rdesc_field_type */
+ __u8 num_collections;
+ __u16 bits_start;
+ __u16 bits_end;
+ __u16 usage_page;
+ union {
+ __u16 usage_id; /* For Variable fields */
+ struct __packed { /* For Array fields */
+ __u16 usage_minimum;
+ __u16 usage_maximum;
+ };
+ };
+ __s32 logical_minimum;
+ __s32 logical_maximum;
+ struct {
+ __u8 is_relative:1; /* Data is relative to previous value */
+ __u8 wraps:1; /* Value wraps around (e.g., rotary encoder) */
+ __u8 is_nonlinear:1; /* Non-linear relationship between logical/physical */
+ __u8 has_no_preferred_state:1; /* No rest position (e.g., free-floating joystick) */
+ __u8 has_null_state:1; /* Can report null/no-data values */
+ __u8 is_volatile:1; /* Volatile (Output/Feature) - NOT POPULATED, always 0 */
+ __u8 is_buffered_bytes:1; /* Fixed-size byte stream vs bitfield */
+ __u8 reserved:1; /* Reserved for future use */
+ } flags;
+ struct hid_rdesc_collection collections[HID_MAX_COLLECTIONS];
+} __packed;
+
+struct hid_rdesc_report {
+ __u8 report_id; /* 0 means no report ID */
+ __u16 size_in_bits;
+ __u8 num_fields;
+ struct hid_rdesc_field fields[HID_MAX_FIELDS];
+} __packed;
+
+struct hid_rdesc_descriptor {
+ __u8 num_input_reports;
+ __u8 num_output_reports;
+ __u8 num_feature_reports;
+ struct hid_rdesc_report input_reports[HID_MAX_REPORTS];
+ struct hid_rdesc_report output_reports[HID_MAX_REPORTS];
+ struct hid_rdesc_report feature_reports[HID_MAX_REPORTS];
+} __packed;
+
+#endif /* __HID_REPORT_DESCRIPTOR_HELPERS_H */
diff --git a/drivers/hid/bpf/progs/hid_usages.h b/drivers/hid/bpf/progs/hid_usages.h
new file mode 100644
index 000000000000..5469b25c9f79
--- /dev/null
+++ b/drivers/hid/bpf/progs/hid_usages.h
@@ -0,0 +1,2810 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2025 Red Hat, Inc
+ */
+
+// THIS FILE IS GENERATED, DO NOT EDIT
+
+#pragma once
+
+/* ----- Generated Usage Pages and Usages ------ */
+#define HidUsagePage_GenericDesktop 0x01
+#define HidUsagePage_SimulationControls 0x02
+#define HidUsagePage_VRControls 0x03
+#define HidUsagePage_SportControls 0x04
+#define HidUsagePage_GameControls 0x05
+#define HidUsagePage_GenericDeviceControls 0x06
+#define HidUsagePage_KeyboardKeypad 0x07
+#define HidUsagePage_LED 0x08
+#define HidUsagePage_Button 0x09
+#define HidUsagePage_Ordinal 0x0a
+#define HidUsagePage_TelephonyDevice 0x0b
+#define HidUsagePage_Consumer 0x0c
+#define HidUsagePage_Digitizers 0x0d
+#define HidUsagePage_Haptics 0x0e
+#define HidUsagePage_PhysicalInputDevice 0x0f
+#define HidUsagePage_Unicode 0x10
+#define HidUsagePage_SoC 0x11
+#define HidUsagePage_EyeandHeadTrackers 0x12
+#define HidUsagePage_AuxiliaryDisplay 0x14
+#define HidUsagePage_Sensors 0x20
+#define HidUsagePage_MedicalInstrument 0x40
+#define HidUsagePage_BrailleDisplay 0x41
+#define HidUsagePage_LightingAndIllumination 0x59
+#define HidUsagePage_Monitor 0x80
+#define HidUsagePage_MonitorEnumerated 0x81
+#define HidUsagePage_VESAVirtualControls 0x82
+#define HidUsagePage_Power 0x84
+#define HidUsagePage_BatterySystem 0x85
+#define HidUsagePage_BarcodeScanner 0x8c
+#define HidUsagePage_Scales 0x8d
+#define HidUsagePage_MagneticStripeReader 0x8e
+#define HidUsagePage_CameraControl 0x90
+#define HidUsagePage_Arcade 0x91
+#define HidUsagePage_FIDOAlliance 0xf1d0
+
+#define HidUsage_GD_Pointer 0x01
+#define HidUsage_GD_Mouse 0x02
+#define HidUsage_GD_Joystick 0x04
+#define HidUsage_GD_Gamepad 0x05
+#define HidUsage_GD_Keyboard 0x06
+#define HidUsage_GD_Keypad 0x07
+#define HidUsage_GD_MultiaxisController 0x08
+#define HidUsage_GD_TabletPCSystemControls 0x09
+#define HidUsage_GD_WaterCoolingDevice 0x0a
+#define HidUsage_GD_ComputerChassisDevice 0x0b
+#define HidUsage_GD_WirelessRadioControls 0x0c
+#define HidUsage_GD_PortableDeviceControl 0x0d
+#define HidUsage_GD_SystemMultiAxisController 0x0e
+#define HidUsage_GD_SpatialController 0x0f
+#define HidUsage_GD_AssistiveControl 0x10
+#define HidUsage_GD_DeviceDock 0x11
+#define HidUsage_GD_DockableDevice 0x12
+#define HidUsage_GD_CallStateManagementControl 0x13
+#define HidUsage_GD_X 0x30
+#define HidUsage_GD_Y 0x31
+#define HidUsage_GD_Z 0x32
+#define HidUsage_GD_Rx 0x33
+#define HidUsage_GD_Ry 0x34
+#define HidUsage_GD_Rz 0x35
+#define HidUsage_GD_Slider 0x36
+#define HidUsage_GD_Dial 0x37
+#define HidUsage_GD_Wheel 0x38
+#define HidUsage_GD_HatSwitch 0x39
+#define HidUsage_GD_CountedBuffer 0x3a
+#define HidUsage_GD_ByteCount 0x3b
+#define HidUsage_GD_MotionWakeup 0x3c
+#define HidUsage_GD_Start 0x3d
+#define HidUsage_GD_Select 0x3e
+#define HidUsage_GD_Vx 0x40
+#define HidUsage_GD_Vy 0x41
+#define HidUsage_GD_Vz 0x42
+#define HidUsage_GD_Vbrx 0x43
+#define HidUsage_GD_Vbry 0x44
+#define HidUsage_GD_Vbrz 0x45
+#define HidUsage_GD_Vno 0x46
+#define HidUsage_GD_FeatureNotification 0x47
+#define HidUsage_GD_ResolutionMultiplier 0x48
+#define HidUsage_GD_Qx 0x49
+#define HidUsage_GD_Qy 0x4a
+#define HidUsage_GD_Qz 0x4b
+#define HidUsage_GD_Qw 0x4c
+#define HidUsage_GD_SystemControl 0x80
+#define HidUsage_GD_SystemPowerDown 0x81
+#define HidUsage_GD_SystemSleep 0x82
+#define HidUsage_GD_SystemWakeUp 0x83
+#define HidUsage_GD_SystemContextMenu 0x84
+#define HidUsage_GD_SystemMainMenu 0x85
+#define HidUsage_GD_SystemAppMenu 0x86
+#define HidUsage_GD_SystemMenuHelp 0x87
+#define HidUsage_GD_SystemMenuExit 0x88
+#define HidUsage_GD_SystemMenuSelect 0x89
+#define HidUsage_GD_SystemMenuRight 0x8a
+#define HidUsage_GD_SystemMenuLeft 0x8b
+#define HidUsage_GD_SystemMenuUp 0x8c
+#define HidUsage_GD_SystemMenuDown 0x8d
+#define HidUsage_GD_SystemColdRestart 0x8e
+#define HidUsage_GD_SystemWarmRestart 0x8f
+#define HidUsage_GD_DpadUp 0x90
+#define HidUsage_GD_DpadDown 0x91
+#define HidUsage_GD_DpadRight 0x92
+#define HidUsage_GD_DpadLeft 0x93
+#define HidUsage_GD_IndexTrigger 0x94
+#define HidUsage_GD_PalmTrigger 0x95
+#define HidUsage_GD_Thumbstick 0x96
+#define HidUsage_GD_SystemFunctionShift 0x97
+#define HidUsage_GD_SystemFunctionShiftLock 0x98
+#define HidUsage_GD_SystemFunctionShiftLockIndicator 0x99
+#define HidUsage_GD_SystemDismissNotification 0x9a
+#define HidUsage_GD_SystemDoNotDisturb 0x9b
+#define HidUsage_GD_SystemDock 0xa0
+#define HidUsage_GD_SystemUndock 0xa1
+#define HidUsage_GD_SystemSetup 0xa2
+#define HidUsage_GD_SystemBreak 0xa3
+#define HidUsage_GD_SystemDebuggerBreak 0xa4
+#define HidUsage_GD_ApplicationBreak 0xa5
+#define HidUsage_GD_ApplicationDebuggerBreak 0xa6
+#define HidUsage_GD_SystemSpeakerMute 0xa7
+#define HidUsage_GD_SystemHibernate 0xa8
+#define HidUsage_GD_SystemMicrophoneMute 0xa9
+#define HidUsage_GD_SystemAccessibilityBinding 0xaa
+#define HidUsage_GD_SystemDisplayInvert 0xb0
+#define HidUsage_GD_SystemDisplayInternal 0xb1
+#define HidUsage_GD_SystemDisplayExternal 0xb2
+#define HidUsage_GD_SystemDisplayBoth 0xb3
+#define HidUsage_GD_SystemDisplayDual 0xb4
+#define HidUsage_GD_SystemDisplayToggleIntExtMode 0xb5
+#define HidUsage_GD_SystemDisplaySwapPrimarySecondary 0xb6
+#define HidUsage_GD_SystemDisplayToggleLCDAutoscale 0xb7
+#define HidUsage_GD_SensorZone 0xc0
+#define HidUsage_GD_RPM 0xc1
+#define HidUsage_GD_CoolantLevel 0xc2
+#define HidUsage_GD_CoolantCriticalLevel 0xc3
+#define HidUsage_GD_CoolantPump 0xc4
+#define HidUsage_GD_ChassisEnclosure 0xc5
+#define HidUsage_GD_WirelessRadioButton 0xc6
+#define HidUsage_GD_WirelessRadioLED 0xc7
+#define HidUsage_GD_WirelessRadioSliderSwitch 0xc8
+#define HidUsage_GD_SystemDisplayRotationLockButton 0xc9
+#define HidUsage_GD_SystemDisplayRotationLockSliderSwitch 0xca
+#define HidUsage_GD_ControlEnable 0xcb
+#define HidUsage_GD_DockableDeviceUniqueID 0xd0
+#define HidUsage_GD_DockableDeviceVendorID 0xd1
+#define HidUsage_GD_DockableDevicePrimaryUsagePage 0xd2
+#define HidUsage_GD_DockableDevicePrimaryUsageID 0xd3
+#define HidUsage_GD_DockableDeviceDockingState 0xd4
+#define HidUsage_GD_DockableDeviceDisplayOcclusion 0xd5
+#define HidUsage_GD_DockableDeviceObjectType 0xd6
+#define HidUsage_GD_CallActiveLED 0xe0
+#define HidUsage_GD_CallMuteToggle 0xe1
+#define HidUsage_GD_CallMuteLED 0xe2
+#define HidUsage_SC_FlightSimulationDevice 0x01
+#define HidUsage_SC_AutomobileSimulationDevice 0x02
+#define HidUsage_SC_TankSimulationDevice 0x03
+#define HidUsage_SC_SpaceshipSimulationDevice 0x04
+#define HidUsage_SC_SubmarineSimulationDevice 0x05
+#define HidUsage_SC_SailingSimulationDevice 0x06
+#define HidUsage_SC_MotorcycleSimulationDevice 0x07
+#define HidUsage_SC_SportsSimulationDevice 0x08
+#define HidUsage_SC_AirplaneSimulationDevice 0x09
+#define HidUsage_SC_HelicopterSimulationDevice 0x0a
+#define HidUsage_SC_MagicCarpetSimulationDevice 0x0b
+#define HidUsage_SC_BicycleSimulationDevice 0x0c
+#define HidUsage_SC_FlightControlStick 0x20
+#define HidUsage_SC_FlightStick 0x21
+#define HidUsage_SC_CyclicControl 0x22
+#define HidUsage_SC_CyclicTrim 0x23
+#define HidUsage_SC_FlightYoke 0x24
+#define HidUsage_SC_TrackControl 0x25
+#define HidUsage_SC_Aileron 0xb0
+#define HidUsage_SC_AileronTrim 0xb1
+#define HidUsage_SC_AntiTorqueControl 0xb2
+#define HidUsage_SC_AutopilotEnable 0xb3
+#define HidUsage_SC_ChaffRelease 0xb4
+#define HidUsage_SC_CollectiveControl 0xb5
+#define HidUsage_SC_DiveBrake 0xb6
+#define HidUsage_SC_ElectronicCountermeasures 0xb7
+#define HidUsage_SC_Elevator 0xb8
+#define HidUsage_SC_ElevatorTrim 0xb9
+#define HidUsage_SC_Rudder 0xba
+#define HidUsage_SC_Throttle 0xbb
+#define HidUsage_SC_FlightCommunications 0xbc
+#define HidUsage_SC_FlareRelease 0xbd
+#define HidUsage_SC_LandingGear 0xbe
+#define HidUsage_SC_ToeBrake 0xbf
+#define HidUsage_SC_Trigger 0xc0
+#define HidUsage_SC_WeaponsArm 0xc1
+#define HidUsage_SC_WeaponsSelect 0xc2
+#define HidUsage_SC_WingFlaps 0xc3
+#define HidUsage_SC_Accelerator 0xc4
+#define HidUsage_SC_Brake 0xc5
+#define HidUsage_SC_Clutch 0xc6
+#define HidUsage_SC_Shifter 0xc7
+#define HidUsage_SC_Steering 0xc8
+#define HidUsage_SC_TurretDirection 0xc9
+#define HidUsage_SC_BarrelElevation 0xca
+#define HidUsage_SC_DivePlane 0xcb
+#define HidUsage_SC_Ballast 0xcc
+#define HidUsage_SC_BicycleCrank 0xcd
+#define HidUsage_SC_HandleBars 0xce
+#define HidUsage_SC_FrontBrake 0xcf
+#define HidUsage_SC_RearBrake 0xd0
+#define HidUsage_VRC_Belt 0x01
+#define HidUsage_VRC_BodySuit 0x02
+#define HidUsage_VRC_Flexor 0x03
+#define HidUsage_VRC_Glove 0x04
+#define HidUsage_VRC_HeadTracker 0x05
+#define HidUsage_VRC_HeadMountedDisplay 0x06
+#define HidUsage_VRC_HandTracker 0x07
+#define HidUsage_VRC_Oculometer 0x08
+#define HidUsage_VRC_Vest 0x09
+#define HidUsage_VRC_AnimatronicDevice 0x0a
+#define HidUsage_VRC_StereoEnable 0x20
+#define HidUsage_VRC_DisplayEnable 0x21
+#define HidUsage_SC_BaseballBat 0x01
+#define HidUsage_SC_GolfClub 0x02
+#define HidUsage_SC_RowingMachine 0x03
+#define HidUsage_SC_Treadmill 0x04
+#define HidUsage_SC_Oar 0x30
+#define HidUsage_SC_Slope 0x31
+#define HidUsage_SC_Rate 0x32
+#define HidUsage_SC_StickSpeed 0x33
+#define HidUsage_SC_StickFaceAngle 0x34
+#define HidUsage_SC_StickHeelToe 0x35
+#define HidUsage_SC_StickFollowThrough 0x36
+#define HidUsage_SC_StickTempo 0x37
+#define HidUsage_SC_StickType 0x38
+#define HidUsage_SC_StickHeight 0x39
+#define HidUsage_SC_Putter 0x50
+#define HidUsage_SC_OneIron 0x51
+#define HidUsage_SC_TwoIron 0x52
+#define HidUsage_SC_ThreeIron 0x53
+#define HidUsage_SC_FourIron 0x54
+#define HidUsage_SC_FiveIron 0x55
+#define HidUsage_SC_SixIron 0x56
+#define HidUsage_SC_SevenIron 0x57
+#define HidUsage_SC_EightIron 0x58
+#define HidUsage_SC_NineIron 0x59
+#define HidUsage_SC_One0Iron 0x5a
+#define HidUsage_SC_One1Iron 0x5b
+#define HidUsage_SC_SandWedge 0x5c
+#define HidUsage_SC_LoftWedge 0x5d
+#define HidUsage_SC_PowerWedge 0x5e
+#define HidUsage_SC_OneWood 0x5f
+#define HidUsage_SC_ThreeWood 0x60
+#define HidUsage_SC_FiveWood 0x61
+#define HidUsage_SC_SevenWood 0x62
+#define HidUsage_SC_NineWood 0x63
+#define HidUsage_GC_ThreeDGameController 0x01
+#define HidUsage_GC_PinballDevice 0x02
+#define HidUsage_GC_GunDevice 0x03
+#define HidUsage_GC_PointofView 0x20
+#define HidUsage_GC_TurnRightLeft 0x21
+#define HidUsage_GC_PitchForwardBackward 0x22
+#define HidUsage_GC_RollRightLeft 0x23
+#define HidUsage_GC_MoveRightLeft 0x24
+#define HidUsage_GC_MoveForwardBackward 0x25
+#define HidUsage_GC_MoveUpDown 0x26
+#define HidUsage_GC_LeanRightLeft 0x27
+#define HidUsage_GC_LeanForwardBackward 0x28
+#define HidUsage_GC_HeightofPOV 0x29
+#define HidUsage_GC_Flipper 0x2a
+#define HidUsage_GC_SecondaryFlipper 0x2b
+#define HidUsage_GC_Bump 0x2c
+#define HidUsage_GC_NewGame 0x2d
+#define HidUsage_GC_ShootBall 0x2e
+#define HidUsage_GC_Player 0x2f
+#define HidUsage_GC_GunBolt 0x30
+#define HidUsage_GC_GunClip 0x31
+#define HidUsage_GC_GunSelector 0x32
+#define HidUsage_GC_GunSingleShot 0x33
+#define HidUsage_GC_GunBurst 0x34
+#define HidUsage_GC_GunAutomatic 0x35
+#define HidUsage_GC_GunSafety 0x36
+#define HidUsage_GC_GamepadFireJump 0x37
+#define HidUsage_GC_GamepadTrigger 0x39
+#define HidUsage_GC_FormfittingGamepad 0x3a
+#define HidUsage_GDC_BackgroundNonuserControls 0x01
+#define HidUsage_GDC_BatteryStrength 0x20
+#define HidUsage_GDC_WirelessChannel 0x21
+#define HidUsage_GDC_WirelessID 0x22
+#define HidUsage_GDC_DiscoverWirelessControl 0x23
+#define HidUsage_GDC_SecurityCodeCharacterEntered 0x24
+#define HidUsage_GDC_SecurityCodeCharacterErased 0x25
+#define HidUsage_GDC_SecurityCodeCleared 0x26
+#define HidUsage_GDC_SequenceID 0x27
+#define HidUsage_GDC_SequenceIDReset 0x28
+#define HidUsage_GDC_RFSignalStrength 0x29
+#define HidUsage_GDC_SoftwareVersion 0x2a
+#define HidUsage_GDC_ProtocolVersion 0x2b
+#define HidUsage_GDC_HardwareVersion 0x2c
+#define HidUsage_GDC_Major 0x2d
+#define HidUsage_GDC_Minor 0x2e
+#define HidUsage_GDC_Revision 0x2f
+#define HidUsage_GDC_Handedness 0x30
+#define HidUsage_GDC_EitherHand 0x31
+#define HidUsage_GDC_LeftHand 0x32
+#define HidUsage_GDC_RightHand 0x33
+#define HidUsage_GDC_BothHands 0x34
+#define HidUsage_GDC_GripPoseOffset 0x40
+#define HidUsage_GDC_PointerPoseOffset 0x41
+#define HidUsage_KK_ErrorRollOver 0x01
+#define HidUsage_KK_POSTFail 0x02
+#define HidUsage_KK_ErrorUndefined 0x03
+#define HidUsage_KK_KeyboardA 0x04
+#define HidUsage_KK_KeyboardB 0x05
+#define HidUsage_KK_KeyboardC 0x06
+#define HidUsage_KK_KeyboardD 0x07
+#define HidUsage_KK_KeyboardE 0x08
+#define HidUsage_KK_KeyboardF 0x09
+#define HidUsage_KK_KeyboardG 0x0a
+#define HidUsage_KK_KeyboardH 0x0b
+#define HidUsage_KK_KeyboardI 0x0c
+#define HidUsage_KK_KeyboardJ 0x0d
+#define HidUsage_KK_KeyboardK 0x0e
+#define HidUsage_KK_KeyboardL 0x0f
+#define HidUsage_KK_KeyboardM 0x10
+#define HidUsage_KK_KeyboardN 0x11
+#define HidUsage_KK_KeyboardO 0x12
+#define HidUsage_KK_KeyboardP 0x13
+#define HidUsage_KK_KeyboardQ 0x14
+#define HidUsage_KK_KeyboardR 0x15
+#define HidUsage_KK_KeyboardS 0x16
+#define HidUsage_KK_KeyboardT 0x17
+#define HidUsage_KK_KeyboardU 0x18
+#define HidUsage_KK_KeyboardV 0x19
+#define HidUsage_KK_KeyboardW 0x1a
+#define HidUsage_KK_KeyboardX 0x1b
+#define HidUsage_KK_KeyboardY 0x1c
+#define HidUsage_KK_KeyboardZ 0x1d
+#define HidUsage_KK_Keyboard1andBang 0x1e
+#define HidUsage_KK_Keyboard2andAt 0x1f
+#define HidUsage_KK_Keyboard3andHash 0x20
+#define HidUsage_KK_Keyboard4andDollar 0x21
+#define HidUsage_KK_Keyboard5andPercent 0x22
+#define HidUsage_KK_Keyboard6andCaret 0x23
+#define HidUsage_KK_Keyboard7andAmpersand 0x24
+#define HidUsage_KK_Keyboard8andStar 0x25
+#define HidUsage_KK_Keyboard9andLeftBracket 0x26
+#define HidUsage_KK_Keyboard0andRightBracket 0x27
+#define HidUsage_KK_KeyboardReturnEnter 0x28
+#define HidUsage_KK_KeyboardEscape 0x29
+#define HidUsage_KK_KeyboardDelete 0x2a
+#define HidUsage_KK_KeyboardTab 0x2b
+#define HidUsage_KK_KeyboardSpacebar 0x2c
+#define HidUsage_KK_KeyboardDashandUnderscore 0x2d
+#define HidUsage_KK_KeyboardEqualsandPlus 0x2e
+#define HidUsage_KK_KeyboardLeftBrace 0x2f
+#define HidUsage_KK_KeyboardRightBrace 0x30
+#define HidUsage_KK_KeyboardBackslashandPipe 0x31
+#define HidUsage_KK_KeyboardNonUSHashandTilde 0x32
+#define HidUsage_KK_KeyboardSemiColonandColon 0x33
+#define HidUsage_KK_KeyboardLeftAposandDouble 0x34
+#define HidUsage_KK_KeyboardGraveAccentandTilde 0x35
+#define HidUsage_KK_KeyboardCommaandLessThan 0x36
+#define HidUsage_KK_KeyboardPeriodandGreaterThan 0x37
+#define HidUsage_KK_KeyboardForwardSlashandQuestionMark 0x38
+#define HidUsage_KK_KeyboardCapsLock 0x39
+#define HidUsage_KK_KeyboardF1 0x3a
+#define HidUsage_KK_KeyboardF2 0x3b
+#define HidUsage_KK_KeyboardF3 0x3c
+#define HidUsage_KK_KeyboardF4 0x3d
+#define HidUsage_KK_KeyboardF5 0x3e
+#define HidUsage_KK_KeyboardF6 0x3f
+#define HidUsage_KK_KeyboardF7 0x40
+#define HidUsage_KK_KeyboardF8 0x41
+#define HidUsage_KK_KeyboardF9 0x42
+#define HidUsage_KK_KeyboardF10 0x43
+#define HidUsage_KK_KeyboardF11 0x44
+#define HidUsage_KK_KeyboardF12 0x45
+#define HidUsage_KK_KeyboardPrintScreen 0x46
+#define HidUsage_KK_KeyboardScrollLock 0x47
+#define HidUsage_KK_KeyboardPause 0x48
+#define HidUsage_KK_KeyboardInsert 0x49
+#define HidUsage_KK_KeyboardHome 0x4a
+#define HidUsage_KK_KeyboardPageUp 0x4b
+#define HidUsage_KK_KeyboardDeleteForward 0x4c
+#define HidUsage_KK_KeyboardEnd 0x4d
+#define HidUsage_KK_KeyboardPageDown 0x4e
+#define HidUsage_KK_KeyboardRightArrow 0x4f
+#define HidUsage_KK_KeyboardLeftArrow 0x50
+#define HidUsage_KK_KeyboardDownArrow 0x51
+#define HidUsage_KK_KeyboardUpArrow 0x52
+#define HidUsage_KK_KeypadNumLockandClear 0x53
+#define HidUsage_KK_KeypadForwardSlash 0x54
+#define HidUsage_KK_KeypadStar 0x55
+#define HidUsage_KK_KeypadDash 0x56
+#define HidUsage_KK_KeypadPlus 0x57
+#define HidUsage_KK_KeypadENTER 0x58
+#define HidUsage_KK_Keypad1andEnd 0x59
+#define HidUsage_KK_Keypad2andDownArrow 0x5a
+#define HidUsage_KK_Keypad3andPageDn 0x5b
+#define HidUsage_KK_Keypad4andLeftArrow 0x5c
+#define HidUsage_KK_Keypad5 0x5d
+#define HidUsage_KK_Keypad6andRightArrow 0x5e
+#define HidUsage_KK_Keypad7andHome 0x5f
+#define HidUsage_KK_Keypad8andUpArrow 0x60
+#define HidUsage_KK_Keypad9andPageUp 0x61
+#define HidUsage_KK_Keypad0andInsert 0x62
+#define HidUsage_KK_KeypadPeriodandDelete 0x63
+#define HidUsage_KK_KeyboardNonUSBackslashandPipe 0x64
+#define HidUsage_KK_KeyboardApplication 0x65
+#define HidUsage_KK_KeyboardPower 0x66
+#define HidUsage_KK_KeypadEquals 0x67
+#define HidUsage_KK_KeyboardF13 0x68
+#define HidUsage_KK_KeyboardF14 0x69
+#define HidUsage_KK_KeyboardF15 0x6a
+#define HidUsage_KK_KeyboardF16 0x6b
+#define HidUsage_KK_KeyboardF17 0x6c
+#define HidUsage_KK_KeyboardF18 0x6d
+#define HidUsage_KK_KeyboardF19 0x6e
+#define HidUsage_KK_KeyboardF20 0x6f
+#define HidUsage_KK_KeyboardF21 0x70
+#define HidUsage_KK_KeyboardF22 0x71
+#define HidUsage_KK_KeyboardF23 0x72
+#define HidUsage_KK_KeyboardF24 0x73
+#define HidUsage_KK_KeyboardExecute 0x74
+#define HidUsage_KK_KeyboardHelp 0x75
+#define HidUsage_KK_KeyboardMenu 0x76
+#define HidUsage_KK_KeyboardSelect 0x77
+#define HidUsage_KK_KeyboardStop 0x78
+#define HidUsage_KK_KeyboardAgain 0x79
+#define HidUsage_KK_KeyboardUndo 0x7a
+#define HidUsage_KK_KeyboardCut 0x7b
+#define HidUsage_KK_KeyboardCopy 0x7c
+#define HidUsage_KK_KeyboardPaste 0x7d
+#define HidUsage_KK_KeyboardFind 0x7e
+#define HidUsage_KK_KeyboardMute 0x7f
+#define HidUsage_KK_KeyboardVolumeUp 0x80
+#define HidUsage_KK_KeyboardVolumeDown 0x81
+#define HidUsage_KK_KeyboardLockingCapsLock 0x82
+#define HidUsage_KK_KeyboardLockingNumLock 0x83
+#define HidUsage_KK_KeyboardLockingScrollLock 0x84
+#define HidUsage_KK_KeypadComma 0x85
+#define HidUsage_KK_KeypadEqualSign 0x86
+#define HidUsage_KK_KeyboardInternational1 0x87
+#define HidUsage_KK_KeyboardInternational2 0x88
+#define HidUsage_KK_KeyboardInternational3 0x89
+#define HidUsage_KK_KeyboardInternational4 0x8a
+#define HidUsage_KK_KeyboardInternational5 0x8b
+#define HidUsage_KK_KeyboardInternational6 0x8c
+#define HidUsage_KK_KeyboardInternational7 0x8d
+#define HidUsage_KK_KeyboardInternational8 0x8e
+#define HidUsage_KK_KeyboardInternational9 0x8f
+#define HidUsage_KK_KeyboardLANG1 0x90
+#define HidUsage_KK_KeyboardLANG2 0x91
+#define HidUsage_KK_KeyboardLANG3 0x92
+#define HidUsage_KK_KeyboardLANG4 0x93
+#define HidUsage_KK_KeyboardLANG5 0x94
+#define HidUsage_KK_KeyboardLANG6 0x95
+#define HidUsage_KK_KeyboardLANG7 0x96
+#define HidUsage_KK_KeyboardLANG8 0x97
+#define HidUsage_KK_KeyboardLANG9 0x98
+#define HidUsage_KK_KeyboardAlternateErase 0x99
+#define HidUsage_KK_KeyboardSysReqAttention 0x9a
+#define HidUsage_KK_KeyboardCancel 0x9b
+#define HidUsage_KK_KeyboardClear 0x9c
+#define HidUsage_KK_KeyboardPrior 0x9d
+#define HidUsage_KK_KeyboardReturn 0x9e
+#define HidUsage_KK_KeyboardSeparator 0x9f
+#define HidUsage_KK_KeyboardOut 0xa0
+#define HidUsage_KK_KeyboardOper 0xa1
+#define HidUsage_KK_KeyboardClearAgain 0xa2
+#define HidUsage_KK_KeyboardCrSelProps 0xa3
+#define HidUsage_KK_KeyboardExSel 0xa4
+#define HidUsage_KK_KeypadDouble0 0xb0
+#define HidUsage_KK_KeypadTriple0 0xb1
+#define HidUsage_KK_ThousandsSeparator 0xb2
+#define HidUsage_KK_DecimalSeparator 0xb3
+#define HidUsage_KK_CurrencyUnit 0xb4
+#define HidUsage_KK_CurrencySubunit 0xb5
+#define HidUsage_KK_KeypadLeftBracket 0xb6
+#define HidUsage_KK_KeypadRightBracket 0xb7
+#define HidUsage_KK_KeypadLeftBrace 0xb8
+#define HidUsage_KK_KeypadRightBrace 0xb9
+#define HidUsage_KK_KeypadTab 0xba
+#define HidUsage_KK_KeypadBackspace 0xbb
+#define HidUsage_KK_KeypadA 0xbc
+#define HidUsage_KK_KeypadB 0xbd
+#define HidUsage_KK_KeypadC 0xbe
+#define HidUsage_KK_KeypadD 0xbf
+#define HidUsage_KK_KeypadE 0xc0
+#define HidUsage_KK_KeypadF 0xc1
+#define HidUsage_KK_KeypadXOR 0xc2
+#define HidUsage_KK_KeypadCaret 0xc3
+#define HidUsage_KK_KeypadPercentage 0xc4
+#define HidUsage_KK_KeypadLess 0xc5
+#define HidUsage_KK_KeypadGreater 0xc6
+#define HidUsage_KK_KeypadAmpersand 0xc7
+#define HidUsage_KK_KeypadDoubleAmpersand 0xc8
+#define HidUsage_KK_KeypadBar 0xc9
+#define HidUsage_KK_KeypadDoubleBar 0xca
+#define HidUsage_KK_KeypadColon 0xcb
+#define HidUsage_KK_KeypadHash 0xcc
+#define HidUsage_KK_KeypadSpace 0xcd
+#define HidUsage_KK_KeypadAt 0xce
+#define HidUsage_KK_KeypadBang 0xcf
+#define HidUsage_KK_KeypadMemoryStore 0xd0
+#define HidUsage_KK_KeypadMemoryRecall 0xd1
+#define HidUsage_KK_KeypadMemoryClear 0xd2
+#define HidUsage_KK_KeypadMemoryAdd 0xd3
+#define HidUsage_KK_KeypadMemorySubtract 0xd4
+#define HidUsage_KK_KeypadMemoryMultiply 0xd5
+#define HidUsage_KK_KeypadMemoryDivide 0xd6
+#define HidUsage_KK_KeypadPlusMinus 0xd7
+#define HidUsage_KK_KeypadClear 0xd8
+#define HidUsage_KK_KeypadClearEntry 0xd9
+#define HidUsage_KK_KeypadBinary 0xda
+#define HidUsage_KK_KeypadOctal 0xdb
+#define HidUsage_KK_KeypadDecimal 0xdc
+#define HidUsage_KK_KeypadHexadecimal 0xdd
+#define HidUsage_KK_KeyboardLeftControl 0xe0
+#define HidUsage_KK_KeyboardLeftShift 0xe1
+#define HidUsage_KK_KeyboardLeftAlt 0xe2
+#define HidUsage_KK_KeyboardLeftGUI 0xe3
+#define HidUsage_KK_KeyboardRightControl 0xe4
+#define HidUsage_KK_KeyboardRightShift 0xe5
+#define HidUsage_KK_KeyboardRightAlt 0xe6
+#define HidUsage_KK_KeyboardRightGUI 0xe7
+#define HidUsage_LED_NumLock 0x01
+#define HidUsage_LED_CapsLock 0x02
+#define HidUsage_LED_ScrollLock 0x03
+#define HidUsage_LED_Compose 0x04
+#define HidUsage_LED_Kana 0x05
+#define HidUsage_LED_Power 0x06
+#define HidUsage_LED_Shift 0x07
+#define HidUsage_LED_DoNotDisturb 0x08
+#define HidUsage_LED_Mute 0x09
+#define HidUsage_LED_ToneEnable 0x0a
+#define HidUsage_LED_HighCutFilter 0x0b
+#define HidUsage_LED_LowCutFilter 0x0c
+#define HidUsage_LED_EqualizerEnable 0x0d
+#define HidUsage_LED_SoundFieldOn 0x0e
+#define HidUsage_LED_SurroundOn 0x0f
+#define HidUsage_LED_Repeat 0x10
+#define HidUsage_LED_Stereo 0x11
+#define HidUsage_LED_SamplingRateDetect 0x12
+#define HidUsage_LED_Spinning 0x13
+#define HidUsage_LED_CAV 0x14
+#define HidUsage_LED_CLV 0x15
+#define HidUsage_LED_RecordingFormatDetect 0x16
+#define HidUsage_LED_OffHook 0x17
+#define HidUsage_LED_Ring 0x18
+#define HidUsage_LED_MessageWaiting 0x19
+#define HidUsage_LED_DataMode 0x1a
+#define HidUsage_LED_BatteryOperation 0x1b
+#define HidUsage_LED_BatteryOK 0x1c
+#define HidUsage_LED_BatteryLow 0x1d
+#define HidUsage_LED_Speaker 0x1e
+#define HidUsage_LED_Headset 0x1f
+#define HidUsage_LED_Hold 0x20
+#define HidUsage_LED_Microphone 0x21
+#define HidUsage_LED_Coverage 0x22
+#define HidUsage_LED_NightMode 0x23
+#define HidUsage_LED_SendCalls 0x24
+#define HidUsage_LED_CallPickup 0x25
+#define HidUsage_LED_Conference 0x26
+#define HidUsage_LED_Standby 0x27
+#define HidUsage_LED_CameraOn 0x28
+#define HidUsage_LED_CameraOff 0x29
+#define HidUsage_LED_OnLine 0x2a
+#define HidUsage_LED_OffLine 0x2b
+#define HidUsage_LED_Busy 0x2c
+#define HidUsage_LED_Ready 0x2d
+#define HidUsage_LED_PaperOut 0x2e
+#define HidUsage_LED_PaperJam 0x2f
+#define HidUsage_LED_Remote 0x30
+#define HidUsage_LED_Forward 0x31
+#define HidUsage_LED_Reverse 0x32
+#define HidUsage_LED_Stop 0x33
+#define HidUsage_LED_Rewind 0x34
+#define HidUsage_LED_FastForward 0x35
+#define HidUsage_LED_Play 0x36
+#define HidUsage_LED_Pause 0x37
+#define HidUsage_LED_Record 0x38
+#define HidUsage_LED_Error 0x39
+#define HidUsage_LED_UsageSelectedIndicator 0x3a
+#define HidUsage_LED_UsageInUseIndicator 0x3b
+#define HidUsage_LED_UsageMultiModeIndicator 0x3c
+#define HidUsage_LED_IndicatorOn 0x3d
+#define HidUsage_LED_IndicatorFlash 0x3e
+#define HidUsage_LED_IndicatorSlowBlink 0x3f
+#define HidUsage_LED_IndicatorFastBlink 0x40
+#define HidUsage_LED_IndicatorOff 0x41
+#define HidUsage_LED_FlashOnTime 0x42
+#define HidUsage_LED_SlowBlinkOnTime 0x43
+#define HidUsage_LED_SlowBlinkOffTime 0x44
+#define HidUsage_LED_FastBlinkOnTime 0x45
+#define HidUsage_LED_FastBlinkOffTime 0x46
+#define HidUsage_LED_UsageIndicatorColor 0x47
+#define HidUsage_LED_IndicatorRed 0x48
+#define HidUsage_LED_IndicatorGreen 0x49
+#define HidUsage_LED_IndicatorAmber 0x4a
+#define HidUsage_LED_GenericIndicator 0x4b
+#define HidUsage_LED_SystemSuspend 0x4c
+#define HidUsage_LED_ExternalPowerConnected 0x4d
+#define HidUsage_LED_IndicatorBlue 0x4e
+#define HidUsage_LED_IndicatorOrange 0x4f
+#define HidUsage_LED_GoodStatus 0x50
+#define HidUsage_LED_WarningStatus 0x51
+#define HidUsage_LED_RGBLED 0x52
+#define HidUsage_LED_RedLEDChannel 0x53
+#define HidUsage_LED_BlueLEDChannel 0x54
+#define HidUsage_LED_GreenLEDChannel 0x55
+#define HidUsage_LED_LEDIntensity 0x56
+#define HidUsage_LED_SystemMicrophoneMute 0x57
+#define HidUsage_LED_PlayerIndicator 0x60
+#define HidUsage_LED_Player1 0x61
+#define HidUsage_LED_Player2 0x62
+#define HidUsage_LED_Player3 0x63
+#define HidUsage_LED_Player4 0x64
+#define HidUsage_LED_Player5 0x65
+#define HidUsage_LED_Player6 0x66
+#define HidUsage_LED_Player7 0x67
+#define HidUsage_LED_Player8 0x68
+#define HidUsage_TD_Phone 0x01
+#define HidUsage_TD_AnsweringMachine 0x02
+#define HidUsage_TD_MessageControls 0x03
+#define HidUsage_TD_Handset 0x04
+#define HidUsage_TD_Headset 0x05
+#define HidUsage_TD_TelephonyKeyPad 0x06
+#define HidUsage_TD_ProgrammableButton 0x07
+#define HidUsage_TD_HookSwitch 0x20
+#define HidUsage_TD_Flash 0x21
+#define HidUsage_TD_Feature 0x22
+#define HidUsage_TD_Hold 0x23
+#define HidUsage_TD_Redial 0x24
+#define HidUsage_TD_Transfer 0x25
+#define HidUsage_TD_Drop 0x26
+#define HidUsage_TD_Park 0x27
+#define HidUsage_TD_ForwardCalls 0x28
+#define HidUsage_TD_AlternateFunction 0x29
+#define HidUsage_TD_Line 0x2a
+#define HidUsage_TD_SpeakerPhone 0x2b
+#define HidUsage_TD_Conference 0x2c
+#define HidUsage_TD_RingEnable 0x2d
+#define HidUsage_TD_RingSelect 0x2e
+#define HidUsage_TD_PhoneMute 0x2f
+#define HidUsage_TD_CallerID 0x30
+#define HidUsage_TD_Send 0x31
+#define HidUsage_TD_SpeedDial 0x50
+#define HidUsage_TD_StoreNumber 0x51
+#define HidUsage_TD_RecallNumber 0x52
+#define HidUsage_TD_PhoneDirectory 0x53
+#define HidUsage_TD_VoiceMail 0x70
+#define HidUsage_TD_ScreenCalls 0x71
+#define HidUsage_TD_DoNotDisturb 0x72
+#define HidUsage_TD_Message 0x73
+#define HidUsage_TD_AnswerOnOff 0x74
+#define HidUsage_TD_InsideDialTone 0x90
+#define HidUsage_TD_OutsideDialTone 0x91
+#define HidUsage_TD_InsideRingTone 0x92
+#define HidUsage_TD_OutsideRingTone 0x93
+#define HidUsage_TD_PriorityRingTone 0x94
+#define HidUsage_TD_InsideRingback 0x95
+#define HidUsage_TD_PriorityRingback 0x96
+#define HidUsage_TD_LineBusyTone 0x97
+#define HidUsage_TD_ReorderTone 0x98
+#define HidUsage_TD_CallWaitingTone 0x99
+#define HidUsage_TD_ConfirmationTone1 0x9a
+#define HidUsage_TD_ConfirmationTone2 0x9b
+#define HidUsage_TD_TonesOff 0x9c
+#define HidUsage_TD_OutsideRingback 0x9d
+#define HidUsage_TD_Ringer 0x9e
+#define HidUsage_TD_PhoneKey0 0xb0
+#define HidUsage_TD_PhoneKey1 0xb1
+#define HidUsage_TD_PhoneKey2 0xb2
+#define HidUsage_TD_PhoneKey3 0xb3
+#define HidUsage_TD_PhoneKey4 0xb4
+#define HidUsage_TD_PhoneKey5 0xb5
+#define HidUsage_TD_PhoneKey6 0xb6
+#define HidUsage_TD_PhoneKey7 0xb7
+#define HidUsage_TD_PhoneKey8 0xb8
+#define HidUsage_TD_PhoneKey9 0xb9
+#define HidUsage_TD_PhoneKeyStar 0xba
+#define HidUsage_TD_PhoneKeyPound 0xbb
+#define HidUsage_TD_PhoneKeyA 0xbc
+#define HidUsage_TD_PhoneKeyB 0xbd
+#define HidUsage_TD_PhoneKeyC 0xbe
+#define HidUsage_TD_PhoneKeyD 0xbf
+#define HidUsage_TD_PhoneCallHistoryKey 0xc0
+#define HidUsage_TD_PhoneCallerIDKey 0xc1
+#define HidUsage_TD_PhoneSettingsKey 0xc2
+#define HidUsage_TD_HostControl 0xf0
+#define HidUsage_TD_HostAvailable 0xf1
+#define HidUsage_TD_HostCallActive 0xf2
+#define HidUsage_TD_ActivateHandsetAudio 0xf3
+#define HidUsage_TD_RingType 0xf4
+#define HidUsage_TD_RedialablePhoneNumber 0xf5
+#define HidUsage_TD_StopRingTone 0xf8
+#define HidUsage_TD_PSTNRingTone 0xf9
+#define HidUsage_TD_HostRingTone 0xfa
+#define HidUsage_TD_AlertSoundError 0xfb
+#define HidUsage_TD_AlertSoundConfirm 0xfc
+#define HidUsage_TD_AlertSoundNotification 0xfd
+#define HidUsage_TD_SilentRing 0xfe
+#define HidUsage_TD_EmailMessageWaiting 0x108
+#define HidUsage_TD_VoicemailMessageWaiting 0x109
+#define HidUsage_TD_HostHold 0x10a
+#define HidUsage_TD_IncomingCallHistoryCount 0x110
+#define HidUsage_TD_OutgoingCallHistoryCount 0x111
+#define HidUsage_TD_IncomingCallHistory 0x112
+#define HidUsage_TD_OutgoingCallHistory 0x113
+#define HidUsage_TD_PhoneLocale 0x114
+#define HidUsage_TD_PhoneTimeSecond 0x140
+#define HidUsage_TD_PhoneTimeMinute 0x141
+#define HidUsage_TD_PhoneTimeHour 0x142
+#define HidUsage_TD_PhoneDateDay 0x143
+#define HidUsage_TD_PhoneDateMonth 0x144
+#define HidUsage_TD_PhoneDateYear 0x145
+#define HidUsage_TD_HandsetNickname 0x146
+#define HidUsage_TD_AddressBookID 0x147
+#define HidUsage_TD_CallDuration 0x14a
+#define HidUsage_TD_DualModePhone 0x14b
+#define HidUsage_Con_ConsumerControl 0x01
+#define HidUsage_Con_NumericKeyPad 0x02
+#define HidUsage_Con_ProgrammableButtons 0x03
+#define HidUsage_Con_Microphone 0x04
+#define HidUsage_Con_Headphone 0x05
+#define HidUsage_Con_GraphicEqualizer 0x06
+#define HidUsage_Con_Plus10 0x20
+#define HidUsage_Con_Plus100 0x21
+#define HidUsage_Con_AMPM 0x22
+#define HidUsage_Con_Power 0x30
+#define HidUsage_Con_Reset 0x31
+#define HidUsage_Con_Sleep 0x32
+#define HidUsage_Con_SleepAfter 0x33
+#define HidUsage_Con_SleepMode 0x34
+#define HidUsage_Con_Illumination 0x35
+#define HidUsage_Con_FunctionButtons 0x36
+#define HidUsage_Con_Menu 0x40
+#define HidUsage_Con_MenuPick 0x41
+#define HidUsage_Con_MenuUp 0x42
+#define HidUsage_Con_MenuDown 0x43
+#define HidUsage_Con_MenuLeft 0x44
+#define HidUsage_Con_MenuRight 0x45
+#define HidUsage_Con_MenuEscape 0x46
+#define HidUsage_Con_MenuValueIncrease 0x47
+#define HidUsage_Con_MenuValueDecrease 0x48
+#define HidUsage_Con_DataOnScreen 0x60
+#define HidUsage_Con_ClosedCaption 0x61
+#define HidUsage_Con_ClosedCaptionSelect 0x62
+#define HidUsage_Con_VCRTV 0x63
+#define HidUsage_Con_BroadcastMode 0x64
+#define HidUsage_Con_Snapshot 0x65
+#define HidUsage_Con_Still 0x66
+#define HidUsage_Con_PictureinPictureToggle 0x67
+#define HidUsage_Con_PictureinPictureSwap 0x68
+#define HidUsage_Con_RedMenuButton 0x69
+#define HidUsage_Con_GreenMenuButton 0x6a
+#define HidUsage_Con_BlueMenuButton 0x6b
+#define HidUsage_Con_YellowMenuButton 0x6c
+#define HidUsage_Con_Aspect 0x6d
+#define HidUsage_Con_ThreeDModeSelect 0x6e
+#define HidUsage_Con_DisplayBrightnessIncrement 0x6f
+#define HidUsage_Con_DisplayBrightnessDecrement 0x70
+#define HidUsage_Con_DisplayBrightness 0x71
+#define HidUsage_Con_DisplayBacklightToggle 0x72
+#define HidUsage_Con_DisplaySetBrightnesstoMinimum 0x73
+#define HidUsage_Con_DisplaySetBrightnesstoMaximum 0x74
+#define HidUsage_Con_DisplaySetAutoBrightness 0x75
+#define HidUsage_Con_CameraAccessEnabled 0x76
+#define HidUsage_Con_CameraAccessDisabled 0x77
+#define HidUsage_Con_CameraAccessToggle 0x78
+#define HidUsage_Con_KeyboardBrightnessIncrement 0x79
+#define HidUsage_Con_KeyboardBrightnessDecrement 0x7a
+#define HidUsage_Con_KeyboardBacklightSetLevel 0x7b
+#define HidUsage_Con_KeyboardBacklightOOC 0x7c
+#define HidUsage_Con_KeyboardBacklightSetMinimum 0x7d
+#define HidUsage_Con_KeyboardBacklightSetMaximum 0x7e
+#define HidUsage_Con_KeyboardBacklightAuto 0x7f
+#define HidUsage_Con_Selection 0x80
+#define HidUsage_Con_AssignSelection 0x81
+#define HidUsage_Con_ModeStep 0x82
+#define HidUsage_Con_RecallLast 0x83
+#define HidUsage_Con_EnterChannel 0x84
+#define HidUsage_Con_OrderMovie 0x85
+#define HidUsage_Con_Channel 0x86
+#define HidUsage_Con_MediaSelection 0x87
+#define HidUsage_Con_MediaSelectComputer 0x88
+#define HidUsage_Con_MediaSelectTV 0x89
+#define HidUsage_Con_MediaSelectWWW 0x8a
+#define HidUsage_Con_MediaSelectDVD 0x8b
+#define HidUsage_Con_MediaSelectTelephone 0x8c
+#define HidUsage_Con_MediaSelectProgramGuide 0x8d
+#define HidUsage_Con_MediaSelectVideoPhone 0x8e
+#define HidUsage_Con_MediaSelectGames 0x8f
+#define HidUsage_Con_MediaSelectMessages 0x90
+#define HidUsage_Con_MediaSelectCD 0x91
+#define HidUsage_Con_MediaSelectVCR 0x92
+#define HidUsage_Con_MediaSelectTuner 0x93
+#define HidUsage_Con_Quit 0x94
+#define HidUsage_Con_Help 0x95
+#define HidUsage_Con_MediaSelectTape 0x96
+#define HidUsage_Con_MediaSelectCable 0x97
+#define HidUsage_Con_MediaSelectSatellite 0x98
+#define HidUsage_Con_MediaSelectSecurity 0x99
+#define HidUsage_Con_MediaSelectHome 0x9a
+#define HidUsage_Con_MediaSelectCall 0x9b
+#define HidUsage_Con_ChannelIncrement 0x9c
+#define HidUsage_Con_ChannelDecrement 0x9d
+#define HidUsage_Con_MediaSelectSAP 0x9e
+#define HidUsage_Con_VCRPlus 0xa0
+#define HidUsage_Con_Once 0xa1
+#define HidUsage_Con_Daily 0xa2
+#define HidUsage_Con_Weekly 0xa3
+#define HidUsage_Con_Monthly 0xa4
+#define HidUsage_Con_Play 0xb0
+#define HidUsage_Con_Pause 0xb1
+#define HidUsage_Con_Record 0xb2
+#define HidUsage_Con_FastForward 0xb3
+#define HidUsage_Con_Rewind 0xb4
+#define HidUsage_Con_ScanNextTrack 0xb5
+#define HidUsage_Con_ScanPreviousTrack 0xb6
+#define HidUsage_Con_Stop 0xb7
+#define HidUsage_Con_Eject 0xb8
+#define HidUsage_Con_RandomPlay 0xb9
+#define HidUsage_Con_SelectDisc 0xba
+#define HidUsage_Con_EnterDisc 0xbb
+#define HidUsage_Con_Repeat 0xbc
+#define HidUsage_Con_Tracking 0xbd
+#define HidUsage_Con_TrackNormal 0xbe
+#define HidUsage_Con_SlowTracking 0xbf
+#define HidUsage_Con_FrameForward 0xc0
+#define HidUsage_Con_FrameBack 0xc1
+#define HidUsage_Con_Mark 0xc2
+#define HidUsage_Con_ClearMark 0xc3
+#define HidUsage_Con_RepeatFromMark 0xc4
+#define HidUsage_Con_ReturnToMark 0xc5
+#define HidUsage_Con_SearchMarkForward 0xc6
+#define HidUsage_Con_SearchMarkBackwards 0xc7
+#define HidUsage_Con_CounterReset 0xc8
+#define HidUsage_Con_ShowCounter 0xc9
+#define HidUsage_Con_TrackingIncrement 0xca
+#define HidUsage_Con_TrackingDecrement 0xcb
+#define HidUsage_Con_StopEject 0xcc
+#define HidUsage_Con_PlayPause 0xcd
+#define HidUsage_Con_PlaySkip 0xce
+#define HidUsage_Con_VoiceCommand 0xcf
+#define HidUsage_Con_InvokeCaptureInterface 0xd0
+#define HidUsage_Con_StartorStopGameRecording 0xd1
+#define HidUsage_Con_HistoricalGameCapture 0xd2
+#define HidUsage_Con_CaptureGameScreenshot 0xd3
+#define HidUsage_Con_ShoworHideRecordingIndicator 0xd4
+#define HidUsage_Con_StartorStopMicrophoneCapture 0xd5
+#define HidUsage_Con_StartorStopCameraCapture 0xd6
+#define HidUsage_Con_StartorStopGameBroadcast 0xd7
+#define HidUsage_Con_StartorStopVoiceDictationSession 0xd8
+#define HidUsage_Con_InvokeDismissEmojiPicker 0xd9
+#define HidUsage_Con_Volume 0xe0
+#define HidUsage_Con_Balance 0xe1
+#define HidUsage_Con_Mute 0xe2
+#define HidUsage_Con_Bass 0xe3
+#define HidUsage_Con_Treble 0xe4
+#define HidUsage_Con_BassBoost 0xe5
+#define HidUsage_Con_SurroundMode 0xe6
+#define HidUsage_Con_Loudness 0xe7
+#define HidUsage_Con_MPX 0xe8
+#define HidUsage_Con_VolumeIncrement 0xe9
+#define HidUsage_Con_VolumeDecrement 0xea
+#define HidUsage_Con_SpeedSelect 0xf0
+#define HidUsage_Con_PlaybackSpeed 0xf1
+#define HidUsage_Con_StandardPlay 0xf2
+#define HidUsage_Con_LongPlay 0xf3
+#define HidUsage_Con_ExtendedPlay 0xf4
+#define HidUsage_Con_Slow 0xf5
+#define HidUsage_Con_FanEnable 0x100
+#define HidUsage_Con_FanSpeed 0x101
+#define HidUsage_Con_LightEnable 0x102
+#define HidUsage_Con_LightIlluminationLevel 0x103
+#define HidUsage_Con_ClimateControlEnable 0x104
+#define HidUsage_Con_RoomTemperature 0x105
+#define HidUsage_Con_SecurityEnable 0x106
+#define HidUsage_Con_FireAlarm 0x107
+#define HidUsage_Con_PoliceAlarm 0x108
+#define HidUsage_Con_Proximity 0x109
+#define HidUsage_Con_Motion 0x10a
+#define HidUsage_Con_DuressAlarm 0x10b
+#define HidUsage_Con_HoldupAlarm 0x10c
+#define HidUsage_Con_MedicalAlarm 0x10d
+#define HidUsage_Con_BalanceRight 0x150
+#define HidUsage_Con_BalanceLeft 0x151
+#define HidUsage_Con_BassIncrement 0x152
+#define HidUsage_Con_BassDecrement 0x153
+#define HidUsage_Con_TrebleIncrement 0x154
+#define HidUsage_Con_TrebleDecrement 0x155
+#define HidUsage_Con_SpeakerSystem 0x160
+#define HidUsage_Con_ChannelLeft 0x161
+#define HidUsage_Con_ChannelRight 0x162
+#define HidUsage_Con_ChannelCenter 0x163
+#define HidUsage_Con_ChannelFront 0x164
+#define HidUsage_Con_ChannelCenterFront 0x165
+#define HidUsage_Con_ChannelSide 0x166
+#define HidUsage_Con_ChannelSurround 0x167
+#define HidUsage_Con_ChannelLowFrequencyEnhancement 0x168
+#define HidUsage_Con_ChannelTop 0x169
+#define HidUsage_Con_ChannelUnknown 0x16a
+#define HidUsage_Con_Subchannel 0x170
+#define HidUsage_Con_SubchannelIncrement 0x171
+#define HidUsage_Con_SubchannelDecrement 0x172
+#define HidUsage_Con_AlternateAudioIncrement 0x173
+#define HidUsage_Con_AlternateAudioDecrement 0x174
+#define HidUsage_Con_ApplicationLaunchButtons 0x180
+#define HidUsage_Con_ALLaunchButtonConfigurationTool 0x181
+#define HidUsage_Con_ALProgrammableButtonConfiguration 0x182
+#define HidUsage_Con_ALConsumerControlConfiguration 0x183
+#define HidUsage_Con_ALWordProcessor 0x184
+#define HidUsage_Con_ALTextEditor 0x185
+#define HidUsage_Con_ALSpreadsheet 0x186
+#define HidUsage_Con_ALGraphicsEditor 0x187
+#define HidUsage_Con_ALPresentationApp 0x188
+#define HidUsage_Con_ALDatabaseApp 0x189
+#define HidUsage_Con_ALEmailReader 0x18a
+#define HidUsage_Con_ALNewsreader 0x18b
+#define HidUsage_Con_ALVoicemail 0x18c
+#define HidUsage_Con_ALContactsAddressBook 0x18d
+#define HidUsage_Con_ALCalendarSchedule 0x18e
+#define HidUsage_Con_ALTaskProjectManager 0x18f
+#define HidUsage_Con_ALLogJournalTimecard 0x190
+#define HidUsage_Con_ALCheckbookFinance 0x191
+#define HidUsage_Con_ALCalculator 0x192
+#define HidUsage_Con_ALAVCapturePlayback 0x193
+#define HidUsage_Con_ALLocalMachineBrowser 0x194
+#define HidUsage_Con_ALLANWANBrowser 0x195
+#define HidUsage_Con_ALInternetBrowser 0x196
+#define HidUsage_Con_ALRemoteNetworkingISPConnect 0x197
+#define HidUsage_Con_ALNetworkConference 0x198
+#define HidUsage_Con_ALNetworkChat 0x199
+#define HidUsage_Con_ALTelephonyDialer 0x19a
+#define HidUsage_Con_ALLogon 0x19b
+#define HidUsage_Con_ALLogoff 0x19c
+#define HidUsage_Con_ALLogonLogoff 0x19d
+#define HidUsage_Con_ALTerminalLockScreensaver 0x19e
+#define HidUsage_Con_ALControlPanel 0x19f
+#define HidUsage_Con_ALCommandLineProcessorRun 0x1a0
+#define HidUsage_Con_ALProcessTaskManager 0x1a1
+#define HidUsage_Con_ALSelectTaskApplication 0x1a2
+#define HidUsage_Con_ALNextTaskApplication 0x1a3
+#define HidUsage_Con_ALPreviousTaskApplication 0x1a4
+#define HidUsage_Con_ALPreemptiveHaltTaskApplication 0x1a5
+#define HidUsage_Con_ALIntegratedHelpCenter 0x1a6
+#define HidUsage_Con_ALDocuments 0x1a7
+#define HidUsage_Con_ALThesaurus 0x1a8
+#define HidUsage_Con_ALDictionary 0x1a9
+#define HidUsage_Con_ALDesktop 0x1aa
+#define HidUsage_Con_ALSpellCheck 0x1ab
+#define HidUsage_Con_ALGrammarCheck 0x1ac
+#define HidUsage_Con_ALWirelessStatus 0x1ad
+#define HidUsage_Con_ALKeyboardLayout 0x1ae
+#define HidUsage_Con_ALVirusProtection 0x1af
+#define HidUsage_Con_ALEncryption 0x1b0
+#define HidUsage_Con_ALScreenSaver 0x1b1
+#define HidUsage_Con_ALAlarms 0x1b2
+#define HidUsage_Con_ALClock 0x1b3
+#define HidUsage_Con_ALFileBrowser 0x1b4
+#define HidUsage_Con_ALPowerStatus 0x1b5
+#define HidUsage_Con_ALImageBrowser 0x1b6
+#define HidUsage_Con_ALAudioBrowser 0x1b7
+#define HidUsage_Con_ALMovieBrowser 0x1b8
+#define HidUsage_Con_ALDigitalRightsManager 0x1b9
+#define HidUsage_Con_ALDigitalWallet 0x1ba
+#define HidUsage_Con_ALInstantMessaging 0x1bc
+#define HidUsage_Con_ALOEMFeaturesTipsTutorialBrowser 0x1bd
+#define HidUsage_Con_ALOEMHelp 0x1be
+#define HidUsage_Con_ALOnlineCommunity 0x1bf
+#define HidUsage_Con_ALEntertainmentContentBrowser 0x1c0
+#define HidUsage_Con_ALOnlineShoppingBrowser 0x1c1
+#define HidUsage_Con_ALSmartCardInformationHelp 0x1c2
+#define HidUsage_Con_ALMarketMonitorFinanceBrowser 0x1c3
+#define HidUsage_Con_ALCustomizedCorporateNewsBrowser 0x1c4
+#define HidUsage_Con_ALOnlineActivityBrowser 0x1c5
+#define HidUsage_Con_ALResearchSearchBrowser 0x1c6
+#define HidUsage_Con_ALAudioPlayer 0x1c7
+#define HidUsage_Con_ALMessageStatus 0x1c8
+#define HidUsage_Con_ALContactSync 0x1c9
+#define HidUsage_Con_ALNavigation 0x1ca
+#define HidUsage_Con_ALContextawareDesktopAssistant 0x1cb
+#define HidUsage_Con_GenericGUIApplicationControls 0x200
+#define HidUsage_Con_ACNew 0x201
+#define HidUsage_Con_ACOpen 0x202
+#define HidUsage_Con_ACClose 0x203
+#define HidUsage_Con_ACExit 0x204
+#define HidUsage_Con_ACMaximize 0x205
+#define HidUsage_Con_ACMinimize 0x206
+#define HidUsage_Con_ACSave 0x207
+#define HidUsage_Con_ACPrint 0x208
+#define HidUsage_Con_ACProperties 0x209
+#define HidUsage_Con_ACUndo 0x21a
+#define HidUsage_Con_ACCopy 0x21b
+#define HidUsage_Con_ACCut 0x21c
+#define HidUsage_Con_ACPaste 0x21d
+#define HidUsage_Con_ACSelectAll 0x21e
+#define HidUsage_Con_ACFind 0x21f
+#define HidUsage_Con_ACFindandReplace 0x220
+#define HidUsage_Con_ACSearch 0x221
+#define HidUsage_Con_ACGoTo 0x222
+#define HidUsage_Con_ACHome 0x223
+#define HidUsage_Con_ACBack 0x224
+#define HidUsage_Con_ACForward 0x225
+#define HidUsage_Con_ACStop 0x226
+#define HidUsage_Con_ACRefresh 0x227
+#define HidUsage_Con_ACPreviousLink 0x228
+#define HidUsage_Con_ACNextLink 0x229
+#define HidUsage_Con_ACBookmarks 0x22a
+#define HidUsage_Con_ACHistory 0x22b
+#define HidUsage_Con_ACSubscriptions 0x22c
+#define HidUsage_Con_ACZoomIn 0x22d
+#define HidUsage_Con_ACZoomOut 0x22e
+#define HidUsage_Con_ACZoom 0x22f
+#define HidUsage_Con_ACFullScreenView 0x230
+#define HidUsage_Con_ACNormalView 0x231
+#define HidUsage_Con_ACViewToggle 0x232
+#define HidUsage_Con_ACScrollUp 0x233
+#define HidUsage_Con_ACScrollDown 0x234
+#define HidUsage_Con_ACScroll 0x235
+#define HidUsage_Con_ACPanLeft 0x236
+#define HidUsage_Con_ACPanRight 0x237
+#define HidUsage_Con_ACPan 0x238
+#define HidUsage_Con_ACNewWindow 0x239
+#define HidUsage_Con_ACTileHorizontally 0x23a
+#define HidUsage_Con_ACTileVertically 0x23b
+#define HidUsage_Con_ACFormat 0x23c
+#define HidUsage_Con_ACEdit 0x23d
+#define HidUsage_Con_ACBold 0x23e
+#define HidUsage_Con_ACItalics 0x23f
+#define HidUsage_Con_ACUnderline 0x240
+#define HidUsage_Con_ACStrikethrough 0x241
+#define HidUsage_Con_ACSubscript 0x242
+#define HidUsage_Con_ACSuperscript 0x243
+#define HidUsage_Con_ACAllCaps 0x244
+#define HidUsage_Con_ACRotate 0x245
+#define HidUsage_Con_ACResize 0x246
+#define HidUsage_Con_ACFlipHorizontal 0x247
+#define HidUsage_Con_ACFlipVertical 0x248
+#define HidUsage_Con_ACMirrorHorizontal 0x249
+#define HidUsage_Con_ACMirrorVertical 0x24a
+#define HidUsage_Con_ACFontSelect 0x24b
+#define HidUsage_Con_ACFontColor 0x24c
+#define HidUsage_Con_ACFontSize 0x24d
+#define HidUsage_Con_ACJustifyLeft 0x24e
+#define HidUsage_Con_ACJustifyCenterH 0x24f
+#define HidUsage_Con_ACJustifyRight 0x250
+#define HidUsage_Con_ACJustifyBlockH 0x251
+#define HidUsage_Con_ACJustifyTop 0x252
+#define HidUsage_Con_ACJustifyCenterV 0x253
+#define HidUsage_Con_ACJustifyBottom 0x254
+#define HidUsage_Con_ACJustifyBlockV 0x255
+#define HidUsage_Con_ACIndentDecrease 0x256
+#define HidUsage_Con_ACIndentIncrease 0x257
+#define HidUsage_Con_ACNumberedList 0x258
+#define HidUsage_Con_ACRestartNumbering 0x259
+#define HidUsage_Con_ACBulletedList 0x25a
+#define HidUsage_Con_ACPromote 0x25b
+#define HidUsage_Con_ACDemote 0x25c
+#define HidUsage_Con_ACYes 0x25d
+#define HidUsage_Con_ACNo 0x25e
+#define HidUsage_Con_ACCancel 0x25f
+#define HidUsage_Con_ACCatalog 0x260
+#define HidUsage_Con_ACBuyCheckout 0x261
+#define HidUsage_Con_ACAddtoCart 0x262
+#define HidUsage_Con_ACExpand 0x263
+#define HidUsage_Con_ACExpandAll 0x264
+#define HidUsage_Con_ACCollapse 0x265
+#define HidUsage_Con_ACCollapseAll 0x266
+#define HidUsage_Con_ACPrintPreview 0x267
+#define HidUsage_Con_ACPasteSpecial 0x268
+#define HidUsage_Con_ACInsertMode 0x269
+#define HidUsage_Con_ACDelete 0x26a
+#define HidUsage_Con_ACLock 0x26b
+#define HidUsage_Con_ACUnlock 0x26c
+#define HidUsage_Con_ACProtect 0x26d
+#define HidUsage_Con_ACUnprotect 0x26e
+#define HidUsage_Con_ACAttachComment 0x26f
+#define HidUsage_Con_ACDeleteComment 0x270
+#define HidUsage_Con_ACViewComment 0x271
+#define HidUsage_Con_ACSelectWord 0x272
+#define HidUsage_Con_ACSelectSentence 0x273
+#define HidUsage_Con_ACSelectParagraph 0x274
+#define HidUsage_Con_ACSelectColumn 0x275
+#define HidUsage_Con_ACSelectRow 0x276
+#define HidUsage_Con_ACSelectTable 0x277
+#define HidUsage_Con_ACSelectObject 0x278
+#define HidUsage_Con_ACRedoRepeat 0x279
+#define HidUsage_Con_ACSort 0x27a
+#define HidUsage_Con_ACSortAscending 0x27b
+#define HidUsage_Con_ACSortDescending 0x27c
+#define HidUsage_Con_ACFilter 0x27d
+#define HidUsage_Con_ACSetClock 0x27e
+#define HidUsage_Con_ACViewClock 0x27f
+#define HidUsage_Con_ACSelectTimeZone 0x280
+#define HidUsage_Con_ACEditTimeZones 0x281
+#define HidUsage_Con_ACSetAlarm 0x282
+#define HidUsage_Con_ACClearAlarm 0x283
+#define HidUsage_Con_ACSnoozeAlarm 0x284
+#define HidUsage_Con_ACResetAlarm 0x285
+#define HidUsage_Con_ACSynchronize 0x286
+#define HidUsage_Con_ACSendReceive 0x287
+#define HidUsage_Con_ACSendTo 0x288
+#define HidUsage_Con_ACReply 0x289
+#define HidUsage_Con_ACReplyAll 0x28a
+#define HidUsage_Con_ACForwardMsg 0x28b
+#define HidUsage_Con_ACSend 0x28c
+#define HidUsage_Con_ACAttachFile 0x28d
+#define HidUsage_Con_ACUpload 0x28e
+#define HidUsage_Con_ACDownloadSaveTargetAs 0x28f
+#define HidUsage_Con_ACSetBorders 0x290
+#define HidUsage_Con_ACInsertRow 0x291
+#define HidUsage_Con_ACInsertColumn 0x292
+#define HidUsage_Con_ACInsertFile 0x293
+#define HidUsage_Con_ACInsertPicture 0x294
+#define HidUsage_Con_ACInsertObject 0x295
+#define HidUsage_Con_ACInsertSymbol 0x296
+#define HidUsage_Con_ACSaveandClose 0x297
+#define HidUsage_Con_ACRename 0x298
+#define HidUsage_Con_ACMerge 0x299
+#define HidUsage_Con_ACSplit 0x29a
+#define HidUsage_Con_ACDisributeHorizontally 0x29b
+#define HidUsage_Con_ACDistributeVertically 0x29c
+#define HidUsage_Con_ACNextKeyboardLayoutSelect 0x29d
+#define HidUsage_Con_ACNavigationGuidance 0x29e
+#define HidUsage_Con_ACDesktopShowAllWindows 0x29f
+#define HidUsage_Con_ACSoftKeyLeft 0x2a0
+#define HidUsage_Con_ACSoftKeyRight 0x2a1
+#define HidUsage_Con_ACDesktopShowAllApplications 0x2a2
+#define HidUsage_Con_ACIdleKeepAlive 0x2b0
+#define HidUsage_Con_ExtendedKeyboardAttributesCollection 0x2c0
+#define HidUsage_Con_KeyboardFormFactor 0x2c1
+#define HidUsage_Con_KeyboardKeyType 0x2c2
+#define HidUsage_Con_KeyboardPhysicalLayout 0x2c3
+#define HidUsage_Con_VendorSpecificKeyboardPhysicalLayout 0x2c4
+#define HidUsage_Con_KeyboardIETFLanguageTagIndex 0x2c5
+#define HidUsage_Con_ImplementedKeyboardInputAssistControls 0x2c6
+#define HidUsage_Con_KeyboardInputAssistPrevious 0x2c7
+#define HidUsage_Con_KeyboardInputAssistNext 0x2c8
+#define HidUsage_Con_KeyboardInputAssistPreviousGroup 0x2c9
+#define HidUsage_Con_KeyboardInputAssistNextGroup 0x2ca
+#define HidUsage_Con_KeyboardInputAssistAccept 0x2cb
+#define HidUsage_Con_KeyboardInputAssistCancel 0x2cc
+#define HidUsage_Con_PrivacyScreenToggle 0x2d0
+#define HidUsage_Con_PrivacyScreenLevelDecrement 0x2d1
+#define HidUsage_Con_PrivacyScreenLevelIncrement 0x2d2
+#define HidUsage_Con_PrivacyScreenLevelMinimum 0x2d3
+#define HidUsage_Con_PrivacyScreenLevelMaximum 0x2d4
+#define HidUsage_Con_ContactEdited 0x500
+#define HidUsage_Con_ContactAdded 0x501
+#define HidUsage_Con_ContactRecordActive 0x502
+#define HidUsage_Con_ContactIndex 0x503
+#define HidUsage_Con_ContactNickname 0x504
+#define HidUsage_Con_ContactFirstName 0x505
+#define HidUsage_Con_ContactLastName 0x506
+#define HidUsage_Con_ContactFullName 0x507
+#define HidUsage_Con_ContactPhoneNumberPersonal 0x508
+#define HidUsage_Con_ContactPhoneNumberBusiness 0x509
+#define HidUsage_Con_ContactPhoneNumberMobile 0x50a
+#define HidUsage_Con_ContactPhoneNumberPager 0x50b
+#define HidUsage_Con_ContactPhoneNumberFax 0x50c
+#define HidUsage_Con_ContactPhoneNumberOther 0x50d
+#define HidUsage_Con_ContactEmailPersonal 0x50e
+#define HidUsage_Con_ContactEmailBusiness 0x50f
+#define HidUsage_Con_ContactEmailOther 0x510
+#define HidUsage_Con_ContactEmailMain 0x511
+#define HidUsage_Con_ContactSpeedDialNumber 0x512
+#define HidUsage_Con_ContactStatusFlag 0x513
+#define HidUsage_Con_ContactMisc 0x514
+#define HidUsage_Dig_Digitizer 0x01
+#define HidUsage_Dig_Pen 0x02
+#define HidUsage_Dig_LightPen 0x03
+#define HidUsage_Dig_TouchScreen 0x04
+#define HidUsage_Dig_TouchPad 0x05
+#define HidUsage_Dig_Whiteboard 0x06
+#define HidUsage_Dig_CoordinateMeasuringMachine 0x07
+#define HidUsage_Dig_ThreeDDigitizer 0x08
+#define HidUsage_Dig_StereoPlotter 0x09
+#define HidUsage_Dig_ArticulatedArm 0x0a
+#define HidUsage_Dig_Armature 0x0b
+#define HidUsage_Dig_MultiplePointDigitizer 0x0c
+#define HidUsage_Dig_FreeSpaceWand 0x0d
+#define HidUsage_Dig_DeviceConfiguration 0x0e
+#define HidUsage_Dig_CapacitiveHeatMapDigitizer 0x0f
+#define HidUsage_Dig_Stylus 0x20
+#define HidUsage_Dig_Puck 0x21
+#define HidUsage_Dig_Finger 0x22
+#define HidUsage_Dig_Devicesettings 0x23
+#define HidUsage_Dig_CharacterGesture 0x24
+#define HidUsage_Dig_TipPressure 0x30
+#define HidUsage_Dig_BarrelPressure 0x31
+#define HidUsage_Dig_InRange 0x32
+#define HidUsage_Dig_Touch 0x33
+#define HidUsage_Dig_Untouch 0x34
+#define HidUsage_Dig_Tap 0x35
+#define HidUsage_Dig_Quality 0x36
+#define HidUsage_Dig_DataValid 0x37
+#define HidUsage_Dig_TransducerIndex 0x38
+#define HidUsage_Dig_TabletFunctionKeys 0x39
+#define HidUsage_Dig_ProgramChangeKeys 0x3a
+#define HidUsage_Dig_BatteryStrength 0x3b
+#define HidUsage_Dig_Invert 0x3c
+#define HidUsage_Dig_XTilt 0x3d
+#define HidUsage_Dig_YTilt 0x3e
+#define HidUsage_Dig_Azimuth 0x3f
+#define HidUsage_Dig_Altitude 0x40
+#define HidUsage_Dig_Twist 0x41
+#define HidUsage_Dig_TipSwitch 0x42
+#define HidUsage_Dig_SecondaryTipSwitch 0x43
+#define HidUsage_Dig_BarrelSwitch 0x44
+#define HidUsage_Dig_Eraser 0x45
+#define HidUsage_Dig_TabletPick 0x46
+#define HidUsage_Dig_TouchValid 0x47
+#define HidUsage_Dig_Width 0x48
+#define HidUsage_Dig_Height 0x49
+#define HidUsage_Dig_ContactIdentifier 0x51
+#define HidUsage_Dig_DeviceMode 0x52
+#define HidUsage_Dig_DeviceIdentifier 0x53
+#define HidUsage_Dig_ContactCount 0x54
+#define HidUsage_Dig_ContactCountMaximum 0x55
+#define HidUsage_Dig_ScanTime 0x56
+#define HidUsage_Dig_SurfaceSwitch 0x57
+#define HidUsage_Dig_ButtonSwitch 0x58
+#define HidUsage_Dig_PadType 0x59
+#define HidUsage_Dig_SecondaryBarrelSwitch 0x5a
+#define HidUsage_Dig_TransducerSerialNumber 0x5b
+#define HidUsage_Dig_PreferredColor 0x5c
+#define HidUsage_Dig_PreferredColorisLocked 0x5d
+#define HidUsage_Dig_PreferredLineWidth 0x5e
+#define HidUsage_Dig_PreferredLineWidthisLocked 0x5f
+#define HidUsage_Dig_LatencyMode 0x60
+#define HidUsage_Dig_GestureCharacterQuality 0x61
+#define HidUsage_Dig_CharacterGestureDataLength 0x62
+#define HidUsage_Dig_CharacterGestureData 0x63
+#define HidUsage_Dig_GestureCharacterEncoding 0x64
+#define HidUsage_Dig_UTF8CharacterGestureEncoding 0x65
+#define HidUsage_Dig_UTF16LittleEndianCharacterGestureEncoding 0x66
+#define HidUsage_Dig_UTF16BigEndianCharacterGestureEncoding 0x67
+#define HidUsage_Dig_UTF32LittleEndianCharacterGestureEncoding 0x68
+#define HidUsage_Dig_UTF32BigEndianCharacterGestureEncoding 0x69
+#define HidUsage_Dig_CapacitiveHeatMapProtocolVendorID 0x6a
+#define HidUsage_Dig_CapacitiveHeatMapProtocolVersion 0x6b
+#define HidUsage_Dig_CapacitiveHeatMapFrameData 0x6c
+#define HidUsage_Dig_GestureCharacterEnable 0x6d
+#define HidUsage_Dig_TransducerSerialNumberPart2 0x6e
+#define HidUsage_Dig_NoPreferredColor 0x6f
+#define HidUsage_Dig_PreferredLineStyle 0x70
+#define HidUsage_Dig_PreferredLineStyleisLocked 0x71
+#define HidUsage_Dig_Ink 0x72
+#define HidUsage_Dig_Pencil 0x73
+#define HidUsage_Dig_Highlighter 0x74
+#define HidUsage_Dig_ChiselMarker 0x75
+#define HidUsage_Dig_Brush 0x76
+#define HidUsage_Dig_NoPreference 0x77
+#define HidUsage_Dig_DigitizerDiagnostic 0x80
+#define HidUsage_Dig_DigitizerError 0x81
+#define HidUsage_Dig_ErrNormalStatus 0x82
+#define HidUsage_Dig_ErrTransducersExceeded 0x83
+#define HidUsage_Dig_ErrFullTransFeaturesUnavailable 0x84
+#define HidUsage_Dig_ErrChargeLow 0x85
+#define HidUsage_Dig_TransducerSoftwareInfo 0x90
+#define HidUsage_Dig_TransducerVendorId 0x91
+#define HidUsage_Dig_TransducerProductId 0x92
+#define HidUsage_Dig_DeviceSupportedProtocols 0x93
+#define HidUsage_Dig_TransducerSupportedProtocols 0x94
+#define HidUsage_Dig_NoProtocol 0x95
+#define HidUsage_Dig_WacomAESProtocol 0x96
+#define HidUsage_Dig_USIProtocol 0x97
+#define HidUsage_Dig_MicrosoftPenProtocol 0x98
+#define HidUsage_Dig_SupportedReportRates 0xa0
+#define HidUsage_Dig_ReportRate 0xa1
+#define HidUsage_Dig_TransducerConnected 0xa2
+#define HidUsage_Dig_SwitchDisabled 0xa3
+#define HidUsage_Dig_SwitchUnimplemented 0xa4
+#define HidUsage_Dig_TransducerSwitches 0xa5
+#define HidUsage_Dig_TransducerIndexSelector 0xa6
+#define HidUsage_Dig_ButtonPressThreshold 0xb0
+#define HidUsage_Hap_SimpleHapticController 0x01
+#define HidUsage_Hap_WaveformList 0x10
+#define HidUsage_Hap_DurationList 0x11
+#define HidUsage_Hap_AutoTrigger 0x20
+#define HidUsage_Hap_ManualTrigger 0x21
+#define HidUsage_Hap_AutoTriggerAssociatedControl 0x22
+#define HidUsage_Hap_Intensity 0x23
+#define HidUsage_Hap_RepeatCount 0x24
+#define HidUsage_Hap_RetriggerPeriod 0x25
+#define HidUsage_Hap_WaveformVendorPage 0x26
+#define HidUsage_Hap_WaveformVendorID 0x27
+#define HidUsage_Hap_WaveformCutoffTime 0x28
+#define HidUsage_Hap_WaveformNone 0x1001
+#define HidUsage_Hap_WaveformStop 0x1002
+#define HidUsage_Hap_WaveformClick 0x1003
+#define HidUsage_Hap_WaveformBuzzContinuous 0x1004
+#define HidUsage_Hap_WaveformRumbleContinuous 0x1005
+#define HidUsage_Hap_WaveformPress 0x1006
+#define HidUsage_Hap_WaveformRelease 0x1007
+#define HidUsage_Hap_WaveformHover 0x1008
+#define HidUsage_Hap_WaveformSuccess 0x1009
+#define HidUsage_Hap_WaveformError 0x100a
+#define HidUsage_Hap_WaveformInkContinuous 0x100b
+#define HidUsage_Hap_WaveformPencilContinuous 0x100c
+#define HidUsage_Hap_WaveformMarkerContinuous 0x100d
+#define HidUsage_Hap_WaveformChiselMarkerContinuous 0x100e
+#define HidUsage_Hap_WaveformBrushContinuous 0x100f
+#define HidUsage_Hap_WaveformEraserContinuous 0x1010
+#define HidUsage_Hap_WaveformSparkleContinuous 0x1011
+#define HidUsage_PID_PhysicalInputDevice 0x01
+#define HidUsage_PID_Normal 0x20
+#define HidUsage_PID_SetEffectReport 0x21
+#define HidUsage_PID_EffectParameterBlockIndex 0x22
+#define HidUsage_PID_ParameterBlockOffset 0x23
+#define HidUsage_PID_ROMFlag 0x24
+#define HidUsage_PID_EffectType 0x25
+#define HidUsage_PID_ETConstantForce 0x26
+#define HidUsage_PID_ETRamp 0x27
+#define HidUsage_PID_ETCustomForce 0x28
+#define HidUsage_PID_ETSquare 0x30
+#define HidUsage_PID_ETSine 0x31
+#define HidUsage_PID_ETTriangle 0x32
+#define HidUsage_PID_ETSawtoothUp 0x33
+#define HidUsage_PID_ETSawtoothDown 0x34
+#define HidUsage_PID_ETSpring 0x40
+#define HidUsage_PID_ETDamper 0x41
+#define HidUsage_PID_ETInertia 0x42
+#define HidUsage_PID_ETFriction 0x43
+#define HidUsage_PID_Duration 0x50
+#define HidUsage_PID_SamplePeriod 0x51
+#define HidUsage_PID_Gain 0x52
+#define HidUsage_PID_TriggerButton 0x53
+#define HidUsage_PID_TriggerRepeatInterval 0x54
+#define HidUsage_PID_AxesEnable 0x55
+#define HidUsage_PID_DirectionEnable 0x56
+#define HidUsage_PID_Direction 0x57
+#define HidUsage_PID_TypeSpecificBlockOffset 0x58
+#define HidUsage_PID_BlockType 0x59
+#define HidUsage_PID_SetEnvelopeReport 0x5a
+#define HidUsage_PID_AttackLevel 0x5b
+#define HidUsage_PID_AttackTime 0x5c
+#define HidUsage_PID_FadeLevel 0x5d
+#define HidUsage_PID_FadeTime 0x5e
+#define HidUsage_PID_SetConditionReport 0x5f
+#define HidUsage_PID_CenterPointOffset 0x60
+#define HidUsage_PID_PositiveCoefficient 0x61
+#define HidUsage_PID_NegativeCoefficient 0x62
+#define HidUsage_PID_PositiveSaturation 0x63
+#define HidUsage_PID_NegativeSaturation 0x64
+#define HidUsage_PID_DeadBand 0x65
+#define HidUsage_PID_DownloadForceSample 0x66
+#define HidUsage_PID_IsochCustomForceEnable 0x67
+#define HidUsage_PID_CustomForceDataReport 0x68
+#define HidUsage_PID_CustomForceData 0x69
+#define HidUsage_PID_CustomForceVendorDefinedData 0x6a
+#define HidUsage_PID_SetCustomForceReport 0x6b
+#define HidUsage_PID_CustomForceDataOffset 0x6c
+#define HidUsage_PID_SampleCount 0x6d
+#define HidUsage_PID_SetPeriodicReport 0x6e
+#define HidUsage_PID_Offset 0x6f
+#define HidUsage_PID_Magnitude 0x70
+#define HidUsage_PID_Phase 0x71
+#define HidUsage_PID_Period 0x72
+#define HidUsage_PID_SetConstantForceReport 0x73
+#define HidUsage_PID_SetRampForceReport 0x74
+#define HidUsage_PID_RampStart 0x75
+#define HidUsage_PID_RampEnd 0x76
+#define HidUsage_PID_EffectOperationReport 0x77
+#define HidUsage_PID_EffectOperation 0x78
+#define HidUsage_PID_OpEffectStart 0x79
+#define HidUsage_PID_OpEffectStartSolo 0x7a
+#define HidUsage_PID_OpEffectStop 0x7b
+#define HidUsage_PID_LoopCount 0x7c
+#define HidUsage_PID_DeviceGainReport 0x7d
+#define HidUsage_PID_DeviceGain 0x7e
+#define HidUsage_PID_ParameterBlockPoolsReport 0x7f
+#define HidUsage_PID_RAMPoolSize 0x80
+#define HidUsage_PID_ROMPoolSize 0x81
+#define HidUsage_PID_ROMEffectBlockCount 0x82
+#define HidUsage_PID_SimultaneousEffectsMax 0x83
+#define HidUsage_PID_PoolAlignment 0x84
+#define HidUsage_PID_ParameterBlockMoveReport 0x85
+#define HidUsage_PID_MoveSource 0x86
+#define HidUsage_PID_MoveDestination 0x87
+#define HidUsage_PID_MoveLength 0x88
+#define HidUsage_PID_EffectParameterBlockLoadReport 0x89
+#define HidUsage_PID_EffectParameterBlockLoadStatus 0x8b
+#define HidUsage_PID_BlockLoadSuccess 0x8c
+#define HidUsage_PID_BlockLoadFull 0x8d
+#define HidUsage_PID_BlockLoadError 0x8e
+#define HidUsage_PID_BlockHandle 0x8f
+#define HidUsage_PID_EffectParameterBlockFreeReport 0x90
+#define HidUsage_PID_TypeSpecificBlockHandle 0x91
+#define HidUsage_PID_PIDStateReport 0x92
+#define HidUsage_PID_EffectPlaying 0x94
+#define HidUsage_PID_PIDDeviceControlReport 0x95
+#define HidUsage_PID_PIDDeviceControl 0x96
+#define HidUsage_PID_DCEnableActuators 0x97
+#define HidUsage_PID_DCDisableActuators 0x98
+#define HidUsage_PID_DCStopAllEffects 0x99
+#define HidUsage_PID_DCReset 0x9a
+#define HidUsage_PID_DCPause 0x9b
+#define HidUsage_PID_DCContinue 0x9c
+#define HidUsage_PID_DevicePaused 0x9f
+#define HidUsage_PID_ActuatorsEnabled 0xa0
+#define HidUsage_PID_SafetySwitch 0xa4
+#define HidUsage_PID_ActuatorOverrideSwitch 0xa5
+#define HidUsage_PID_ActuatorPower 0xa6
+#define HidUsage_PID_StartDelay 0xa7
+#define HidUsage_PID_ParameterBlockSize 0xa8
+#define HidUsage_PID_DeviceManagedPool 0xa9
+#define HidUsage_PID_SharedParameterBlocks 0xaa
+#define HidUsage_PID_CreateNewEffectParameterBlockReport 0xab
+#define HidUsage_PID_RAMPoolAvailable 0xac
+#define HidUsage_SC_SocControl 0x01
+#define HidUsage_SC_FirmwareTransfer 0x02
+#define HidUsage_SC_FirmwareFileId 0x03
+#define HidUsage_SC_FileOffsetInBytes 0x04
+#define HidUsage_SC_FileTransferSizeMaxInBytes 0x05
+#define HidUsage_SC_FilePayload 0x06
+#define HidUsage_SC_FilePayloadSizeInBytes 0x07
+#define HidUsage_SC_FilePayloadContainsLastBytes 0x08
+#define HidUsage_SC_FileTransferStop 0x09
+#define HidUsage_SC_FileTransferTillEnd 0x0a
+#define HidUsage_EHT_EyeTracker 0x01
+#define HidUsage_EHT_HeadTracker 0x02
+#define HidUsage_EHT_TrackingData 0x10
+#define HidUsage_EHT_Capabilities 0x11
+#define HidUsage_EHT_Configuration 0x12
+#define HidUsage_EHT_Status 0x13
+#define HidUsage_EHT_Control 0x14
+#define HidUsage_EHT_SensorTimestamp 0x20
+#define HidUsage_EHT_PositionX 0x21
+#define HidUsage_EHT_PositionY 0x22
+#define HidUsage_EHT_PositionZ 0x23
+#define HidUsage_EHT_GazePoint 0x24
+#define HidUsage_EHT_LeftEyePosition 0x25
+#define HidUsage_EHT_RightEyePosition 0x26
+#define HidUsage_EHT_HeadPosition 0x27
+#define HidUsage_EHT_HeadDirectionPoint 0x28
+#define HidUsage_EHT_RotationaboutXaxis 0x29
+#define HidUsage_EHT_RotationaboutYaxis 0x2a
+#define HidUsage_EHT_RotationaboutZaxis 0x2b
+#define HidUsage_EHT_TrackerQuality 0x100
+#define HidUsage_EHT_MinimumTrackingDistance 0x101
+#define HidUsage_EHT_OptimumTrackingDistance 0x102
+#define HidUsage_EHT_MaximumTrackingDistance 0x103
+#define HidUsage_EHT_MaximumScreenPlaneWidth 0x104
+#define HidUsage_EHT_MaximumScreenPlaneHeight 0x105
+#define HidUsage_EHT_DisplayManufacturerID 0x200
+#define HidUsage_EHT_DisplayProductID 0x201
+#define HidUsage_EHT_DisplaySerialNumber 0x202
+#define HidUsage_EHT_DisplayManufacturerDate 0x203
+#define HidUsage_EHT_CalibratedScreenWidth 0x204
+#define HidUsage_EHT_CalibratedScreenHeight 0x205
+#define HidUsage_EHT_SamplingFrequency 0x300
+#define HidUsage_EHT_ConfigurationStatus 0x301
+#define HidUsage_EHT_DeviceModeRequest 0x400
+#define HidUsage_AD_AlphanumericDisplay 0x01
+#define HidUsage_AD_AuxiliaryDisplay 0x02
+#define HidUsage_AD_DisplayAttributesReport 0x20
+#define HidUsage_AD_ASCIICharacterSet 0x21
+#define HidUsage_AD_DataReadBack 0x22
+#define HidUsage_AD_FontReadBack 0x23
+#define HidUsage_AD_DisplayControlReport 0x24
+#define HidUsage_AD_ClearDisplay 0x25
+#define HidUsage_AD_DisplayEnable 0x26
+#define HidUsage_AD_ScreenSaverDelay 0x27
+#define HidUsage_AD_ScreenSaverEnable 0x28
+#define HidUsage_AD_VerticalScroll 0x29
+#define HidUsage_AD_HorizontalScroll 0x2a
+#define HidUsage_AD_CharacterReport 0x2b
+#define HidUsage_AD_DisplayData 0x2c
+#define HidUsage_AD_DisplayStatus 0x2d
+#define HidUsage_AD_StatNotReady 0x2e
+#define HidUsage_AD_StatReady 0x2f
+#define HidUsage_AD_ErrNotaloadablecharacter 0x30
+#define HidUsage_AD_ErrFontdatacannotberead 0x31
+#define HidUsage_AD_CursorPositionReport 0x32
+#define HidUsage_AD_Row 0x33
+#define HidUsage_AD_Column 0x34
+#define HidUsage_AD_Rows 0x35
+#define HidUsage_AD_Columns 0x36
+#define HidUsage_AD_CursorPixelPositioning 0x37
+#define HidUsage_AD_CursorMode 0x38
+#define HidUsage_AD_CursorEnable 0x39
+#define HidUsage_AD_CursorBlink 0x3a
+#define HidUsage_AD_FontReport 0x3b
+#define HidUsage_AD_FontData 0x3c
+#define HidUsage_AD_CharacterWidth 0x3d
+#define HidUsage_AD_CharacterHeight 0x3e
+#define HidUsage_AD_CharacterSpacingHorizontal 0x3f
+#define HidUsage_AD_CharacterSpacingVertical 0x40
+#define HidUsage_AD_UnicodeCharacterSet 0x41
+#define HidUsage_AD_Font7Segment 0x42
+#define HidUsage_AD_SevenSegmentDirectMap 0x43
+#define HidUsage_AD_Font14Segment 0x44
+#define HidUsage_AD_One4SegmentDirectMap 0x45
+#define HidUsage_AD_DisplayBrightness 0x46
+#define HidUsage_AD_DisplayContrast 0x47
+#define HidUsage_AD_CharacterAttribute 0x48
+#define HidUsage_AD_AttributeReadback 0x49
+#define HidUsage_AD_AttributeData 0x4a
+#define HidUsage_AD_CharAttrEnhance 0x4b
+#define HidUsage_AD_CharAttrUnderline 0x4c
+#define HidUsage_AD_CharAttrBlink 0x4d
+#define HidUsage_AD_BitmapSizeX 0x80
+#define HidUsage_AD_BitmapSizeY 0x81
+#define HidUsage_AD_MaxBlitSize 0x82
+#define HidUsage_AD_BitDepthFormat 0x83
+#define HidUsage_AD_DisplayOrientation 0x84
+#define HidUsage_AD_PaletteReport 0x85
+#define HidUsage_AD_PaletteDataSize 0x86
+#define HidUsage_AD_PaletteDataOffset 0x87
+#define HidUsage_AD_PaletteData 0x88
+#define HidUsage_AD_BlitReport 0x8a
+#define HidUsage_AD_BlitRectangleX1 0x8b
+#define HidUsage_AD_BlitRectangleY1 0x8c
+#define HidUsage_AD_BlitRectangleX2 0x8d
+#define HidUsage_AD_BlitRectangleY2 0x8e
+#define HidUsage_AD_BlitData 0x8f
+#define HidUsage_AD_SoftButton 0x90
+#define HidUsage_AD_SoftButtonID 0x91
+#define HidUsage_AD_SoftButtonSide 0x92
+#define HidUsage_AD_SoftButtonOffset1 0x93
+#define HidUsage_AD_SoftButtonOffset2 0x94
+#define HidUsage_AD_SoftButtonReport 0x95
+#define HidUsage_AD_SoftKeys 0xc2
+#define HidUsage_AD_DisplayDataExtensions 0xcc
+#define HidUsage_AD_CharacterMapping 0xcf
+#define HidUsage_AD_UnicodeEquivalent 0xdd
+#define HidUsage_AD_CharacterPageMapping 0xdf
+#define HidUsage_AD_RequestReport 0xff
+#define HidUsage_Sen_Sensor 0x01
+#define HidUsage_Sen_Biometric 0x10
+#define HidUsage_Sen_BiometricHumanPresence 0x11
+#define HidUsage_Sen_BiometricHumanProximity 0x12
+#define HidUsage_Sen_BiometricHumanTouch 0x13
+#define HidUsage_Sen_BiometricBloodPressure 0x14
+#define HidUsage_Sen_BiometricBodyTemperature 0x15
+#define HidUsage_Sen_BiometricHeartRate 0x16
+#define HidUsage_Sen_BiometricHeartRateVariability 0x17
+#define HidUsage_Sen_BiometricPeripheralOxygenSaturation 0x18
+#define HidUsage_Sen_BiometricRespiratoryRate 0x19
+#define HidUsage_Sen_Electrical 0x20
+#define HidUsage_Sen_ElectricalCapacitance 0x21
+#define HidUsage_Sen_ElectricalCurrent 0x22
+#define HidUsage_Sen_ElectricalPower 0x23
+#define HidUsage_Sen_ElectricalInductance 0x24
+#define HidUsage_Sen_ElectricalResistance 0x25
+#define HidUsage_Sen_ElectricalVoltage 0x26
+#define HidUsage_Sen_ElectricalPotentiometer 0x27
+#define HidUsage_Sen_ElectricalFrequency 0x28
+#define HidUsage_Sen_ElectricalPeriod 0x29
+#define HidUsage_Sen_Environmental 0x30
+#define HidUsage_Sen_EnvironmentalAtmosphericPressure 0x31
+#define HidUsage_Sen_EnvironmentalHumidity 0x32
+#define HidUsage_Sen_EnvironmentalTemperature 0x33
+#define HidUsage_Sen_EnvironmentalWindDirection 0x34
+#define HidUsage_Sen_EnvironmentalWindSpeed 0x35
+#define HidUsage_Sen_EnvironmentalAirQuality 0x36
+#define HidUsage_Sen_EnvironmentalHeatIndex 0x37
+#define HidUsage_Sen_EnvironmentalSurfaceTemperature 0x38
+#define HidUsage_Sen_EnvironmentalVolatileOrganicCompounds 0x39
+#define HidUsage_Sen_EnvironmentalObjectPresence 0x3a
+#define HidUsage_Sen_EnvironmentalObjectProximity 0x3b
+#define HidUsage_Sen_Light 0x40
+#define HidUsage_Sen_LightAmbientLight 0x41
+#define HidUsage_Sen_LightConsumerInfrared 0x42
+#define HidUsage_Sen_LightInfraredLight 0x43
+#define HidUsage_Sen_LightVisibleLight 0x44
+#define HidUsage_Sen_LightUltravioletLight 0x45
+#define HidUsage_Sen_Location 0x50
+#define HidUsage_Sen_LocationBroadcast 0x51
+#define HidUsage_Sen_LocationDeadReckoning 0x52
+#define HidUsage_Sen_LocationGPSGlobalPositioningSystem 0x53
+#define HidUsage_Sen_LocationLookup 0x54
+#define HidUsage_Sen_LocationOther 0x55
+#define HidUsage_Sen_LocationStatic 0x56
+#define HidUsage_Sen_LocationTriangulation 0x57
+#define HidUsage_Sen_Mechanical 0x60
+#define HidUsage_Sen_MechanicalBooleanSwitch 0x61
+#define HidUsage_Sen_MechanicalBooleanSwitchArray 0x62
+#define HidUsage_Sen_MechanicalMultivalueSwitch 0x63
+#define HidUsage_Sen_MechanicalForce 0x64
+#define HidUsage_Sen_MechanicalPressure 0x65
+#define HidUsage_Sen_MechanicalStrain 0x66
+#define HidUsage_Sen_MechanicalWeight 0x67
+#define HidUsage_Sen_MechanicalHapticVibrator 0x68
+#define HidUsage_Sen_MechanicalHallEffectSwitch 0x69
+#define HidUsage_Sen_Motion 0x70
+#define HidUsage_Sen_MotionAccelerometer1D 0x71
+#define HidUsage_Sen_MotionAccelerometer2D 0x72
+#define HidUsage_Sen_MotionAccelerometer3D 0x73
+#define HidUsage_Sen_MotionGyrometer1D 0x74
+#define HidUsage_Sen_MotionGyrometer2D 0x75
+#define HidUsage_Sen_MotionGyrometer3D 0x76
+#define HidUsage_Sen_MotionMotionDetector 0x77
+#define HidUsage_Sen_MotionSpeedometer 0x78
+#define HidUsage_Sen_MotionAccelerometer 0x79
+#define HidUsage_Sen_MotionGyrometer 0x7a
+#define HidUsage_Sen_MotionGravityVector 0x7b
+#define HidUsage_Sen_MotionLinearAccelerometer 0x7c
+#define HidUsage_Sen_Orientation 0x80
+#define HidUsage_Sen_OrientationCompass1D 0x81
+#define HidUsage_Sen_OrientationCompass2D 0x82
+#define HidUsage_Sen_OrientationCompass3D 0x83
+#define HidUsage_Sen_OrientationInclinometer1D 0x84
+#define HidUsage_Sen_OrientationInclinometer2D 0x85
+#define HidUsage_Sen_OrientationInclinometer3D 0x86
+#define HidUsage_Sen_OrientationDistance1D 0x87
+#define HidUsage_Sen_OrientationDistance2D 0x88
+#define HidUsage_Sen_OrientationDistance3D 0x89
+#define HidUsage_Sen_OrientationDeviceOrientation 0x8a
+#define HidUsage_Sen_OrientationCompass 0x8b
+#define HidUsage_Sen_OrientationInclinometer 0x8c
+#define HidUsage_Sen_OrientationDistance 0x8d
+#define HidUsage_Sen_OrientationRelativeOrientation 0x8e
+#define HidUsage_Sen_OrientationSimpleOrientation 0x8f
+#define HidUsage_Sen_Scanner 0x90
+#define HidUsage_Sen_ScannerBarcode 0x91
+#define HidUsage_Sen_ScannerRFID 0x92
+#define HidUsage_Sen_ScannerNFC 0x93
+#define HidUsage_Sen_Time 0xa0
+#define HidUsage_Sen_TimeAlarmTimer 0xa1
+#define HidUsage_Sen_TimeRealTimeClock 0xa2
+#define HidUsage_Sen_PersonalActivity 0xb0
+#define HidUsage_Sen_PersonalActivityActivityDetection 0xb1
+#define HidUsage_Sen_PersonalActivityDevicePosition 0xb2
+#define HidUsage_Sen_PersonalActivityFloorTracker 0xb3
+#define HidUsage_Sen_PersonalActivityPedometer 0xb4
+#define HidUsage_Sen_PersonalActivityStepDetection 0xb5
+#define HidUsage_Sen_OrientationExtended 0xc0
+#define HidUsage_Sen_OrientationExtendedGeomagneticOrientation 0xc1
+#define HidUsage_Sen_OrientationExtendedMagnetometer 0xc2
+#define HidUsage_Sen_Gesture 0xd0
+#define HidUsage_Sen_GestureChassisFlipGesture 0xd1
+#define HidUsage_Sen_GestureHingeFoldGesture 0xd2
+#define HidUsage_Sen_Other 0xe0
+#define HidUsage_Sen_OtherCustom 0xe1
+#define HidUsage_Sen_OtherGeneric 0xe2
+#define HidUsage_Sen_OtherGenericEnumerator 0xe3
+#define HidUsage_Sen_OtherHingeAngle 0xe4
+#define HidUsage_Sen_VendorReserved1 0xf0
+#define HidUsage_Sen_VendorReserved2 0xf1
+#define HidUsage_Sen_VendorReserved3 0xf2
+#define HidUsage_Sen_VendorReserved4 0xf3
+#define HidUsage_Sen_VendorReserved5 0xf4
+#define HidUsage_Sen_VendorReserved6 0xf5
+#define HidUsage_Sen_VendorReserved7 0xf6
+#define HidUsage_Sen_VendorReserved8 0xf7
+#define HidUsage_Sen_VendorReserved9 0xf8
+#define HidUsage_Sen_VendorReserved10 0xf9
+#define HidUsage_Sen_VendorReserved11 0xfa
+#define HidUsage_Sen_VendorReserved12 0xfb
+#define HidUsage_Sen_VendorReserved13 0xfc
+#define HidUsage_Sen_VendorReserved14 0xfd
+#define HidUsage_Sen_VendorReserved15 0xfe
+#define HidUsage_Sen_VendorReserved16 0xff
+#define HidUsage_Sen_Event 0x200
+#define HidUsage_Sen_EventSensorState 0x201
+#define HidUsage_Sen_EventSensorEvent 0x202
+#define HidUsage_Sen_Property 0x300
+#define HidUsage_Sen_PropertyFriendlyName 0x301
+#define HidUsage_Sen_PropertyPersistentUniqueID 0x302
+#define HidUsage_Sen_PropertySensorStatus 0x303
+#define HidUsage_Sen_PropertyMinimumReportInterval 0x304
+#define HidUsage_Sen_PropertySensorManufacturer 0x305
+#define HidUsage_Sen_PropertySensorModel 0x306
+#define HidUsage_Sen_PropertySensorSerialNumber 0x307
+#define HidUsage_Sen_PropertySensorDescription 0x308
+#define HidUsage_Sen_PropertySensorConnectionType 0x309
+#define HidUsage_Sen_PropertySensorDevicePath 0x30a
+#define HidUsage_Sen_PropertyHardwareRevision 0x30b
+#define HidUsage_Sen_PropertyFirmwareVersion 0x30c
+#define HidUsage_Sen_PropertyReleaseDate 0x30d
+#define HidUsage_Sen_PropertyReportInterval 0x30e
+#define HidUsage_Sen_PropertyChangeSensitivityAbsolute 0x30f
+#define HidUsage_Sen_PropertyChangeSensitivityPercentofRange 0x310
+#define HidUsage_Sen_PropertyChangeSensitivityPercentRelative 0x311
+#define HidUsage_Sen_PropertyAccuracy 0x312
+#define HidUsage_Sen_PropertyResolution 0x313
+#define HidUsage_Sen_PropertyMaximum 0x314
+#define HidUsage_Sen_PropertyMinimum 0x315
+#define HidUsage_Sen_PropertyReportingState 0x316
+#define HidUsage_Sen_PropertySamplingRate 0x317
+#define HidUsage_Sen_PropertyResponseCurve 0x318
+#define HidUsage_Sen_PropertyPowerState 0x319
+#define HidUsage_Sen_PropertyMaximumFIFOEvents 0x31a
+#define HidUsage_Sen_PropertyReportLatency 0x31b
+#define HidUsage_Sen_PropertyFlushFIFOEvents 0x31c
+#define HidUsage_Sen_PropertyMaximumPowerConsumption 0x31d
+#define HidUsage_Sen_PropertyIsPrimary 0x31e
+#define HidUsage_Sen_PropertyHumanPresenceDetectionType 0x31f
+#define HidUsage_Sen_DataFieldLocation 0x400
+#define HidUsage_Sen_DataFieldAltitudeAntennaSeaLevel 0x402
+#define HidUsage_Sen_DataFieldDifferentialReferenceStationID 0x403
+#define HidUsage_Sen_DataFieldAltitudeEllipsoidError 0x404
+#define HidUsage_Sen_DataFieldAltitudeEllipsoid 0x405
+#define HidUsage_Sen_DataFieldAltitudeSeaLevelError 0x406
+#define HidUsage_Sen_DataFieldAltitudeSeaLevel 0x407
+#define HidUsage_Sen_DataFieldDifferentialGPSDataAge 0x408
+#define HidUsage_Sen_DataFieldErrorRadius 0x409
+#define HidUsage_Sen_DataFieldFixQuality 0x40a
+#define HidUsage_Sen_DataFieldFixType 0x40b
+#define HidUsage_Sen_DataFieldGeoidalSeparation 0x40c
+#define HidUsage_Sen_DataFieldGPSOperationMode 0x40d
+#define HidUsage_Sen_DataFieldGPSSelectionMode 0x40e
+#define HidUsage_Sen_DataFieldGPSStatus 0x40f
+#define HidUsage_Sen_DataFieldPositionDilutionofPrecision 0x410
+#define HidUsage_Sen_DataFieldHorizontalDilutionofPrecision 0x411
+#define HidUsage_Sen_DataFieldVerticalDilutionofPrecision 0x412
+#define HidUsage_Sen_DataFieldLatitude 0x413
+#define HidUsage_Sen_DataFieldLongitude 0x414
+#define HidUsage_Sen_DataFieldTrueHeading 0x415
+#define HidUsage_Sen_DataFieldMagneticHeading 0x416
+#define HidUsage_Sen_DataFieldMagneticVariation 0x417
+#define HidUsage_Sen_DataFieldSpeed 0x418
+#define HidUsage_Sen_DataFieldSatellitesinView 0x419
+#define HidUsage_Sen_DataFieldSatellitesinViewAzimuth 0x41a
+#define HidUsage_Sen_DataFieldSatellitesinViewElevation 0x41b
+#define HidUsage_Sen_DataFieldSatellitesinViewIDs 0x41c
+#define HidUsage_Sen_DataFieldSatellitesinViewPRNs 0x41d
+#define HidUsage_Sen_DataFieldSatellitesinViewSNRatios 0x41e
+#define HidUsage_Sen_DataFieldSatellitesUsedCount 0x41f
+#define HidUsage_Sen_DataFieldSatellitesUsedPRNs 0x420
+#define HidUsage_Sen_DataFieldNMEASentence 0x421
+#define HidUsage_Sen_DataFieldAddressLine1 0x422
+#define HidUsage_Sen_DataFieldAddressLine2 0x423
+#define HidUsage_Sen_DataFieldCity 0x424
+#define HidUsage_Sen_DataFieldStateorProvince 0x425
+#define HidUsage_Sen_DataFieldCountryorRegion 0x426
+#define HidUsage_Sen_DataFieldPostalCode 0x427
+#define HidUsage_Sen_PropertyLocation 0x42a
+#define HidUsage_Sen_PropertyLocationDesiredAccuracy 0x42b
+#define HidUsage_Sen_DataFieldEnvironmental 0x430
+#define HidUsage_Sen_DataFieldAtmosphericPressure 0x431
+#define HidUsage_Sen_DataFieldRelativeHumidity 0x433
+#define HidUsage_Sen_DataFieldTemperature 0x434
+#define HidUsage_Sen_DataFieldWindDirection 0x435
+#define HidUsage_Sen_DataFieldWindSpeed 0x436
+#define HidUsage_Sen_DataFieldAirQualityIndex 0x437
+#define HidUsage_Sen_DataFieldEquivalentCO2 0x438
+#define HidUsage_Sen_DataFieldVolatileOrganicCompoundConcentration 0x439
+#define HidUsage_Sen_DataFieldObjectPresence 0x43a
+#define HidUsage_Sen_DataFieldObjectProximityRange 0x43b
+#define HidUsage_Sen_DataFieldObjectProximityOutofRange 0x43c
+#define HidUsage_Sen_PropertyEnvironmental 0x440
+#define HidUsage_Sen_PropertyReferencePressure 0x441
+#define HidUsage_Sen_DataFieldMotion 0x450
+#define HidUsage_Sen_DataFieldMotionState 0x451
+#define HidUsage_Sen_DataFieldAcceleration 0x452
+#define HidUsage_Sen_DataFieldAccelerationAxisX 0x453
+#define HidUsage_Sen_DataFieldAccelerationAxisY 0x454
+#define HidUsage_Sen_DataFieldAccelerationAxisZ 0x455
+#define HidUsage_Sen_DataFieldAngularVelocity 0x456
+#define HidUsage_Sen_DataFieldAngularVelocityaboutXAxis 0x457
+#define HidUsage_Sen_DataFieldAngularVelocityaboutYAxis 0x458
+#define HidUsage_Sen_DataFieldAngularVelocityaboutZAxis 0x459
+#define HidUsage_Sen_DataFieldAngularPosition 0x45a
+#define HidUsage_Sen_DataFieldAngularPositionaboutXAxis 0x45b
+#define HidUsage_Sen_DataFieldAngularPositionaboutYAxis 0x45c
+#define HidUsage_Sen_DataFieldAngularPositionaboutZAxis 0x45d
+#define HidUsage_Sen_DataFieldMotionSpeed 0x45e
+#define HidUsage_Sen_DataFieldMotionIntensity 0x45f
+#define HidUsage_Sen_DataFieldOrientation 0x470
+#define HidUsage_Sen_DataFieldHeading 0x471
+#define HidUsage_Sen_DataFieldHeadingXAxis 0x472
+#define HidUsage_Sen_DataFieldHeadingYAxis 0x473
+#define HidUsage_Sen_DataFieldHeadingZAxis 0x474
+#define HidUsage_Sen_DataFieldHeadingCompensatedMagneticNorth 0x475
+#define HidUsage_Sen_DataFieldHeadingCompensatedTrueNorth 0x476
+#define HidUsage_Sen_DataFieldHeadingMagneticNorth 0x477
+#define HidUsage_Sen_DataFieldHeadingTrueNorth 0x478
+#define HidUsage_Sen_DataFieldDistance 0x479
+#define HidUsage_Sen_DataFieldDistanceXAxis 0x47a
+#define HidUsage_Sen_DataFieldDistanceYAxis 0x47b
+#define HidUsage_Sen_DataFieldDistanceZAxis 0x47c
+#define HidUsage_Sen_DataFieldDistanceOutofRange 0x47d
+#define HidUsage_Sen_DataFieldTilt 0x47e
+#define HidUsage_Sen_DataFieldTiltXAxis 0x47f
+#define HidUsage_Sen_DataFieldTiltYAxis 0x480
+#define HidUsage_Sen_DataFieldTiltZAxis 0x481
+#define HidUsage_Sen_DataFieldRotationMatrix 0x482
+#define HidUsage_Sen_DataFieldQuaternion 0x483
+#define HidUsage_Sen_DataFieldMagneticFlux 0x484
+#define HidUsage_Sen_DataFieldMagneticFluxXAxis 0x485
+#define HidUsage_Sen_DataFieldMagneticFluxYAxis 0x486
+#define HidUsage_Sen_DataFieldMagneticFluxZAxis 0x487
+#define HidUsage_Sen_DataFieldMagnetometerAccuracy 0x488
+#define HidUsage_Sen_DataFieldSimpleOrientationDirection 0x489
+#define HidUsage_Sen_DataFieldMechanical 0x490
+#define HidUsage_Sen_DataFieldBooleanSwitchState 0x491
+#define HidUsage_Sen_DataFieldBooleanSwitchArrayStates 0x492
+#define HidUsage_Sen_DataFieldMultivalueSwitchValue 0x493
+#define HidUsage_Sen_DataFieldForce 0x494
+#define HidUsage_Sen_DataFieldAbsolutePressure 0x495
+#define HidUsage_Sen_DataFieldGaugePressure 0x496
+#define HidUsage_Sen_DataFieldStrain 0x497
+#define HidUsage_Sen_DataFieldWeight 0x498
+#define HidUsage_Sen_PropertyMechanical 0x4a0
+#define HidUsage_Sen_PropertyVibrationState 0x4a1
+#define HidUsage_Sen_PropertyForwardVibrationSpeed 0x4a2
+#define HidUsage_Sen_PropertyBackwardVibrationSpeed 0x4a3
+#define HidUsage_Sen_DataFieldBiometric 0x4b0
+#define HidUsage_Sen_DataFieldHumanPresence 0x4b1
+#define HidUsage_Sen_DataFieldHumanProximityRange 0x4b2
+#define HidUsage_Sen_DataFieldHumanProximityOutofRange 0x4b3
+#define HidUsage_Sen_DataFieldHumanTouchState 0x4b4
+#define HidUsage_Sen_DataFieldBloodPressure 0x4b5
+#define HidUsage_Sen_DataFieldBloodPressureDiastolic 0x4b6
+#define HidUsage_Sen_DataFieldBloodPressureSystolic 0x4b7
+#define HidUsage_Sen_DataFieldHeartRate 0x4b8
+#define HidUsage_Sen_DataFieldRestingHeartRate 0x4b9
+#define HidUsage_Sen_DataFieldHeartbeatInterval 0x4ba
+#define HidUsage_Sen_DataFieldRespiratoryRate 0x4bb
+#define HidUsage_Sen_DataFieldSpO2 0x4bc
+#define HidUsage_Sen_DataFieldHumanAttentionDetected 0x4bd
+#define HidUsage_Sen_DataFieldHumanHeadAzimuth 0x4be
+#define HidUsage_Sen_DataFieldHumanHeadAltitude 0x4bf
+#define HidUsage_Sen_DataFieldHumanHeadRoll 0x4c0
+#define HidUsage_Sen_DataFieldHumanHeadPitch 0x4c1
+#define HidUsage_Sen_DataFieldHumanHeadYaw 0x4c2
+#define HidUsage_Sen_DataFieldHumanCorrelationId 0x4c3
+#define HidUsage_Sen_DataFieldLight 0x4d0
+#define HidUsage_Sen_DataFieldIlluminance 0x4d1
+#define HidUsage_Sen_DataFieldColorTemperature 0x4d2
+#define HidUsage_Sen_DataFieldChromaticity 0x4d3
+#define HidUsage_Sen_DataFieldChromaticityX 0x4d4
+#define HidUsage_Sen_DataFieldChromaticityY 0x4d5
+#define HidUsage_Sen_DataFieldConsumerIRSentenceReceive 0x4d6
+#define HidUsage_Sen_DataFieldInfraredLight 0x4d7
+#define HidUsage_Sen_DataFieldRedLight 0x4d8
+#define HidUsage_Sen_DataFieldGreenLight 0x4d9
+#define HidUsage_Sen_DataFieldBlueLight 0x4da
+#define HidUsage_Sen_DataFieldUltravioletALight 0x4db
+#define HidUsage_Sen_DataFieldUltravioletBLight 0x4dc
+#define HidUsage_Sen_DataFieldUltravioletIndex 0x4dd
+#define HidUsage_Sen_DataFieldNearInfraredLight 0x4de
+#define HidUsage_Sen_PropertyLight 0x4df
+#define HidUsage_Sen_PropertyConsumerIRSentenceSend 0x4e0
+#define HidUsage_Sen_PropertyAutoBrightnessPreferred 0x4e2
+#define HidUsage_Sen_PropertyAutoColorPreferred 0x4e3
+#define HidUsage_Sen_DataFieldScanner 0x4f0
+#define HidUsage_Sen_DataFieldRFIDTag40Bit 0x4f1
+#define HidUsage_Sen_DataFieldNFCSentenceReceive 0x4f2
+#define HidUsage_Sen_PropertyScanner 0x4f8
+#define HidUsage_Sen_PropertyNFCSentenceSend 0x4f9
+#define HidUsage_Sen_DataFieldElectrical 0x500
+#define HidUsage_Sen_DataFieldCapacitance 0x501
+#define HidUsage_Sen_DataFieldCurrent 0x502
+#define HidUsage_Sen_DataFieldElectricalPower 0x503
+#define HidUsage_Sen_DataFieldInductance 0x504
+#define HidUsage_Sen_DataFieldResistance 0x505
+#define HidUsage_Sen_DataFieldVoltage 0x506
+#define HidUsage_Sen_DataFieldFrequency 0x507
+#define HidUsage_Sen_DataFieldPeriod 0x508
+#define HidUsage_Sen_DataFieldPercentofRange 0x509
+#define HidUsage_Sen_DataFieldTime 0x520
+#define HidUsage_Sen_DataFieldYear 0x521
+#define HidUsage_Sen_DataFieldMonth 0x522
+#define HidUsage_Sen_DataFieldDay 0x523
+#define HidUsage_Sen_DataFieldDayofWeek 0x524
+#define HidUsage_Sen_DataFieldHour 0x525
+#define HidUsage_Sen_DataFieldMinute 0x526
+#define HidUsage_Sen_DataFieldSecond 0x527
+#define HidUsage_Sen_DataFieldMillisecond 0x528
+#define HidUsage_Sen_DataFieldTimestamp 0x529
+#define HidUsage_Sen_DataFieldJulianDayofYear 0x52a
+#define HidUsage_Sen_DataFieldTimeSinceSystemBoot 0x52b
+#define HidUsage_Sen_PropertyTime 0x530
+#define HidUsage_Sen_PropertyTimeZoneOffsetfromUTC 0x531
+#define HidUsage_Sen_PropertyTimeZoneName 0x532
+#define HidUsage_Sen_PropertyDaylightSavingsTimeObserved 0x533
+#define HidUsage_Sen_PropertyTimeTrimAdjustment 0x534
+#define HidUsage_Sen_PropertyArmAlarm 0x535
+#define HidUsage_Sen_DataFieldCustom 0x540
+#define HidUsage_Sen_DataFieldCustomUsage 0x541
+#define HidUsage_Sen_DataFieldCustomBooleanArray 0x542
+#define HidUsage_Sen_DataFieldCustomValue 0x543
+#define HidUsage_Sen_DataFieldCustomValue1 0x544
+#define HidUsage_Sen_DataFieldCustomValue2 0x545
+#define HidUsage_Sen_DataFieldCustomValue3 0x546
+#define HidUsage_Sen_DataFieldCustomValue4 0x547
+#define HidUsage_Sen_DataFieldCustomValue5 0x548
+#define HidUsage_Sen_DataFieldCustomValue6 0x549
+#define HidUsage_Sen_DataFieldCustomValue7 0x54a
+#define HidUsage_Sen_DataFieldCustomValue8 0x54b
+#define HidUsage_Sen_DataFieldCustomValue9 0x54c
+#define HidUsage_Sen_DataFieldCustomValue10 0x54d
+#define HidUsage_Sen_DataFieldCustomValue11 0x54e
+#define HidUsage_Sen_DataFieldCustomValue12 0x54f
+#define HidUsage_Sen_DataFieldCustomValue13 0x550
+#define HidUsage_Sen_DataFieldCustomValue14 0x551
+#define HidUsage_Sen_DataFieldCustomValue15 0x552
+#define HidUsage_Sen_DataFieldCustomValue16 0x553
+#define HidUsage_Sen_DataFieldCustomValue17 0x554
+#define HidUsage_Sen_DataFieldCustomValue18 0x555
+#define HidUsage_Sen_DataFieldCustomValue19 0x556
+#define HidUsage_Sen_DataFieldCustomValue20 0x557
+#define HidUsage_Sen_DataFieldCustomValue21 0x558
+#define HidUsage_Sen_DataFieldCustomValue22 0x559
+#define HidUsage_Sen_DataFieldCustomValue23 0x55a
+#define HidUsage_Sen_DataFieldCustomValue24 0x55b
+#define HidUsage_Sen_DataFieldCustomValue25 0x55c
+#define HidUsage_Sen_DataFieldCustomValue26 0x55d
+#define HidUsage_Sen_DataFieldCustomValue27 0x55e
+#define HidUsage_Sen_DataFieldCustomValue28 0x55f
+#define HidUsage_Sen_DataFieldGeneric 0x560
+#define HidUsage_Sen_DataFieldGenericGUIDorPROPERTYKEY 0x561
+#define HidUsage_Sen_DataFieldGenericCategoryGUID 0x562
+#define HidUsage_Sen_DataFieldGenericTypeGUID 0x563
+#define HidUsage_Sen_DataFieldGenericEventPROPERTYKEY 0x564
+#define HidUsage_Sen_DataFieldGenericPropertyPROPERTYKEY 0x565
+#define HidUsage_Sen_DataFieldGenericDataFieldPROPERTYKEY 0x566
+#define HidUsage_Sen_DataFieldGenericEvent 0x567
+#define HidUsage_Sen_DataFieldGenericProperty 0x568
+#define HidUsage_Sen_DataFieldGenericDataField 0x569
+#define HidUsage_Sen_DataFieldEnumeratorTableRowIndex 0x56a
+#define HidUsage_Sen_DataFieldEnumeratorTableRowCount 0x56b
+#define HidUsage_Sen_DataFieldGenericGUIDorPROPERTYKEYkind 0x56c
+#define HidUsage_Sen_DataFieldGenericGUID 0x56d
+#define HidUsage_Sen_DataFieldGenericPROPERTYKEY 0x56e
+#define HidUsage_Sen_DataFieldGenericTopLevelCollectionID 0x56f
+#define HidUsage_Sen_DataFieldGenericReportID 0x570
+#define HidUsage_Sen_DataFieldGenericReportItemPositionIndex 0x571
+#define HidUsage_Sen_DataFieldGenericFirmwareVARTYPE 0x572
+#define HidUsage_Sen_DataFieldGenericUnitofMeasure 0x573
+#define HidUsage_Sen_DataFieldGenericUnitExponent 0x574
+#define HidUsage_Sen_DataFieldGenericReportSize 0x575
+#define HidUsage_Sen_DataFieldGenericReportCount 0x576
+#define HidUsage_Sen_PropertyGeneric 0x580
+#define HidUsage_Sen_PropertyEnumeratorTableRowIndex 0x581
+#define HidUsage_Sen_PropertyEnumeratorTableRowCount 0x582
+#define HidUsage_Sen_DataFieldPersonalActivity 0x590
+#define HidUsage_Sen_DataFieldActivityType 0x591
+#define HidUsage_Sen_DataFieldActivityState 0x592
+#define HidUsage_Sen_DataFieldDevicePosition 0x593
+#define HidUsage_Sen_DataFieldStepCount 0x594
+#define HidUsage_Sen_DataFieldStepCountReset 0x595
+#define HidUsage_Sen_DataFieldStepDuration 0x596
+#define HidUsage_Sen_DataFieldStepType 0x597
+#define HidUsage_Sen_PropertyMinimumActivityDetectionInterval 0x5a0
+#define HidUsage_Sen_PropertySupportedActivityTypes 0x5a1
+#define HidUsage_Sen_PropertySubscribedActivityTypes 0x5a2
+#define HidUsage_Sen_PropertySupportedStepTypes 0x5a3
+#define HidUsage_Sen_PropertySubscribedStepTypes 0x5a4
+#define HidUsage_Sen_PropertyFloorHeight 0x5a5
+#define HidUsage_Sen_DataFieldCustomTypeID 0x5b0
+#define HidUsage_Sen_PropertyCustom 0x5c0
+#define HidUsage_Sen_PropertyCustomValue1 0x5c1
+#define HidUsage_Sen_PropertyCustomValue2 0x5c2
+#define HidUsage_Sen_PropertyCustomValue3 0x5c3
+#define HidUsage_Sen_PropertyCustomValue4 0x5c4
+#define HidUsage_Sen_PropertyCustomValue5 0x5c5
+#define HidUsage_Sen_PropertyCustomValue6 0x5c6
+#define HidUsage_Sen_PropertyCustomValue7 0x5c7
+#define HidUsage_Sen_PropertyCustomValue8 0x5c8
+#define HidUsage_Sen_PropertyCustomValue9 0x5c9
+#define HidUsage_Sen_PropertyCustomValue10 0x5ca
+#define HidUsage_Sen_PropertyCustomValue11 0x5cb
+#define HidUsage_Sen_PropertyCustomValue12 0x5cc
+#define HidUsage_Sen_PropertyCustomValue13 0x5cd
+#define HidUsage_Sen_PropertyCustomValue14 0x5ce
+#define HidUsage_Sen_PropertyCustomValue15 0x5cf
+#define HidUsage_Sen_PropertyCustomValue16 0x5d0
+#define HidUsage_Sen_DataFieldHinge 0x5e0
+#define HidUsage_Sen_DataFieldHingeAngle 0x5e1
+#define HidUsage_Sen_DataFieldGestureSensor 0x5f0
+#define HidUsage_Sen_DataFieldGestureState 0x5f1
+#define HidUsage_Sen_DataFieldHingeFoldInitialAngle 0x5f2
+#define HidUsage_Sen_DataFieldHingeFoldFinalAngle 0x5f3
+#define HidUsage_Sen_DataFieldHingeFoldContributingPanel 0x5f4
+#define HidUsage_Sen_DataFieldHingeFoldType 0x5f5
+#define HidUsage_Sen_SensorStateUndefined 0x800
+#define HidUsage_Sen_SensorStateReady 0x801
+#define HidUsage_Sen_SensorStateNotAvailable 0x802
+#define HidUsage_Sen_SensorStateNoData 0x803
+#define HidUsage_Sen_SensorStateInitializing 0x804
+#define HidUsage_Sen_SensorStateAccessDenied 0x805
+#define HidUsage_Sen_SensorStateError 0x806
+#define HidUsage_Sen_SensorEventUnknown 0x810
+#define HidUsage_Sen_SensorEventStateChanged 0x811
+#define HidUsage_Sen_SensorEventPropertyChanged 0x812
+#define HidUsage_Sen_SensorEventDataUpdated 0x813
+#define HidUsage_Sen_SensorEventPollResponse 0x814
+#define HidUsage_Sen_SensorEventChangeSensitivity 0x815
+#define HidUsage_Sen_SensorEventRangeMaximumReached 0x816
+#define HidUsage_Sen_SensorEventRangeMinimumReached 0x817
+#define HidUsage_Sen_SensorEventHighThresholdCrossUpward 0x818
+#define HidUsage_Sen_SensorEventHighThresholdCrossDownward 0x819
+#define HidUsage_Sen_SensorEventLowThresholdCrossUpward 0x81a
+#define HidUsage_Sen_SensorEventLowThresholdCrossDownward 0x81b
+#define HidUsage_Sen_SensorEventZeroThresholdCrossUpward 0x81c
+#define HidUsage_Sen_SensorEventZeroThresholdCrossDownward 0x81d
+#define HidUsage_Sen_SensorEventPeriodExceeded 0x81e
+#define HidUsage_Sen_SensorEventFrequencyExceeded 0x81f
+#define HidUsage_Sen_SensorEventComplexTrigger 0x820
+#define HidUsage_Sen_ConnectionTypePCIntegrated 0x830
+#define HidUsage_Sen_ConnectionTypePCAttached 0x831
+#define HidUsage_Sen_ConnectionTypePCExternal 0x832
+#define HidUsage_Sen_ReportingStateReportNoEvents 0x840
+#define HidUsage_Sen_ReportingStateReportAllEvents 0x841
+#define HidUsage_Sen_ReportingStateReportThresholdEvents 0x842
+#define HidUsage_Sen_ReportingStateWakeOnNoEvents 0x843
+#define HidUsage_Sen_ReportingStateWakeOnAllEvents 0x844
+#define HidUsage_Sen_ReportingStateWakeOnThresholdEvents 0x845
+#define HidUsage_Sen_ReportingStateAnytime 0x846
+#define HidUsage_Sen_PowerStateUndefined 0x850
+#define HidUsage_Sen_PowerStateD0FullPower 0x851
+#define HidUsage_Sen_PowerStateD1LowPower 0x852
+#define HidUsage_Sen_PowerStateD2StandbyPowerwithWakeup 0x853
+#define HidUsage_Sen_PowerStateD3SleepwithWakeup 0x854
+#define HidUsage_Sen_PowerStateD4PowerOff 0x855
+#define HidUsage_Sen_AccuracyDefault 0x860
+#define HidUsage_Sen_AccuracyHigh 0x861
+#define HidUsage_Sen_AccuracyMedium 0x862
+#define HidUsage_Sen_AccuracyLow 0x863
+#define HidUsage_Sen_FixQualityNoFix 0x870
+#define HidUsage_Sen_FixQualityGPS 0x871
+#define HidUsage_Sen_FixQualityDGPS 0x872
+#define HidUsage_Sen_FixTypeNoFix 0x880
+#define HidUsage_Sen_FixTypeGPSSPSModeFixValid 0x881
+#define HidUsage_Sen_FixTypeDGPSSPSModeFixValid 0x882
+#define HidUsage_Sen_FixTypeGPSPPSModeFixValid 0x883
+#define HidUsage_Sen_FixTypeRealTimeKinematic 0x884
+#define HidUsage_Sen_FixTypeFloatRTK 0x885
+#define HidUsage_Sen_FixTypeEstimateddeadreckoned 0x886
+#define HidUsage_Sen_FixTypeManualInputMode 0x887
+#define HidUsage_Sen_FixTypeSimulatorMode 0x888
+#define HidUsage_Sen_GPSOperationModeManual 0x890
+#define HidUsage_Sen_GPSOperationModeAutomatic 0x891
+#define HidUsage_Sen_GPSSelectionModeAutonomous 0x8a0
+#define HidUsage_Sen_GPSSelectionModeDGPS 0x8a1
+#define HidUsage_Sen_GPSSelectionModeEstimateddeadreckoned 0x8a2
+#define HidUsage_Sen_GPSSelectionModeManualInput 0x8a3
+#define HidUsage_Sen_GPSSelectionModeSimulator 0x8a4
+#define HidUsage_Sen_GPSSelectionModeDataNotValid 0x8a5
+#define HidUsage_Sen_GPSStatusDataValid 0x8b0
+#define HidUsage_Sen_GPSStatusDataNotValid 0x8b1
+#define HidUsage_Sen_DayofWeekSunday 0x8c0
+#define HidUsage_Sen_DayofWeekMonday 0x8c1
+#define HidUsage_Sen_DayofWeekTuesday 0x8c2
+#define HidUsage_Sen_DayofWeekWednesday 0x8c3
+#define HidUsage_Sen_DayofWeekThursday 0x8c4
+#define HidUsage_Sen_DayofWeekFriday 0x8c5
+#define HidUsage_Sen_DayofWeekSaturday 0x8c6
+#define HidUsage_Sen_KindCategory 0x8d0
+#define HidUsage_Sen_KindType 0x8d1
+#define HidUsage_Sen_KindEvent 0x8d2
+#define HidUsage_Sen_KindProperty 0x8d3
+#define HidUsage_Sen_KindDataField 0x8d4
+#define HidUsage_Sen_MagnetometerAccuracyLow 0x8e0
+#define HidUsage_Sen_MagnetometerAccuracyMedium 0x8e1
+#define HidUsage_Sen_MagnetometerAccuracyHigh 0x8e2
+#define HidUsage_Sen_SimpleOrientationDirectionNotRotated 0x8f0
+#define HidUsage_Sen_SimpleOrientationDirectionRotated90DegreesCCW 0x8f1
+#define HidUsage_Sen_SimpleOrientationDirectionRotated180DegreesCCW 0x8f2
+#define HidUsage_Sen_SimpleOrientationDirectionRotated270DegreesCCW 0x8f3
+#define HidUsage_Sen_SimpleOrientationDirectionFaceUp 0x8f4
+#define HidUsage_Sen_SimpleOrientationDirectionFaceDown 0x8f5
+#define HidUsage_Sen_VT_NULL 0x900
+#define HidUsage_Sen_VT_BOOL 0x901
+#define HidUsage_Sen_VT_UI1 0x902
+#define HidUsage_Sen_VT_I1 0x903
+#define HidUsage_Sen_VT_UI2 0x904
+#define HidUsage_Sen_VT_I2 0x905
+#define HidUsage_Sen_VT_UI4 0x906
+#define HidUsage_Sen_VT_I4 0x907
+#define HidUsage_Sen_VT_UI8 0x908
+#define HidUsage_Sen_VT_I8 0x909
+#define HidUsage_Sen_VT_R4 0x90a
+#define HidUsage_Sen_VT_R8 0x90b
+#define HidUsage_Sen_VT_WSTR 0x90c
+#define HidUsage_Sen_VT_STR 0x90d
+#define HidUsage_Sen_VT_CLSID 0x90e
+#define HidUsage_Sen_VT_VECTORVT_UI1 0x90f
+#define HidUsage_Sen_VT_F16E0 0x910
+#define HidUsage_Sen_VT_F16E1 0x911
+#define HidUsage_Sen_VT_F16E2 0x912
+#define HidUsage_Sen_VT_F16E3 0x913
+#define HidUsage_Sen_VT_F16E4 0x914
+#define HidUsage_Sen_VT_F16E5 0x915
+#define HidUsage_Sen_VT_F16E6 0x916
+#define HidUsage_Sen_VT_F16E7 0x917
+#define HidUsage_Sen_VT_F16E8 0x918
+#define HidUsage_Sen_VT_F16E9 0x919
+#define HidUsage_Sen_VT_F16EA 0x91a
+#define HidUsage_Sen_VT_F16EB 0x91b
+#define HidUsage_Sen_VT_F16EC 0x91c
+#define HidUsage_Sen_VT_F16ED 0x91d
+#define HidUsage_Sen_VT_F16EE 0x91e
+#define HidUsage_Sen_VT_F16EF 0x91f
+#define HidUsage_Sen_VT_F32E0 0x920
+#define HidUsage_Sen_VT_F32E1 0x921
+#define HidUsage_Sen_VT_F32E2 0x922
+#define HidUsage_Sen_VT_F32E3 0x923
+#define HidUsage_Sen_VT_F32E4 0x924
+#define HidUsage_Sen_VT_F32E5 0x925
+#define HidUsage_Sen_VT_F32E6 0x926
+#define HidUsage_Sen_VT_F32E7 0x927
+#define HidUsage_Sen_VT_F32E8 0x928
+#define HidUsage_Sen_VT_F32E9 0x929
+#define HidUsage_Sen_VT_F32EA 0x92a
+#define HidUsage_Sen_VT_F32EB 0x92b
+#define HidUsage_Sen_VT_F32EC 0x92c
+#define HidUsage_Sen_VT_F32ED 0x92d
+#define HidUsage_Sen_VT_F32EE 0x92e
+#define HidUsage_Sen_VT_F32EF 0x92f
+#define HidUsage_Sen_ActivityTypeUnknown 0x930
+#define HidUsage_Sen_ActivityTypeStationary 0x931
+#define HidUsage_Sen_ActivityTypeFidgeting 0x932
+#define HidUsage_Sen_ActivityTypeWalking 0x933
+#define HidUsage_Sen_ActivityTypeRunning 0x934
+#define HidUsage_Sen_ActivityTypeInVehicle 0x935
+#define HidUsage_Sen_ActivityTypeBiking 0x936
+#define HidUsage_Sen_ActivityTypeIdle 0x937
+#define HidUsage_Sen_UnitNotSpecified 0x940
+#define HidUsage_Sen_UnitLux 0x941
+#define HidUsage_Sen_UnitDegreesKelvin 0x942
+#define HidUsage_Sen_UnitDegreesCelsius 0x943
+#define HidUsage_Sen_UnitPascal 0x944
+#define HidUsage_Sen_UnitNewton 0x945
+#define HidUsage_Sen_UnitMetersSecond 0x946
+#define HidUsage_Sen_UnitKilogram 0x947
+#define HidUsage_Sen_UnitMeter 0x948
+#define HidUsage_Sen_UnitMetersSecondSecond 0x949
+#define HidUsage_Sen_UnitFarad 0x94a
+#define HidUsage_Sen_UnitAmpere 0x94b
+#define HidUsage_Sen_UnitWatt 0x94c
+#define HidUsage_Sen_UnitHenry 0x94d
+#define HidUsage_Sen_UnitOhm 0x94e
+#define HidUsage_Sen_UnitVolt 0x94f
+#define HidUsage_Sen_UnitHertz 0x950
+#define HidUsage_Sen_UnitBar 0x951
+#define HidUsage_Sen_UnitDegreesAnticlockwise 0x952
+#define HidUsage_Sen_UnitDegreesClockwise 0x953
+#define HidUsage_Sen_UnitDegrees 0x954
+#define HidUsage_Sen_UnitDegreesSecond 0x955
+#define HidUsage_Sen_UnitDegreesSecondSecond 0x956
+#define HidUsage_Sen_UnitKnot 0x957
+#define HidUsage_Sen_UnitPercent 0x958
+#define HidUsage_Sen_UnitSecond 0x959
+#define HidUsage_Sen_UnitMillisecond 0x95a
+#define HidUsage_Sen_UnitG 0x95b
+#define HidUsage_Sen_UnitBytes 0x95c
+#define HidUsage_Sen_UnitMilligauss 0x95d
+#define HidUsage_Sen_UnitBits 0x95e
+#define HidUsage_Sen_ActivityStateNoStateChange 0x960
+#define HidUsage_Sen_ActivityStateStartActivity 0x961
+#define HidUsage_Sen_ActivityStateEndActivity 0x962
+#define HidUsage_Sen_Exponent0 0x970
+#define HidUsage_Sen_Exponent1 0x971
+#define HidUsage_Sen_Exponent2 0x972
+#define HidUsage_Sen_Exponent3 0x973
+#define HidUsage_Sen_Exponent4 0x974
+#define HidUsage_Sen_Exponent5 0x975
+#define HidUsage_Sen_Exponent6 0x976
+#define HidUsage_Sen_Exponent7 0x977
+#define HidUsage_Sen_Exponent8 0x978
+#define HidUsage_Sen_Exponent9 0x979
+#define HidUsage_Sen_ExponentA 0x97a
+#define HidUsage_Sen_ExponentB 0x97b
+#define HidUsage_Sen_ExponentC 0x97c
+#define HidUsage_Sen_ExponentD 0x97d
+#define HidUsage_Sen_ExponentE 0x97e
+#define HidUsage_Sen_ExponentF 0x97f
+#define HidUsage_Sen_DevicePositionUnknown 0x980
+#define HidUsage_Sen_DevicePositionUnchanged 0x981
+#define HidUsage_Sen_DevicePositionOnDesk 0x982
+#define HidUsage_Sen_DevicePositionInHand 0x983
+#define HidUsage_Sen_DevicePositionMovinginBag 0x984
+#define HidUsage_Sen_DevicePositionStationaryinBag 0x985
+#define HidUsage_Sen_StepTypeUnknown 0x990
+#define HidUsage_Sen_StepTypeWalking 0x991
+#define HidUsage_Sen_StepTypeRunning 0x992
+#define HidUsage_Sen_GestureStateUnknown 0x9a0
+#define HidUsage_Sen_GestureStateStarted 0x9a1
+#define HidUsage_Sen_GestureStateCompleted 0x9a2
+#define HidUsage_Sen_GestureStateCancelled 0x9a3
+#define HidUsage_Sen_HingeFoldContributingPanelUnknown 0x9b0
+#define HidUsage_Sen_HingeFoldContributingPanelPanel1 0x9b1
+#define HidUsage_Sen_HingeFoldContributingPanelPanel2 0x9b2
+#define HidUsage_Sen_HingeFoldContributingPanelBoth 0x9b3
+#define HidUsage_Sen_HingeFoldTypeUnknown 0x9b4
+#define HidUsage_Sen_HingeFoldTypeIncreasing 0x9b5
+#define HidUsage_Sen_HingeFoldTypeDecreasing 0x9b6
+#define HidUsage_Sen_HumanPresenceDetectionTypeVendorDefinedNonBiometric 0x9c0
+#define HidUsage_Sen_HumanPresenceDetectionTypeVendorDefinedBiometric 0x9c1
+#define HidUsage_Sen_HumanPresenceDetectionTypeFacialBiometric 0x9c2
+#define HidUsage_Sen_HumanPresenceDetectionTypeAudioBiometric 0x9c3
+#define HidUsage_Sen_ModifierChangeSensitivityAbsolute 0x1000
+#define HidUsage_Sen_ModifierMaximum 0x2000
+#define HidUsage_Sen_ModifierMinimum 0x3000
+#define HidUsage_Sen_ModifierAccuracy 0x4000
+#define HidUsage_Sen_ModifierResolution 0x5000
+#define HidUsage_Sen_ModifierThresholdHigh 0x6000
+#define HidUsage_Sen_ModifierThresholdLow 0x7000
+#define HidUsage_Sen_ModifierCalibrationOffset 0x8000
+#define HidUsage_Sen_ModifierCalibrationMultiplier 0x9000
+#define HidUsage_Sen_ModifierReportInterval 0xa000
+#define HidUsage_Sen_ModifierFrequencyMax 0xb000
+#define HidUsage_Sen_ModifierPeriodMax 0xc000
+#define HidUsage_Sen_ModifierChangeSensitivityPercentofRange 0xd000
+#define HidUsage_Sen_ModifierChangeSensitivityPercentRelative 0xe000
+#define HidUsage_Sen_ModifierVendorReserved 0xf000
+#define HidUsage_MI_MedicalUltrasound 0x01
+#define HidUsage_MI_VCRAcquisition 0x20
+#define HidUsage_MI_FreezeThaw 0x21
+#define HidUsage_MI_ClipStore 0x22
+#define HidUsage_MI_Update 0x23
+#define HidUsage_MI_Next 0x24
+#define HidUsage_MI_Save 0x25
+#define HidUsage_MI_Print 0x26
+#define HidUsage_MI_MicrophoneEnable 0x27
+#define HidUsage_MI_Cine 0x40
+#define HidUsage_MI_TransmitPower 0x41
+#define HidUsage_MI_Volume 0x42
+#define HidUsage_MI_Focus 0x43
+#define HidUsage_MI_Depth 0x44
+#define HidUsage_MI_SoftStepPrimary 0x60
+#define HidUsage_MI_SoftStepSecondary 0x61
+#define HidUsage_MI_DepthGainCompensation 0x70
+#define HidUsage_MI_ZoomSelect 0x80
+#define HidUsage_MI_ZoomAdjust 0x81
+#define HidUsage_MI_SpectralDopplerModeSelect 0x82
+#define HidUsage_MI_SpectralDopplerAdjust 0x83
+#define HidUsage_MI_ColorDopplerModeSelect 0x84
+#define HidUsage_MI_ColorDopplerAdjust 0x85
+#define HidUsage_MI_MotionModeSelect 0x86
+#define HidUsage_MI_MotionModeAdjust 0x87
+#define HidUsage_MI_TwoDModeSelect 0x88
+#define HidUsage_MI_TwoDModeAdjust 0x89
+#define HidUsage_MI_SoftControlSelect 0xa0
+#define HidUsage_MI_SoftControlAdjust 0xa1
+#define HidUsage_BD_BrailleDisplay 0x01
+#define HidUsage_BD_BrailleRow 0x02
+#define HidUsage_BD_EightDotBrailleCell 0x03
+#define HidUsage_BD_SixDotBrailleCell 0x04
+#define HidUsage_BD_NumberofBrailleCells 0x05
+#define HidUsage_BD_ScreenReaderControl 0x06
+#define HidUsage_BD_ScreenReaderIdentifier 0x07
+#define HidUsage_BD_RouterSet1 0xfa
+#define HidUsage_BD_RouterSet2 0xfb
+#define HidUsage_BD_RouterSet3 0xfc
+#define HidUsage_BD_RouterKey 0x100
+#define HidUsage_BD_RowRouterKey 0x101
+#define HidUsage_BD_BrailleButtons 0x200
+#define HidUsage_BD_BrailleKeyboardDot1 0x201
+#define HidUsage_BD_BrailleKeyboardDot2 0x202
+#define HidUsage_BD_BrailleKeyboardDot3 0x203
+#define HidUsage_BD_BrailleKeyboardDot4 0x204
+#define HidUsage_BD_BrailleKeyboardDot5 0x205
+#define HidUsage_BD_BrailleKeyboardDot6 0x206
+#define HidUsage_BD_BrailleKeyboardDot7 0x207
+#define HidUsage_BD_BrailleKeyboardDot8 0x208
+#define HidUsage_BD_BrailleKeyboardSpace 0x209
+#define HidUsage_BD_BrailleKeyboardLeftSpace 0x20a
+#define HidUsage_BD_BrailleKeyboardRightSpace 0x20b
+#define HidUsage_BD_BrailleFaceControls 0x20c
+#define HidUsage_BD_BrailleLeftControls 0x20d
+#define HidUsage_BD_BrailleRightControls 0x20e
+#define HidUsage_BD_BrailleTopControls 0x20f
+#define HidUsage_BD_BrailleJoystickCenter 0x210
+#define HidUsage_BD_BrailleJoystickUp 0x211
+#define HidUsage_BD_BrailleJoystickDown 0x212
+#define HidUsage_BD_BrailleJoystickLeft 0x213
+#define HidUsage_BD_BrailleJoystickRight 0x214
+#define HidUsage_BD_BrailleDPadCenter 0x215
+#define HidUsage_BD_BrailleDPadUp 0x216
+#define HidUsage_BD_BrailleDPadDown 0x217
+#define HidUsage_BD_BrailleDPadLeft 0x218
+#define HidUsage_BD_BrailleDPadRight 0x219
+#define HidUsage_BD_BraillePanLeft 0x21a
+#define HidUsage_BD_BraillePanRight 0x21b
+#define HidUsage_BD_BrailleRockerUp 0x21c
+#define HidUsage_BD_BrailleRockerDown 0x21d
+#define HidUsage_BD_BrailleRockerPress 0x21e
+#define HidUsage_LAI_LampArray 0x01
+#define HidUsage_LAI_LampArrayAttributesReport 0x02
+#define HidUsage_LAI_LampCount 0x03
+#define HidUsage_LAI_BoundingBoxWidthInMicrometers 0x04
+#define HidUsage_LAI_BoundingBoxHeightInMicrometers 0x05
+#define HidUsage_LAI_BoundingBoxDepthInMicrometers 0x06
+#define HidUsage_LAI_LampArrayKind 0x07
+#define HidUsage_LAI_MinUpdateIntervalInMicroseconds 0x08
+#define HidUsage_LAI_LampAttributesRequestReport 0x20
+#define HidUsage_LAI_LampId 0x21
+#define HidUsage_LAI_LampAttributesResponseReport 0x22
+#define HidUsage_LAI_PositionXInMicrometers 0x23
+#define HidUsage_LAI_PositionYInMicrometers 0x24
+#define HidUsage_LAI_PositionZInMicrometers 0x25
+#define HidUsage_LAI_LampPurposes 0x26
+#define HidUsage_LAI_UpdateLatencyInMicroseconds 0x27
+#define HidUsage_LAI_RedLevelCount 0x28
+#define HidUsage_LAI_GreenLevelCount 0x29
+#define HidUsage_LAI_BlueLevelCount 0x2a
+#define HidUsage_LAI_IntensityLevelCount 0x2b
+#define HidUsage_LAI_IsProgrammable 0x2c
+#define HidUsage_LAI_InputBinding 0x2d
+#define HidUsage_LAI_LampMultiUpdateReport 0x50
+#define HidUsage_LAI_RedUpdateChannel 0x51
+#define HidUsage_LAI_GreenUpdateChannel 0x52
+#define HidUsage_LAI_BlueUpdateChannel 0x53
+#define HidUsage_LAI_IntensityUpdateChannel 0x54
+#define HidUsage_LAI_LampUpdateFlags 0x55
+#define HidUsage_LAI_LampRangeUpdateReport 0x60
+#define HidUsage_LAI_LampIdStart 0x61
+#define HidUsage_LAI_LampIdEnd 0x62
+#define HidUsage_LAI_LampArrayControlReport 0x70
+#define HidUsage_LAI_AutonomousMode 0x71
+#define HidUsage_Mon_MonitorControl 0x01
+#define HidUsage_Mon_EDIDInformation 0x02
+#define HidUsage_Mon_VDIFInformation 0x03
+#define HidUsage_Mon_VESAVersion 0x04
+#define HidUsage_VESAVC_Degauss 0x01
+#define HidUsage_VESAVC_Brightness 0x10
+#define HidUsage_VESAVC_Contrast 0x12
+#define HidUsage_VESAVC_RedVideoGain 0x16
+#define HidUsage_VESAVC_GreenVideoGain 0x18
+#define HidUsage_VESAVC_BlueVideoGain 0x1a
+#define HidUsage_VESAVC_Focus 0x1c
+#define HidUsage_VESAVC_HorizontalPosition 0x20
+#define HidUsage_VESAVC_HorizontalSize 0x22
+#define HidUsage_VESAVC_HorizontalPincushion 0x24
+#define HidUsage_VESAVC_HorizontalPincushionBalance 0x26
+#define HidUsage_VESAVC_HorizontalMisconvergence 0x28
+#define HidUsage_VESAVC_HorizontalLinearity 0x2a
+#define HidUsage_VESAVC_HorizontalLinearityBalance 0x2c
+#define HidUsage_VESAVC_VerticalPosition 0x30
+#define HidUsage_VESAVC_VerticalSize 0x32
+#define HidUsage_VESAVC_VerticalPincushion 0x34
+#define HidUsage_VESAVC_VerticalPincushionBalance 0x36
+#define HidUsage_VESAVC_VerticalMisconvergence 0x38
+#define HidUsage_VESAVC_VerticalLinearity 0x3a
+#define HidUsage_VESAVC_VerticalLinearityBalance 0x3c
+#define HidUsage_VESAVC_ParallelogramDistortionKeyBalance 0x40
+#define HidUsage_VESAVC_TrapezoidalDistortionKey 0x42
+#define HidUsage_VESAVC_TiltRotation 0x44
+#define HidUsage_VESAVC_TopCornerDistortionControl 0x46
+#define HidUsage_VESAVC_TopCornerDistortionBalance 0x48
+#define HidUsage_VESAVC_BottomCornerDistortionControl 0x4a
+#define HidUsage_VESAVC_BottomCornerDistortionBalance 0x4c
+#define HidUsage_VESAVC_HorizontalMoiré 0x56
+#define HidUsage_VESAVC_VerticalMoiré 0x58
+#define HidUsage_VESAVC_InputLevelSelect 0x5e
+#define HidUsage_VESAVC_InputSourceSelect 0x60
+#define HidUsage_VESAVC_RedVideoBlackLevel 0x6c
+#define HidUsage_VESAVC_GreenVideoBlackLevel 0x6e
+#define HidUsage_VESAVC_BlueVideoBlackLevel 0x70
+#define HidUsage_VESAVC_AutoSizeCenter 0xa2
+#define HidUsage_VESAVC_PolarityHorizontalSynchronization 0xa4
+#define HidUsage_VESAVC_PolarityVerticalSynchronization 0xa6
+#define HidUsage_VESAVC_SynchronizationType 0xa8
+#define HidUsage_VESAVC_ScreenOrientation 0xaa
+#define HidUsage_VESAVC_HorizontalFrequency 0xac
+#define HidUsage_VESAVC_VerticalFrequency 0xae
+#define HidUsage_VESAVC_Settings 0xb0
+#define HidUsage_VESAVC_OnScreenDisplay 0xca
+#define HidUsage_VESAVC_StereoMode 0xd4
+#define HidUsage_Pow_iName 0x01
+#define HidUsage_Pow_PresentStatus 0x02
+#define HidUsage_Pow_ChangedStatus 0x03
+#define HidUsage_Pow_UPS 0x04
+#define HidUsage_Pow_PowerSupply 0x05
+#define HidUsage_Pow_BatterySystem 0x10
+#define HidUsage_Pow_BatterySystemId 0x11
+#define HidUsage_Pow_Battery 0x12
+#define HidUsage_Pow_BatteryId 0x13
+#define HidUsage_Pow_Charger 0x14
+#define HidUsage_Pow_ChargerId 0x15
+#define HidUsage_Pow_PowerConverter 0x16
+#define HidUsage_Pow_PowerConverterId 0x17
+#define HidUsage_Pow_OutletSystem 0x18
+#define HidUsage_Pow_OutletSystemId 0x19
+#define HidUsage_Pow_Input 0x1a
+#define HidUsage_Pow_InputId 0x1b
+#define HidUsage_Pow_Output 0x1c
+#define HidUsage_Pow_OutputId 0x1d
+#define HidUsage_Pow_Flow 0x1e
+#define HidUsage_Pow_FlowId 0x1f
+#define HidUsage_Pow_Outlet 0x20
+#define HidUsage_Pow_OutletId 0x21
+#define HidUsage_Pow_Gang 0x22
+#define HidUsage_Pow_GangId 0x23
+#define HidUsage_Pow_PowerSummary 0x24
+#define HidUsage_Pow_PowerSummaryId 0x25
+#define HidUsage_Pow_Voltage 0x30
+#define HidUsage_Pow_Current 0x31
+#define HidUsage_Pow_Frequency 0x32
+#define HidUsage_Pow_ApparentPower 0x33
+#define HidUsage_Pow_ActivePower 0x34
+#define HidUsage_Pow_PercentLoad 0x35
+#define HidUsage_Pow_Temperature 0x36
+#define HidUsage_Pow_Humidity 0x37
+#define HidUsage_Pow_BadCount 0x38
+#define HidUsage_Pow_ConfigVoltage 0x40
+#define HidUsage_Pow_ConfigCurrent 0x41
+#define HidUsage_Pow_ConfigFrequency 0x42
+#define HidUsage_Pow_ConfigApparentPower 0x43
+#define HidUsage_Pow_ConfigActivePower 0x44
+#define HidUsage_Pow_ConfigPercentLoad 0x45
+#define HidUsage_Pow_ConfigTemperature 0x46
+#define HidUsage_Pow_ConfigHumidity 0x47
+#define HidUsage_Pow_SwitchOnControl 0x50
+#define HidUsage_Pow_SwitchOffControl 0x51
+#define HidUsage_Pow_ToggleControl 0x52
+#define HidUsage_Pow_LowVoltageTransfer 0x53
+#define HidUsage_Pow_HighVoltageTransfer 0x54
+#define HidUsage_Pow_DelayBeforeReboot 0x55
+#define HidUsage_Pow_DelayBeforeStartup 0x56
+#define HidUsage_Pow_DelayBeforeShutdown 0x57
+#define HidUsage_Pow_Test 0x58
+#define HidUsage_Pow_ModuleReset 0x59
+#define HidUsage_Pow_AudibleAlarmControl 0x5a
+#define HidUsage_Pow_Present 0x60
+#define HidUsage_Pow_Good 0x61
+#define HidUsage_Pow_InternalFailure 0x62
+#define HidUsage_Pow_VoltagOutOfRange 0x63
+#define HidUsage_Pow_FrequencyOutOfRange 0x64
+#define HidUsage_Pow_Overload 0x65
+#define HidUsage_Pow_OverCharged 0x66
+#define HidUsage_Pow_OverTemperature 0x67
+#define HidUsage_Pow_ShutdownRequested 0x68
+#define HidUsage_Pow_ShutdownImminent 0x69
+#define HidUsage_Pow_SwitchOnOff 0x6b
+#define HidUsage_Pow_Switchable 0x6c
+#define HidUsage_Pow_Used 0x6d
+#define HidUsage_Pow_Boost 0x6e
+#define HidUsage_Pow_Buck 0x6f
+#define HidUsage_Pow_Initialized 0x70
+#define HidUsage_Pow_Tested 0x71
+#define HidUsage_Pow_AwaitingPower 0x72
+#define HidUsage_Pow_CommunicationLost 0x73
+#define HidUsage_Pow_iManufacturer 0xfd
+#define HidUsage_Pow_iProduct 0xfe
+#define HidUsage_Pow_iSerialNumber 0xff
+#define HidUsage_BS_SmartBatteryBatteryMode 0x01
+#define HidUsage_BS_SmartBatteryBatteryStatus 0x02
+#define HidUsage_BS_SmartBatteryAlarmWarning 0x03
+#define HidUsage_BS_SmartBatteryChargerMode 0x04
+#define HidUsage_BS_SmartBatteryChargerStatus 0x05
+#define HidUsage_BS_SmartBatteryChargerSpecInfo 0x06
+#define HidUsage_BS_SmartBatterySelectorState 0x07
+#define HidUsage_BS_SmartBatterySelectorPresets 0x08
+#define HidUsage_BS_SmartBatterySelectorInfo 0x09
+#define HidUsage_BS_OptionalMfgFunction1 0x10
+#define HidUsage_BS_OptionalMfgFunction2 0x11
+#define HidUsage_BS_OptionalMfgFunction3 0x12
+#define HidUsage_BS_OptionalMfgFunction4 0x13
+#define HidUsage_BS_OptionalMfgFunction5 0x14
+#define HidUsage_BS_ConnectionToSMBus 0x15
+#define HidUsage_BS_OutputConnection 0x16
+#define HidUsage_BS_ChargerConnection 0x17
+#define HidUsage_BS_BatteryInsertion 0x18
+#define HidUsage_BS_UseNext 0x19
+#define HidUsage_BS_OKToUse 0x1a
+#define HidUsage_BS_BatterySupported 0x1b
+#define HidUsage_BS_SelectorRevision 0x1c
+#define HidUsage_BS_ChargingIndicator 0x1d
+#define HidUsage_BS_ManufacturerAccess 0x28
+#define HidUsage_BS_RemainingCapacityLimit 0x29
+#define HidUsage_BS_RemainingTimeLimit 0x2a
+#define HidUsage_BS_AtRate 0x2b
+#define HidUsage_BS_CapacityMode 0x2c
+#define HidUsage_BS_BroadcastToCharger 0x2d
+#define HidUsage_BS_PrimaryBattery 0x2e
+#define HidUsage_BS_ChargeController 0x2f
+#define HidUsage_BS_TerminateCharge 0x40
+#define HidUsage_BS_TerminateDischarge 0x41
+#define HidUsage_BS_BelowRemainingCapacityLimit 0x42
+#define HidUsage_BS_RemainingTimeLimitExpired 0x43
+#define HidUsage_BS_Charging 0x44
+#define HidUsage_BS_Discharging 0x45
+#define HidUsage_BS_FullyCharged 0x46
+#define HidUsage_BS_FullyDischarged 0x47
+#define HidUsage_BS_ConditioningFlag 0x48
+#define HidUsage_BS_AtRateOK 0x49
+#define HidUsage_BS_SmartBatteryErrorCode 0x4a
+#define HidUsage_BS_NeedReplacement 0x4b
+#define HidUsage_BS_AtRateTimeToFull 0x60
+#define HidUsage_BS_AtRateTimeToEmpty 0x61
+#define HidUsage_BS_AverageCurrent 0x62
+#define HidUsage_BS_MaxError 0x63
+#define HidUsage_BS_RelativeStateOfCharge 0x64
+#define HidUsage_BS_AbsoluteStateOfCharge 0x65
+#define HidUsage_BS_RemainingCapacity 0x66
+#define HidUsage_BS_FullChargeCapacity 0x67
+#define HidUsage_BS_RunTimeToEmpty 0x68
+#define HidUsage_BS_AverageTimeToEmpty 0x69
+#define HidUsage_BS_AverageTimeToFull 0x6a
+#define HidUsage_BS_CycleCount 0x6b
+#define HidUsage_BS_BatteryPackModelLevel 0x80
+#define HidUsage_BS_InternalChargeController 0x81
+#define HidUsage_BS_PrimaryBatterySupport 0x82
+#define HidUsage_BS_DesignCapacity 0x83
+#define HidUsage_BS_SpecificationInfo 0x84
+#define HidUsage_BS_ManufactureDate 0x85
+#define HidUsage_BS_SerialNumber 0x86
+#define HidUsage_BS_iManufacturerName 0x87
+#define HidUsage_BS_iDeviceName 0x88
+#define HidUsage_BS_iDeviceChemistry 0x89
+#define HidUsage_BS_ManufacturerData 0x8a
+#define HidUsage_BS_Rechargeable 0x8b
+#define HidUsage_BS_WarningCapacityLimit 0x8c
+#define HidUsage_BS_CapacityGranularity1 0x8d
+#define HidUsage_BS_CapacityGranularity2 0x8e
+#define HidUsage_BS_iOEMInformation 0x8f
+#define HidUsage_BS_InhibitCharge 0xc0
+#define HidUsage_BS_EnablePolling 0xc1
+#define HidUsage_BS_ResetToZero 0xc2
+#define HidUsage_BS_ACPresent 0xd0
+#define HidUsage_BS_BatteryPresent 0xd1
+#define HidUsage_BS_PowerFail 0xd2
+#define HidUsage_BS_AlarmInhibited 0xd3
+#define HidUsage_BS_ThermistorUnderRange 0xd4
+#define HidUsage_BS_ThermistorHot 0xd5
+#define HidUsage_BS_ThermistorCold 0xd6
+#define HidUsage_BS_ThermistorOverRange 0xd7
+#define HidUsage_BS_VoltageOutOfRange 0xd8
+#define HidUsage_BS_CurrentOutOfRange 0xd9
+#define HidUsage_BS_CurrentNotRegulated 0xda
+#define HidUsage_BS_VoltageNotRegulated 0xdb
+#define HidUsage_BS_MasterMode 0xdc
+#define HidUsage_BS_ChargerSelectorSupport 0xf0
+#define HidUsage_BS_ChargerSpec 0xf1
+#define HidUsage_BS_Level2 0xf2
+#define HidUsage_BS_Level3 0xf3
+#define HidUsage_BS_BarcodeBadgeReader 0x01
+#define HidUsage_BS_BarcodeScanner 0x02
+#define HidUsage_BS_DumbBarCodeScanner 0x03
+#define HidUsage_BS_CordlessScannerBase 0x04
+#define HidUsage_BS_BarCodeScannerCradle 0x05
+#define HidUsage_BS_AttributeReport 0x10
+#define HidUsage_BS_SettingsReport 0x11
+#define HidUsage_BS_ScannedDataReport 0x12
+#define HidUsage_BS_RawScannedDataReport 0x13
+#define HidUsage_BS_TriggerReport 0x14
+#define HidUsage_BS_StatusReport 0x15
+#define HidUsage_BS_UPCEANControlReport 0x16
+#define HidUsage_BS_EAN23LabelControlReport 0x17
+#define HidUsage_BS_Code39ControlReport 0x18
+#define HidUsage_BS_Interleaved2of5ControlReport 0x19
+#define HidUsage_BS_Standard2of5ControlReport 0x1a
+#define HidUsage_BS_MSIPlesseyControlReport 0x1b
+#define HidUsage_BS_CodabarControlReport 0x1c
+#define HidUsage_BS_Code128ControlReport 0x1d
+#define HidUsage_BS_Misc1DControlReport 0x1e
+#define HidUsage_BS_TwoDControlReport 0x1f
+#define HidUsage_BS_AimingPointerMode 0x30
+#define HidUsage_BS_BarCodePresentSensor 0x31
+#define HidUsage_BS_Class1ALaser 0x32
+#define HidUsage_BS_Class2Laser 0x33
+#define HidUsage_BS_HeaterPresent 0x34
+#define HidUsage_BS_ContactScanner 0x35
+#define HidUsage_BS_ElectronicArticleSurveillanceNotification 0x36
+#define HidUsage_BS_ConstantElectronicArticleSurveillance 0x37
+#define HidUsage_BS_ErrorIndication 0x38
+#define HidUsage_BS_FixedBeeper 0x39
+#define HidUsage_BS_GoodDecodeIndication 0x3a
+#define HidUsage_BS_HandsFreeScanning 0x3b
+#define HidUsage_BS_IntrinsicallySafe 0x3c
+#define HidUsage_BS_KlasseEinsLaser 0x3d
+#define HidUsage_BS_LongRangeScanner 0x3e
+#define HidUsage_BS_MirrorSpeedControl 0x3f
+#define HidUsage_BS_NotOnFileIndication 0x40
+#define HidUsage_BS_ProgrammableBeeper 0x41
+#define HidUsage_BS_Triggerless 0x42
+#define HidUsage_BS_Wand 0x43
+#define HidUsage_BS_WaterResistant 0x44
+#define HidUsage_BS_MultiRangeScanner 0x45
+#define HidUsage_BS_ProximitySensor 0x46
+#define HidUsage_BS_FragmentDecoding 0x4d
+#define HidUsage_BS_ScannerReadConfidence 0x4e
+#define HidUsage_BS_DataPrefix 0x4f
+#define HidUsage_BS_PrefixAIMI 0x50
+#define HidUsage_BS_PrefixNone 0x51
+#define HidUsage_BS_PrefixProprietary 0x52
+#define HidUsage_BS_ActiveTime 0x55
+#define HidUsage_BS_AimingLaserPattern 0x56
+#define HidUsage_BS_BarCodePresent 0x57
+#define HidUsage_BS_BeeperState 0x58
+#define HidUsage_BS_LaserOnTime 0x59
+#define HidUsage_BS_LaserState 0x5a
+#define HidUsage_BS_LockoutTime 0x5b
+#define HidUsage_BS_MotorState 0x5c
+#define HidUsage_BS_MotorTimeout 0x5d
+#define HidUsage_BS_PowerOnResetScanner 0x5e
+#define HidUsage_BS_PreventReadofBarcodes 0x5f
+#define HidUsage_BS_InitiateBarcodeRead 0x60
+#define HidUsage_BS_TriggerState 0x61
+#define HidUsage_BS_TriggerMode 0x62
+#define HidUsage_BS_TriggerModeBlinkingLaserOn 0x63
+#define HidUsage_BS_TriggerModeContinuousLaserOn 0x64
+#define HidUsage_BS_TriggerModeLaseronwhilePulled 0x65
+#define HidUsage_BS_TriggerModeLaserstaysonafterrelease 0x66
+#define HidUsage_BS_CommitParameterstoNVM 0x6d
+#define HidUsage_BS_ParameterScanning 0x6e
+#define HidUsage_BS_ParametersChanged 0x6f
+#define HidUsage_BS_Setparameterdefaultvalues 0x70
+#define HidUsage_BS_ScannerInCradle 0x75
+#define HidUsage_BS_ScannerInRange 0x76
+#define HidUsage_BS_AimDuration 0x7a
+#define HidUsage_BS_GoodReadLampDuration 0x7b
+#define HidUsage_BS_GoodReadLampIntensity 0x7c
+#define HidUsage_BS_GoodReadLED 0x7d
+#define HidUsage_BS_GoodReadToneFrequency 0x7e
+#define HidUsage_BS_GoodReadToneLength 0x7f
+#define HidUsage_BS_GoodReadToneVolume 0x80
+#define HidUsage_BS_NoReadMessage 0x82
+#define HidUsage_BS_NotonFileVolume 0x83
+#define HidUsage_BS_PowerupBeep 0x84
+#define HidUsage_BS_SoundErrorBeep 0x85
+#define HidUsage_BS_SoundGoodReadBeep 0x86
+#define HidUsage_BS_SoundNotOnFileBeep 0x87
+#define HidUsage_BS_GoodReadWhentoWrite 0x88
+#define HidUsage_BS_GRWTIAfterDecode 0x89
+#define HidUsage_BS_GRWTIBeepLampaftertransmit 0x8a
+#define HidUsage_BS_GRWTINoBeepLampuseatall 0x8b
+#define HidUsage_BS_BooklandEAN 0x91
+#define HidUsage_BS_ConvertEAN8to13Type 0x92
+#define HidUsage_BS_ConvertUPCAtoEAN13 0x93
+#define HidUsage_BS_ConvertUPCEtoA 0x94
+#define HidUsage_BS_EAN13 0x95
+#define HidUsage_BS_EAN8 0x96
+#define HidUsage_BS_EAN99128Mandatory 0x97
+#define HidUsage_BS_EAN99P5128Optional 0x98
+#define HidUsage_BS_EnableEANTwoLabel 0x99
+#define HidUsage_BS_UPCEAN 0x9a
+#define HidUsage_BS_UPCEANCouponCode 0x9b
+#define HidUsage_BS_UPCEANPeriodicals 0x9c
+#define HidUsage_BS_UPCA 0x9d
+#define HidUsage_BS_UPCAwith128Mandatory 0x9e
+#define HidUsage_BS_UPCAwith128Optional 0x9f
+#define HidUsage_BS_UPCAwithP5Optional 0xa0
+#define HidUsage_BS_UPCE 0xa1
+#define HidUsage_BS_UPCE1 0xa2
+#define HidUsage_BS_Periodical 0xa9
+#define HidUsage_BS_PeriodicalAutoDiscriminatePlus2 0xaa
+#define HidUsage_BS_PeriodicalOnlyDecodewithPlus2 0xab
+#define HidUsage_BS_PeriodicalIgnorePlus2 0xac
+#define HidUsage_BS_PeriodicalAutoDiscriminatePlus5 0xad
+#define HidUsage_BS_PeriodicalOnlyDecodewithPlus5 0xae
+#define HidUsage_BS_PeriodicalIgnorePlus5 0xaf
+#define HidUsage_BS_Check 0xb0
+#define HidUsage_BS_CheckDisablePrice 0xb1
+#define HidUsage_BS_CheckEnable4digitPrice 0xb2
+#define HidUsage_BS_CheckEnable5digitPrice 0xb3
+#define HidUsage_BS_CheckEnableEuropean4digitPrice 0xb4
+#define HidUsage_BS_CheckEnableEuropean5digitPrice 0xb5
+#define HidUsage_BS_EANTwoLabel 0xb7
+#define HidUsage_BS_EANThreeLabel 0xb8
+#define HidUsage_BS_EAN8FlagDigit1 0xb9
+#define HidUsage_BS_EAN8FlagDigit2 0xba
+#define HidUsage_BS_EAN8FlagDigit3 0xbb
+#define HidUsage_BS_EAN13FlagDigit1 0xbc
+#define HidUsage_BS_EAN13FlagDigit2 0xbd
+#define HidUsage_BS_EAN13FlagDigit3 0xbe
+#define HidUsage_BS_AddEAN23LabelDefinition 0xbf
+#define HidUsage_BS_ClearallEAN23LabelDefinitions 0xc0
+#define HidUsage_BS_Codabar 0xc3
+#define HidUsage_BS_Code128 0xc4
+#define HidUsage_BS_Code39 0xc7
+#define HidUsage_BS_Code93 0xc8
+#define HidUsage_BS_FullASCIIConversion 0xc9
+#define HidUsage_BS_Interleaved2of5 0xca
+#define HidUsage_BS_ItalianPharmacyCode 0xcb
+#define HidUsage_BS_MSIPlessey 0xcc
+#define HidUsage_BS_Standard2of5IATA 0xcd
+#define HidUsage_BS_Standard2of5 0xce
+#define HidUsage_BS_TransmitStartStop 0xd3
+#define HidUsage_BS_TriOptic 0xd4
+#define HidUsage_BS_UCCEAN128 0xd5
+#define HidUsage_BS_CheckDigit 0xd6
+#define HidUsage_BS_CheckDigitDisable 0xd7
+#define HidUsage_BS_CheckDigitEnableInterleaved2of5OPCC 0xd8
+#define HidUsage_BS_CheckDigitEnableInterleaved2of5USS 0xd9
+#define HidUsage_BS_CheckDigitEnableStandard2of5OPCC 0xda
+#define HidUsage_BS_CheckDigitEnableStandard2of5USS 0xdb
+#define HidUsage_BS_CheckDigitEnableOneMSIPlessey 0xdc
+#define HidUsage_BS_CheckDigitEnableTwoMSIPlessey 0xdd
+#define HidUsage_BS_CheckDigitCodabarEnable 0xde
+#define HidUsage_BS_CheckDigitCode39Enable 0xdf
+#define HidUsage_BS_TransmitCheckDigit 0xf0
+#define HidUsage_BS_DisableCheckDigitTransmit 0xf1
+#define HidUsage_BS_EnableCheckDigitTransmit 0xf2
+#define HidUsage_BS_SymbologyIdentifier1 0xfb
+#define HidUsage_BS_SymbologyIdentifier2 0xfc
+#define HidUsage_BS_SymbologyIdentifier3 0xfd
+#define HidUsage_BS_DecodedData 0xfe
+#define HidUsage_BS_DecodeDataContinued 0xff
+#define HidUsage_BS_BarSpaceData 0x100
+#define HidUsage_BS_ScannerDataAccuracy 0x101
+#define HidUsage_BS_RawDataPolarity 0x102
+#define HidUsage_BS_PolarityInvertedBarCode 0x103
+#define HidUsage_BS_PolarityNormalBarCode 0x104
+#define HidUsage_BS_MinimumLengthtoDecode 0x106
+#define HidUsage_BS_MaximumLengthtoDecode 0x107
+#define HidUsage_BS_DiscreteLengthtoDecode1 0x108
+#define HidUsage_BS_DiscreteLengthtoDecode2 0x109
+#define HidUsage_BS_DataLengthMethod 0x10a
+#define HidUsage_BS_DLMethodReadany 0x10b
+#define HidUsage_BS_DLMethodCheckinRange 0x10c
+#define HidUsage_BS_DLMethodCheckforDiscrete 0x10d
+#define HidUsage_BS_AztecCode 0x110
+#define HidUsage_BS_BC412 0x111
+#define HidUsage_BS_ChannelCode 0x112
+#define HidUsage_BS_Code16 0x113
+#define HidUsage_BS_Code32 0x114
+#define HidUsage_BS_Code49 0x115
+#define HidUsage_BS_CodeOne 0x116
+#define HidUsage_BS_Colorcode 0x117
+#define HidUsage_BS_DataMatrix 0x118
+#define HidUsage_BS_MaxiCode 0x119
+#define HidUsage_BS_MicroPDF 0x11a
+#define HidUsage_BS_PDF417 0x11b
+#define HidUsage_BS_PosiCode 0x11c
+#define HidUsage_BS_QRCode 0x11d
+#define HidUsage_BS_SuperCode 0x11e
+#define HidUsage_BS_UltraCode 0x11f
+#define HidUsage_BS_USD5SlugCode 0x120
+#define HidUsage_BS_VeriCode 0x121
+#define HidUsage_Sca_Scales 0x01
+#define HidUsage_Sca_ScaleDevice 0x20
+#define HidUsage_Sca_ScaleClass 0x21
+#define HidUsage_Sca_ScaleClassIMetric 0x22
+#define HidUsage_Sca_ScaleClassIIMetric 0x23
+#define HidUsage_Sca_ScaleClassIIIMetric 0x24
+#define HidUsage_Sca_ScaleClassIIILMetric 0x25
+#define HidUsage_Sca_ScaleClassIVMetric 0x26
+#define HidUsage_Sca_ScaleClassIIIEnglish 0x27
+#define HidUsage_Sca_ScaleClassIIILEnglish 0x28
+#define HidUsage_Sca_ScaleClassIVEnglish 0x29
+#define HidUsage_Sca_ScaleClassGeneric 0x2a
+#define HidUsage_Sca_ScaleAttributeReport 0x30
+#define HidUsage_Sca_ScaleControlReport 0x31
+#define HidUsage_Sca_ScaleDataReport 0x32
+#define HidUsage_Sca_ScaleStatusReport 0x33
+#define HidUsage_Sca_ScaleWeightLimitReport 0x34
+#define HidUsage_Sca_ScaleStatisticsReport 0x35
+#define HidUsage_Sca_DataWeight 0x40
+#define HidUsage_Sca_DataScaling 0x41
+#define HidUsage_Sca_WeightUnit 0x50
+#define HidUsage_Sca_WeightUnitMilligram 0x51
+#define HidUsage_Sca_WeightUnitGram 0x52
+#define HidUsage_Sca_WeightUnitKilogram 0x53
+#define HidUsage_Sca_WeightUnitCarats 0x54
+#define HidUsage_Sca_WeightUnitTaels 0x55
+#define HidUsage_Sca_WeightUnitGrains 0x56
+#define HidUsage_Sca_WeightUnitPennyweights 0x57
+#define HidUsage_Sca_WeightUnitMetricTon 0x58
+#define HidUsage_Sca_WeightUnitAvoirTon 0x59
+#define HidUsage_Sca_WeightUnitTroyOunce 0x5a
+#define HidUsage_Sca_WeightUnitOunce 0x5b
+#define HidUsage_Sca_WeightUnitPound 0x5c
+#define HidUsage_Sca_CalibrationCount 0x60
+#define HidUsage_Sca_ReZeroCount 0x61
+#define HidUsage_Sca_ScaleStatus 0x70
+#define HidUsage_Sca_ScaleStatusFault 0x71
+#define HidUsage_Sca_ScaleStatusStableatCenterofZero 0x72
+#define HidUsage_Sca_ScaleStatusInMotion 0x73
+#define HidUsage_Sca_ScaleStatusWeightStable 0x74
+#define HidUsage_Sca_ScaleStatusUnderZero 0x75
+#define HidUsage_Sca_ScaleStatusOverWeightLimit 0x76
+#define HidUsage_Sca_ScaleStatusRequiresCalibration 0x77
+#define HidUsage_Sca_ScaleStatusRequiresRezeroing 0x78
+#define HidUsage_Sca_ZeroScale 0x80
+#define HidUsage_Sca_EnforcedZeroReturn 0x81
+#define HidUsage_MSR_MSRDeviceReadOnly 0x01
+#define HidUsage_MSR_Track1Length 0x11
+#define HidUsage_MSR_Track2Length 0x12
+#define HidUsage_MSR_Track3Length 0x13
+#define HidUsage_MSR_TrackJISLength 0x14
+#define HidUsage_MSR_TrackData 0x20
+#define HidUsage_MSR_Track1Data 0x21
+#define HidUsage_MSR_Track2Data 0x22
+#define HidUsage_MSR_Track3Data 0x23
+#define HidUsage_MSR_TrackJISData 0x24
+#define HidUsage_CC_CameraAutofocus 0x20
+#define HidUsage_CC_CameraShutter 0x21
+#define HidUsage_Arc_GeneralPurposeIOCard 0x01
+#define HidUsage_Arc_CoinDoor 0x02
+#define HidUsage_Arc_WatchdogTimer 0x03
+#define HidUsage_Arc_GeneralPurposeAnalogInputState 0x30
+#define HidUsage_Arc_GeneralPurposeDigitalInputState 0x31
+#define HidUsage_Arc_GeneralPurposeOpticalInputState 0x32
+#define HidUsage_Arc_GeneralPurposeDigitalOutputState 0x33
+#define HidUsage_Arc_NumberofCoinDoors 0x34
+#define HidUsage_Arc_CoinDrawerDropCount 0x35
+#define HidUsage_Arc_CoinDrawerStart 0x36
+#define HidUsage_Arc_CoinDrawerService 0x37
+#define HidUsage_Arc_CoinDrawerTilt 0x38
+#define HidUsage_Arc_CoinDoorTest 0x39
+#define HidUsage_Arc_CoinDoorLockout 0x40
+#define HidUsage_Arc_WatchdogTimeout 0x41
+#define HidUsage_Arc_WatchdogAction 0x42
+#define HidUsage_Arc_WatchdogReboot 0x43
+#define HidUsage_Arc_WatchdogRestart 0x44
+#define HidUsage_Arc_AlarmInput 0x45
+#define HidUsage_Arc_CoinDoorCounter 0x46
+#define HidUsage_Arc_IODirectionMapping 0x47
+#define HidUsage_Arc_SetIODirectionMapping 0x48
+#define HidUsage_Arc_ExtendedOpticalInputState 0x49
+#define HidUsage_Arc_PinPadInputState 0x4a
+#define HidUsage_Arc_PinPadStatus 0x4b
+#define HidUsage_Arc_PinPadOutput 0x4c
+#define HidUsage_Arc_PinPadCommand 0x4d
+#define HidUsage_FIDOA_U2FAuthenticatorDevice 0x01
+#define HidUsage_FIDOA_InputReportData 0x20
+#define HidUsage_FIDOA_OutputReportData 0x21
--
2.53.0
^ permalink raw reply related
* [PATCH 3/8] HID: bpf: add helper macros for LE/BE conversion
From: Benjamin Tissoires @ 2026-04-03 16:12 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, linux-kernel, Benjamin Tissoires, Peter Hutterer
In-Reply-To: <20260403-wip-sync-udev-hid-bpf-2026-04-v1-0-978cedb9a074@kernel.org>
From: Peter Hutterer <peter.hutterer@who-t.net>
BPF has bpf_htons and friends but those only work with data in Big
Endian format. HID is little endian so we need our own macros.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/221
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
drivers/hid/bpf/progs/hid_bpf_helpers.h | 67 +++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/drivers/hid/bpf/progs/hid_bpf_helpers.h b/drivers/hid/bpf/progs/hid_bpf_helpers.h
index 5e3ffca1ed7b..f9071444c938 100644
--- a/drivers/hid/bpf/progs/hid_bpf_helpers.h
+++ b/drivers/hid/bpf/progs/hid_bpf_helpers.h
@@ -7,6 +7,7 @@
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
#include <linux/errno.h>
extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx,
@@ -263,4 +264,70 @@ DEFINE_GUARD(bpf_spin, struct bpf_spin_lock, bpf_spin_lock, bpf_spin_unlock);
_EXPAND(_ARG, __VA_ARGS__) \
} _device_ids SEC(".hid_bpf_config")
+
+/* Equivalency macros for bpf_htons and friends which are
+ * Big Endian only - HID needs little endian so these are the
+ * corresponding macros for that. See bpf/bpf_endian.h
+ */
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define __hid_bpf_le16_to_cpu(x) (x)
+# define __hid_bpf_le32_to_cpu(x) (x)
+# define __hid_bpf_le64_to_cpu(x) (x)
+# define __hid_bpf_cpu_to_le16(x) (x)
+# define __hid_bpf_cpu_to_le32(x) (x)
+# define __hid_bpf_cpu_to_le64(x) (x)
+# define __hid_bpf_constant_le16_to_cpu(x) (x)
+# define __hid_bpf_constant_le32_to_cpu(x) (x)
+# define __hid_bpf_constant_le64_to_cpu(x) (x)
+# define __hid_bpf_constant_cpu_to_le16(x) (x)
+# define __hid_bpf_constant_cpu_to_le32(x) (x)
+# define __hid_bpf_constant_cpu_to_le64(x) (x)
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define __hid_bpf_le16_to_cpu(x) __builtin_bswap16(x)
+# define __hid_bpf_le32_to_cpu(x) __builtin_bswap32(x)
+# define __hid_bpf_le64_to_cpu(x) __builtin_bswap64(x)
+# define __hid_bpf_cpu_to_le16(x) __builtin_bswap16(x)
+# define __hid_bpf_cpu_to_le32(x) __builtin_bswap32(x)
+# define __hid_bpf_cpu_to_le64(x) __builtin_bswap64(x)
+# define __hid_bpf_constant_le16_to_cpu(x) __bpf_swab16(x)
+# define __hid_bpf_constant_le32_to_cpu(x) __bpf_swab32(x)
+# define __hid_bpf_constant_le64_to_cpu(x) __bpf_swab64(x)
+# define __hid_bpf_constant_cpu_to_le16(x) __bpf_swab16(x)
+# define __hid_bpf_constant_cpu_to_le32(x) __bpf_swab32(x)
+# define __hid_bpf_constant_cpu_to_le64(x) __bpf_swab64(x)
+#else
+# error "Invalid __BYTE_ORDER__"
+#endif
+
+#define hid_bpf_le16_to_cpu(x) \
+ (__builtin_constant_p(x) ? \
+ __hid_bpf_constant_le16_to_cpu(x) : __hid_bpf_le16_to_cpu(x))
+
+#define hid_bpf_le32_to_cpu(x) \
+ (__builtin_constant_p(x) ? \
+ __hid_bpf_constant_le32_to_cpu(x) : __hid_bpf_le32_to_cpu(x))
+
+#define hid_bpf_le64_to_cpu(x) \
+ (__builtin_constant_p(x) ? \
+ __hid_bpf_constant_le64_to_cpu(x) : __hid_bpf_le64_to_cpu(x))
+
+#define hid_bpf_cpu_to_le16(x) \
+ (__builtin_constant_p(x) ? \
+ __hid_bpf_constant_cpu_to_le16(x) : __hid_bpf_cpu_to_le16(x))
+
+#define hid_bpf_cpu_to_le32(x) \
+ (__builtin_constant_p(x) ? \
+ __hid_bpf_constant_cpu_to_le32(x) : __hid_bpf_cpu_to_le32(x))
+
+#define hid_bpf_cpu_to_le64(x) \
+ (__builtin_constant_p(x) ? \
+ __hid_bpf_constant_cpu_to_le64(x) : __hid_bpf_cpu_to_le64(x))
+
+#define hid_bpf_be16_to_cpu(x) bpf_ntohs(x)
+#define hid_bpf_be32_to_cpu(x) bpf_ntohl(x)
+#define hid_bpf_be64_to_cpu(x) bpf_be64_to_cpu(x)
+#define hid_bpf_cpu_to_be16(x) bpf_htons(x)
+#define hid_bpf_cpu_to_be32(x) bpf_htonl(x)
+#define hid_bpf_cpu_to_be64(x) bpf_cpu_to_be64(x)
+
#endif /* __HID_BPF_HELPERS_H */
--
2.53.0
^ permalink raw reply related
* [PATCH 2/8] HID: bpf: hid_bpf_helpers: provide a cleanup functions
From: Benjamin Tissoires @ 2026-04-03 16:12 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, linux-kernel, Benjamin Tissoires
In-Reply-To: <20260403-wip-sync-udev-hid-bpf-2026-04-v1-0-978cedb9a074@kernel.org>
Combination of 2 udev-hid-bpf commits:
bpf: hid_bpf_helpers: provide a cleanup function for hid_bpf_release_context
bpf: helpers: add guard(bpf_spin) macro
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/221
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
drivers/hid/bpf/progs/hid_bpf_async.h | 36 +++++++--------
drivers/hid/bpf/progs/hid_bpf_helpers.h | 80 +++++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+), 18 deletions(-)
diff --git a/drivers/hid/bpf/progs/hid_bpf_async.h b/drivers/hid/bpf/progs/hid_bpf_async.h
index 9ab585434239..877bb7e81f03 100644
--- a/drivers/hid/bpf/progs/hid_bpf_async.h
+++ b/drivers/hid/bpf/progs/hid_bpf_async.h
@@ -116,15 +116,14 @@ static int hid_bpf_async_find_empty_key(void)
if (!elem)
return -ENOMEM; /* should never happen */
- bpf_spin_lock(&elem->lock);
+ {
+ guard(bpf_spin)(&elem->lock);
- if (elem->state == HID_BPF_ASYNC_STATE_UNSET) {
- elem->state = HID_BPF_ASYNC_STATE_INITIALIZING;
- bpf_spin_unlock(&elem->lock);
- return i;
+ if (elem->state == HID_BPF_ASYNC_STATE_UNSET) {
+ elem->state = HID_BPF_ASYNC_STATE_INITIALIZING;
+ return i;
+ }
}
-
- bpf_spin_unlock(&elem->lock);
}
return -EINVAL;
@@ -175,18 +174,19 @@ static int hid_bpf_async_delayed_call(struct hid_bpf_ctx *hctx, u64 milliseconds
if (!elem)
return -EINVAL;
- bpf_spin_lock(&elem->lock);
- /* The wq must be:
- * - HID_BPF_ASYNC_STATE_INITIALIZED -> it's been initialized and ready to be called
- * - HID_BPF_ASYNC_STATE_RUNNING -> possible re-entry from the wq itself
- */
- if (elem->state != HID_BPF_ASYNC_STATE_INITIALIZED &&
- elem->state != HID_BPF_ASYNC_STATE_RUNNING) {
- bpf_spin_unlock(&elem->lock);
- return -EINVAL;
+ {
+ guard(bpf_spin)(&elem->lock);
+
+ /* The wq must be:
+ * - HID_BPF_ASYNC_STATE_INITIALIZED -> it's been initialized and ready to be called
+ * - HID_BPF_ASYNC_STATE_RUNNING -> possible re-entry from the wq itself
+ */
+ if (elem->state != HID_BPF_ASYNC_STATE_INITIALIZED &&
+ elem->state != HID_BPF_ASYNC_STATE_RUNNING)
+ return -EINVAL;
+
+ elem->state = HID_BPF_ASYNC_STATE_STARTING;
}
- elem->state = HID_BPF_ASYNC_STATE_STARTING;
- bpf_spin_unlock(&elem->lock);
elem->hid = hctx->hid->id;
diff --git a/drivers/hid/bpf/progs/hid_bpf_helpers.h b/drivers/hid/bpf/progs/hid_bpf_helpers.h
index 228f8d787567..5e3ffca1ed7b 100644
--- a/drivers/hid/bpf/progs/hid_bpf_helpers.h
+++ b/drivers/hid/bpf/progs/hid_bpf_helpers.h
@@ -40,6 +40,86 @@ extern int bpf_wq_set_callback(struct bpf_wq *wq,
#define HID_MAX_DESCRIPTOR_SIZE 4096
#define HID_IGNORE_EVENT -1
+/**
+ * Use: _cleanup_(somefunction) struct foo *bar;
+ */
+#define _cleanup_(_x) __attribute__((cleanup(_x)))
+
+/**
+ * Use: _release_(foo) *bar;
+ *
+ * This requires foo_releasep() to be present, use DEFINE_RELEASE_CLEANUP_FUNC.
+ */
+#define _release_(_type) struct _type __attribute__((cleanup(_type##_releasep)))
+
+/**
+ * Define a cleanup function for the struct type foo with a matching
+ * foo_release(). Use:
+ * DEFINE_RELEASE_CLEANUP_FUNC(foo)
+ * _unref_(foo) struct foo *bar;
+ */
+#define DEFINE_RELEASE_CLEANUP_FUNC(_type) \
+ static inline void _type##_releasep(struct _type **_p) { \
+ if (*_p) \
+ _type##_release(*_p); \
+ } \
+ struct __useless_struct_to_allow_trailing_semicolon__
+
+/* for being able to have a cleanup function */
+#define hid_bpf_ctx_release hid_bpf_release_context
+DEFINE_RELEASE_CLEANUP_FUNC(hid_bpf_ctx);
+
+/*
+ * Kernel-style guard macros adapted for BPF
+ * Based on include/linux/cleanup.h from the Linux kernel
+ *
+ * These provide automatic lock/unlock using __attribute__((cleanup))
+ * similar to how _release_() works for contexts.
+ */
+
+/**
+ * DEFINE_GUARD(name, type, lock, unlock):
+ * Define a guard for automatic lock/unlock using the same pattern as _release_()
+ * @name: identifier for the guard (e.g., bpf_spin)
+ * @type: lock variable type (e.g., struct bpf_spin_lock)
+ * @lock: lock function name (e.g., bpf_spin_lock)
+ * @unlock: unlock function name (e.g., bpf_spin_unlock)
+ *
+ * guard(name):
+ * Declare and lock in one statement - lock held until end of scope
+ *
+ * Example:
+ * DEFINE_GUARD(bpf_spin, struct bpf_spin_lock, bpf_spin_lock, bpf_spin_unlock)
+ *
+ * void foo(struct bpf_spin_lock *lock) {
+ * guard(bpf_spin)(lock);
+ * // lock held until end of scope
+ * }
+ */
+
+/* Guard helper struct - stores lock pointer for cleanup */
+#define DEFINE_GUARD(_name, _type, _lock, _unlock) \
+struct _name##_guard { \
+ _type *lock; \
+}; \
+static inline void _name##_guard_cleanup(struct _name##_guard *g) { \
+ if (g && g->lock) \
+ _unlock(g->lock); \
+} \
+static inline struct _name##_guard _name##_guard_init(_type *l) { \
+ if (l) \
+ _lock(l); \
+ return (struct _name##_guard){.lock = l}; \
+} \
+struct __useless_struct_to_allow_trailing_semicolon__
+
+#define guard(_name) \
+ struct _name##_guard COMBINE(guard, __LINE__) __attribute__((cleanup(_name##_guard_cleanup))) = \
+ _name##_guard_init
+
+/* Define BPF spinlock guard */
+DEFINE_GUARD(bpf_spin, struct bpf_spin_lock, bpf_spin_lock, bpf_spin_unlock);
+
/* extracted from <linux/input.h> */
#define BUS_ANY 0x00
#define BUS_PCI 0x01
--
2.53.0
^ permalink raw reply related
* [PATCH 1/8] HID: bpf: fix some signed vs unsigned compiler warnings
From: Benjamin Tissoires @ 2026-04-03 16:12 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, linux-kernel, Benjamin Tissoires, Peter Hutterer
In-Reply-To: <20260403-wip-sync-udev-hid-bpf-2026-04-v1-0-978cedb9a074@kernel.org>
From: Peter Hutterer <peter.hutterer@who-t.net>
On udev-hid-bpf, we are now getting warnings here, shut them off.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/227
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
drivers/hid/bpf/progs/Huion__KeydialK20.bpf.c | 3 ++-
drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c | 2 +-
drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c | 2 +-
drivers/hid/bpf/progs/XPPen__DecoMini4.bpf.c | 2 +-
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/bpf/progs/Huion__KeydialK20.bpf.c b/drivers/hid/bpf/progs/Huion__KeydialK20.bpf.c
index ec360d71130f..c562c2d684fe 100644
--- a/drivers/hid/bpf/progs/Huion__KeydialK20.bpf.c
+++ b/drivers/hid/bpf/progs/Huion__KeydialK20.bpf.c
@@ -462,7 +462,8 @@ int BPF_PROG(k20_fix_events, struct hid_bpf_ctx *hctx)
__u32 buttons;
__u8 wheel;
} __attribute__((packed)) *pad_report;
- int i, b;
+ int i;
+ size_t b;
__u8 modifiers = data[1];
__u32 buttons = 0;
diff --git a/drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c b/drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c
index 82f1950445dd..253b96458c58 100644
--- a/drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c
+++ b/drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c
@@ -34,7 +34,7 @@ int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx)
if (data[3] != 0x06)
return 0;
- for (int idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
+ for (size_t idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
u8 offset = offsets[idx];
/* if Input (Cnst,Var,Abs) , make it Input (Data,Var,Abs) */
diff --git a/drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c b/drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c
index 2da680bc4e11..ed60a660cc1a 100644
--- a/drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c
+++ b/drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c
@@ -148,7 +148,7 @@ int probe(struct hid_bpf_probe_args *ctx)
{
struct hid_bpf_ctx *hid_ctx;
__u16 pid;
- int i;
+ size_t i;
/* get a struct hid_device to access the actual pid of the device */
hid_ctx = hid_bpf_allocate_context(ctx->hid);
diff --git a/drivers/hid/bpf/progs/XPPen__DecoMini4.bpf.c b/drivers/hid/bpf/progs/XPPen__DecoMini4.bpf.c
index 46d5c459d0c9..ac07216f5b67 100644
--- a/drivers/hid/bpf/progs/XPPen__DecoMini4.bpf.c
+++ b/drivers/hid/bpf/progs/XPPen__DecoMini4.bpf.c
@@ -173,7 +173,7 @@ int BPF_PROG(hid_device_event_xppen_deco_mini_4, struct hid_bpf_ctx *hctx)
{
__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 8 /* size */);
__u8 button_mask = 0;
- int d, b;
+ size_t d, b;
if (!data)
return 0; /* EPERM check */
--
2.53.0
^ permalink raw reply related
* [PATCH 0/8] HID: bpf: sync up programs with udev-hid-bpf
From: Benjamin Tissoires @ 2026-04-03 16:12 UTC (permalink / raw)
To: Jiri Kosina
Cc: linux-input, linux-kernel, Benjamin Tissoires, Peter Hutterer,
muhammed Rishal, Benjamin Tissoires
Not a full sync of udev-hid-bpf as the remaining .h syncs are not used
in merged HID-BPF progs (namely Logitech Bolt support).
I've tried to re-apply the header changes by merging the resulting code
and put references where I could.
We now gain support for:
- Huion KeyDial K20 over bluetooth
- Trust Philips SPK6327 keyboard
- A small helper to add a udev property to touchpads not running v6.18
yet
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
Benjamin Tissoires (8):
HID: bpf: fix some signed vs unsigned compiler warnings
HID: bpf: hid_bpf_helpers: provide a cleanup functions
HID: bpf: add helper macros for LE/BE conversion
HID: bpf: handle injected report descriptor in HID-BPF
hid: bpf: hid_bpf_helpers: add helper for having read/write udev properties
HID: bpf: add a BPF to get the touchpad type
HID: bpf: Add support for the Huion KeyDial K20 over bluetooth
bpf: Add fix for Trust Philips SPK6327 (145f:024b) modifier keys
drivers/hid/bpf/progs/Generic__touchpad.bpf.c | 90 +
.../bpf/progs/Huion__KeydialK20-Bluetooth.bpf.c | 492 ++++
drivers/hid/bpf/progs/Huion__KeydialK20.bpf.c | 3 +-
.../hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c | 2 +-
drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c | 49 +
drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c | 2 +-
drivers/hid/bpf/progs/XPPen__DecoMini4.bpf.c | 2 +-
drivers/hid/bpf/progs/hid_bpf_async.h | 36 +-
drivers/hid/bpf/progs/hid_bpf_helpers.h | 321 +++
.../hid/bpf/progs/hid_report_descriptor_helpers.h | 80 +
drivers/hid/bpf/progs/hid_usages.h | 2810 ++++++++++++++++++++
11 files changed, 3865 insertions(+), 22 deletions(-)
---
base-commit: 26639c5427d32a90301b31bc8ab82719629c1864
change-id: 20260403-wip-sync-udev-hid-bpf-2026-04-7bcea43616cc
Best regards,
--
Benjamin Tissoires <bentiss@kernel.org>
^ permalink raw reply
* [PATCH 1/3] Add Apple T2 HID identifiers
From: deqrocks @ 2026-04-03 13:06 UTC (permalink / raw)
To: jikos, benjamin.tissoires; +Cc: linux-input
In-Reply-To: <20260403130620.91999-1-andre@negmaster.com>
Add the Apple T2 HID identifiers used by the Touch Bar and related\ndevices so the follow-up resume handling can bind to the affected\ninterfaces.
Signed-off-by: deqrocks <andre@negmaster.com>
---
hid-ids.h | 1574 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1574 insertions(+)
create mode 100644 hid-ids.h
diff --git a/hid-ids.h b/hid-ids.h
new file mode 100644
index 0000000..e170944
--- /dev/null
+++ b/hid-ids.h
@@ -0,0 +1,1574 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * USB HID quirks support for Linux
+ *
+ * Copyright (c) 1999 Andreas Gal
+ * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
+ * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
+ * Copyright (c) 2006-2007 Jiri Kosina
+ */
+
+/*
+ */
+
+#ifndef HID_IDS_H_FILE
+#define HID_IDS_H_FILE
+
+#define USB_VENDOR_ID_258A 0x258a
+#define USB_DEVICE_ID_258A_6A88 0x6a88
+
+#define USB_VENDOR_ID_3M 0x0596
+#define USB_DEVICE_ID_3M1968 0x0500
+#define USB_DEVICE_ID_3M2256 0x0502
+#define USB_DEVICE_ID_3M3266 0x0506
+
+#define USB_VENDOR_ID_A4TECH 0x09da
+#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
+#define USB_DEVICE_ID_A4TECH_X5_005D 0x000a
+#define USB_DEVICE_ID_A4TECH_RP_649 0x001a
+#define USB_DEVICE_ID_A4TECH_NB_95 0x022b
+
+#define USB_VENDOR_ID_AASHIMA 0x06d6
+#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025
+#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026
+
+#define USB_VENDOR_ID_ACECAD 0x0460
+#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
+#define USB_DEVICE_ID_ACECAD_302 0x0008
+
+#define USB_VENDOR_ID_ACRUX 0x1a34
+
+#define USB_VENDOR_ID_ACTIONSTAR 0x2101
+#define USB_DEVICE_ID_ACTIONSTAR_1011 0x1011
+
+#define USB_VENDOR_ID_ADATA_XPG 0x125f
+#define USB_VENDOR_ID_ADATA_XPG_WL_GAMING_MOUSE 0x7505
+#define USB_VENDOR_ID_ADATA_XPG_WL_GAMING_MOUSE_DONGLE 0x7506
+
+#define USB_VENDOR_ID_ADS_TECH 0x06e1
+#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155
+
+#define USB_VENDOR_ID_AFATECH 0x15a4
+#define USB_DEVICE_ID_AFATECH_AF9016 0x9016
+
+#define USB_VENDOR_ID_AIPTEK 0x08ca
+#define USB_DEVICE_ID_AIPTEK_01 0x0001
+#define USB_DEVICE_ID_AIPTEK_10 0x0010
+#define USB_DEVICE_ID_AIPTEK_20 0x0020
+#define USB_DEVICE_ID_AIPTEK_21 0x0021
+#define USB_DEVICE_ID_AIPTEK_22 0x0022
+#define USB_DEVICE_ID_AIPTEK_23 0x0023
+#define USB_DEVICE_ID_AIPTEK_24 0x0024
+
+#define USB_VENDOR_ID_AIRCABLE 0x16CA
+#define USB_DEVICE_ID_AIRCABLE1 0x1502
+
+#define USB_VENDOR_ID_AIREN 0x1a2c
+#define USB_DEVICE_ID_AIREN_SLIMPLUS 0x0002
+
+#define USB_VENDOR_ID_AKAI 0x2011
+#define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715
+
+#define USB_VENDOR_ID_AKAI_09E8 0x09E8
+#define USB_DEVICE_ID_AKAI_09E8_MIDIMIX 0x0031
+
+#define USB_VENDOR_ID_ALCOR 0x058f
+#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720
+#define USB_DEVICE_ID_ALCOR_MALTRON_KB 0x9410
+
+#define USB_VENDOR_ID_ALPS 0x0433
+#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101
+
+#define USB_VENDOR_ID_ALPS_JP 0x044E
+#define HID_DEVICE_ID_ALPS_U1_DUAL 0x120B
+#define HID_DEVICE_ID_ALPS_U1 0x1215
+#define HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY 0x121E
+#define HID_DEVICE_ID_ALPS_T4_BTNLESS 0x120C
+
+#define USB_VENDOR_ID_AMI 0x046b
+#define USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE 0xff10
+
+#define USB_VENDOR_ID_ANTON 0x1130
+#define USB_DEVICE_ID_ANTON_TOUCH_PAD 0x3101
+
+#define USB_VENDOR_ID_APPLE 0x05ac
+#define BT_VENDOR_ID_APPLE 0x004c
+#define SPI_VENDOR_ID_APPLE 0x05ac
+#define HOST_VENDOR_ID_APPLE 0x05ac
+#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
+#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
+#define USB_DEVICE_ID_APPLE_MAGICMOUSE2 0x0269
+#define USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC 0x0323
+#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
+#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 0x0265
+#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC 0x0324
+#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
+#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
+#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
+#define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215
+#define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216
+#define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217
+#define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218
+#define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219
+#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a
+#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b
+#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI 0x021d
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ISO 0x021e
+#define USB_DEVICE_ID_APPLE_ALU_MINI_JIS 0x021f
+#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220
+#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221
+#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222
+#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
+#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
+#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
+#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229
+#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a
+#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e
+#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
+#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
+#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
+#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
+#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
+#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240
+#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243
+#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244
+#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245
+#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246
+#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247
+#define USB_DEVICE_ID_APPLE_ALU_REVB_ANSI 0x024f
+#define USB_DEVICE_ID_APPLE_ALU_REVB_ISO 0x0250
+#define USB_DEVICE_ID_APPLE_ALU_REVB_JIS 0x0251
+#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252
+#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253
+#define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254
+#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259
+#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a
+#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b
+#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249
+#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a
+#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b
+#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c
+#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d
+#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e
+#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262
+#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263
+#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS 0x0257
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015 0x0267
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015 0x026c
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 0x029c
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 0x029a
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024 0x0320
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024 0x0321
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024 0x0322
+#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290
+#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291
+#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292
+#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272
+#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273
+#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274
+#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K 0x027a
+#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132 0x027b
+#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680 0x027c
+#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT 0x0278
+#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213 0x027d
+#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K 0x027e
+#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223 0x027f
+#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K 0x0280
+#define USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F 0x0340
+#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
+#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
+#define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240
+#define USB_DEVICE_ID_APPLE_IRCONTROL2 0x1440
+#define USB_DEVICE_ID_APPLE_IRCONTROL3 0x8241
+#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
+#define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243
+#define USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT 0x8102
+#define USB_DEVICE_ID_APPLE_TOUCHBAR_DISPLAY 0x8302
+#define SPI_DEVICE_ID_APPLE_MACBOOK_AIR_2020 0x0281
+#define SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020 0x0341
+#define SPI_DEVICE_ID_APPLE_MACBOOK_PRO14_2021 0x0342
+#define SPI_DEVICE_ID_APPLE_MACBOOK_PRO16_2021 0x0343
+#define HOST_DEVICE_ID_APPLE_MACBOOK_AIR13_2022 0x0351
+#define HOST_DEVICE_ID_APPLE_MACBOOK_PRO14_2023 0x0352
+#define HOST_DEVICE_ID_APPLE_MACBOOK_PRO16_2023 0x0353
+#define HOST_DEVICE_ID_APPLE_MACBOOK_PRO13_2022 0x0354
+
+#define USB_VENDOR_ID_ASETEK 0x2433
+#define USB_DEVICE_ID_ASETEK_INVICTA 0xf300
+#define USB_DEVICE_ID_ASETEK_FORTE 0xf301
+#define USB_DEVICE_ID_ASETEK_LA_PRIMA 0xf303
+#define USB_DEVICE_ID_ASETEK_TONY_KANAAN 0xf306
+
+#define USB_VENDOR_ID_ASUS 0x0486
+#define USB_DEVICE_ID_ASUS_T91MT 0x0185
+#define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO 0x0186
+
+#define USB_VENDOR_ID_ASUSTEK 0x0b05
+#define USB_DEVICE_ID_ASUSTEK_LCM 0x1726
+#define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b
+#define USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD 0x17e0
+#define USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD 0x1807
+#define USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD 0x8502
+#define USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD 0x183d
+#define USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD 0x184a
+#define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD 0x8585
+#define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD 0x0101
+#define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854
+#define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2 0x1837
+#define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3 0x1822
+#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD 0x1866
+#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6
+#define USB_DEVICE_ID_ASUSTEK_ROG_Z13_FOLIO 0x1a30
+#define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6
+#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe
+#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X 0x1b4c
+#define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b
+#define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869
+
+#define USB_VENDOR_ID_ATEN 0x0557
+#define USB_DEVICE_ID_ATEN_UC100KM 0x2004
+#define USB_DEVICE_ID_ATEN_CS124U 0x2202
+#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204
+#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205
+#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208
+#define USB_DEVICE_ID_ATEN_CS682 0x2213
+#define USB_DEVICE_ID_ATEN_CS692 0x8021
+#define USB_DEVICE_ID_ATEN_CS1758 0x2220
+
+#define USB_VENDOR_ID_ATMEL 0x03eb
+#define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c
+#define USB_DEVICE_ID_ATMEL_MXT_DIGITIZER 0x2118
+#define USB_VENDOR_ID_ATMEL_V_USB 0x16c0
+#define USB_DEVICE_ID_ATMEL_V_USB 0x05df
+
+#define USB_VENDOR_ID_AUREAL 0x0755
+#define USB_DEVICE_ID_AUREAL_W01RN 0x2626
+
+#define USB_VENDOR_ID_AVERMEDIA 0x07ca
+#define USB_DEVICE_ID_AVER_FM_MR800 0xb800
+
+#define USB_VENDOR_ID_AXENTIA 0x12cf
+#define USB_DEVICE_ID_AXENTIA_FM_RADIO 0x7111
+
+#define USB_VENDOR_ID_BAANTO 0x2453
+#define USB_DEVICE_ID_BAANTO_MT_190W2 0x0100
+
+#define USB_VENDOR_ID_BELKIN 0x050d
+#define USB_DEVICE_ID_FLIP_KVM 0x3201
+
+#define USB_VENDOR_ID_BERKSHIRE 0x0c98
+#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
+
+#define USB_VENDOR_ID_BETOP_2185BFM 0x11c2
+#define USB_VENDOR_ID_BETOP_2185PC 0x11c0
+#define USB_VENDOR_ID_BETOP_2185V2PC 0x8380
+#define USB_VENDOR_ID_BETOP_2185V2BFM 0x20bc
+
+#define USB_VENDOR_ID_BIGBEN 0x146b
+#define USB_DEVICE_ID_BIGBEN_PS3OFMINIPAD 0x0902
+
+#define USB_VENDOR_ID_BTC 0x046e
+#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
+#define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577
+
+#define USB_VENDOR_ID_CAMMUS 0x3416
+#define USB_DEVICE_ID_CAMMUS_C5 0x0301
+#define USB_DEVICE_ID_CAMMUS_C12 0x0302
+
+#define USB_VENDOR_ID_CANDO 0x2087
+#define USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH 0x0703
+#define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01
+#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1 0x0a02
+#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03
+#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6 0x0f01
+
+#define USB_VENDOR_ID_CH 0x068e
+#define USB_DEVICE_ID_CH_PRO_THROTTLE 0x00f1
+#define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2
+#define USB_DEVICE_ID_CH_FIGHTERSTICK 0x00f3
+#define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4
+#define USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE 0x0051
+#define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff
+#define USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK 0x00d3
+#define USB_DEVICE_ID_CH_AXIS_295 0x001c
+
+#define USB_VENDOR_ID_CHERRY 0x046a
+#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
+#define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027
+
+#define USB_VENDOR_ID_CHIC 0x05fe
+#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014
+
+#define USB_VENDOR_ID_CHICONY 0x04f2
+#define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418
+#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d
+#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618
+#define USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE 0x1053
+#define USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2 0x0939
+#define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123
+#define USB_DEVICE_ID_CHICONY_WIRELESS3 0x1236
+#define USB_DEVICE_ID_ASUS_AK1D 0x1125
+#define USB_DEVICE_ID_CHICONY_TOSHIBA_WT10A 0x1408
+#define USB_DEVICE_ID_CHICONY_ACER_SWITCH12 0x1421
+#define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA 0xb824
+#define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA2 0xb82c
+#define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA3 0xb882
+
+#define USB_VENDOR_ID_CHUNGHWAT 0x2247
+#define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001
+
+#define USB_VENDOR_ID_CIDC 0x1677
+
+#define I2C_VENDOR_ID_CIRQUE 0x0488
+#define I2C_PRODUCT_ID_CIRQUE_1063 0x1063
+
+#define USB_VENDOR_ID_CJTOUCH 0x24b8
+#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020
+#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040
+
+#define USB_VENDOR_ID_CLAY_LOGIC 0x20a0
+#define USB_DEVICE_ID_NITROKEY_U2F 0x4287
+
+#define USB_VENDOR_ID_CMEDIA 0x0d8c
+#define USB_DEVICE_ID_CM109 0x000e
+#define USB_DEVICE_ID_CMEDIA_HS100B 0x0014
+#define USB_DEVICE_ID_CM6533 0x0022
+
+#define USB_VENDOR_ID_CODEMERCS 0x07c0
+#define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500
+#define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff
+
+#define USB_VENDOR_ID_COOLER_MASTER 0x2516
+#define USB_DEVICE_ID_COOLER_MASTER_MICE_DONGLE 0x01b7
+
+#define USB_VENDOR_ID_CORSAIR 0x1b1c
+#define USB_DEVICE_ID_CORSAIR_K90 0x1b02
+#define USB_DEVICE_ID_CORSAIR_K70R 0x1b09
+#define USB_DEVICE_ID_CORSAIR_K95RGB 0x1b11
+#define USB_DEVICE_ID_CORSAIR_M65RGB 0x1b12
+#define USB_DEVICE_ID_CORSAIR_K70RGB 0x1b13
+#define USB_DEVICE_ID_CORSAIR_STRAFE 0x1b15
+#define USB_DEVICE_ID_CORSAIR_K65RGB 0x1b17
+#define USB_DEVICE_ID_CORSAIR_GLAIVE_RGB 0x1b34
+#define USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE 0x1b38
+#define USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE 0x1b39
+#define USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB 0x1b3e
+
+#define USB_VENDOR_ID_CREATIVELABS 0x041e
+#define USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51 0x322c
+#define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801
+#define USB_DEVICE_ID_CREATIVE_SB0540 0x3100
+
+#define USB_VENDOR_ID_CVTOUCH 0x1ff7
+#define USB_DEVICE_ID_CVTOUCH_SCREEN 0x0013
+
+#define USB_VENDOR_ID_CYGNAL 0x10c4
+#define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a
+#define USB_DEVICE_ID_FOCALTECH_FTXXXX_MULTITOUCH 0x81b9
+#define USB_DEVICE_ID_CYGNAL_CP2112 0xea90
+#define USB_DEVICE_ID_U2F_ZERO 0x8acf
+
+#define USB_DEVICE_ID_CYGNAL_RADIO_SI4713 0x8244
+
+#define USB_VENDOR_ID_CYPRESS 0x04b4
+#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
+#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
+#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417
+#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
+#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
+#define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1
+#define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81
+#define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001
+
+#define USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1 0X07b1
+
+#define USB_VENDOR_ID_DATA_MODUL 0x7374
+#define USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH 0x1201
+
+#define USB_VENDOR_ID_DEALEXTREAME 0x10c5
+#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a
+
+#define USB_VENDOR_ID_DELCOM 0x0fc5
+#define USB_DEVICE_ID_DELCOM_VISUAL_IND 0xb080
+
+#define USB_VENDOR_ID_DELL 0x413c
+#define USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE 0x301a
+#define USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W 0x4503
+
+#define USB_VENDOR_ID_DELORME 0x1163
+#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
+#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200
+
+#define USB_VENDOR_ID_DMI 0x0c0b
+#define USB_DEVICE_ID_DMI_ENC 0x5fab
+
+#define USB_VENDOR_ID_DRAGONRISE 0x0079
+#define USB_DEVICE_ID_REDRAGON_SEYMUR2 0x0006
+#define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800
+#define USB_DEVICE_ID_DRAGONRISE_PS3 0x1801
+#define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803
+#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE1 0x1843
+#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE2 0x1844
+#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE3 0x1846
+
+#define USB_VENDOR_ID_DWAV 0x0eef
+#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
+#define USB_DEVICE_ID_DWAV_TOUCHCONTROLLER 0x0002
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207 0x7207
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C 0x720c
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224 0x7224
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A 0x722A
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E 0x725e
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262 0x7262
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA 0x72aa
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4 0x72c4
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0 0x72d0
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C000 0xc000
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002 0xc002
+
+#define USB_VENDOR_ID_EDIFIER 0x2d99
+#define USB_DEVICE_ID_EDIFIER_QR30 0xa101 /* EDIFIER Hal0 2.0 SE */
+
+#define USB_VENDOR_ID_ELAN 0x04f3
+#define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401
+#define USB_DEVICE_ID_HP_X2 0x074d
+#define USB_DEVICE_ID_HP_X2_10_COVER 0x0755
+#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
+#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
+#define I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM 0x2F81
+
+#define USB_VENDOR_ID_ELECOM 0x056e
+#define USB_DEVICE_ID_ELECOM_BM084 0x0061
+#define USB_DEVICE_ID_ELECOM_M_XGL20DLBK 0x00e6
+#define USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB 0x00fb
+#define USB_DEVICE_ID_ELECOM_M_XT3URBK_018F 0x018f
+#define USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC 0x00fc
+#define USB_DEVICE_ID_ELECOM_M_XT3DRBK_018C 0x018c
+#define USB_DEVICE_ID_ELECOM_M_XT4DRBK 0x00fd
+#define USB_DEVICE_ID_ELECOM_M_DT1URBK 0x00fe
+#define USB_DEVICE_ID_ELECOM_M_DT1DRBK 0x00ff
+#define USB_DEVICE_ID_ELECOM_M_DT2DRBK 0x018d
+#define USB_DEVICE_ID_ELECOM_M_HT1URBK_010C 0x010c
+#define USB_DEVICE_ID_ELECOM_M_HT1URBK_019B 0x019b
+#define USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D 0x010d
+#define USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C 0x011c
+#define USB_DEVICE_ID_ELECOM_M_HT1MRBK 0x01aa
+#define USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AB 0x01ab
+#define USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC 0x01ac
+
+#define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34
+#define USB_DEVICE_ID_DREAM_CHEEKY_WN 0x0004
+#define USB_DEVICE_ID_DREAM_CHEEKY_FA 0x000a
+
+#define USB_VENDOR_ID_ELITEGROUP 0x03fc
+#define USB_DEVICE_ID_ELITEGROUP_05D8 0x05d8
+
+#define USB_VENDOR_ID_ELO 0x04E7
+#define USB_DEVICE_ID_ELO_TS2515 0x0022
+#define USB_DEVICE_ID_ELO_TS2700 0x0020
+#define USB_DEVICE_ID_ELO_ACCUTOUCH_2216 0x0050
+
+#define USB_VENDOR_ID_EMS 0x2006
+#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118
+
+#define USB_VENDOR_ID_EVISION 0x320f
+#define USB_DEVICE_ID_EV_TELINK_RECEIVER 0x226f
+#define USB_DEVICE_ID_EVISION_ICL01 0x5041
+
+#define USB_VENDOR_ID_FFBEAST 0x045b
+#define USB_DEVICE_ID_FFBEAST_JOYSTICK 0x58f9
+#define USB_DEVICE_ID_FFBEAST_RUDDER 0x5968
+#define USB_DEVICE_ID_FFBEAST_WHEEL 0x59d7
+
+#define USB_VENDOR_ID_FLATFROG 0x25b5
+#define USB_DEVICE_ID_MULTITOUCH_3200 0x0002
+
+#define USB_VENDOR_ID_FUTABA 0x0547
+#define USB_DEVICE_ID_LED_DISPLAY 0x7000
+
+#define USB_VENDOR_ID_FUTURE_TECHNOLOGY 0x0403
+#define USB_DEVICE_ID_RETRODE2 0x97c1
+#define USB_DEVICE_ID_FT260 0x6030
+
+#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
+#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
+
+#define USB_VENDOR_ID_ETT 0x0664
+#define USB_DEVICE_ID_TC5UH 0x0309
+#define USB_DEVICE_ID_TC4UM 0x0306
+
+#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
+#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
+#define USB_DEVICE_ID_ETURBOTOUCH_2968 0x2968
+
+#define USB_VENDOR_ID_EZKEY 0x0518
+#define USB_DEVICE_ID_BTC_8193 0x0002
+
+#define USB_VENDOR_ID_FORMOSA 0x147a
+#define USB_DEVICE_ID_FORMOSA_IR_RECEIVER 0xe03e
+
+#define USB_VENDOR_ID_FREESCALE 0x15A2
+#define USB_DEVICE_ID_FREESCALE_MX28 0x004F
+
+#define USB_VENDOR_ID_FRUCTEL 0x25B6
+#define USB_DEVICE_ID_GAMETEL_MT_MODE 0x0002
+
+#define USB_VENDOR_ID_GAMEVICE 0x27F8
+#define USB_DEVICE_ID_GAMEVICE_GV186 0x0BBE
+#define USB_DEVICE_ID_GAMEVICE_KISHI 0x0BBF
+
+#define USB_VENDOR_ID_GAMERON 0x0810
+#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
+#define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002
+
+#define USB_VENDOR_ID_GEMBIRD 0x11ff
+#define USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2 0x3331
+
+#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS 0x0100
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0101 0x0101
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0102 0x0102
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0106 0x0106
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
+
+#define I2C_VENDOR_ID_GOODIX 0x27c6
+#define I2C_DEVICE_ID_GOODIX_01E8 0x01e8
+#define I2C_DEVICE_ID_GOODIX_01E9 0x01e9
+#define I2C_DEVICE_ID_GOODIX_01F0 0x01f0
+#define I2C_DEVICE_ID_GOODIX_0D42 0x0d42
+
+#define USB_VENDOR_ID_GOODTOUCH 0x1aad
+#define USB_DEVICE_ID_GOODTOUCH_000f 0x000f
+
+#define USB_VENDOR_ID_GOOGLE 0x18d1
+#define USB_DEVICE_ID_GOOGLE_HAMMER 0x5022
+#define USB_DEVICE_ID_GOOGLE_TOUCH_ROSE 0x5028
+#define USB_DEVICE_ID_GOOGLE_STAFF 0x502b
+#define USB_DEVICE_ID_GOOGLE_WAND 0x502d
+#define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030
+#define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c
+#define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d
+#define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044
+#define USB_DEVICE_ID_GOOGLE_DON 0x5050
+#define USB_DEVICE_ID_GOOGLE_EEL 0x5057
+#define USB_DEVICE_ID_GOOGLE_JEWEL 0x5061
+#define USB_DEVICE_ID_GOOGLE_STADIA 0x9400
+
+#define USB_VENDOR_ID_GOTOP 0x08f2
+#define USB_DEVICE_ID_SUPER_Q2 0x007f
+#define USB_DEVICE_ID_GOGOPEN 0x00ce
+#define USB_DEVICE_ID_PENPOWER 0x00f4
+
+#define USB_VENDOR_ID_GREENASIA 0x0e8f
+#define USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR 0x3010
+#define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013
+
+#define USB_VENDOR_ID_GRETAGMACBETH 0x0971
+#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005
+
+#define USB_VENDOR_ID_GRIFFIN 0x077d
+#define USB_DEVICE_ID_POWERMATE 0x0410
+#define USB_DEVICE_ID_SOUNDKNOB 0x04AA
+#define USB_DEVICE_ID_RADIOSHARK 0x627a
+
+#define USB_VENDOR_ID_GTCO 0x078c
+#define USB_DEVICE_ID_GTCO_90 0x0090
+#define USB_DEVICE_ID_GTCO_100 0x0100
+#define USB_DEVICE_ID_GTCO_101 0x0101
+#define USB_DEVICE_ID_GTCO_103 0x0103
+#define USB_DEVICE_ID_GTCO_104 0x0104
+#define USB_DEVICE_ID_GTCO_105 0x0105
+#define USB_DEVICE_ID_GTCO_106 0x0106
+#define USB_DEVICE_ID_GTCO_107 0x0107
+#define USB_DEVICE_ID_GTCO_108 0x0108
+#define USB_DEVICE_ID_GTCO_200 0x0200
+#define USB_DEVICE_ID_GTCO_201 0x0201
+#define USB_DEVICE_ID_GTCO_202 0x0202
+#define USB_DEVICE_ID_GTCO_203 0x0203
+#define USB_DEVICE_ID_GTCO_204 0x0204
+#define USB_DEVICE_ID_GTCO_205 0x0205
+#define USB_DEVICE_ID_GTCO_206 0x0206
+#define USB_DEVICE_ID_GTCO_207 0x0207
+#define USB_DEVICE_ID_GTCO_300 0x0300
+#define USB_DEVICE_ID_GTCO_301 0x0301
+#define USB_DEVICE_ID_GTCO_302 0x0302
+#define USB_DEVICE_ID_GTCO_303 0x0303
+#define USB_DEVICE_ID_GTCO_304 0x0304
+#define USB_DEVICE_ID_GTCO_305 0x0305
+#define USB_DEVICE_ID_GTCO_306 0x0306
+#define USB_DEVICE_ID_GTCO_307 0x0307
+#define USB_DEVICE_ID_GTCO_308 0x0308
+#define USB_DEVICE_ID_GTCO_309 0x0309
+#define USB_DEVICE_ID_GTCO_400 0x0400
+#define USB_DEVICE_ID_GTCO_401 0x0401
+#define USB_DEVICE_ID_GTCO_402 0x0402
+#define USB_DEVICE_ID_GTCO_403 0x0403
+#define USB_DEVICE_ID_GTCO_404 0x0404
+#define USB_DEVICE_ID_GTCO_405 0x0405
+#define USB_DEVICE_ID_GTCO_500 0x0500
+#define USB_DEVICE_ID_GTCO_501 0x0501
+#define USB_DEVICE_ID_GTCO_502 0x0502
+#define USB_DEVICE_ID_GTCO_503 0x0503
+#define USB_DEVICE_ID_GTCO_504 0x0504
+#define USB_DEVICE_ID_GTCO_1000 0x1000
+#define USB_DEVICE_ID_GTCO_1001 0x1001
+#define USB_DEVICE_ID_GTCO_1002 0x1002
+#define USB_DEVICE_ID_GTCO_1003 0x1003
+#define USB_DEVICE_ID_GTCO_1004 0x1004
+#define USB_DEVICE_ID_GTCO_1005 0x1005
+#define USB_DEVICE_ID_GTCO_1006 0x1006
+#define USB_DEVICE_ID_GTCO_1007 0x1007
+
+#define USB_VENDOR_ID_GYRATION 0x0c16
+#define USB_DEVICE_ID_GYRATION_REMOTE 0x0002
+#define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003
+#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008
+
+#define I2C_VENDOR_ID_HANTICK 0x0911
+#define I2C_PRODUCT_ID_HANTICK_5288 0x5288
+
+#define USB_VENDOR_ID_HANWANG 0x0b57
+#define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000
+#define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff
+
+#define USB_VENDOR_ID_HANVON 0x20b3
+#define USB_DEVICE_ID_HANVON_MULTITOUCH 0x0a18
+
+#define USB_VENDOR_ID_HANVON_ALT 0x22ed
+#define USB_DEVICE_ID_HANVON_ALT_MULTITOUCH 0x1010
+
+#define USB_VENDOR_ID_HAPP 0x078b
+#define USB_DEVICE_ID_UGCI_DRIVING 0x0010
+#define USB_DEVICE_ID_UGCI_FLYING 0x0020
+#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030
+
+#define USB_VENDOR_ID_HP 0x03f0
+#define USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A 0x464a
+#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a
+#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a
+#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a
+#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A 0x094a
+#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941 0x0941
+#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641 0x0641
+#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a 0x1f4a
+
+#define USB_VENDOR_ID_HUION 0x256c
+#define USB_DEVICE_ID_HUION_TABLET 0x006e
+#define USB_DEVICE_ID_HUION_TABLET2 0x006d
+
+#define USB_VENDOR_ID_IBM 0x04b3
+#define USB_DEVICE_ID_IBM_SCROLLPOINT_III 0x3100
+#define USB_DEVICE_ID_IBM_SCROLLPOINT_PRO 0x3103
+#define USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL 0x3105
+#define USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL 0x3108
+#define USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO 0x3109
+
+#define USB_VENDOR_ID_IDEACOM 0x1cb6
+#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
+#define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651
+#define USB_DEVICE_ID_IDEACOM_IDC6680 0x6680
+
+#define USB_VENDOR_ID_ILITEK 0x222a
+#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001
+
+#define USB_VENDOR_ID_INTEL_0 0x8086
+#define USB_VENDOR_ID_INTEL_1 0x8087
+#define USB_DEVICE_ID_INTEL_HID_SENSOR_0 0x09fa
+#define USB_DEVICE_ID_INTEL_HID_SENSOR_1 0x0a04
+
+#define USB_VENDOR_ID_STM_0 0x0483
+#define USB_DEVICE_ID_STM_HID_SENSOR 0x91d1
+#define USB_DEVICE_ID_STM_HID_SENSOR_1 0x9100
+
+#define USB_VENDOR_ID_ION 0x15e4
+#define USB_DEVICE_ID_ICADE 0x0132
+
+#define USB_VENDOR_ID_HOLTEK 0x1241
+#define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015
+
+#define USB_VENDOR_ID_HOLTEK_ALT 0x04d9
+#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A 0xa04a
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070 0xa070
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072 0xa072
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2 0xa0c2
+#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096 0xa096
+#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293 0xa293
+
+#define USB_VENDOR_ID_IMATION 0x0718
+#define USB_DEVICE_ID_DISC_STAKKA 0xd000
+
+#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615
+#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070
+
+#define USB_VENDOR_ID_INNOMEDIA 0x1292
+#define USB_DEVICE_ID_INNEX_GENESIS_ATARI 0x4745
+
+#define USB_VENDOR_ID_ITE 0x048d
+#define I2C_VENDOR_ID_ITE 0x103c
+#define I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15 0x184f
+#define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386
+#define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350
+#define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a
+#define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396
+#define I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD 0x8987
+#define USB_DEVICE_ID_ITE8595 0x8595
+#define USB_DEVICE_ID_ITE_MEDION_E1239T 0xce50
+
+#define USB_VENDOR_ID_JABRA 0x0b0e
+#define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412
+#define USB_DEVICE_ID_JABRA_SPEAK_510 0x0420
+#define USB_DEVICE_ID_JABRA_GN9350E 0x9350
+
+#define USB_VENDOR_ID_JESS 0x0c45
+#define USB_DEVICE_ID_JESS_YUREX 0x1010
+#define USB_DEVICE_ID_ASUS_MD_5112 0x5112
+#define USB_DEVICE_ID_REDRAGON_ASURA 0x760b
+
+#define USB_VENDOR_ID_JESS2 0x0f30
+#define USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD 0x0111
+
+#define USB_VENDOR_ID_KBGEAR 0x084e
+#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
+
+#define USB_VENDOR_ID_KENSINGTON 0x047d
+#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
+
+#define USB_VENDOR_ID_KWORLD 0x1b80
+#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700
+
+#define USB_VENDOR_ID_KEYTOUCH 0x0926
+#define USB_DEVICE_ID_KEYTOUCH_IEC 0x3333
+
+#define USB_VENDOR_ID_KYE 0x0458
+#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
+#define USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE 0x0138
+#define USB_DEVICE_ID_GENIUS_MANTICORE 0x0153
+#define USB_DEVICE_ID_GENIUS_GX_IMPERATOR 0x4018
+#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
+#define USB_DEVICE_ID_KYE_EASYPEN_M406 0x5005
+#define USB_DEVICE_ID_KYE_EASYPEN_M506 0x500F
+#define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010
+#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011
+#define USB_DEVICE_ID_KYE_EASYPEN_M406W 0x5012
+#define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013
+#define USB_DEVICE_ID_KYE_EASYPEN_340 0x5014
+#define USB_DEVICE_ID_KYE_PENSKETCH_M912 0x5015
+#define USB_DEVICE_ID_KYE_MOUSEPEN_M508WX 0x5016
+#define USB_DEVICE_ID_KYE_MOUSEPEN_M508X 0x5017
+#define USB_DEVICE_ID_KYE_EASYPEN_M406XE 0x5019
+#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2 0x501A
+#define USB_DEVICE_ID_KYE_PENSKETCH_T609A 0x501B
+
+#define USB_VENDOR_ID_KYSONA 0x3554
+#define USB_DEVICE_ID_KYSONA_M600_DONGLE 0xF57C
+#define USB_DEVICE_ID_KYSONA_M600_WIRED 0xF57D
+
+#define USB_VENDOR_ID_LABTEC 0x1020
+#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
+#define USB_DEVICE_ID_LABTEC_ODDOR_HANDBRAKE 0x8888
+
+#define USB_VENDOR_ID_LAVIEW 0x22D4
+#define USB_DEVICE_ID_GLORIOUS_MODEL_I 0x1503
+
+#define USB_VENDOR_ID_LCPOWER 0x1241
+#define USB_DEVICE_ID_LCPOWER_LC1000 0xf767
+
+#define USB_VENDOR_ID_LD 0x0f11
+#define USB_DEVICE_ID_LD_CASSY 0x1000
+#define USB_DEVICE_ID_LD_CASSY2 0x1001
+#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010
+#define USB_DEVICE_ID_LD_POCKETCASSY2 0x1011
+#define USB_DEVICE_ID_LD_MOBILECASSY 0x1020
+#define USB_DEVICE_ID_LD_MOBILECASSY2 0x1021
+#define USB_DEVICE_ID_LD_MICROCASSYVOLTAGE 0x1031
+#define USB_DEVICE_ID_LD_MICROCASSYCURRENT 0x1032
+#define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033
+#define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035
+#define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038
+#define USB_DEVICE_ID_LD_POWERANALYSERCASSY 0x1040
+#define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY 0x1042
+#define USB_DEVICE_ID_LD_MACHINETESTCASSY 0x1043
+#define USB_DEVICE_ID_LD_JWM 0x1080
+#define USB_DEVICE_ID_LD_DMMP 0x1081
+#define USB_DEVICE_ID_LD_UMIP 0x1090
+#define USB_DEVICE_ID_LD_UMIC 0x10A0
+#define USB_DEVICE_ID_LD_UMIB 0x10B0
+#define USB_DEVICE_ID_LD_XRAY 0x1100
+#define USB_DEVICE_ID_LD_XRAY2 0x1101
+#define USB_DEVICE_ID_LD_XRAYCT 0x1110
+#define USB_DEVICE_ID_LD_VIDEOCOM 0x1200
+#define USB_DEVICE_ID_LD_MOTOR 0x1210
+#define USB_DEVICE_ID_LD_COM3LAB 0x2000
+#define USB_DEVICE_ID_LD_TELEPORT 0x2010
+#define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020
+#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
+#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
+#define USB_DEVICE_ID_LD_MOSTANALYSER 0x2050
+#define USB_DEVICE_ID_LD_MOSTANALYSER2 0x2051
+#define USB_DEVICE_ID_LD_ABSESP 0x2060
+#define USB_DEVICE_ID_LD_AUTODATABUS 0x2070
+#define USB_DEVICE_ID_LD_MCT 0x2080
+#define USB_DEVICE_ID_LD_HYBRID 0x2090
+#define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0
+
+#define USB_VENDOR_ID_LENOVO 0x17ef
+#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009
+#define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047
+#define USB_DEVICE_ID_LENOVO_TPIIUSBKBD 0x60ee
+#define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048
+#define USB_DEVICE_ID_LENOVO_TPIIBTKBD 0x60e1
+#define USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL 0x6049
+#define USB_DEVICE_ID_LENOVO_TP10UBKBD 0x6062
+#define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067
+#define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085
+#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3
+#define USB_DEVICE_ID_LENOVO_X1_TAB2 0x60a4
+#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5
+#define USB_DEVICE_ID_LENOVO_X12_TAB 0x60fe
+#define USB_DEVICE_ID_LENOVO_X12_TAB2 0x61ae
+#define USB_DEVICE_ID_LENOVO_YOGABOOK9I 0x6161
+#define USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E 0x600e
+#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d
+#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
+#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e
+#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093 0x6093
+#define USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT 0x6184
+#define USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT 0x61ed
+
+#define USB_VENDOR_ID_LETSKETCH 0x6161
+#define USB_DEVICE_ID_WP9620N 0x4d15
+
+#define USB_VENDOR_ID_LG 0x1fd2
+#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
+#define USB_DEVICE_ID_LG_MELFAS_MT 0x6007
+#define I2C_DEVICE_ID_LG_8001 0x8001
+#define I2C_DEVICE_ID_LG_7010 0x7010
+
+#define USB_VENDOR_ID_LITE_STAR 0x11ff
+#define USB_DEVICE_ID_PXN_V10 0x3245
+#define USB_DEVICE_ID_PXN_V12 0x1212
+#define USB_DEVICE_ID_PXN_V12_LITE 0x1112
+#define USB_DEVICE_ID_PXN_V12_LITE_2 0x1211
+#define USB_DEVICE_ID_LITE_STAR_GT987 0x2141
+
+#define USB_VENDOR_ID_LOGITECH 0x046d
+#define USB_DEVICE_ID_LOGITECH_Z_10_SPK 0x0a07
+#define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
+#define USB_DEVICE_ID_LOGITECH_T651 0xb00c
+#define USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD 0xb309
+#define USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD 0xbb00
+#define USB_DEVICE_ID_LOGITECH_C007 0xc007
+#define USB_DEVICE_ID_LOGITECH_C077 0xc077
+#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
+#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
+#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
+#define USB_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306
+#define USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS 0xc24d
+#define USB_DEVICE_ID_LOGITECH_MOUSE_C01A 0xc01a
+#define USB_DEVICE_ID_LOGITECH_MOUSE_C05A 0xc05a
+#define USB_DEVICE_ID_LOGITECH_MOUSE_C06A 0xc06a
+#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a
+#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211
+#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
+#define USB_DEVICE_ID_LOGITECH_DUAL_ACTION 0xc216
+#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218
+#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219
+#define USB_DEVICE_ID_LOGITECH_G13 0xc21c
+#define USB_DEVICE_ID_LOGITECH_G15_LCD 0xc222
+#define USB_DEVICE_ID_LOGITECH_G11 0xc225
+#define USB_DEVICE_ID_LOGITECH_G15_V2_LCD 0xc227
+#define USB_DEVICE_ID_LOGITECH_G510 0xc22d
+#define USB_DEVICE_ID_LOGITECH_G510_USB_AUDIO 0xc22e
+#define USB_DEVICE_ID_LOGITECH_G29_WHEEL 0xc24f
+#define USB_DEVICE_ID_LOGITECH_G920_WHEEL 0xc262
+#define USB_DEVICE_ID_LOGITECH_G923_XBOX_WHEEL 0xc26e
+#define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283
+#define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286
+#define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287
+#define USB_DEVICE_ID_LOGITECH_WINGMAN_FG 0xc20e
+#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293
+#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
+#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
+#define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298
+#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299
+#define USB_DEVICE_ID_LOGITECH_DFGT_WHEEL 0xc29a
+#define USB_DEVICE_ID_LOGITECH_G27_WHEEL 0xc29b
+#define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c
+#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
+#define USB_DEVICE_ID_LOGITECH_GROUP_AUDIO 0x0882
+#define USB_DEVICE_ID_S510_RECEIVER 0xc50c
+#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
+#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
+#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
+#define USB_DEVICE_ID_LOGITECH_27MHZ_MOUSE_RECEIVER 0xc51b
+#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER 0xc52b
+#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER 0xc52f
+#define USB_DEVICE_ID_LOGITECH_G700_RECEIVER 0xc531
+#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2 0xc532
+#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534
+#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539
+#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f
+#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 0xc543
+#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_3 0xc547
+#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_4 0xc54d
+#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
+#define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER 0xc548
+#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
+#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
+#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
+#define USB_DEVICE_ID_MX5000_RECEIVER_MOUSE_DEV 0xc70a
+#define USB_DEVICE_ID_MX5000_RECEIVER_KBD_DEV 0xc70e
+#define USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_KBD_DEV 0xc713
+#define USB_DEVICE_ID_DINOVO_EDGE_RECEIVER_MOUSE_DEV 0xc714
+#define USB_DEVICE_ID_MX5500_RECEIVER_KBD_DEV 0xc71b
+#define USB_DEVICE_ID_MX5500_RECEIVER_MOUSE_DEV 0xc71c
+#define USB_DEVICE_ID_DINOVO_MINI_RECEIVER_KBD_DEV 0xc71e
+#define USB_DEVICE_ID_DINOVO_MINI_RECEIVER_MOUSE_DEV 0xc71f
+#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03
+#define USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL 0xca04
+
+#define USB_VENDOR_ID_LUMIO 0x202e
+#define USB_DEVICE_ID_CRYSTALTOUCH 0x0006
+#define USB_DEVICE_ID_CRYSTALTOUCH_DUAL 0x0007
+
+#define USB_VENDOR_ID_MADCATZ 0x0738
+#define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540
+#define USB_DEVICE_ID_MADCATZ_RAT5 0x1705
+#define USB_DEVICE_ID_MADCATZ_RAT9 0x1709
+#define USB_DEVICE_ID_MADCATZ_MMO7 0x1713
+
+#define USB_VENDOR_ID_MCC 0x09db
+#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
+#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a
+
+#define USB_VENDOR_ID_MCS 0x16d0
+#define USB_DEVICE_ID_MCS_GAMEPADBLOCK 0x0bcc
+
+#define USB_VENDOR_MEGAWORLD 0x07b5
+#define USB_DEVICE_ID_MEGAWORLD_GAMEPAD 0x0312
+
+#define USB_VENDOR_ID_MGE 0x0463
+#define USB_DEVICE_ID_MGE_UPS 0xffff
+#define USB_DEVICE_ID_MGE_UPS1 0x0001
+
+#define USB_VENDOR_ID_MICROCHIP 0x04d8
+#define USB_DEVICE_ID_PICKIT1 0x0032
+#define USB_DEVICE_ID_PICKIT2 0x0033
+#define USB_DEVICE_ID_PICOLCD 0xc002
+#define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002
+#define USB_DEVICE_ID_PICK16F1454 0x0042
+#define USB_DEVICE_ID_PICK16F1454_V2 0xf2f7
+#define USB_DEVICE_ID_LUXAFOR 0xf372
+#define USB_DEVICE_ID_MCP2200 0x00df
+#define USB_DEVICE_ID_MCP2221 0x00dd
+
+#define USB_VENDOR_ID_MICROSOFT 0x045e
+#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
+#define USB_DEVICE_ID_MS_OFFICE_KB 0x0048
+#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
+#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K 0x00b4
+#define USB_DEVICE_ID_MS_NE4K 0x00db
+#define USB_DEVICE_ID_MS_NE4K_JP 0x00dc
+#define USB_DEVICE_ID_MS_LK6K 0x00f9
+#define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701
+#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
+#define USB_DEVICE_ID_MS_NE7K 0x071d
+#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730
+#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1 0x0732
+#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_600 0x0750
+#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c
+#define USB_DEVICE_ID_MS_COMFORT_KEYBOARD 0x00e3
+#define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799
+#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
+#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
+#define USB_DEVICE_ID_MS_POWER_COVER 0x07da
+#define USB_DEVICE_ID_MS_SURFACE3_COVER 0x07de
+/*
+ * For a description of the Xbox controller models, refer to:
+ * https://en.wikipedia.org/wiki/Xbox_Wireless_Controller#Summary
+ */
+#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708 0x02fd
+#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708_BLE 0x0b20
+#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1914 0x0b13
+#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797 0x0b05
+#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797_BLE 0x0b22
+#define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb
+#define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0
+#define USB_DEVICE_ID_MS_MOUSE_0783 0x0783
+
+#define USB_VENDOR_ID_MOJO 0x8282
+#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
+
+#define USB_VENDOR_ID_MONTEREY 0x0566
+#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
+
+#define USB_VENDOR_ID_MOZA 0x346e
+#define USB_DEVICE_ID_MOZA_R3 0x0005
+#define USB_DEVICE_ID_MOZA_R3_2 0x0015
+#define USB_DEVICE_ID_MOZA_R5 0x0004
+#define USB_DEVICE_ID_MOZA_R5_2 0x0014
+#define USB_DEVICE_ID_MOZA_R9 0x0002
+#define USB_DEVICE_ID_MOZA_R9_2 0x0012
+#define USB_DEVICE_ID_MOZA_R12 0x0006
+#define USB_DEVICE_ID_MOZA_R12_2 0x0016
+#define USB_DEVICE_ID_MOZA_R16_R21 0x0000
+#define USB_DEVICE_ID_MOZA_R16_R21_2 0x0010
+
+#define USB_VENDOR_ID_MSI 0x1770
+#define USB_DEVICE_ID_MSI_GT683R_LED_PANEL 0xff00
+
+#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
+#define USB_DEVICE_ID_N_S_HARMONY 0xc359
+
+#define USB_VENDOR_ID_NATSU 0x08b7
+#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
+
+#define USB_VENDOR_ID_NCR 0x0404
+#define USB_DEVICE_ID_NCR_FIRST 0x0300
+#define USB_DEVICE_ID_NCR_LAST 0x03ff
+
+#define USB_VENDOR_ID_NEC 0x073e
+#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
+
+#define USB_VENDOR_ID_NEXIO 0x1870
+#define USB_DEVICE_ID_NEXIO_MULTITOUCH_420 0x010d
+#define USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750 0x0110
+
+#define USB_VENDOR_ID_NEXTWINDOW 0x1926
+#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
+
+#define USB_VENDOR_ID_NINTENDO 0x057e
+#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306
+#define USB_DEVICE_ID_NINTENDO_WIIMOTE2 0x0330
+#define USB_DEVICE_ID_NINTENDO_JOYCONL 0x2006
+#define USB_DEVICE_ID_NINTENDO_JOYCONR 0x2007
+#define USB_DEVICE_ID_NINTENDO_PROCON 0x2009
+#define USB_DEVICE_ID_NINTENDO_CHRGGRIP 0x200e
+#define USB_DEVICE_ID_NINTENDO_SNESCON 0x2017
+#define USB_DEVICE_ID_NINTENDO_GENCON 0x201e
+#define USB_DEVICE_ID_NINTENDO_N64CON 0x2019
+
+#define USB_VENDOR_ID_NOVATEK 0x0603
+#define USB_DEVICE_ID_NOVATEK_PCT 0x0600
+#define USB_DEVICE_ID_NOVATEK_MOUSE 0x1602
+
+#define USB_VENDOR_ID_NTI 0x0757
+#define USB_DEVICE_ID_USB_SUN 0x0a00
+
+#define USB_VENDOR_ID_NTRIG 0x1b96
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3 0x0005
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4 0x0006
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5 0x0007
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6 0x0008
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7 0x0009
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8 0x000A
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9 0x000B
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10 0x000C
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11 0x000D
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12 0x000E
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13 0x000F
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14 0x0010
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15 0x0011
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16 0x0012
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013
+#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014
+#define USB_DEVICE_ID_NTRIG_DUOSENSE 0x1500
+
+#define USB_VENDOR_ID_NVIDIA 0x0955
+#define USB_DEVICE_ID_NVIDIA_THUNDERSTRIKE_CONTROLLER 0x7214
+
+#define USB_VENDOR_ID_ONTRAK 0x0a07
+#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
+
+#define USB_VENDOR_ID_ORTEK 0x05a4
+#define USB_DEVICE_ID_ORTEK_PKB1700 0x1700
+#define USB_DEVICE_ID_ORTEK_WKB2000 0x2000
+#define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S 0x8003
+
+#define USB_VENDOR_ID_PLANTRONICS 0x047f
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES 0xc055
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES 0x430c
+#define USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES 0x431e
+
+#define USB_VENDOR_ID_PANASONIC 0x04da
+#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
+#define USB_DEVICE_ID_PANABOARD_UBT880 0x104d
+
+#define USB_VENDOR_ID_PANJIT 0x134c
+
+#define USB_VENDOR_ID_PANTHERLORD 0x0810
+#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001
+
+#define USB_VENDOR_ID_PENMOUNT 0x14e1
+#define USB_DEVICE_ID_PENMOUNT_PCI 0x3500
+#define USB_DEVICE_ID_PENMOUNT_1610 0x1610
+#define USB_DEVICE_ID_PENMOUNT_1640 0x1640
+#define USB_DEVICE_ID_PENMOUNT_6000 0x6000
+
+#define USB_VENDOR_ID_PETALYNX 0x18b1
+#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
+
+#define USB_VENDOR_ID_PETZL 0x2122
+#define USB_DEVICE_ID_PETZL_HEADLAMP 0x1234
+
+#define USB_VENDOR_ID_PHILIPS 0x0471
+#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617
+
+#define USB_VENDOR_ID_PI_ENGINEERING 0x05f3
+#define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff
+
+#define USB_VENDOR_ID_PIXART 0x093a
+#define USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2 0x0137
+#define USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE 0x2510
+#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN 0x8001
+#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1 0x8002
+#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2 0x8003
+
+#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
+#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
+
+#define USB_VENDOR_ID_POWERCOM 0x0d9f
+#define USB_DEVICE_ID_POWERCOM_UPS 0x0002
+
+#define USB_VENDOR_ID_PRODIGE 0x05af
+#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062
+
+#define I2C_VENDOR_ID_QTEC 0x6243
+
+#define USB_VENDOR_ID_QUANTA 0x0408
+#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000
+#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001
+#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003 0x3003
+#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008
+#define USB_DEVICE_ID_QUANTA_HP_5MP_CAMERA_5473 0x5473
+
+#define I2C_VENDOR_ID_RAYDIUM 0x2386
+#define I2C_PRODUCT_ID_RAYDIUM_4B33 0x4b33
+#define I2C_PRODUCT_ID_RAYDIUM_3118 0x3118
+
+#define USB_VENDOR_ID_RAZER 0x1532
+#define USB_DEVICE_ID_RAZER_BLACKWIDOW_ULTIMATE 0x010D
+#define USB_DEVICE_ID_RAZER_BLACKWIDOW 0x010e
+#define USB_DEVICE_ID_RAZER_BLACKWIDOW_CLASSIC 0x011b
+#define USB_DEVICE_ID_RAZER_BLADE_14 0x011D
+
+#define USB_VENDOR_ID_REALTEK 0x0bda
+#define USB_DEVICE_ID_REALTEK_READER 0x0152
+
+#define USB_VENDOR_ID_REDOCTANE 0x1430
+#define USB_DEVICE_ID_REDOCTANE_GUITAR_DONGLE 0x474c
+#define USB_DEVICE_ID_REDOCTANE_PS4_GHLIVE_DONGLE 0x07bb
+
+#define USB_VENDOR_ID_RETROUSB 0xf000
+#define USB_DEVICE_ID_RETROUSB_SNES_RETROPAD 0x0003
+#define USB_DEVICE_ID_RETROUSB_SNES_RETROPORT 0x00f1
+
+#define USB_VENDOR_ID_ROCCAT 0x1e7d
+#define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4
+#define USB_DEVICE_ID_ROCCAT_ISKU 0x319c
+#define USB_DEVICE_ID_ROCCAT_ISKUFX 0x3264
+#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
+#define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51
+#define USB_DEVICE_ID_ROCCAT_KONEPURE 0x2dbe
+#define USB_DEVICE_ID_ROCCAT_KONEPURE_OPTICAL 0x2db4
+#define USB_DEVICE_ID_ROCCAT_KONEXTD 0x2e22
+#define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50
+#define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e
+#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
+#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
+#define USB_DEVICE_ID_ROCCAT_RYOS_MK 0x3138
+#define USB_DEVICE_ID_ROCCAT_RYOS_MK_GLOW 0x31ce
+#define USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO 0x3232
+#define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a
+
+#define USB_VENDOR_ID_SAI 0x17dd
+
+#define USB_VENDOR_ID_SAITEK 0x06a3
+#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
+#define USB_DEVICE_ID_SAITEK_PS1000 0x0621
+#define USB_DEVICE_ID_SAITEK_RAT7_OLD 0x0ccb
+#define USB_DEVICE_ID_SAITEK_RAT7_CONTAGION 0x0ccd
+#define USB_DEVICE_ID_SAITEK_RAT7 0x0cd7
+#define USB_DEVICE_ID_SAITEK_RAT9 0x0cfa
+#define USB_DEVICE_ID_SAITEK_MMO7 0x0cd0
+#define USB_DEVICE_ID_SAITEK_X52 0x075c
+#define USB_DEVICE_ID_SAITEK_X52_2 0x0255
+#define USB_DEVICE_ID_SAITEK_X52_PRO 0x0762
+#define USB_DEVICE_ID_SAITEK_X65 0x0b6a
+
+#define USB_VENDOR_ID_SAMSUNG 0x0419
+#define USB_VENDOR_ID_SAMSUNG_ELECTRONICS 0x04e8
+#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD 0x7021
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD 0xa000
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE 0xa004
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_BOOKCOVER 0xa005
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD 0xa006
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD 0xa064
+
+#define USB_VENDOR_ID_SEMICO 0x1a2c
+#define USB_DEVICE_ID_SEMICO_USB_KEYKOARD 0x0023
+#define USB_DEVICE_ID_SEMICO_USB_KEYKOARD2 0x0027
+
+#define USB_VENDOR_ID_SEMITEK 0x1ea7
+#define USB_DEVICE_ID_SEMITEK_KEYBOARD 0x0907
+
+#define USB_VENDOR_ID_SENNHEISER 0x1395
+#define USB_DEVICE_ID_SENNHEISER_BTD500USB 0x002c
+
+#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f
+#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002
+#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD2 0x0059
+
+#define USB_VENDOR_ID_SIGMATEL 0x066F
+#define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780
+
+#define USB_VENDOR_ID_SINOWEALTH 0x258a
+#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033
+#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036
+
+#define USB_VENDOR_ID_SIS_TOUCH 0x0457
+#define USB_DEVICE_ID_SIS9200_TOUCH 0x9200
+#define USB_DEVICE_ID_SIS817_TOUCH 0x0817
+#define USB_DEVICE_ID_SIS_TS 0x1013
+#define USB_DEVICE_ID_SIS1030_TOUCH 0x1030
+
+#define USB_VENDOR_ID_SKYCABLE 0x1223
+#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07
+
+#define USB_VENDOR_ID_SMK 0x0609
+#define USB_DEVICE_ID_SMK_PS3_BDREMOTE 0x0306
+#define USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE 0x0368
+#define USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE 0x0369
+
+#define USB_VENDOR_ID_SONY 0x054c
+#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
+#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374
+#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
+#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
+#define USB_DEVICE_ID_SONY_PS4_CONTROLLER 0x05c4
+#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2 0x09cc
+#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE 0x0ba0
+#define USB_DEVICE_ID_SONY_PS5_CONTROLLER 0x0ce6
+#define USB_DEVICE_ID_SONY_PS5_CONTROLLER_2 0x0df2
+#define USB_DEVICE_ID_SONY_MOTION_CONTROLLER 0x03d5
+#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
+#define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002
+#define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000
+
+#define USB_VENDOR_ID_SONY_RHYTHM 0x12ba
+#define USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE_DONGLE 0x074b
+#define USB_DEVICE_ID_SONY_PS3_GUITAR_DONGLE 0x0100
+
+#define USB_VENDOR_ID_SINO_LITE 0x1345
+#define USB_DEVICE_ID_SINO_LITE_CONTROLLER 0x3008
+
+#define USB_VENDOR_ID_SOLID_YEAR 0x060b
+#define USB_DEVICE_ID_MACALLY_IKEY_KEYBOARD 0x0001
+#define USB_DEVICE_ID_COUGAR_500K_GAMING_KEYBOARD 0x500a
+#define USB_DEVICE_ID_COUGAR_700K_GAMING_KEYBOARD 0x700a
+
+#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST 0x0046
+
+#define USB_VENDOR_ID_STANTUM 0x1f87
+#define USB_DEVICE_ID_MTP 0x0002
+
+#define USB_VENDOR_ID_STANTUM_STM 0x0483
+#define USB_DEVICE_ID_MTP_STM 0x3261
+
+#define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403
+#define USB_DEVICE_ID_MTP_SITRONIX 0x5001
+
+#define USB_VENDOR_ID_VALVE 0x28de
+#define USB_DEVICE_ID_STEAM_CONTROLLER 0x1102
+#define USB_DEVICE_ID_STEAM_CONTROLLER_WIRELESS 0x1142
+#define USB_DEVICE_ID_STEAM_DECK 0x1205
+
+#define USB_VENDOR_ID_STEELSERIES 0x1038
+#define USB_DEVICE_ID_STEELSERIES_SRWS1 0x1410
+#define USB_DEVICE_ID_STEELSERIES_ARCTIS_1 0x12b6
+#define USB_DEVICE_ID_STEELSERIES_ARCTIS_9 0x12c2
+
+#define USB_VENDOR_ID_SUN 0x0430
+#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
+
+#define USB_VENDOR_ID_SUNPLUS 0x04fc
+#define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8
+
+#define USB_VENDOR_ID_SYMBOL 0x05e0
+#define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800
+#define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300
+#define USB_DEVICE_ID_SYMBOL_SCANNER_3 0x1200
+
+#define I2C_VENDOR_ID_SYNAPTICS 0x06cb
+#define I2C_PRODUCT_ID_SYNAPTICS_SYNA2393 0x7a13
+
+#define USB_VENDOR_ID_SYNAPTICS 0x06cb
+#define USB_DEVICE_ID_SYNAPTICS_TP 0x0001
+#define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002
+#define USB_DEVICE_ID_SYNAPTICS_CPAD 0x0003
+#define USB_DEVICE_ID_SYNAPTICS_TS 0x0006
+#define USB_DEVICE_ID_SYNAPTICS_STICK 0x0007
+#define USB_DEVICE_ID_SYNAPTICS_WP 0x0008
+#define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009
+#define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010
+#define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013
+#define USB_DEVICE_ID_SYNAPTICS_LTS1 0x0af8
+#define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10
+#define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3
+#define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3
+#define USB_DEVICE_ID_SYNAPTICS_DELL_K12A 0x2819
+#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012 0x2968
+#define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710
+#define USB_DEVICE_ID_SYNAPTICS_DELL_K15A 0x6e21
+#define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1002 0x73f4
+#define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003 0x73f5
+#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_017 0x73f6
+#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7
+
+#define USB_VENDOR_ID_TEXAS_INSTRUMENTS 0x2047
+#define USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA 0x0855
+
+#define USB_VENDOR_ID_THINGM 0x27b8
+#define USB_DEVICE_ID_BLINK1 0x01ed
+
+#define USB_VENDOR_ID_THQ 0x20d6
+#define USB_DEVICE_ID_THQ_PS3_UDRAW 0xcb17
+
+#define USB_VENDOR_ID_THRUSTMASTER 0x044f
+
+#define USB_VENDOR_ID_TIVO 0x150a
+#define USB_DEVICE_ID_TIVO_SLIDE_BT 0x1200
+#define USB_DEVICE_ID_TIVO_SLIDE 0x1201
+#define USB_DEVICE_ID_TIVO_SLIDE_PRO 0x1203
+
+#define USB_VENDOR_ID_TOPRE 0x0853
+#define USB_DEVICE_ID_TOPRE_REALFORCE_R2_108 0x0148
+#define USB_DEVICE_ID_TOPRE_REALFORCE_R2_87 0x0146
+#define USB_DEVICE_ID_TOPRE_REALFORCE_R3S_87 0x0313
+
+#define USB_VENDOR_ID_TOPSEED 0x0766
+#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
+
+#define USB_VENDOR_ID_TOPSEED2 0x1784
+#define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004
+#define USB_DEVICE_ID_TOPSEED2_PERIPAD_701 0x0016
+
+#define USB_VENDOR_ID_TOPMAX 0x0663
+#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
+
+#define USB_VENDOR_ID_TOUCH_INTL 0x1e5e
+#define USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH 0x0313
+
+#define USB_VENDOR_ID_TOUCHPACK 0x1bfd
+#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688
+
+#define USB_VENDOR_ID_TPV 0x25aa
+#define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882 0x8882
+#define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883 0x8883
+
+#define USB_VENDOR_ID_TRUST 0x145f
+#define USB_DEVICE_ID_TRUST_PANORA_TABLET 0x0212
+
+#define USB_VENDOR_ID_TURBOX 0x062a
+#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
+#define USB_DEVICE_ID_ASUS_MD_5110 0x5110
+#define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100
+
+#define USB_VENDOR_ID_TWINHAN 0x6253
+#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100
+
+#define USB_VENDOR_ID_UCLOGIC 0x5543
+#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
+#define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001
+#define USB_DEVICE_ID_UCLOGIC_TABLET_TWA60 0x0064
+#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003
+#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004
+#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005
+#define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064
+#define USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850 0x0522
+#define USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60 0x0781
+#define USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3 0x3031
+#define USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_81 0x0081
+#define USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_45 0x0045
+#define USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_47 0x0047
+#define USB_DEVICE_ID_YIYNOVA_TABLET 0x004d
+
+#define USB_VENDOR_ID_UGEE 0x28bd
+#define USB_DEVICE_ID_UGEE_PARBLO_A610_PRO 0x1903
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540 0x0075
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640 0x0094
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01 0x0042
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01_V2 0x0905
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L 0x0935
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_MW 0x0934
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S 0x0909
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW 0x0933
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06 0x0078
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_22R_PRO 0x091b
+#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_24_PRO 0x092d
+#define USB_DEVICE_ID_UGEE_TABLET_G5 0x0074
+#define USB_DEVICE_ID_UGEE_TABLET_EX07S 0x0071
+#define USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720 0x0055
+
+#define USB_VENDOR_ID_UNITEC 0x227d
+#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709
+#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19 0x0a19
+
+#define USB_VENDOR_ID_VELLEMAN 0x10cf
+#define USB_DEVICE_ID_VELLEMAN_K8055_FIRST 0x5500
+#define USB_DEVICE_ID_VELLEMAN_K8055_LAST 0x5503
+#define USB_DEVICE_ID_VELLEMAN_K8061_FIRST 0x8061
+#define USB_DEVICE_ID_VELLEMAN_K8061_LAST 0x8068
+
+#define USB_VENDOR_ID_VRS 0x0483
+#define USB_DEVICE_ID_VRS_DFP 0xa355
+#define USB_DEVICE_ID_VRS_R295 0xa44c
+
+#define USB_VENDOR_ID_VTL 0x0306
+#define USB_DEVICE_ID_VTL_MULTITOUCH_FF3F 0xff3f
+
+#define USB_VENDOR_ID_WACOM 0x056a
+#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
+#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0x00BD
+
+#define USB_VENDOR_ID_WALTOP 0x172f
+#define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH 0x0032
+#define USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH 0x0034
+#define USB_DEVICE_ID_WALTOP_Q_PAD 0x0037
+#define USB_DEVICE_ID_WALTOP_PID_0038 0x0038
+#define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH 0x0501
+#define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500
+#define USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET 0x0502
+
+#define USB_VENDOR_ID_WEIDA 0x2575
+#define USB_DEVICE_ID_WEIDA_8752 0xC300
+#define USB_DEVICE_ID_WEIDA_8755 0xC301
+
+#define USB_VENDOR_ID_WINBOND 0x0416
+#define USB_DEVICE_ID_TSTP_MTOUCH 0xc168
+
+#define USB_VENDOR_ID_WISEGROUP 0x0925
+#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005
+#define USB_DEVICE_ID_SUPER_JOY_BOX_3 0x8888
+#define USB_DEVICE_ID_QUAD_USB_JOYPAD 0x8800
+#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866
+
+#define USB_VENDOR_ID_WISEGROUP_LTD 0x6666
+#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677
+#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
+#define USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO 0x8801
+#define USB_DEVICE_ID_SUPER_DUAL_BOX_PRO 0x8802
+#define USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO 0x8804
+
+#define USB_VENDOR_ID_WISTRON 0x0fb8
+#define USB_DEVICE_ID_WISTRON_OPTICAL_TOUCH 0x1109
+
+#define USB_VENDOR_ID_X_TENSIONS 0x1ae7
+#define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE 0x9001
+
+#define USB_VENDOR_ID_XAT 0x2505
+#define USB_DEVICE_ID_XAT_CSR 0x0220
+
+#define USB_VENDOR_ID_XIAOMI 0x2717
+#define USB_DEVICE_ID_MI_SILENT_MOUSE 0x5014
+
+#define USB_VENDOR_ID_XIN_MO 0x16c0
+#define USB_DEVICE_ID_XIN_MO_DUAL_ARCADE 0x05e1
+#define USB_DEVICE_ID_THT_2P_ARCADE 0x75e1
+
+#define USB_VENDOR_ID_XIROKU 0x1477
+#define USB_DEVICE_ID_XIROKU_SPX 0x1006
+#define USB_DEVICE_ID_XIROKU_MPX 0x1007
+#define USB_DEVICE_ID_XIROKU_CSR 0x100e
+#define USB_DEVICE_ID_XIROKU_SPX1 0x1021
+#define USB_DEVICE_ID_XIROKU_CSR1 0x1022
+#define USB_DEVICE_ID_XIROKU_MPX1 0x1023
+#define USB_DEVICE_ID_XIROKU_SPX2 0x1024
+#define USB_DEVICE_ID_XIROKU_CSR2 0x1025
+#define USB_DEVICE_ID_XIROKU_MPX2 0x1026
+
+#define USB_VENDOR_ID_YEALINK 0x6993
+#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001
+
+#define USB_VENDOR_ID_ZEROPLUS 0x0c12
+
+#define USB_VENDOR_ID_ZYDACRON 0x13EC
+#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
+
+#define USB_VENDOR_ID_ZYTRONIC 0x14c8
+#define USB_DEVICE_ID_ZYTRONIC_ZXY100 0x0005
+
+#define USB_VENDOR_ID_PRIMAX 0x0461
+#define USB_DEVICE_ID_PRIMAX_MOUSE_4D22 0x4d22
+#define USB_DEVICE_ID_PRIMAX_MOUSE_4E2A 0x4e2a
+#define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05
+#define USB_DEVICE_ID_PRIMAX_REZEL 0x4e72
+#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F 0x4d0f
+#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65 0x4d65
+#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22 0x4e22
+
+#define USB_VENDOR_ID_RISO_KAGAKU 0x1294 /* Riso Kagaku Corp. */
+#define USB_DEVICE_ID_RI_KA_WEBMAIL 0x1320 /* Webmail Notifier */
+
+#define USB_VENDOR_ID_MULTIPLE_1781 0x1781
+#define USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD 0x0a9d
+#define USB_DEVICE_ID_PHOENIXRC 0x0898
+
+#define USB_VENDOR_ID_DRACAL_RAPHNET 0x289b
+#define USB_DEVICE_ID_RAPHNET_2NES2SNES 0x0002
+#define USB_DEVICE_ID_RAPHNET_4NES4SNES 0x0003
+
+#define USB_VENDOR_ID_UGTIZER 0x2179
+#define USB_DEVICE_ID_UGTIZER_TABLET_GP0610 0x0053
+#define USB_DEVICE_ID_UGTIZER_TABLET_GT5040 0x0077
+#define USB_DEVICE_ID_UGTIZER_TABLET_WP5540 0x0004
+
+#define USB_VENDOR_ID_VIEWSONIC 0x0543
+#define USB_DEVICE_ID_VIEWSONIC_PD1011 0xe621
+
+#define USB_VENDOR_ID_SIGNOTEC 0x2133
+#define USB_DEVICE_ID_SIGNOTEC_VIEWSONIC_PD1011 0x0018
+
+#define USB_VENDOR_ID_JIELI_SDK_DEFAULT 0x4c4a
+#define USB_DEVICE_ID_JIELI_SDK_4155 0x4155
+
+#endif
--
2.53.0
^ permalink raw reply related
* [PATCH 2/3] hid-apple: add pm path to 8102
From: deqrocks @ 2026-04-03 13:06 UTC (permalink / raw)
To: jikos, benjamin.tissoires; +Cc: linux-input
In-Reply-To: <20260403130620.91999-1-andre@negmaster.com>
Add PM handling for the Apple 8102 path so the driver can\nparticipate in suspend and resume on T2 systems.
Signed-off-by: deqrocks <andre@negmaster.com>
---
hid-apple.c | 1328 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1328 insertions(+)
create mode 100644 hid-apple.c
diff --git a/hid-apple.c b/hid-apple.c
new file mode 100644
index 0000000..c620890
--- /dev/null
+++ b/hid-apple.c
@@ -0,0 +1,1328 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * USB HID quirks support for Linux
+ *
+ * Copyright (c) 1999 Andreas Gal
+ * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
+ * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
+ * Copyright (c) 2006-2007 Jiri Kosina
+ * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2019 Paul Pawlowski <paul@mrarm.io>
+ * Copyright (c) 2023 Orlando Chamberlain <orlandoch.dev@gmail.com>
+ * Copyright (c) 2024 Aditya Garg <gargaditya08@live.com>
+ */
+
+/*
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/string.h>
+#include <linux/leds.h>
+#include <dt-bindings/leds/common.h>
+
+#include "hid-ids.h"
+
+#define APPLE_RDESC_JIS BIT(0)
+#define APPLE_IGNORE_MOUSE BIT(1)
+#define APPLE_HAS_FN BIT(2)
+/* BIT(3) reserved, was: APPLE_HIDDEV */
+#define APPLE_ISO_TILDE_QUIRK BIT(4)
+#define APPLE_MIGHTYMOUSE BIT(5)
+#define APPLE_INVERT_HWHEEL BIT(6)
+/* BIT(7) reserved, was: APPLE_IGNORE_HIDINPUT */
+#define APPLE_NUMLOCK_EMULATION BIT(8)
+#define APPLE_RDESC_BATTERY BIT(9)
+#define APPLE_BACKLIGHT_CTL BIT(10)
+#define APPLE_IS_NON_APPLE BIT(11)
+#define APPLE_MAGIC_BACKLIGHT BIT(12)
+#define APPLE_DISABLE_FKEYS BIT(13)
+
+#define APPLE_FLAG_FKEY BIT(0)
+#define APPLE_FLAG_TB_FKEY BIT(1)
+
+#define HID_COUNTRY_INTERNATIONAL_ISO 13
+#define APPLE_BATTERY_TIMEOUT_SEC 60
+
+#define HID_USAGE_MAGIC_BL 0xff00000f
+#define APPLE_MAGIC_REPORT_ID_POWER 3
+#define APPLE_MAGIC_REPORT_ID_BRIGHTNESS 1
+
+static unsigned int fnmode = 3;
+module_param(fnmode, uint, 0644);
+MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
+ "1 = fkeyslast, 2 = fkeysfirst, [3] = auto, 4 = fkeysdisabled)");
+
+static int iso_layout = -1;
+module_param(iso_layout, int, 0644);
+MODULE_PARM_DESC(iso_layout, "Swap the backtick/tilde and greater-than/less-than keys. "
+ "([-1] = auto, 0 = disabled, 1 = enabled)");
+
+static unsigned int swap_opt_cmd;
+module_param(swap_opt_cmd, uint, 0644);
+MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") keys. "
+ "(For people who want to keep Windows PC keyboard muscle memory. "
+ "[0] = as-is, Mac layout. 1 = swapped, Windows layout., 2 = swapped, Swap only left side)");
+
+static unsigned int swap_ctrl_cmd;
+module_param(swap_ctrl_cmd, uint, 0644);
+MODULE_PARM_DESC(swap_ctrl_cmd, "Swap the Control (\"Ctrl\") and Command (\"Flag\") keys. "
+ "(For people who are used to Mac shortcuts involving Command instead of Control. "
+ "[0] = No change. 1 = Swapped.)");
+
+static unsigned int swap_fn_leftctrl;
+module_param(swap_fn_leftctrl, uint, 0644);
+MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
+ "(For people who want to keep PC keyboard muscle memory. "
+ "[0] = as-is, Mac layout, 1 = swapped, PC layout)");
+
+struct apple_non_apple_keyboard {
+ char *name;
+};
+
+struct apple_sc_backlight {
+ struct led_classdev cdev;
+ struct hid_device *hdev;
+ u16 current_brightness;
+ u16 saved_brightness;
+};
+
+struct apple_backlight_config_report {
+ u8 report_id;
+ u8 version;
+ u16 backlight_off, backlight_on_min, backlight_on_max;
+};
+
+struct apple_backlight_set_report {
+ u8 report_id;
+ u8 version;
+ u16 backlight;
+ u16 rate;
+};
+
+struct apple_magic_backlight {
+ struct led_classdev cdev;
+ struct hid_report *brightness;
+ struct hid_report *power;
+ u16 current_brightness;
+ u16 saved_brightness;
+};
+
+struct apple_sc {
+ struct hid_device *hdev;
+ unsigned long quirks;
+ unsigned int fn_on;
+ unsigned int fn_found;
+ DECLARE_BITMAP(pressed_numlock, KEY_CNT);
+ struct timer_list battery_timer;
+ struct apple_sc_backlight *backlight;
+ struct apple_magic_backlight *magic_backlight;
+};
+
+struct apple_key_translation {
+ u16 from;
+ u16 to;
+ unsigned long flags;
+};
+
+static const struct apple_key_translation magic_keyboard_alu_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_ENTER, KEY_INSERT },
+ { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
+ { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
+ { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY },
+ { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY },
+ { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY },
+ { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
+ { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
+ { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
+ { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
+ { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
+ { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
+static const struct apple_key_translation magic_keyboard_2015_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_ENTER, KEY_INSERT },
+ { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
+ { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
+ { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY },
+ { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY },
+ { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
+ { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
+ { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
+ { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
+ { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
+ { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
+static const struct apple_key_translation magic_keyboard_2021_and_2024_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_ENTER, KEY_INSERT },
+ { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
+ { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
+ { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY },
+ { KEY_F4, KEY_SEARCH, APPLE_FLAG_FKEY },
+ { KEY_F5, KEY_MICMUTE, APPLE_FLAG_FKEY },
+ { KEY_F6, KEY_SLEEP, APPLE_FLAG_FKEY },
+ { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
+ { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
+ { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
+ { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
+ { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
+ { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
+static const struct apple_key_translation macbookair_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_ENTER, KEY_INSERT },
+ { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
+ { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
+ { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY },
+ { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY },
+ { KEY_F6, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
+ { KEY_F7, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
+ { KEY_F8, KEY_NEXTSONG, APPLE_FLAG_FKEY },
+ { KEY_F9, KEY_MUTE, APPLE_FLAG_FKEY },
+ { KEY_F10, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
+ { KEY_F11, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
+ { KEY_F12, KEY_EJECTCD, APPLE_FLAG_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
+static const struct apple_key_translation macbookpro_no_esc_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_ENTER, KEY_INSERT },
+ { KEY_GRAVE, KEY_ESC, APPLE_FLAG_TB_FKEY },
+ { KEY_1, KEY_F1, APPLE_FLAG_TB_FKEY },
+ { KEY_2, KEY_F2, APPLE_FLAG_TB_FKEY },
+ { KEY_3, KEY_F3, APPLE_FLAG_TB_FKEY },
+ { KEY_4, KEY_F4, APPLE_FLAG_TB_FKEY },
+ { KEY_5, KEY_F5, APPLE_FLAG_TB_FKEY },
+ { KEY_6, KEY_F6, APPLE_FLAG_TB_FKEY },
+ { KEY_7, KEY_F7, APPLE_FLAG_TB_FKEY },
+ { KEY_8, KEY_F8, APPLE_FLAG_TB_FKEY },
+ { KEY_9, KEY_F9, APPLE_FLAG_TB_FKEY },
+ { KEY_0, KEY_F10, APPLE_FLAG_TB_FKEY },
+ { KEY_MINUS, KEY_F11, APPLE_FLAG_TB_FKEY },
+ { KEY_EQUAL, KEY_F12, APPLE_FLAG_TB_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
+static const struct apple_key_translation macbookpro_dedicated_esc_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_ENTER, KEY_INSERT },
+ { KEY_1, KEY_F1, APPLE_FLAG_TB_FKEY },
+ { KEY_2, KEY_F2, APPLE_FLAG_TB_FKEY },
+ { KEY_3, KEY_F3, APPLE_FLAG_TB_FKEY },
+ { KEY_4, KEY_F4, APPLE_FLAG_TB_FKEY },
+ { KEY_5, KEY_F5, APPLE_FLAG_TB_FKEY },
+ { KEY_6, KEY_F6, APPLE_FLAG_TB_FKEY },
+ { KEY_7, KEY_F7, APPLE_FLAG_TB_FKEY },
+ { KEY_8, KEY_F8, APPLE_FLAG_TB_FKEY },
+ { KEY_9, KEY_F9, APPLE_FLAG_TB_FKEY },
+ { KEY_0, KEY_F10, APPLE_FLAG_TB_FKEY },
+ { KEY_MINUS, KEY_F11, APPLE_FLAG_TB_FKEY },
+ { KEY_EQUAL, KEY_F12, APPLE_FLAG_TB_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
+static const struct apple_key_translation apple_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_ENTER, KEY_INSERT },
+ { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
+ { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
+ { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY },
+ { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY },
+ { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
+ { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
+ { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
+ { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
+ { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
+ { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
+ { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
+ { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
+static const struct apple_key_translation powerbook_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
+ { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
+ { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY },
+ { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
+ { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
+ { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY },
+ { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY },
+ { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY },
+ { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
+ { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
+static const struct apple_key_translation powerbook_numlock_keys[] = {
+ { KEY_J, KEY_KP1 },
+ { KEY_K, KEY_KP2 },
+ { KEY_L, KEY_KP3 },
+ { KEY_U, KEY_KP4 },
+ { KEY_I, KEY_KP5 },
+ { KEY_O, KEY_KP6 },
+ { KEY_7, KEY_KP7 },
+ { KEY_8, KEY_KP8 },
+ { KEY_9, KEY_KP9 },
+ { KEY_M, KEY_KP0 },
+ { KEY_DOT, KEY_KPDOT },
+ { KEY_SLASH, KEY_KPPLUS },
+ { KEY_SEMICOLON, KEY_KPMINUS },
+ { KEY_P, KEY_KPASTERISK },
+ { KEY_MINUS, KEY_KPEQUAL },
+ { KEY_0, KEY_KPSLASH },
+ { KEY_F6, KEY_NUMLOCK },
+ { KEY_KPENTER, KEY_KPENTER },
+ { KEY_BACKSPACE, KEY_BACKSPACE },
+ { }
+};
+
+static const struct apple_key_translation apple_iso_keyboard[] = {
+ { KEY_GRAVE, KEY_102ND },
+ { KEY_102ND, KEY_GRAVE },
+ { }
+};
+
+static const struct apple_key_translation swapped_option_cmd_keys[] = {
+ { KEY_LEFTALT, KEY_LEFTMETA },
+ { KEY_LEFTMETA, KEY_LEFTALT },
+ { KEY_RIGHTALT, KEY_RIGHTMETA },
+ { KEY_RIGHTMETA, KEY_RIGHTALT },
+ { }
+};
+
+static const struct apple_key_translation swapped_option_cmd_left_keys[] = {
+ { KEY_LEFTALT, KEY_LEFTMETA },
+ { KEY_LEFTMETA, KEY_LEFTALT },
+ { }
+};
+
+static const struct apple_key_translation swapped_ctrl_cmd_keys[] = {
+ { KEY_LEFTCTRL, KEY_LEFTMETA },
+ { KEY_LEFTMETA, KEY_LEFTCTRL },
+ { KEY_RIGHTCTRL, KEY_RIGHTMETA },
+ { KEY_RIGHTMETA, KEY_RIGHTCTRL },
+ { }
+};
+
+static const struct apple_key_translation swapped_fn_leftctrl_keys[] = {
+ { KEY_FN, KEY_LEFTCTRL },
+ { KEY_LEFTCTRL, KEY_FN },
+ { }
+};
+
+static const struct apple_non_apple_keyboard non_apple_keyboards[] = {
+ { "SONiX KN85 Keyboard" },
+ { "SONiX USB DEVICE" },
+ { "SONiX AK870 PRO" },
+ { "Keychron" },
+ { "AONE" },
+ { "GANSS" },
+ { "Hailuck" },
+ { "Jamesdonkey" },
+ { "A3R" },
+ { "hfd.cn" },
+ { "WKB603" },
+};
+
+static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(non_apple_keyboards); i++) {
+ char *non_apple = non_apple_keyboards[i].name;
+
+ if (strncmp(hdev->name, non_apple, strlen(non_apple)) == 0)
+ return true;
+ }
+
+ return false;
+}
+
+static bool apple_is_omoton_kb066(struct hid_device *hdev)
+{
+ return hdev->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI &&
+ strcmp(hdev->name, "Bluetooth Keyboard") == 0;
+}
+
+static inline void apple_setup_key_translation(struct input_dev *input,
+ const struct apple_key_translation *table)
+{
+ const struct apple_key_translation *trans;
+
+ for (trans = table; trans->from; trans++)
+ set_bit(trans->to, input->keybit);
+}
+
+static const struct apple_key_translation *apple_find_translation(
+ const struct apple_key_translation *table, u16 from)
+{
+ const struct apple_key_translation *trans;
+
+ /* Look for the translation */
+ for (trans = table; trans->from; trans++)
+ if (trans->from == from)
+ return trans;
+
+ return NULL;
+}
+
+static void input_event_with_scancode(struct input_dev *input,
+ __u8 type, __u16 code, unsigned int hid, __s32 value)
+{
+ if (type == EV_KEY &&
+ (!test_bit(code, input->key)) == value)
+ input_event(input, EV_MSC, MSC_SCAN, hid);
+ input_event(input, type, code, value);
+}
+
+static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
+ struct hid_usage *usage, __s32 value)
+{
+ struct apple_sc *asc = hid_get_drvdata(hid);
+ const struct apple_key_translation *trans, *table;
+ bool do_translate;
+ u16 code = usage->code;
+ unsigned int real_fnmode;
+
+ if (fnmode == 3) {
+ if (asc->quirks & APPLE_DISABLE_FKEYS)
+ real_fnmode = 4;
+ else if (asc->quirks & APPLE_IS_NON_APPLE)
+ real_fnmode = 2;
+ else
+ real_fnmode = 1;
+ } else {
+ real_fnmode = fnmode;
+ }
+
+ if (swap_fn_leftctrl) {
+ trans = apple_find_translation(swapped_fn_leftctrl_keys, code);
+
+ if (trans)
+ code = trans->to;
+ }
+
+ if (iso_layout > 0 || (iso_layout < 0 && (asc->quirks & APPLE_ISO_TILDE_QUIRK) &&
+ hid->country == HID_COUNTRY_INTERNATIONAL_ISO)) {
+ trans = apple_find_translation(apple_iso_keyboard, code);
+
+ if (trans)
+ code = trans->to;
+ }
+
+ if (swap_opt_cmd) {
+ if (swap_opt_cmd == 2)
+ trans = apple_find_translation(swapped_option_cmd_left_keys, code);
+ else
+ trans = apple_find_translation(swapped_option_cmd_keys, code);
+
+ if (trans)
+ code = trans->to;
+ }
+
+ if (swap_ctrl_cmd) {
+ trans = apple_find_translation(swapped_ctrl_cmd_keys, code);
+
+ if (trans)
+ code = trans->to;
+ }
+
+ if (code == KEY_FN)
+ asc->fn_on = !!value;
+
+ if (real_fnmode) {
+ switch (hid->product) {
+ case USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI:
+ case USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO:
+ case USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS:
+ case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI:
+ case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO:
+ case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS:
+ case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI:
+ case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO:
+ case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS:
+ table = magic_keyboard_alu_fn_keys;
+ break;
+ case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015:
+ case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015:
+ table = magic_keyboard_2015_fn_keys;
+ break;
+ case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021:
+ case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021:
+ case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021:
+ case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024:
+ case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024:
+ case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024:
+ table = magic_keyboard_2021_and_2024_fn_keys;
+ break;
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT:
+ table = macbookpro_no_esc_fn_keys;
+ break;
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223:
+ table = macbookpro_dedicated_esc_fn_keys;
+ break;
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K:
+ case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K:
+ table = apple_fn_keys;
+ break;
+ default:
+ if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
+ hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
+ table = macbookair_fn_keys;
+ else if (hid->product < 0x21d || hid->product >= 0x300)
+ table = powerbook_fn_keys;
+ else if (hid->bus == BUS_HOST || hid->bus == BUS_SPI)
+ switch (hid->product) {
+ case SPI_DEVICE_ID_APPLE_MACBOOK_PRO13_2020:
+ case HOST_DEVICE_ID_APPLE_MACBOOK_PRO13_2022:
+ table = macbookpro_dedicated_esc_fn_keys;
+ break;
+ default:
+ table = magic_keyboard_2021_and_2024_fn_keys;
+ break;
+ }
+ else
+ table = apple_fn_keys;
+ }
+
+ trans = apple_find_translation(table, code);
+
+ if (trans) {
+ bool from_is_set = test_bit(trans->from, input->key);
+ bool to_is_set = test_bit(trans->to, input->key);
+
+ if (from_is_set)
+ code = trans->from;
+ else if (to_is_set)
+ code = trans->to;
+
+ if (!(from_is_set || to_is_set)) {
+ if (trans->flags & APPLE_FLAG_FKEY) {
+ switch (real_fnmode) {
+ case 1:
+ do_translate = !asc->fn_on;
+ break;
+ case 2:
+ do_translate = asc->fn_on;
+ break;
+ default:
+ /* case 4 */
+ do_translate = false;
+ }
+ } else if (trans->flags & APPLE_FLAG_TB_FKEY) {
+ switch (real_fnmode) {
+ case 4:
+ do_translate = false;
+ break;
+ default:
+ do_translate = asc->fn_on;
+ }
+ } else {
+ do_translate = asc->fn_on;
+ }
+
+ if (do_translate)
+ code = trans->to;
+ }
+ }
+
+ if (asc->quirks & APPLE_NUMLOCK_EMULATION &&
+ (test_bit(code, asc->pressed_numlock) ||
+ test_bit(LED_NUML, input->led))) {
+ trans = apple_find_translation(powerbook_numlock_keys, code);
+
+ if (trans) {
+ if (value)
+ set_bit(code, asc->pressed_numlock);
+ else
+ clear_bit(code, asc->pressed_numlock);
+
+ code = trans->to;
+ }
+ }
+ }
+
+ if (usage->code != code) {
+ input_event_with_scancode(input, usage->type, code, usage->hid, value);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static int apple_event(struct hid_device *hdev, struct hid_field *field,
+ struct hid_usage *usage, __s32 value)
+{
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+
+ if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
+ !usage->type)
+ return 0;
+
+ if ((asc->quirks & APPLE_INVERT_HWHEEL) &&
+ usage->code == REL_HWHEEL) {
+ input_event_with_scancode(field->hidinput->input, usage->type,
+ usage->code, usage->hid, -value);
+ return 1;
+ }
+
+ if ((asc->quirks & APPLE_HAS_FN) &&
+ hidinput_apple_event(hdev, field->hidinput->input,
+ usage, value))
+ return 1;
+
+
+ return 0;
+}
+
+static int apple_fetch_battery(struct hid_device *hdev)
+{
+#ifdef CONFIG_HID_BATTERY_STRENGTH
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+ struct hid_report_enum *report_enum;
+ struct hid_report *report;
+
+ if (!(asc->quirks & APPLE_RDESC_BATTERY) || !hdev->battery)
+ return -1;
+
+ report_enum = &hdev->report_enum[hdev->battery_report_type];
+ report = report_enum->report_id_hash[hdev->battery_report_id];
+
+ if (!report || report->maxfield < 1)
+ return -1;
+
+ if (hdev->battery_capacity == hdev->battery_max)
+ return -1;
+
+ hid_hw_request(hdev, report, HID_REQ_GET_REPORT);
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+static void apple_battery_timer_tick(struct timer_list *t)
+{
+ struct apple_sc *asc = timer_container_of(asc, t, battery_timer);
+ struct hid_device *hdev = asc->hdev;
+
+ if (apple_fetch_battery(hdev) == 0) {
+ mod_timer(&asc->battery_timer,
+ jiffies + secs_to_jiffies(APPLE_BATTERY_TIMEOUT_SEC));
+ }
+}
+
+/*
+ * MacBook JIS keyboard has wrong logical maximum
+ * Magic Keyboard JIS has wrong logical maximum
+ */
+static const __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
+{
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+
+ if (*rsize >= 71 && rdesc[70] == 0x65 && rdesc[64] == 0x65) {
+ hid_info(hdev,
+ "fixing up Magic Keyboard JIS report descriptor\n");
+ rdesc[64] = rdesc[70] = 0xe7;
+ }
+
+ if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 &&
+ rdesc[53] == 0x65 && rdesc[59] == 0x65) {
+ hid_info(hdev,
+ "fixing up MacBook JIS keyboard report descriptor\n");
+ rdesc[53] = rdesc[59] = 0xe7;
+ }
+
+ /*
+ * Change the usage from:
+ * 0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1) 0
+ * 0x09, 0x0b, // Usage (Vendor Usage 0x0b) 3
+ * To:
+ * 0x05, 0x01, // Usage Page (Generic Desktop) 0
+ * 0x09, 0x06, // Usage (Keyboard) 2
+ */
+ if ((asc->quirks & APPLE_RDESC_BATTERY) && *rsize == 83 &&
+ rdesc[46] == 0x84 && rdesc[58] == 0x85) {
+ hid_info(hdev,
+ "fixing up Magic Keyboard battery report descriptor\n");
+ *rsize = *rsize - 1;
+ rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL);
+ if (!rdesc)
+ return NULL;
+
+ rdesc[0] = 0x05;
+ rdesc[1] = 0x01;
+ rdesc[2] = 0x09;
+ rdesc[3] = 0x06;
+ }
+
+ return rdesc;
+}
+
+static void apple_setup_input(struct input_dev *input)
+{
+ set_bit(KEY_NUMLOCK, input->keybit);
+
+ /* Enable all needed keys */
+ apple_setup_key_translation(input, apple_fn_keys);
+ apple_setup_key_translation(input, powerbook_fn_keys);
+ apple_setup_key_translation(input, powerbook_numlock_keys);
+ apple_setup_key_translation(input, apple_iso_keyboard);
+ apple_setup_key_translation(input, magic_keyboard_alu_fn_keys);
+ apple_setup_key_translation(input, magic_keyboard_2015_fn_keys);
+ apple_setup_key_translation(input, magic_keyboard_2021_and_2024_fn_keys);
+ apple_setup_key_translation(input, macbookpro_no_esc_fn_keys);
+ apple_setup_key_translation(input, macbookpro_dedicated_esc_fn_keys);
+}
+
+static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+ struct hid_field *field, struct hid_usage *usage,
+ unsigned long **bit, int *max)
+{
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+
+ if (usage->hid == (HID_UP_CUSTOM | 0x0003) ||
+ usage->hid == (HID_UP_MSVENDOR | 0x0003) ||
+ usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) {
+ /* The fn key on Apple USB keyboards */
+ set_bit(EV_REP, hi->input->evbit);
+ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
+ asc->fn_found = true;
+ apple_setup_input(hi->input);
+ return 1;
+ }
+
+ /* we want the hid layer to go through standard path (set and ignore) */
+ return 0;
+}
+
+static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+ struct hid_field *field, struct hid_usage *usage,
+ unsigned long **bit, int *max)
+{
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+
+ if (asc->quirks & APPLE_MIGHTYMOUSE) {
+ if (usage->hid == HID_GD_Z)
+ hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL);
+ else if (usage->code == BTN_1)
+ hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_2);
+ else if (usage->code == BTN_2)
+ hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_1);
+ }
+
+ return 0;
+}
+
+static int apple_input_configured(struct hid_device *hdev,
+ struct hid_input *hidinput)
+{
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+
+ if (((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) || apple_is_omoton_kb066(hdev)) {
+ hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
+ asc->quirks &= ~APPLE_HAS_FN;
+ }
+
+ if (apple_is_non_apple_keyboard(hdev)) {
+ hid_info(hdev, "Non-apple keyboard detected; function keys will default to fnmode=2 behavior\n");
+ asc->quirks |= APPLE_IS_NON_APPLE;
+ }
+
+ return 0;
+}
+
+static bool apple_backlight_check_support(struct hid_device *hdev)
+{
+ int i;
+ unsigned int hid;
+ struct hid_report *report;
+
+ list_for_each_entry(report, &hdev->report_enum[HID_INPUT_REPORT].report_list, list) {
+ for (i = 0; i < report->maxfield; i++) {
+ hid = report->field[i]->usage->hid;
+ if ((hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR && (hid & HID_USAGE) == 0xf)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static int apple_backlight_set(struct hid_device *hdev, u16 value, u16 rate)
+{
+ int ret = 0;
+ struct apple_backlight_set_report *rep;
+
+ rep = kmalloc(sizeof(*rep), GFP_KERNEL);
+ if (rep == NULL)
+ return -ENOMEM;
+
+ rep->report_id = 0xB0;
+ rep->version = 1;
+ rep->backlight = value;
+ rep->rate = rate;
+
+ ret = hid_hw_raw_request(hdev, 0xB0u, (u8 *) rep, sizeof(*rep),
+ HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
+
+ kfree(rep);
+ return ret;
+}
+
+static int apple_backlight_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct apple_sc_backlight *backlight = container_of(led_cdev,
+ struct apple_sc_backlight, cdev);
+ int ret;
+
+ ret = apple_backlight_set(backlight->hdev, brightness, 0);
+ if (!ret)
+ backlight->current_brightness = brightness;
+ return ret;
+}
+
+static int apple_backlight_init(struct hid_device *hdev)
+{
+ int ret;
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+ struct apple_backlight_config_report *rep;
+
+ if (!apple_backlight_check_support(hdev))
+ return -EINVAL;
+
+ rep = kmalloc(0x200, GFP_KERNEL);
+ if (rep == NULL)
+ return -ENOMEM;
+
+ ret = hid_hw_raw_request(hdev, 0xBFu, (u8 *) rep, sizeof(*rep),
+ HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
+ if (ret < 0) {
+ hid_err(hdev, "backlight request failed: %d\n", ret);
+ goto cleanup_and_exit;
+ }
+ if (ret < 8 || rep->version != 1) {
+ hid_err(hdev, "backlight config struct: bad version %i\n", rep->version);
+ ret = -EINVAL;
+ goto cleanup_and_exit;
+ }
+
+ hid_dbg(hdev, "backlight config: off=%u, on_min=%u, on_max=%u\n",
+ rep->backlight_off, rep->backlight_on_min, rep->backlight_on_max);
+
+ asc->backlight = devm_kzalloc(&hdev->dev, sizeof(*asc->backlight), GFP_KERNEL);
+ if (!asc->backlight) {
+ ret = -ENOMEM;
+ goto cleanup_and_exit;
+ }
+
+ asc->backlight->hdev = hdev;
+ asc->backlight->cdev.name = "apple::kbd_backlight";
+ asc->backlight->cdev.max_brightness = rep->backlight_on_max;
+ asc->backlight->cdev.brightness_set_blocking = apple_backlight_led_set;
+ asc->backlight->current_brightness = 0;
+ asc->backlight->saved_brightness = 0;
+
+ ret = apple_backlight_set(hdev, 0, 0);
+ if (ret < 0) {
+ hid_err(hdev, "backlight set request failed: %d\n", ret);
+ goto cleanup_and_exit;
+ }
+
+ ret = devm_led_classdev_register(&hdev->dev, &asc->backlight->cdev);
+
+cleanup_and_exit:
+ kfree(rep);
+ return ret;
+}
+
+static void apple_magic_backlight_report_set(struct hid_report *rep, s32 value, u8 rate)
+{
+ rep->field[0]->value[0] = value;
+ rep->field[1]->value[0] = 0x5e; /* Mimic Windows */
+ rep->field[1]->value[0] |= rate << 8;
+
+ hid_hw_request(rep->device, rep, HID_REQ_SET_REPORT);
+}
+
+static void apple_magic_backlight_set(struct apple_magic_backlight *backlight,
+ int brightness, char rate)
+{
+ apple_magic_backlight_report_set(backlight->power, brightness ? 1 : 0, rate);
+ if (brightness)
+ apple_magic_backlight_report_set(backlight->brightness, brightness, rate);
+}
+
+static int apple_magic_backlight_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct apple_magic_backlight *backlight = container_of(led_cdev,
+ struct apple_magic_backlight, cdev);
+
+ apple_magic_backlight_set(backlight, brightness, 1);
+ backlight->current_brightness = brightness;
+ return 0;
+}
+
+static int apple_magic_backlight_init(struct hid_device *hdev)
+{
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+ struct apple_magic_backlight *backlight;
+ struct hid_report_enum *report_enum;
+
+ /*
+ * Ensure this usb endpoint is for the keyboard backlight, not touchbar
+ * backlight.
+ */
+ if (hdev->collection[0].usage != HID_USAGE_MAGIC_BL)
+ return -ENODEV;
+
+ backlight = devm_kzalloc(&hdev->dev, sizeof(*backlight), GFP_KERNEL);
+ if (!backlight)
+ return -ENOMEM;
+
+ report_enum = &hdev->report_enum[HID_FEATURE_REPORT];
+ backlight->brightness = report_enum->report_id_hash[APPLE_MAGIC_REPORT_ID_BRIGHTNESS];
+ backlight->power = report_enum->report_id_hash[APPLE_MAGIC_REPORT_ID_POWER];
+
+ if (!backlight->brightness || backlight->brightness->maxfield < 2 ||
+ !backlight->power || backlight->power->maxfield < 2)
+ return -ENODEV;
+
+ backlight->cdev.name = ":white:" LED_FUNCTION_KBD_BACKLIGHT;
+ backlight->cdev.max_brightness = backlight->brightness->field[0]->logical_maximum;
+ backlight->cdev.brightness_set_blocking = apple_magic_backlight_led_set;
+ backlight->current_brightness = 0;
+ backlight->saved_brightness = 0;
+ asc->magic_backlight = backlight;
+
+ apple_magic_backlight_set(backlight, 0, 0);
+
+ return devm_led_classdev_register(&hdev->dev, &backlight->cdev);
+
+}
+
+static int apple_probe(struct hid_device *hdev,
+ const struct hid_device_id *id)
+{
+ unsigned long quirks = id->driver_data;
+ struct apple_sc *asc;
+ int ret;
+
+ if ((id->bus == BUS_SPI || id->bus == BUS_HOST) && id->vendor == SPI_VENDOR_ID_APPLE &&
+ hdev->type != HID_TYPE_SPI_KEYBOARD)
+ return -ENODEV;
+
+ if (quirks & APPLE_IGNORE_MOUSE && hdev->type == HID_TYPE_USBMOUSE)
+ return -ENODEV;
+
+ asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL);
+ if (asc == NULL) {
+ hid_err(hdev, "can't alloc apple descriptor\n");
+ return -ENOMEM;
+ }
+
+ asc->hdev = hdev;
+ asc->quirks = quirks;
+
+ hid_set_drvdata(hdev, asc);
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ hid_err(hdev, "parse failed\n");
+ return ret;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (ret) {
+ hid_err(hdev, "hw start failed\n");
+ return ret;
+ }
+
+ if (quirks & APPLE_RDESC_BATTERY) {
+ timer_setup(&asc->battery_timer, apple_battery_timer_tick, 0);
+ mod_timer(&asc->battery_timer,
+ jiffies + secs_to_jiffies(APPLE_BATTERY_TIMEOUT_SEC));
+ apple_fetch_battery(hdev);
+ }
+
+ if (quirks & APPLE_BACKLIGHT_CTL)
+ apple_backlight_init(hdev);
+
+ if (quirks & APPLE_MAGIC_BACKLIGHT) {
+ ret = apple_magic_backlight_init(hdev);
+ if (ret)
+ goto out_err;
+ }
+
+ return 0;
+
+out_err:
+ if (quirks & APPLE_RDESC_BATTERY)
+ timer_delete_sync(&asc->battery_timer);
+
+ hid_hw_stop(hdev);
+ return ret;
+}
+
+static void apple_remove(struct hid_device *hdev)
+{
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+
+ if (asc->quirks & APPLE_RDESC_BATTERY)
+ timer_delete_sync(&asc->battery_timer);
+
+ hid_hw_stop(hdev);
+}
+
+#ifdef CONFIG_PM
+static int apple_suspend(struct hid_device *hdev, pm_message_t msg)
+{
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+
+ if (asc->backlight) {
+ asc->backlight->saved_brightness = asc->backlight->current_brightness;
+ apple_backlight_set(hdev, 0, 0);
+ asc->backlight->current_brightness = 0;
+ }
+
+ if (asc->magic_backlight) {
+ asc->magic_backlight->saved_brightness = asc->magic_backlight->current_brightness;
+ apple_magic_backlight_set(asc->magic_backlight, 0, 0);
+ asc->magic_backlight->current_brightness = 0;
+ }
+
+ return 0;
+}
+
+static int apple_resume(struct hid_device *hdev)
+{
+ struct apple_sc *asc = hid_get_drvdata(hdev);
+ int ret = 0;
+
+ if (asc->backlight && asc->backlight->saved_brightness) {
+ ret = apple_backlight_set(hdev, asc->backlight->saved_brightness, 0);
+ if (!ret)
+ asc->backlight->current_brightness = asc->backlight->saved_brightness;
+ }
+
+ if (asc->magic_backlight && asc->magic_backlight->saved_brightness) {
+ apple_magic_backlight_set(asc->magic_backlight,
+ asc->magic_backlight->saved_brightness, 0);
+ asc->magic_backlight->current_brightness = asc->magic_backlight->saved_brightness;
+ }
+
+ return ret;
+}
+#endif
+
+static const struct hid_device_id apple_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE),
+ .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
+
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
+ .driver_data = APPLE_HAS_FN },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS),
+ .driver_data = APPLE_HAS_FN },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_ISO_TILDE_QUIRK },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_ISO_TILDE_QUIRK },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS),
+ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K),
+ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
+ APPLE_IGNORE_MOUSE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132),
+ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
+ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680),
+ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
+ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT),
+ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
+ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213),
+ .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK |
+ APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS |
+ APPLE_IGNORE_MOUSE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS |
+ APPLE_IGNORE_MOUSE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_IGNORE_MOUSE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS |
+ APPLE_IGNORE_MOUSE },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+ APPLE_ISO_TILDE_QUIRK },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
+ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_SPI_DEVICE(SPI_VENDOR_ID_APPLE, HID_ANY_ID),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_DEVICE(BUS_HOST, HID_GROUP_ANY, HOST_VENDOR_ID_APPLE, HID_ANY_ID),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT),
+ .driver_data = APPLE_MAGIC_BACKLIGHT },
+
+ { }
+};
+MODULE_DEVICE_TABLE(hid, apple_devices);
+
+static struct hid_driver apple_driver = {
+ .name = "apple",
+ .id_table = apple_devices,
+ .report_fixup = apple_report_fixup,
+ .probe = apple_probe,
+ .remove = apple_remove,
+ .event = apple_event,
+ .input_mapping = apple_input_mapping,
+ .input_mapped = apple_input_mapped,
+ .input_configured = apple_input_configured,
+#ifdef CONFIG_PM
+ .suspend = apple_suspend,
+ .resume = apple_resume,
+ .reset_resume = apple_resume,
+#endif
+};
+module_hid_driver(apple_driver);
+
+MODULE_DESCRIPTION("Apple USB HID quirks support for Linux");
+MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related
* [PATCH 3/3] Add Touch Bar and backlight reprobe support
From: deqrocks @ 2026-04-03 13:06 UTC (permalink / raw)
To: jikos, benjamin.tissoires; +Cc: linux-input
In-Reply-To: <20260403130620.91999-1-andre@negmaster.com>
Drop stale device state across suspend and let the Touch Bar\nrelated drivers tear down and reinitialize through reprobe after\nresume.
Signed-off-by: deqrocks <andre@negmaster.com>
---
hid-apple.c | 50 +++++++++++++++++++--
hid-appletb-bl.c | 44 ++++++++++++++++++-
hid-appletb-kbd.c | 109 ++++++++++++++++++++++++++++++++++++----------
3 files changed, 174 insertions(+), 29 deletions(-)
diff --git a/hid-apple.c b/hid-apple.c
index c620890..dc9d244 100644
--- a/hid-apple.c
+++ b/hid-apple.c
@@ -114,6 +114,15 @@ struct apple_magic_backlight {
u16 saved_brightness;
};
+static u16 apple_saved_kbd_backlight_brightness;
+
+static u16 apple_initial_kbd_backlight_brightness(u16 max_brightness)
+{
+ if (apple_saved_kbd_backlight_brightness)
+ return apple_saved_kbd_backlight_brightness;
+ return max_t(u16, max_brightness / 2, 1);
+}
+
struct apple_sc {
struct hid_device *hdev;
unsigned long quirks;
@@ -123,6 +132,7 @@ struct apple_sc {
struct timer_list battery_timer;
struct apple_sc_backlight *backlight;
struct apple_magic_backlight *magic_backlight;
+ bool suspend_preparing_remove;
};
struct apple_key_translation {
@@ -833,8 +843,10 @@ static int apple_backlight_led_set(struct led_classdev *led_cdev,
int ret;
ret = apple_backlight_set(backlight->hdev, brightness, 0);
- if (!ret)
+ if (!ret) {
backlight->current_brightness = brightness;
+ apple_saved_kbd_backlight_brightness = brightness;
+ }
return ret;
}
@@ -878,12 +890,19 @@ static int apple_backlight_init(struct hid_device *hdev)
asc->backlight->cdev.brightness_set_blocking = apple_backlight_led_set;
asc->backlight->current_brightness = 0;
asc->backlight->saved_brightness = 0;
+ asc->backlight->cdev.brightness = 0;
+
+ asc->backlight->cdev.brightness =
+ apple_initial_kbd_backlight_brightness(rep->backlight_on_max);
- ret = apple_backlight_set(hdev, 0, 0);
+ ret = apple_backlight_set(hdev, asc->backlight->cdev.brightness, 0);
if (ret < 0) {
hid_err(hdev, "backlight set request failed: %d\n", ret);
goto cleanup_and_exit;
}
+ asc->backlight->current_brightness = asc->backlight->cdev.brightness;
+ asc->backlight->saved_brightness = asc->backlight->current_brightness;
+ apple_saved_kbd_backlight_brightness = asc->backlight->current_brightness;
ret = devm_led_classdev_register(&hdev->dev, &asc->backlight->cdev);
@@ -917,6 +936,7 @@ static int apple_magic_backlight_led_set(struct led_classdev *led_cdev,
apple_magic_backlight_set(backlight, brightness, 1);
backlight->current_brightness = brightness;
+ apple_saved_kbd_backlight_brightness = brightness;
return 0;
}
@@ -950,9 +970,16 @@ static int apple_magic_backlight_init(struct hid_device *hdev)
backlight->cdev.brightness_set_blocking = apple_magic_backlight_led_set;
backlight->current_brightness = 0;
backlight->saved_brightness = 0;
+ backlight->cdev.brightness = 0;
asc->magic_backlight = backlight;
- apple_magic_backlight_set(backlight, 0, 0);
+ backlight->cdev.brightness =
+ apple_initial_kbd_backlight_brightness(backlight->cdev.max_brightness);
+ backlight->current_brightness = backlight->cdev.brightness;
+ backlight->saved_brightness = backlight->current_brightness;
+ apple_saved_kbd_backlight_brightness = backlight->current_brightness;
+
+ apple_magic_backlight_set(backlight, backlight->current_brightness, 0);
return devm_led_classdev_register(&hdev->dev, &backlight->cdev);
@@ -1028,6 +1055,17 @@ static void apple_remove(struct hid_device *hdev)
if (asc->quirks & APPLE_RDESC_BATTERY)
timer_delete_sync(&asc->battery_timer);
+ /* Only tear down LEDs on suspend-driven remove. */
+ if (asc->suspend_preparing_remove && asc->backlight) {
+ devm_led_classdev_unregister(&hdev->dev, &asc->backlight->cdev);
+ asc->backlight = NULL;
+ }
+
+ if (asc->suspend_preparing_remove && asc->magic_backlight) {
+ devm_led_classdev_unregister(&hdev->dev, &asc->magic_backlight->cdev);
+ asc->magic_backlight = NULL;
+ }
+
hid_hw_stop(hdev);
}
@@ -1036,14 +1074,18 @@ static int apple_suspend(struct hid_device *hdev, pm_message_t msg)
{
struct apple_sc *asc = hid_get_drvdata(hdev);
+ asc->suspend_preparing_remove = true;
+
if (asc->backlight) {
asc->backlight->saved_brightness = asc->backlight->current_brightness;
+ apple_saved_kbd_backlight_brightness = asc->backlight->current_brightness;
apple_backlight_set(hdev, 0, 0);
asc->backlight->current_brightness = 0;
}
if (asc->magic_backlight) {
asc->magic_backlight->saved_brightness = asc->magic_backlight->current_brightness;
+ apple_saved_kbd_backlight_brightness = asc->magic_backlight->current_brightness;
apple_magic_backlight_set(asc->magic_backlight, 0, 0);
asc->magic_backlight->current_brightness = 0;
}
@@ -1056,6 +1098,8 @@ static int apple_resume(struct hid_device *hdev)
struct apple_sc *asc = hid_get_drvdata(hdev);
int ret = 0;
+ asc->suspend_preparing_remove = false;
+
if (asc->backlight && asc->backlight->saved_brightness) {
ret = apple_backlight_set(hdev, asc->backlight->saved_brightness, 0);
if (!ret)
diff --git a/hid-appletb-bl.c b/hid-appletb-bl.c
index bad2aea..5fc5a00 100644
--- a/hid-appletb-bl.c
+++ b/hid-appletb-bl.c
@@ -36,6 +36,7 @@ struct appletb_bl {
struct backlight_device *bdev;
bool full_on;
+ bool suspend_preparing_remove;
};
static const u8 appletb_bl_brightness_map[] = {
@@ -44,6 +45,15 @@ static const u8 appletb_bl_brightness_map[] = {
APPLETB_BL_ON,
};
+static int appletb_bl_default_brightness_index(void)
+{
+ if (appletb_bl_def_brightness < 0)
+ return 0;
+ if (appletb_bl_def_brightness >= ARRAY_SIZE(appletb_bl_brightness_map))
+ return ARRAY_SIZE(appletb_bl_brightness_map) - 1;
+ return appletb_bl_def_brightness;
+}
+
static int appletb_bl_set_brightness(struct appletb_bl *bl, u8 brightness)
{
struct hid_report *report = bl->brightness_field->report;
@@ -142,7 +152,7 @@ static int appletb_bl_probe(struct hid_device *hdev, const struct hid_device_id
bl->brightness_field = brightness_field;
ret = appletb_bl_set_brightness(bl,
- appletb_bl_brightness_map[(appletb_bl_def_brightness > 2) ? 2 : appletb_bl_def_brightness]);
+ appletb_bl_brightness_map[appletb_bl_default_brightness_index()]);
if (ret) {
dev_err_probe(dev, ret, "Failed to set default touch bar brightness to %d\n",
@@ -177,12 +187,39 @@ static void appletb_bl_remove(struct hid_device *hdev)
{
struct appletb_bl *bl = hid_get_drvdata(hdev);
- appletb_bl_set_brightness(bl, APPLETB_BL_OFF);
+ /* Only tear down the backlight on suspend-driven remove. */
+ if (bl && bl->suspend_preparing_remove)
+ appletb_bl_set_brightness(bl, APPLETB_BL_OFF);
+
+ if (bl && bl->suspend_preparing_remove && bl->bdev) {
+ devm_backlight_device_unregister(&hdev->dev, bl->bdev);
+ bl->bdev = NULL;
+ }
hid_hw_close(hdev);
hid_hw_stop(hdev);
}
+static int appletb_bl_suspend(struct hid_device *hdev, pm_message_t msg)
+{
+ struct appletb_bl *bl = hid_get_drvdata(hdev);
+
+ if (bl)
+ bl->suspend_preparing_remove = true;
+
+ return 0;
+}
+
+static int appletb_bl_resume(struct hid_device *hdev)
+{
+ struct appletb_bl *bl = hid_get_drvdata(hdev);
+
+ if (bl)
+ bl->suspend_preparing_remove = false;
+
+ return 0;
+}
+
static const struct hid_device_id appletb_bl_hid_ids[] = {
/* MacBook Pro's 2018, 2019, with T2 chip: iBridge DFR Brightness */
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLIGHT) },
@@ -195,6 +232,9 @@ static struct hid_driver appletb_bl_hid_driver = {
.id_table = appletb_bl_hid_ids,
.probe = appletb_bl_probe,
.remove = appletb_bl_remove,
+ .suspend = pm_ptr(appletb_bl_suspend),
+ .resume = pm_ptr(appletb_bl_resume),
+ .reset_resume = pm_ptr(appletb_bl_resume),
};
module_hid_driver(appletb_bl_hid_driver);
diff --git a/hid-appletb-kbd.c b/hid-appletb-kbd.c
index 0fdc096..63238ab 100644
--- a/hid-appletb-kbd.c
+++ b/hid-appletb-kbd.c
@@ -65,10 +65,25 @@ struct appletb_kbd {
struct timer_list inactivity_timer;
bool has_dimmed;
bool has_turned_off;
+ bool suspend_preparing_remove;
+ bool fn_down;
+ unsigned long last_mode_jiffies;
u8 saved_mode;
u8 current_mode;
};
+#define APPLETB_MODE_SUBMIT_INTERVAL_MS 50
+
+static void appletb_kbd_reset_state(struct appletb_kbd *kbd)
+{
+ kbd->saved_mode = APPLETB_KBD_MODE_OFF;
+ kbd->current_mode = APPLETB_KBD_MODE_OFF;
+ kbd->has_dimmed = false;
+ kbd->has_turned_off = false;
+ kbd->fn_down = false;
+ kbd->last_mode_jiffies = 0;
+}
+
static const struct key_entry appletb_kbd_keymap[] = {
{ KE_KEY, KEY_ESC, { KEY_ESC } },
{ KE_KEY, KEY_F1, { KEY_BRIGHTNESSDOWN } },
@@ -92,6 +107,18 @@ static int appletb_kbd_set_mode(struct appletb_kbd *kbd, u8 mode)
struct hid_device *hdev = report->device;
int ret;
+ if (kbd->suspend_preparing_remove && mode != APPLETB_KBD_MODE_OFF)
+ return -EBUSY;
+
+ if (kbd->current_mode == mode)
+ return 0;
+
+ if (kbd->last_mode_jiffies &&
+ time_before(jiffies, kbd->last_mode_jiffies +
+ msecs_to_jiffies(APPLETB_MODE_SUBMIT_INTERVAL_MS))) {
+ return -EAGAIN;
+ }
+
ret = hid_hw_power(hdev, PM_HINT_FULLON);
if (ret) {
hid_err(hdev, "Device didn't resume (%pe)\n", ERR_PTR(ret));
@@ -105,8 +132,8 @@ static int appletb_kbd_set_mode(struct appletb_kbd *kbd, u8 mode)
}
hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
-
kbd->current_mode = mode;
+ kbd->last_mode_jiffies = jiffies;
power_normal:
hid_hw_power(hdev, PM_HINT_NORMAL);
@@ -114,6 +141,22 @@ power_normal:
return ret;
}
+static void appletb_kbd_teardown(struct hid_device *hdev, struct appletb_kbd *kbd,
+ bool send_mode_off)
+{
+ if (send_mode_off)
+ appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF);
+
+ input_unregister_handler(&kbd->inp_handler);
+ if (kbd->backlight_dev) {
+ put_device(&kbd->backlight_dev->dev);
+ kbd->backlight_dev = NULL;
+ timer_delete_sync(&kbd->inactivity_timer);
+ }
+
+ appletb_kbd_reset_state(kbd);
+}
+
static ssize_t mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -238,18 +281,35 @@ static void appletb_kbd_inp_event(struct input_handle *handle, unsigned int type
reset_inactivity_timer(kbd);
- if (type == EV_KEY && code == KEY_FN && appletb_tb_fn_toggle &&
- (kbd->current_mode == APPLETB_KBD_MODE_SPCL ||
- kbd->current_mode == APPLETB_KBD_MODE_FN)) {
- if (value == 1) {
- kbd->saved_mode = kbd->current_mode;
- appletb_kbd_set_mode(kbd, kbd->current_mode == APPLETB_KBD_MODE_SPCL
- ? APPLETB_KBD_MODE_FN : APPLETB_KBD_MODE_SPCL);
- } else if (value == 0) {
- if (kbd->saved_mode != kbd->current_mode)
- appletb_kbd_set_mode(kbd, kbd->saved_mode);
- }
+ if (type != EV_KEY || code != KEY_FN || !appletb_tb_fn_toggle)
+ return;
+
+ if (kbd->current_mode != APPLETB_KBD_MODE_SPCL &&
+ kbd->current_mode != APPLETB_KBD_MODE_FN)
+ return;
+
+ if (value == 2)
+ return;
+
+ if (value == 1) {
+ if (kbd->fn_down)
+ return;
+
+ kbd->fn_down = true;
+ kbd->saved_mode = kbd->current_mode;
+ appletb_kbd_set_mode(kbd,
+ kbd->current_mode == APPLETB_KBD_MODE_SPCL
+ ? APPLETB_KBD_MODE_FN
+ : APPLETB_KBD_MODE_SPCL);
+ return;
}
+
+ if (value != 0 || !kbd->fn_down)
+ return;
+
+ kbd->fn_down = false;
+ if (kbd->saved_mode != kbd->current_mode)
+ appletb_kbd_set_mode(kbd, kbd->saved_mode);
}
static int appletb_kbd_inp_connect(struct input_handler *handler,
@@ -392,6 +452,8 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id
return -ENOMEM;
kbd->mode_field = mode_field;
+ kbd->suspend_preparing_remove = false;
+ appletb_kbd_reset_state(kbd);
ret = hid_hw_start(hdev, HID_CONNECT_HIDINPUT);
if (ret)
@@ -405,7 +467,9 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id
kbd->backlight_dev = backlight_device_get_by_name("appletb_backlight");
if (!kbd->backlight_dev) {
- dev_err_probe(dev, -ENODEV, "Failed to get backlight device\n");
+ ret = dev_err_probe(dev, -EPROBE_DEFER,
+ "Backlight device not ready, deferring probe\n");
+ goto close_hw;
} else {
backlight_device_set_brightness(kbd->backlight_dev, 2);
timer_setup(&kbd->inactivity_timer, appletb_inactivity_timer, 0);
@@ -453,14 +517,14 @@ stop_hw:
static void appletb_kbd_remove(struct hid_device *hdev)
{
struct appletb_kbd *kbd = hid_get_drvdata(hdev);
+ bool send_mode_off = false;
- appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF);
+ /* Only force MODE_OFF on suspend-driven remove. */
+ if (kbd)
+ send_mode_off = kbd->suspend_preparing_remove &&
+ kbd->current_mode != APPLETB_KBD_MODE_OFF;
- input_unregister_handler(&kbd->inp_handler);
- if (kbd->backlight_dev) {
- put_device(&kbd->backlight_dev->dev);
- timer_delete_sync(&kbd->inactivity_timer);
- }
+ appletb_kbd_teardown(hdev, kbd, send_mode_off);
hid_hw_close(hdev);
hid_hw_stop(hdev);
@@ -470,9 +534,7 @@ static int appletb_kbd_suspend(struct hid_device *hdev, pm_message_t msg)
{
struct appletb_kbd *kbd = hid_get_drvdata(hdev);
- kbd->saved_mode = kbd->current_mode;
- appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF);
-
+ kbd->suspend_preparing_remove = true;
return 0;
}
@@ -480,8 +542,7 @@ static int appletb_kbd_resume(struct hid_device *hdev)
{
struct appletb_kbd *kbd = hid_get_drvdata(hdev);
- appletb_kbd_set_mode(kbd, kbd->saved_mode);
-
+ kbd->suspend_preparing_remove = false;
return 0;
}
--
2.53.0
^ permalink raw reply related
* [PATCH 0/3] HID: apple: reinitialize T2 HID devices after resume
From: deqrocks @ 2026-04-03 13:06 UTC (permalink / raw)
To: jikos, benjamin.tissoires; +Cc: linux-input
This series improves suspend and resume handling for Apple T2 based Macs.
On affected systems, Apple T2 HID-backed devices can disappear across suspend and resume and come back with freshly enumerated interfaces. Reusing the pre-suspend device state leaves parts of the stack non-functional after resume, especially keyboard backlight and Touch Bar related devices.
This series adds the required Apple T2 HID identifiers, wires up PM handling for the relevant Apple HID path, and reworks teardown and reprobe handling so stale state is discarded and devices are initialized again after resume.
Tested on: MacBookAir9,1, MacBookPro15,1, MacBookPro16,1, MacBookPro16,2, MacBookPro16,4
deqrocks (3):
Add Apple T2 HID identifiers
hid-apple: add pm path to 8102
Add Touch Bar and backlight reprobe support
hid-apple.c | 1372 +++++++++++++++++++++++++++++++++++++++
hid-appletb-bl.c | 44 +-
hid-appletb-kbd.c | 109 +++-
hid-ids.h | 1574 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 3073 insertions(+), 26 deletions(-)
create mode 100644 hid-apple.c
create mode 100644 hid-ids.h
--
2.53.0
^ permalink raw reply
* Re: [PATCH] HID: multitouch: Fix Yoga Book 9 14IAH10 touchscreen misclassification
From: Benjamin Tissoires @ 2026-04-03 13:02 UTC (permalink / raw)
To: Dave Carey; +Cc: jikos, linux-input, linux-kernel
In-Reply-To: <20260402182937.388847-1-carvsdriver@gmail.com>
Hi Dave,
On Apr 02 2026, Dave Carey wrote:
> The Lenovo Yoga Book 9 14IAH10 (83KJ) uses a composite USB HID device
> (17EF:6161) where three descriptor quirks combine to cause hid-multitouch
> to incorrectly set INPUT_PROP_BUTTONPAD on both touchscreen nodes, making
> libinput treat them as indirect clickpads rather than direct touchscreens.
>
> Quirk 1: The HID_DG_TOUCHSCREEN application collection contains
> HID_UP_BUTTON usages (stylus barrel buttons). The generic heuristic in
> mt_touch_input_mapping() treats any touchscreen-with-buttons as a
> touchpad, setting INPUT_MT_POINTER.
>
> Quirk 2: A HID_DG_TOUCHPAD collection ("Emulated Touchpad") sets
> INPUT_MT_POINTER unconditionally in mt_allocate_application().
>
> Quirk 3: The HID_DG_BUTTONTYPE feature report (0x51) returns
> MT_BUTTONTYPE_CLICKPAD, directly setting td->is_buttonpad = true.
>
> These combine to produce INPUT_PROP_BUTTONPAD on the touchscreen input
> nodes. libinput treats the devices as indirect clickpads and suppresses
> direct touch events, leaving the touchscreens non-functional under
> KDE/Wayland.
This looks like a completely borked report descriptor. Out of curiosity,
do you know if there is a specific Windows driver for it or if it's
using the plain generic driver there.
The reasoning is that if it's using the generic win driver, we are
probably doing something wrong, and we need to fix it in a more generic
way.
>
> Additionally, the firmware resets if any USB control request is received
> during the CDC ACM initialization window. The existing GET_REPORT call
> in mt_check_input_mode() during probe triggers this reset.
Ouch, even better :(
>
> Fix by extending MT_QUIRK_YOGABOOK9I (already defined for the earlier
> Yoga Book 9i) to guard all three BUTTONPAD heuristics and skip the
> HID_DG_BUTTONTYPE GET_REPORT during probe for this device.
Really not a big fan of the approach taken here: We are sprinkling the
code with special quirks for one particular device and that makes
everything worse.
I would much prefer a report descriptor fixup where:
- we drop the HID_UP_BUTTON
- we drop the HID_DG_TOUCHPAD collection entirely
- we drop the HID_DG_BUTTONTYPE feature entirely
- we drop the Win8 blob feature as well to prevent queries during
initialization.
For ease of development I would recomend working with a separate HID-BPF
program instead of a in-kernel fix, but we already have a .report_fixup
here, so I wouldn't mind having the fix here as well.
Cheers,
Benjamin
>
> Signed-off-by: Dave Carey <carvsdriver@gmail.com>
> Tested-by: Dave Carey <carvsdriver@gmail.com>
> ---
> drivers/hid/hid-multitouch.c | 34 +++++++++++++++++++++++++++-------
> 1 file changed, 27 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
> index e82a3c4e5..1bef32b1d 100644
> --- a/drivers/hid/hid-multitouch.c
> +++ b/drivers/hid/hid-multitouch.c
> @@ -549,7 +549,14 @@ static void mt_feature_mapping(struct hid_device *hdev,
>
> switch (usage->hid) {
> case HID_DG_CONTACTMAX:
> - mt_get_feature(hdev, field->report);
> + /*
> + * Yoga Book 9: skip GET_REPORT during probe; the firmware
> + * resets if it receives any control request before the init
> + * Output report is sent (within ~1.18s of USB enumeration).
> + * Logical maximum from the descriptor is used as the fallback.
> + */
> + if (!(td->mtclass.quirks & MT_QUIRK_YOGABOOK9I))
> + mt_get_feature(hdev, field->report);
>
> td->maxcontacts = field->value[0];
> if (!td->maxcontacts &&
> @@ -566,6 +573,10 @@ static void mt_feature_mapping(struct hid_device *hdev,
> break;
> }
>
> + /* Yoga Book 9 reports Clickpad but is a direct touchscreen */
> + if (td->mtclass.quirks & MT_QUIRK_YOGABOOK9I)
> + break;
> +
> mt_get_feature(hdev, field->report);
> switch (field->value[usage->usage_index]) {
> case MT_BUTTONTYPE_CLICKPAD:
> @@ -579,7 +590,9 @@ static void mt_feature_mapping(struct hid_device *hdev,
> break;
> case 0xff0000c5:
> /* Retrieve the Win8 blob once to enable some devices */
> - if (usage->usage_index == 0)
> + /* Yoga Book 9: skip; firmware resets before init if queried */
> + if (usage->usage_index == 0 &&
> + !(td->mtclass.quirks & MT_QUIRK_YOGABOOK9I))
> mt_get_feature(hdev, field->report);
> break;
> }
> @@ -644,8 +657,11 @@ static struct mt_application *mt_allocate_application(struct mt_device *td,
>
> /*
> * Model touchscreens providing buttons as touchpads.
> + * Yoga Book 9 has an emulated touchpad but its touch surfaces
> + * are direct screens, not indirect pointers.
> */
> - if (application == HID_DG_TOUCHPAD) {
> + if (application == HID_DG_TOUCHPAD &&
> + !(td->mtclass.quirks & MT_QUIRK_YOGABOOK9I)) {
> mt_application->mt_flags |= INPUT_MT_POINTER;
> td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
> }
> @@ -802,11 +818,15 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
>
> /*
> * Model touchscreens providing buttons as touchpads.
> + * Skip for Yoga Book 9 which has stylus buttons inside
> + * touchscreen collections, not physical touchpad buttons.
> */
> if (field->application == HID_DG_TOUCHSCREEN &&
> (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
> - app->mt_flags |= INPUT_MT_POINTER;
> - td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
> + if (!(app->quirks & MT_QUIRK_YOGABOOK9I)) {
> + app->mt_flags |= INPUT_MT_POINTER;
> + td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
> + }
> }
>
> /* count the buttons on touchpads */
> @@ -1420,7 +1440,6 @@ static int mt_touch_input_configured(struct hid_device *hdev,
> */
> if (cls->quirks & MT_QUIRK_APPLE_TOUCHBAR)
> app->mt_flags |= INPUT_MT_DIRECT;
> -
> if (cls->is_indirect)
> app->mt_flags |= INPUT_MT_POINTER;
>
> @@ -1432,7 +1451,8 @@ static int mt_touch_input_configured(struct hid_device *hdev,
>
> /* check for clickpads */
> if ((app->mt_flags & INPUT_MT_POINTER) &&
> - (app->buttons_count == 1))
> + (app->buttons_count == 1) &&
> + !(app->quirks & MT_QUIRK_YOGABOOK9I))
> td->is_buttonpad = true;
>
> if (td->is_buttonpad)
> --
> 2.53.0
>
>
^ permalink raw reply
* Re: [PATCH v3 3/3] input: touchscreen: st1232: add system wakeup support
From: Bui Duc Phuc @ 2026-04-03 11:39 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Magnus Damm, Wolfram Sang, Jeff LaBundy, Bastian Hecht,
Javier Carrasco, linux-input, devicetree, linux-renesas-soc,
linux-kernel
In-Reply-To: <CAMuHMdW6y4MkCYR-rgn=FA38ZUE_X=3oQWNOvfdyMo=D5_xoxA@mail.gmail.com>
Hi Dmitry, Geert,
Thank you, Dmitry, for the review and the explanation. You are
absolutely right; I realized the I2C core handles this automatically,
which is tại sao I dropped those changes in the v4 series [1] as Geert
mentioned.
Thank you, Geert, for pointing that out and for your support.
While working on this, I also noticed similar redundant wakeup
handling in the mpr121 driver and sent a cleanup patch to remove
it [2].
[1] https://lore.kernel.org/20260309000319.74880-1-phucduc.bui@gmail.com
[2] https://lore.kernel.org/all/20260309071413.92709-1-phucduc.bui@gmail.com/
Thanks,
Phuc
On Thu, Apr 2, 2026 at 1:56 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Dmitry,
>
> On Thu, 2 Apr 2026 at 07:17, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> > On Fri, Mar 06, 2026 at 06:19:12PM +0700, phucduc.bui@gmail.com wrote:
> > > From: bui duc phuc <phucduc.bui@gmail.com>
> > >
> > > The ST1232 touchscreen controller can generate an interrupt when the
> > > panel is touched, which may be used as a wakeup source for the system.
> > >
> > > Add support for system wakeup by initializing the device wakeup
> > > capability in probe() based on the "wakeup-source" device property.
> > > When wakeup is enabled, the driver enables IRQ wake during suspend
> > > so that touch events can wake the system.
> > >
> > > If wakeup is not enabled, the driver retains the existing behavior of
> > > disabling the IRQ and powering down the controller during suspend.
> >
> > I do not believe this patch is needed: i2c core already handles
> > "wakeup-source" property and manages wakeup IRQ.
>
> No, it is not needed, as mentioned in the cover letter of v4[1],
> and as tested by me[2].
>
> [1] https://lore.kernel.org/20260309000319.74880-1-phucduc.bui@gmail.com
> [2] https://lore.kernel.org/CAMuHMdUqiaP=COTkKU_jK6Hdii+YJ5+zXnxFkOOnhLri5NakTw@mail.gmail.com
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox