On these laptops, there seems to be a device that, when probed by i2c-hid, constantly sends bogus interrupts and interferes with the keyboard controller. When the device is enabled, it takes the keyboard around 8 seconds to register that keys are being pressed or released. Nothing I tried seemed to make the device work, and preventing the device from being probed doesn't seem to break any functionality of the laptop. Signed-off-by: Friedrich Vock <friedrich.vock@xxxxxx> --- drivers/hid/i2c-hid/i2c-hid-core.c | 5 +++ drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 48 ++++++++++++++++++++++++ drivers/hid/i2c-hid/i2c-hid.h | 3 ++ 3 files changed, 56 insertions(+) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index efbba0465eef..5f0686d058df 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -1035,6 +1035,11 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product); + if (i2c_hid_device_blocked(hid->vendor, hid->product)) { + ret = -ENODEV; + goto err_irq; + } + ret = hid_add_device(hid); if (ret) { if (ret != -ENODEV) diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c index 210f17c3a0be..d2c2806b64b4 100644 --- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c @@ -440,6 +440,38 @@ static const struct dmi_system_id i2c_hid_dmi_quirk_table[] = { { } /* Terminate list */ }; +static const struct hid_device_id i2c_hid_blocked_ite_device = { + HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC, USB_VENDOR_ID_ITE, 0x8051) +}; + +/* + * This list contains devices that can't be activated at all, for example + * because activating them breaks other important parts of the system. + */ +static const struct dmi_system_id i2c_hid_dmi_block_table[] = { + /* + * On ASUS TUF Gaming A16 laptops, there is a device that will make the + * keyboard controller stop working correctly and flood the CPU with bogus + * interrupts. + */ + { + .ident = "ASUS TUF Gaming A16 (Ryzen 7 7735HS)", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "FA617NS"), + }, + .driver_data = (void *)&i2c_hid_blocked_ite_device, + }, + { + .ident = "ASUS TUF Gaming A16 (Ryzen 9 7940HS)", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "FA617XS"), + }, + .driver_data = (void *)&i2c_hid_blocked_ite_device, + }, + { } /* Terminate list */ +}; struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name) { @@ -492,3 +524,19 @@ u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product) return quirks; } + +bool i2c_hid_device_blocked(const u16 vendor, const u16 product) +{ + const struct dmi_system_id *system_id = + dmi_first_match(i2c_hid_dmi_block_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) + return true; + } + return false; +} diff --git a/drivers/hid/i2c-hid/i2c-hid.h b/drivers/hid/i2c-hid/i2c-hid.h index 2c7b66d5caa0..e17bdd758f39 100644 --- a/drivers/hid/i2c-hid/i2c-hid.h +++ b/drivers/hid/i2c-hid/i2c-hid.h @@ -10,6 +10,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); +bool i2c_hid_device_blocked(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) @@ -19,6 +20,8 @@ static inline char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name, { return NULL; } static inline u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product) { return 0; } +static inline bool i2c_hid_device_blocked(const u16 vendor, const u16 product) +{ return false; } #endif /** -- 2.40.1