diff mbox series

[1/2] HID: i2c-hid: expand the quirk lookup table to support dmi_table

Message ID 20201204152912.151604-1-hui.wang@canonical.com (mailing list archive)
State New
Delegated to: Jiri Kosina
Headers show
Series [1/2] HID: i2c-hid: expand the quirk lookup table to support dmi_table | expand

Commit Message

Hui Wang Dec. 4, 2020, 3:29 p.m. UTC
After adding the dmi_table, we could apply the quirk to the specific
machine, and the dmi_table is optional when define a quirk table, if
not define the dmi_table, the lookup_quirk() works the same as before.

Signed-off-by: Hui Wang <hui.wang@canonical.com>
---
 drivers/hid/i2c-hid/i2c-hid-core.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index aeff1ffb0c8b..953877cf1051 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -37,6 +37,7 @@ 
 #include <linux/mutex.h>
 #include <linux/acpi.h>
 #include <linux/of.h>
+#include <linux/dmi.h>
 #include <linux/regulator/consumer.h>
 
 #include <linux/platform_data/i2c-hid.h>
@@ -166,6 +167,7 @@  static const struct i2c_hid_quirks {
 	__u16 idVendor;
 	__u16 idProduct;
 	__u32 quirks;
+	const struct dmi_system_id *dmi_table;
 } i2c_hid_quirks[] = {
 	{ USB_VENDOR_ID_WEIDA, HID_ANY_ID,
 		I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
@@ -188,21 +190,20 @@  static const struct i2c_hid_quirks {
  * i2c_hid_lookup_quirk: return any quirks associated with a I2C HID device
  * @idVendor: the 16-bit vendor ID
  * @idProduct: the 16-bit product ID
+ * @table: struct i2c_hid_quirks table pointer
+ * @len: the 32-bit table length
  *
  * Returns: a u32 quirks value.
  */
-static u32 i2c_hid_lookup_quirk(const u16 idVendor, const u16 idProduct)
+static u32 i2c_hid_lookup_quirk(const u16 idVendor, const u16 idProduct,
+				const struct i2c_hid_quirks *table, u32 len)
 {
-	u32 quirks = 0;
-	int n;
+	for (; len > 0; len--, table++)
+		if (table->idVendor == idVendor && table->idProduct == idProduct)
+			if (!table->dmi_table || dmi_check_system(table->dmi_table))
+				return table->quirks;
 
-	for (n = 0; i2c_hid_quirks[n].idVendor; n++)
-		if (i2c_hid_quirks[n].idVendor == idVendor &&
-		    (i2c_hid_quirks[n].idProduct == (__u16)HID_ANY_ID ||
-		     i2c_hid_quirks[n].idProduct == idProduct))
-			quirks = i2c_hid_quirks[n].quirks;
-
-	return quirks;
+	return 0;
 }
 
 static int __i2c_hid_command(struct i2c_client *client,
@@ -1133,7 +1134,8 @@  static int i2c_hid_probe(struct i2c_client *client,
 		 client->name, hid->vendor, hid->product);
 	strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys));
 
-	ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product);
+	ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product, i2c_hid_quirks,
+					    ARRAY_SIZE(i2c_hid_quirks));
 
 	ret = hid_add_device(hid);
 	if (ret) {