-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0036-Block_a_rogue_device_on_ASUS_TUF_A16.patch
121 lines (109 loc) · 4.09 KB
/
0036-Block_a_rogue_device_on_ASUS_TUF_A16.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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@gmx.de>
---
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