[PATCH 2/2] hid: multitouch: improve custom quirks kernel parameter

From: Tao Jin
Date: Sun Apr 17 2022 - 23:19:06 EST


This allows a list of different quirks to be matched against
corresponding hardware ids in case there are multiple devices present on
the same system.

The code borrowed some idea from vfio_pci.c

Signed-off-by: Tao Jin <tao-j@xxxxxxxxxxx>
---
drivers/hid/hid-multitouch.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index c6d64f8..f662960 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -398,9 +398,9 @@ static const struct mt_class mt_classes[] = {
{ }
};

-static int override_quirks = -1;
-module_param(override_quirks, int, 0444);
-MODULE_PARM_DESC(override_quirks, "Signed integer to override quirks in mtclass, must >= 0 to enable override.");
+static char override_quirks[128] = "";
+module_param_string(override_quirks, override_quirks, sizeof(override_quirks), 0444);
+MODULE_PARM_DESC(override_quirks, "List of quirks and corresponding device ids in hex to override quirks, format is \"wanted_quirks:vendor:product\", multiple comma separated entries can be specified.");

static ssize_t mt_show_quirks(struct device *dev,
struct device_attribute *attr,
@@ -1714,6 +1714,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
int ret, i;
struct mt_device *td;
const struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */
+ char *p, *qk;

for (i = 0; mt_classes[i].name ; i++) {
if (id->driver_data == mt_classes[i].name) {
@@ -1753,9 +1754,28 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (id->group != HID_GROUP_MULTITOUCH_WIN_8)
hdev->quirks |= HID_QUIRK_MULTI_INPUT;

- if (override_quirks >= 0) {
- hid_info(hdev, "overriding quirks with: %d(0x%x)", override_quirks, override_quirks);
- td->mtclass.quirks = override_quirks;
+ p = override_quirks;
+ while ((qk = strsep(&p, ","))) {
+ __u32 wanted_quirks = 0;
+ __u32 vendor, product = HID_ANY_ID;
+ int fields;
+
+ if (!strlen(qk))
+ continue;
+
+ fields = sscanf(qk, "%x:%x:%x", &wanted_quirks,
+ &vendor, &product);
+
+ if (fields != 3) {
+ continue;
+ }
+
+ if (id->vendor == vendor && id->product == product) {
+ hid_info(hdev, "overriding quirks of %04x:%04x with: %x",
+ id->vendor, id->product, wanted_quirks);
+ td->mtclass.quirks = wanted_quirks;
+ break;
+ }
}

if (td->mtclass.quirks & MT_QUIRK_FORCE_MULTI_INPUT) {
--
2.35.1