HID: retain initial quirks set up when creating HID devices
PATCH v2 1/1 HID: retain initial quirks set up when creating HID devices
In certain circumstances, such as when creating I2C-connected HID devices, we want to pass and retain some quirks (axis inversion, etc). The source of such quirks may be device tree, or DMI data, or something else not readily available to the HID core itself and therefore cannot be reconstructed easily. To allow this, introduce "initial_quirks" field in hid_device structure and use it when determining the final set of quirks.
This fixes the problem with i2c-hid setting up device-tree sourced quirks too late and losing them on device rebind, and also allows to sever the tie between hid-code and i2c-hid when applying DMI-based quirks.
---
v2:
- corrected spelling/grammar in the commit message per Guenter
- added reviewed-by/tested-by tags
drivers/hid/hid-quirks.c | 8 +------- drivers/hid/i2c-hid/i2c-hid-core.c | 6 ++++-- drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 1 - include/linux/hid.h | 1 + 4 files changed, 6 insertions(+), 10 deletions(-)
drivers/hid/hid-quirks.c +1 -7
@@ -19,7 +19,6 @@#include <linux/input/elan-i2c-ids.h> #include "hid-ids.h" -#include "i2c-hid/i2c-hid.h" /* * Alphabetically sorted by vendor then product.
@@ -1238,7 +1237,7 @@ EXPORT_SYMBOL_GPL(hid_quirks_exit);static unsigned long hid_gets_squirk (const struct hid_device *hdev) {const struct hid_device_id *bl_entry; -unsigned long quirks =0 ; +unsigned long quirks = hdev->initial_quirks;if (hid_match_id (hdev, hid_ignore_list)) quirks |=HID_QUIRK_IGNORE ;
@@ -1299,11 +1298,6 @@ unsigned long hid_lookup_quirk(const struct hid_device *hdev) quirks =hid_gets_squirk (hdev);mutex_unlock (&dquirks_lock); -/* Get quirks specific to I2C devices */ -if (IS_ENABLED (CONFIG_I2C_DMI_CORE ) &&IS_ENABLED (CONFIG_DMI ) && - hdev->bus ==BUS_I2C ) - quirks |=i2c_hid_get_dmi_quirks (hdev->vendor, hdev->product); -return quirks; }EXPORT_SYMBOL_GPL (hid_lookup_quirk);
drivers/hid/i2c-hid/i2c-hid-core.c +4 -2
@@ -1025,6 +1025,10 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, hid->vendor =le16_to_cpu (ihid->hdesc.wVendorID); hid->product =le16_to_cpu (ihid->hdesc.wProductID); + hid->initial_quirks = quirks; + hid->initial_quirks |=i2c_hid_get_dmi_quirks (hid->vendor, + hid->product); +snprintf (hid->name,sizeof (hid->name),"%s %04X:%04X" , client->name, (u16 )hid->vendor, (u16 )hid->product);strscpy (hid->phys,dev_name (&client->dev),sizeof (hid->phys));
@@ -1038,8 +1042,6 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, goto err_mem_free; } - hid->quirks |= quirks; -return 0 ; err_mem_free:
drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +0 -1
@@ -492,4 +492,3 @@ u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product)return quirks; } -EXPORT_SYMBOL_GPL (i2c_hid_get_dmi_quirks);
include/linux/hid.h +1 -0
@@ -622,6 +622,7 @@ struct hid_device { /* device report descriptor */unsigned long status;/* see STAT flags above */ unsigned claimed;/* Claimed by hidinput, hiddev? */ unsigned quirks;/* Various quirks the device can pull on us */ +unsigned initial_quirks;/* Initial set of quirks supplied when creating device */ bool io_started;/* If IO has started */ struct list_head inputs;/* The list of inputs */
Signature · 5 lines
2.39.1.519.gcb327c4b5f-goog -- Dmitry
Quoted 13 lines · Dmitry Torokhov
In certain circumstances, such as when creating I2C-connected HID devices, we want to pass and retain some quirks (axis inversion, etc). The source of such quirks may be device tree, or DMI data, or something else not readily available to the HID core itself and therefore cannot be reconstructed easily. To allow this, introduce "
initial_quirks" field inhid_devicestructure and use it when determining the final set of quirks.This fixes the problem with i2c-hid setting up device-tree sourced quirks too late and losing them on device rebind, and also allows to sever the tie between hid-code and i2c-hid when applying DMI-based quirks.
Quoted 5 lines
Fixes b60d3c803d76 ("HID: i2c-hid-of: Expose the touchscreen-inverted properties")Fixes a2f416bf062a ("HID: multitouch: Add quirks for flipped axes")Reviewed-by Guenter Roeck <[email protected]>Tested-by Allen Ballway <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>
Alistair
Quoted 98 lines
---
v2:
- corrected spelling/grammar in the commit message per Guenter
- added reviewed-by/tested-by tagsdrivers/hid/hid-quirks.c | 8 +------- drivers/hid/i2c-hid/i2c-hid-core.c | 6 ++++-- drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 1 - include/linux/hid.h | 1 + 4 files changed, 6 insertions(+), 10 deletions(-)drivers/hid/hid-quirks.c +1
-7@@ -19,7 +19,6 @@#include <linux/input/elan-i2c-ids.h> #include "hid-ids.h" -#include "i2c-hid/i2c-hid.h" /* * Alphabetically sorted by vendor then product. @@ -1238,7 +1237,7 @@ EXPORT_SYMBOL_GPL(hid_quirks_exit);static unsigned long hid_gets_squirk (const struct hid_device *hdev) {const struct hid_device_id *bl_entry; -unsigned long quirks =0 ; +unsigned long quirks = hdev->initial_quirks;if (hid_match_id (hdev, hid_ignore_list)) quirks |=HID_QUIRK_IGNORE ;@@ -1299,11 +1298,6 @@ unsigned long hid_lookup_quirk(const struct hid_device *hdev) quirks =hid_gets_squirk (hdev);mutex_unlock (&dquirks_lock); -/* Get quirks specific to I2C devices */ -if (IS_ENABLED (CONFIG_I2C_DMI_CORE ) &&IS_ENABLED (CONFIG_DMI ) && - hdev->bus ==BUS_I2C ) - quirks |=i2c_hid_get_dmi_quirks (hdev->vendor, hdev->product); -return quirks; }EXPORT_SYMBOL_GPL (hid_lookup_quirk);drivers/hid/i2c-hid/i2c-hid-core.c +4
-2@@ -1025,6 +1025,10 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, hid->vendor =le16_to_cpu (ihid->hdesc.wVendorID); hid->product =le16_to_cpu (ihid->hdesc.wProductID); + hid->initial_quirks = quirks; + hid->initial_quirks |=i2c_hid_get_dmi_quirks (hid->vendor, + hid->product); +snprintf (hid->name,sizeof (hid->name),"%s %04X:%04X" , client->name, (u16 )hid->vendor, (u16 )hid->product);strscpy (hid->phys,dev_name (&client->dev),sizeof (hid->phys));@@ -1038,8 +1042,6 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, goto err_mem_free; } - hid->quirks |= quirks; -return 0 ;
err_mem_free:drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +0
-1@@ -492,4 +492,3 @@ u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product)return quirks; } -EXPORT_SYMBOL_GPL (i2c_hid_get_dmi_quirks);include/linux/hid.h +0
-0@@ -622,6 +622,7 @@ struct hid_device { /* device report descriptor */unsigned long status; /* see STAT flags above */
unsigned claimed; /* Claimed by hidinput, hiddev? */
unsigned quirks; /* Various quirks the device can pull on us */
+ unsignedinitial_quirks; /* Initial set of quirks supplied when creating device */ boolio_started; /* If IO has started */struct
list_headinputs; /* The list of inputs */Signature · 5 lines
2.39.1.519.gcb327c4b5f-goog -- Dmitry
Benjamin Tissoires
AppliedQuoted 9 lines · Dmitry Torokhov
In certain circumstances, such as when creating I2C-connected HID devices, we want to pass and retain some quirks (axis inversion, etc). The source of such quirks may be device tree, or DMI data, or something else not readily available to the HID core itself and therefore cannot be reconstructed easily. To allow this, introduce "
initial_quirks" field inhid_devicestructure and use it when determining the final set of quirks.[...]
Applied to hid/hid.git (for-6.3/multitouch), thanks!
[1/1] HID: retain initial quirks set up when creating HID devices
https://git.kernel.org/hid/hid/c/03a86105556e
Cheers,
Signature · 1 line
Benjamin Tissoires <[email protected]>