diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2023-02-22 10:39:05 +0100 |
---|---|---|
committer | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2023-02-22 10:39:05 +0100 |
commit | c21c9feed40e8e64ad73d81acaecf6feaf860300 (patch) | |
tree | 539b93527febbf003069f9a89d5485484e73b6c7 /drivers/hid/i2c-hid | |
parent | Merge branch 'for-6.3/mcp2221' into for-linus (diff) | |
parent | HID: retain initial quirks set up when creating HID devices (diff) | |
download | linux-c21c9feed40e8e64ad73d81acaecf6feaf860300.tar.xz linux-c21c9feed40e8e64ad73d81acaecf6feaf860300.zip |
Merge branch 'for-6.3/multitouch' into for-linus
Allow to pass quirks from i2c-hid to hid-multitouch (Allen Ballway &
Dmitry Torokhov)
Diffstat (limited to 'drivers/hid/i2c-hid')
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid-core.c | 6 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 42 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.h | 3 |
3 files changed, 49 insertions, 2 deletions
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 0ab8f47a84e9..efbba0465eef 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -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: diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c index 8e0f67455c09..210f17c3a0be 100644 --- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c @@ -10,8 +10,10 @@ #include <linux/types.h> #include <linux/dmi.h> #include <linux/mod_devicetable.h> +#include <linux/hid.h> #include "i2c-hid.h" +#include "../hid-ids.h" struct i2c_hid_desc_override { @@ -416,6 +418,28 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { { } /* Terminate list */ }; +static const struct hid_device_id i2c_hid_elan_flipped_quirks = { + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_ELAN, 0x2dcd), + HID_QUIRK_X_INVERT | HID_QUIRK_Y_INVERT +}; + +/* + * This list contains devices which have specific issues based on the system + * they're on and not just the device itself. The driver_data will have a + * specific hid device to match against. + */ +static const struct dmi_system_id i2c_hid_dmi_quirk_table[] = { + { + .ident = "DynaBook K50/FR", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dynabook Inc."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "dynabook K50/FR"), + }, + .driver_data = (void *)&i2c_hid_elan_flipped_quirks, + }, + { } /* Terminate list */ +}; + struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name) { @@ -450,3 +474,21 @@ char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name, *size = override->hid_report_desc_size; return override->hid_report_desc; } + +u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product) +{ + u32 quirks = 0; + const struct dmi_system_id *system_id = + dmi_first_match(i2c_hid_dmi_quirk_table); + + if (system_id) { + const struct hid_device_id *device_id = + (struct hid_device_id *)(system_id->driver_data); + + if (device_id && device_id->vendor == vendor && + device_id->product == product) + quirks = device_id->driver_data; + } + + return quirks; +} diff --git a/drivers/hid/i2c-hid/i2c-hid.h b/drivers/hid/i2c-hid/i2c-hid.h index 96c75510ad3f..2c7b66d5caa0 100644 --- a/drivers/hid/i2c-hid/i2c-hid.h +++ b/drivers/hid/i2c-hid/i2c-hid.h @@ -9,6 +9,7 @@ struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name); char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name, unsigned int *size); +u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product); #else static inline struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name) @@ -16,6 +17,8 @@ static inline struct i2c_hid_desc static inline char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name, unsigned int *size) { return NULL; } +static inline u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product) +{ return 0; } #endif /** |