19ee3e066SJulian Sax // SPDX-License-Identifier: GPL-2.0+
29ee3e066SJulian Sax
39ee3e066SJulian Sax /*
49ee3e066SJulian Sax * Quirks for I2C-HID devices that do not supply proper descriptors
59ee3e066SJulian Sax *
69ee3e066SJulian Sax * Copyright (c) 2018 Julian Sax <jsbc@gmx.de>
79ee3e066SJulian Sax *
89ee3e066SJulian Sax */
99ee3e066SJulian Sax
109ee3e066SJulian Sax #include <linux/types.h>
119ee3e066SJulian Sax #include <linux/dmi.h>
129ee3e066SJulian Sax #include <linux/mod_devicetable.h>
13*a2f416bfSAllen Ballway #include <linux/hid.h>
149ee3e066SJulian Sax
159ee3e066SJulian Sax #include "i2c-hid.h"
16*a2f416bfSAllen Ballway #include "../hid-ids.h"
179ee3e066SJulian Sax
189ee3e066SJulian Sax
199ee3e066SJulian Sax struct i2c_hid_desc_override {
209ee3e066SJulian Sax union {
219ee3e066SJulian Sax struct i2c_hid_desc *i2c_hid_desc;
229ee3e066SJulian Sax uint8_t *i2c_hid_desc_buffer;
239ee3e066SJulian Sax };
249ee3e066SJulian Sax uint8_t *hid_report_desc;
259ee3e066SJulian Sax unsigned int hid_report_desc_size;
269ee3e066SJulian Sax uint8_t *i2c_name;
279ee3e066SJulian Sax };
289ee3e066SJulian Sax
299ee3e066SJulian Sax
309ee3e066SJulian Sax /*
319ee3e066SJulian Sax * descriptors for the SIPODEV SP1064 touchpad
329ee3e066SJulian Sax *
339ee3e066SJulian Sax * This device does not supply any descriptors and on windows a filter
349ee3e066SJulian Sax * driver operates between the i2c-hid layer and the device and injects
359ee3e066SJulian Sax * these descriptors when the device is prompted. The descriptors were
369ee3e066SJulian Sax * extracted by listening to the i2c-hid traffic that occurs between the
379ee3e066SJulian Sax * windows filter driver and the windows i2c-hid driver.
389ee3e066SJulian Sax */
399ee3e066SJulian Sax
409ee3e066SJulian Sax static const struct i2c_hid_desc_override sipodev_desc = {
419ee3e066SJulian Sax .i2c_hid_desc_buffer = (uint8_t [])
429ee3e066SJulian Sax {0x1e, 0x00, /* Length of descriptor */
439ee3e066SJulian Sax 0x00, 0x01, /* Version of descriptor */
449ee3e066SJulian Sax 0xdb, 0x01, /* Length of report descriptor */
459ee3e066SJulian Sax 0x21, 0x00, /* Location of report descriptor */
469ee3e066SJulian Sax 0x24, 0x00, /* Location of input report */
479ee3e066SJulian Sax 0x1b, 0x00, /* Max input report length */
489ee3e066SJulian Sax 0x25, 0x00, /* Location of output report */
499ee3e066SJulian Sax 0x11, 0x00, /* Max output report length */
509ee3e066SJulian Sax 0x22, 0x00, /* Location of command register */
519ee3e066SJulian Sax 0x23, 0x00, /* Location of data register */
529ee3e066SJulian Sax 0x11, 0x09, /* Vendor ID */
539ee3e066SJulian Sax 0x88, 0x52, /* Product ID */
549ee3e066SJulian Sax 0x06, 0x00, /* Version ID */
559ee3e066SJulian Sax 0x00, 0x00, 0x00, 0x00 /* Reserved */
569ee3e066SJulian Sax },
579ee3e066SJulian Sax
589ee3e066SJulian Sax .hid_report_desc = (uint8_t [])
599ee3e066SJulian Sax {0x05, 0x01, /* Usage Page (Desktop), */
609ee3e066SJulian Sax 0x09, 0x02, /* Usage (Mouse), */
619ee3e066SJulian Sax 0xA1, 0x01, /* Collection (Application), */
629ee3e066SJulian Sax 0x85, 0x01, /* Report ID (1), */
639ee3e066SJulian Sax 0x09, 0x01, /* Usage (Pointer), */
649ee3e066SJulian Sax 0xA1, 0x00, /* Collection (Physical), */
659ee3e066SJulian Sax 0x05, 0x09, /* Usage Page (Button), */
669ee3e066SJulian Sax 0x19, 0x01, /* Usage Minimum (01h), */
679ee3e066SJulian Sax 0x29, 0x02, /* Usage Maximum (02h), */
689ee3e066SJulian Sax 0x25, 0x01, /* Logical Maximum (1), */
699ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
709ee3e066SJulian Sax 0x95, 0x02, /* Report Count (2), */
719ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
729ee3e066SJulian Sax 0x95, 0x06, /* Report Count (6), */
739ee3e066SJulian Sax 0x81, 0x01, /* Input (Constant), */
749ee3e066SJulian Sax 0x05, 0x01, /* Usage Page (Desktop), */
759ee3e066SJulian Sax 0x09, 0x30, /* Usage (X), */
769ee3e066SJulian Sax 0x09, 0x31, /* Usage (Y), */
779ee3e066SJulian Sax 0x15, 0x81, /* Logical Minimum (-127), */
789ee3e066SJulian Sax 0x25, 0x7F, /* Logical Maximum (127), */
799ee3e066SJulian Sax 0x75, 0x08, /* Report Size (8), */
809ee3e066SJulian Sax 0x95, 0x02, /* Report Count (2), */
819ee3e066SJulian Sax 0x81, 0x06, /* Input (Variable, Relative), */
829ee3e066SJulian Sax 0xC0, /* End Collection, */
839ee3e066SJulian Sax 0xC0, /* End Collection, */
849ee3e066SJulian Sax 0x05, 0x0D, /* Usage Page (Digitizer), */
859ee3e066SJulian Sax 0x09, 0x05, /* Usage (Touchpad), */
869ee3e066SJulian Sax 0xA1, 0x01, /* Collection (Application), */
879ee3e066SJulian Sax 0x85, 0x04, /* Report ID (4), */
889ee3e066SJulian Sax 0x05, 0x0D, /* Usage Page (Digitizer), */
899ee3e066SJulian Sax 0x09, 0x22, /* Usage (Finger), */
909ee3e066SJulian Sax 0xA1, 0x02, /* Collection (Logical), */
919ee3e066SJulian Sax 0x15, 0x00, /* Logical Minimum (0), */
929ee3e066SJulian Sax 0x25, 0x01, /* Logical Maximum (1), */
939ee3e066SJulian Sax 0x09, 0x47, /* Usage (Touch Valid), */
949ee3e066SJulian Sax 0x09, 0x42, /* Usage (Tip Switch), */
959ee3e066SJulian Sax 0x95, 0x02, /* Report Count (2), */
969ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
979ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
989ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
999ee3e066SJulian Sax 0x75, 0x03, /* Report Size (3), */
1009ee3e066SJulian Sax 0x25, 0x05, /* Logical Maximum (5), */
1019ee3e066SJulian Sax 0x09, 0x51, /* Usage (Contact Identifier), */
1029ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1039ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
1049ee3e066SJulian Sax 0x95, 0x03, /* Report Count (3), */
1059ee3e066SJulian Sax 0x81, 0x03, /* Input (Constant, Variable), */
1069ee3e066SJulian Sax 0x05, 0x01, /* Usage Page (Desktop), */
1079ee3e066SJulian Sax 0x26, 0x44, 0x0A, /* Logical Maximum (2628), */
1089ee3e066SJulian Sax 0x75, 0x10, /* Report Size (16), */
1099ee3e066SJulian Sax 0x55, 0x0E, /* Unit Exponent (14), */
1109ee3e066SJulian Sax 0x65, 0x11, /* Unit (Centimeter), */
1119ee3e066SJulian Sax 0x09, 0x30, /* Usage (X), */
1129ee3e066SJulian Sax 0x46, 0x1A, 0x04, /* Physical Maximum (1050), */
1139ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
1149ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1159ee3e066SJulian Sax 0x46, 0xBC, 0x02, /* Physical Maximum (700), */
1169ee3e066SJulian Sax 0x26, 0x34, 0x05, /* Logical Maximum (1332), */
1179ee3e066SJulian Sax 0x09, 0x31, /* Usage (Y), */
1189ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1199ee3e066SJulian Sax 0xC0, /* End Collection, */
1209ee3e066SJulian Sax 0x05, 0x0D, /* Usage Page (Digitizer), */
1219ee3e066SJulian Sax 0x09, 0x22, /* Usage (Finger), */
1229ee3e066SJulian Sax 0xA1, 0x02, /* Collection (Logical), */
1239ee3e066SJulian Sax 0x25, 0x01, /* Logical Maximum (1), */
1249ee3e066SJulian Sax 0x09, 0x47, /* Usage (Touch Valid), */
1259ee3e066SJulian Sax 0x09, 0x42, /* Usage (Tip Switch), */
1269ee3e066SJulian Sax 0x95, 0x02, /* Report Count (2), */
1279ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
1289ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1299ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
1309ee3e066SJulian Sax 0x75, 0x03, /* Report Size (3), */
1319ee3e066SJulian Sax 0x25, 0x05, /* Logical Maximum (5), */
1329ee3e066SJulian Sax 0x09, 0x51, /* Usage (Contact Identifier), */
1339ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1349ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
1359ee3e066SJulian Sax 0x95, 0x03, /* Report Count (3), */
1369ee3e066SJulian Sax 0x81, 0x03, /* Input (Constant, Variable), */
1379ee3e066SJulian Sax 0x05, 0x01, /* Usage Page (Desktop), */
1389ee3e066SJulian Sax 0x26, 0x44, 0x0A, /* Logical Maximum (2628), */
1399ee3e066SJulian Sax 0x75, 0x10, /* Report Size (16), */
1409ee3e066SJulian Sax 0x09, 0x30, /* Usage (X), */
1419ee3e066SJulian Sax 0x46, 0x1A, 0x04, /* Physical Maximum (1050), */
1429ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
1439ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1449ee3e066SJulian Sax 0x46, 0xBC, 0x02, /* Physical Maximum (700), */
1459ee3e066SJulian Sax 0x26, 0x34, 0x05, /* Logical Maximum (1332), */
1469ee3e066SJulian Sax 0x09, 0x31, /* Usage (Y), */
1479ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1489ee3e066SJulian Sax 0xC0, /* End Collection, */
1499ee3e066SJulian Sax 0x05, 0x0D, /* Usage Page (Digitizer), */
1509ee3e066SJulian Sax 0x09, 0x22, /* Usage (Finger), */
1519ee3e066SJulian Sax 0xA1, 0x02, /* Collection (Logical), */
1529ee3e066SJulian Sax 0x25, 0x01, /* Logical Maximum (1), */
1539ee3e066SJulian Sax 0x09, 0x47, /* Usage (Touch Valid), */
1549ee3e066SJulian Sax 0x09, 0x42, /* Usage (Tip Switch), */
1559ee3e066SJulian Sax 0x95, 0x02, /* Report Count (2), */
1569ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
1579ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1589ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
1599ee3e066SJulian Sax 0x75, 0x03, /* Report Size (3), */
1609ee3e066SJulian Sax 0x25, 0x05, /* Logical Maximum (5), */
1619ee3e066SJulian Sax 0x09, 0x51, /* Usage (Contact Identifier), */
1629ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1639ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
1649ee3e066SJulian Sax 0x95, 0x03, /* Report Count (3), */
1659ee3e066SJulian Sax 0x81, 0x03, /* Input (Constant, Variable), */
1669ee3e066SJulian Sax 0x05, 0x01, /* Usage Page (Desktop), */
1679ee3e066SJulian Sax 0x26, 0x44, 0x0A, /* Logical Maximum (2628), */
1689ee3e066SJulian Sax 0x75, 0x10, /* Report Size (16), */
1699ee3e066SJulian Sax 0x09, 0x30, /* Usage (X), */
1709ee3e066SJulian Sax 0x46, 0x1A, 0x04, /* Physical Maximum (1050), */
1719ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
1729ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1739ee3e066SJulian Sax 0x46, 0xBC, 0x02, /* Physical Maximum (700), */
1749ee3e066SJulian Sax 0x26, 0x34, 0x05, /* Logical Maximum (1332), */
1759ee3e066SJulian Sax 0x09, 0x31, /* Usage (Y), */
1769ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1779ee3e066SJulian Sax 0xC0, /* End Collection, */
1789ee3e066SJulian Sax 0x05, 0x0D, /* Usage Page (Digitizer), */
1799ee3e066SJulian Sax 0x09, 0x22, /* Usage (Finger), */
1809ee3e066SJulian Sax 0xA1, 0x02, /* Collection (Logical), */
1819ee3e066SJulian Sax 0x25, 0x01, /* Logical Maximum (1), */
1829ee3e066SJulian Sax 0x09, 0x47, /* Usage (Touch Valid), */
1839ee3e066SJulian Sax 0x09, 0x42, /* Usage (Tip Switch), */
1849ee3e066SJulian Sax 0x95, 0x02, /* Report Count (2), */
1859ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
1869ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1879ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
1889ee3e066SJulian Sax 0x75, 0x03, /* Report Size (3), */
1899ee3e066SJulian Sax 0x25, 0x05, /* Logical Maximum (5), */
1909ee3e066SJulian Sax 0x09, 0x51, /* Usage (Contact Identifier), */
1919ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
1929ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
1939ee3e066SJulian Sax 0x95, 0x03, /* Report Count (3), */
1949ee3e066SJulian Sax 0x81, 0x03, /* Input (Constant, Variable), */
1959ee3e066SJulian Sax 0x05, 0x01, /* Usage Page (Desktop), */
1969ee3e066SJulian Sax 0x26, 0x44, 0x0A, /* Logical Maximum (2628), */
1979ee3e066SJulian Sax 0x75, 0x10, /* Report Size (16), */
1989ee3e066SJulian Sax 0x09, 0x30, /* Usage (X), */
1999ee3e066SJulian Sax 0x46, 0x1A, 0x04, /* Physical Maximum (1050), */
2009ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
2019ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
2029ee3e066SJulian Sax 0x46, 0xBC, 0x02, /* Physical Maximum (700), */
2039ee3e066SJulian Sax 0x26, 0x34, 0x05, /* Logical Maximum (1332), */
2049ee3e066SJulian Sax 0x09, 0x31, /* Usage (Y), */
2059ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
2069ee3e066SJulian Sax 0xC0, /* End Collection, */
2079ee3e066SJulian Sax 0x05, 0x0D, /* Usage Page (Digitizer), */
2089ee3e066SJulian Sax 0x55, 0x0C, /* Unit Exponent (12), */
2099ee3e066SJulian Sax 0x66, 0x01, 0x10, /* Unit (Seconds), */
2109ee3e066SJulian Sax 0x47, 0xFF, 0xFF, 0x00, 0x00,/* Physical Maximum (65535), */
2119ee3e066SJulian Sax 0x27, 0xFF, 0xFF, 0x00, 0x00,/* Logical Maximum (65535), */
2129ee3e066SJulian Sax 0x75, 0x10, /* Report Size (16), */
2139ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
2149ee3e066SJulian Sax 0x09, 0x56, /* Usage (Scan Time), */
2159ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
2169ee3e066SJulian Sax 0x09, 0x54, /* Usage (Contact Count), */
2179ee3e066SJulian Sax 0x25, 0x7F, /* Logical Maximum (127), */
2189ee3e066SJulian Sax 0x75, 0x08, /* Report Size (8), */
2199ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
2209ee3e066SJulian Sax 0x05, 0x09, /* Usage Page (Button), */
2219ee3e066SJulian Sax 0x09, 0x01, /* Usage (01h), */
2229ee3e066SJulian Sax 0x25, 0x01, /* Logical Maximum (1), */
2239ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
2249ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
2259ee3e066SJulian Sax 0x81, 0x02, /* Input (Variable), */
2269ee3e066SJulian Sax 0x95, 0x07, /* Report Count (7), */
2279ee3e066SJulian Sax 0x81, 0x03, /* Input (Constant, Variable), */
2289ee3e066SJulian Sax 0x05, 0x0D, /* Usage Page (Digitizer), */
2299ee3e066SJulian Sax 0x85, 0x02, /* Report ID (2), */
2309ee3e066SJulian Sax 0x09, 0x55, /* Usage (Contact Count Maximum), */
2319ee3e066SJulian Sax 0x09, 0x59, /* Usage (59h), */
2329ee3e066SJulian Sax 0x75, 0x04, /* Report Size (4), */
2339ee3e066SJulian Sax 0x95, 0x02, /* Report Count (2), */
2349ee3e066SJulian Sax 0x25, 0x0F, /* Logical Maximum (15), */
2359ee3e066SJulian Sax 0xB1, 0x02, /* Feature (Variable), */
2369ee3e066SJulian Sax 0x05, 0x0D, /* Usage Page (Digitizer), */
2379ee3e066SJulian Sax 0x85, 0x07, /* Report ID (7), */
2389ee3e066SJulian Sax 0x09, 0x60, /* Usage (60h), */
2399ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
2409ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
2419ee3e066SJulian Sax 0x25, 0x01, /* Logical Maximum (1), */
2429ee3e066SJulian Sax 0xB1, 0x02, /* Feature (Variable), */
2439ee3e066SJulian Sax 0x95, 0x07, /* Report Count (7), */
2449ee3e066SJulian Sax 0xB1, 0x03, /* Feature (Constant, Variable), */
2459ee3e066SJulian Sax 0x85, 0x06, /* Report ID (6), */
2469ee3e066SJulian Sax 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
2479ee3e066SJulian Sax 0x09, 0xC5, /* Usage (C5h), */
2489ee3e066SJulian Sax 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
2499ee3e066SJulian Sax 0x75, 0x08, /* Report Size (8), */
2509ee3e066SJulian Sax 0x96, 0x00, 0x01, /* Report Count (256), */
2519ee3e066SJulian Sax 0xB1, 0x02, /* Feature (Variable), */
2529ee3e066SJulian Sax 0xC0, /* End Collection, */
2539ee3e066SJulian Sax 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
2549ee3e066SJulian Sax 0x09, 0x01, /* Usage (01h), */
2559ee3e066SJulian Sax 0xA1, 0x01, /* Collection (Application), */
2569ee3e066SJulian Sax 0x85, 0x0D, /* Report ID (13), */
2579ee3e066SJulian Sax 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
2589ee3e066SJulian Sax 0x19, 0x01, /* Usage Minimum (01h), */
2599ee3e066SJulian Sax 0x29, 0x02, /* Usage Maximum (02h), */
2609ee3e066SJulian Sax 0x75, 0x08, /* Report Size (8), */
2619ee3e066SJulian Sax 0x95, 0x02, /* Report Count (2), */
2629ee3e066SJulian Sax 0xB1, 0x02, /* Feature (Variable), */
2639ee3e066SJulian Sax 0xC0, /* End Collection, */
2649ee3e066SJulian Sax 0x05, 0x0D, /* Usage Page (Digitizer), */
2659ee3e066SJulian Sax 0x09, 0x0E, /* Usage (Configuration), */
2669ee3e066SJulian Sax 0xA1, 0x01, /* Collection (Application), */
2679ee3e066SJulian Sax 0x85, 0x03, /* Report ID (3), */
2689ee3e066SJulian Sax 0x09, 0x22, /* Usage (Finger), */
2699ee3e066SJulian Sax 0xA1, 0x02, /* Collection (Logical), */
2709ee3e066SJulian Sax 0x09, 0x52, /* Usage (Device Mode), */
2719ee3e066SJulian Sax 0x25, 0x0A, /* Logical Maximum (10), */
2729ee3e066SJulian Sax 0x95, 0x01, /* Report Count (1), */
2739ee3e066SJulian Sax 0xB1, 0x02, /* Feature (Variable), */
2749ee3e066SJulian Sax 0xC0, /* End Collection, */
2759ee3e066SJulian Sax 0x09, 0x22, /* Usage (Finger), */
2769ee3e066SJulian Sax 0xA1, 0x00, /* Collection (Physical), */
2779ee3e066SJulian Sax 0x85, 0x05, /* Report ID (5), */
2789ee3e066SJulian Sax 0x09, 0x57, /* Usage (57h), */
2799ee3e066SJulian Sax 0x09, 0x58, /* Usage (58h), */
2809ee3e066SJulian Sax 0x75, 0x01, /* Report Size (1), */
2819ee3e066SJulian Sax 0x95, 0x02, /* Report Count (2), */
2829ee3e066SJulian Sax 0x25, 0x01, /* Logical Maximum (1), */
2839ee3e066SJulian Sax 0xB1, 0x02, /* Feature (Variable), */
2849ee3e066SJulian Sax 0x95, 0x06, /* Report Count (6), */
2859ee3e066SJulian Sax 0xB1, 0x03, /* Feature (Constant, Variable),*/
2869ee3e066SJulian Sax 0xC0, /* End Collection, */
2879ee3e066SJulian Sax 0xC0 /* End Collection */
2889ee3e066SJulian Sax },
2899ee3e066SJulian Sax .hid_report_desc_size = 475,
2909ee3e066SJulian Sax .i2c_name = "SYNA3602:00"
2919ee3e066SJulian Sax };
2929ee3e066SJulian Sax
2939ee3e066SJulian Sax
2949ee3e066SJulian Sax static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
2959ee3e066SJulian Sax {
2969ee3e066SJulian Sax .ident = "Teclast F6 Pro",
2979ee3e066SJulian Sax .matches = {
2989ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TECLAST"),
2999ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "F6 Pro"),
3009ee3e066SJulian Sax },
3019ee3e066SJulian Sax .driver_data = (void *)&sipodev_desc
3029ee3e066SJulian Sax },
3039ee3e066SJulian Sax {
3049ee3e066SJulian Sax .ident = "Teclast F7",
3059ee3e066SJulian Sax .matches = {
3069ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TECLAST"),
3079ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "F7"),
3089ee3e066SJulian Sax },
3099ee3e066SJulian Sax .driver_data = (void *)&sipodev_desc
3109ee3e066SJulian Sax },
3119ee3e066SJulian Sax {
3129ee3e066SJulian Sax .ident = "Trekstor Primebook C13",
3139ee3e066SJulian Sax .matches = {
3149ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
3159ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
3169ee3e066SJulian Sax },
3179ee3e066SJulian Sax .driver_data = (void *)&sipodev_desc
3189ee3e066SJulian Sax },
3199ee3e066SJulian Sax {
3209ee3e066SJulian Sax .ident = "Trekstor Primebook C11",
3219ee3e066SJulian Sax .matches = {
3229ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
3239ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11"),
3249ee3e066SJulian Sax },
3259ee3e066SJulian Sax .driver_data = (void *)&sipodev_desc
3269ee3e066SJulian Sax },
3279ee3e066SJulian Sax {
32809f3dbe4SHans de Goede /*
32909f3dbe4SHans de Goede * There are at least 2 Primebook C11B versions, the older
33009f3dbe4SHans de Goede * version has a product-name of "Primebook C11B", and a
33109f3dbe4SHans de Goede * bios version / release / firmware revision of:
33209f3dbe4SHans de Goede * V2.1.2 / 05/03/2018 / 18.2
33309f3dbe4SHans de Goede * The new version has "PRIMEBOOK C11B" as product-name and a
33409f3dbe4SHans de Goede * bios version / release / firmware revision of:
33509f3dbe4SHans de Goede * CFALKSW05_BIOS_V1.1.2 / 11/19/2018 / 19.2
33609f3dbe4SHans de Goede * Only the older version needs this quirk, note the newer
33709f3dbe4SHans de Goede * version will not match as it has a different product-name.
33809f3dbe4SHans de Goede */
33909f3dbe4SHans de Goede .ident = "Trekstor Primebook C11B",
34009f3dbe4SHans de Goede .matches = {
34109f3dbe4SHans de Goede DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
34209f3dbe4SHans de Goede DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11B"),
34309f3dbe4SHans de Goede },
34409f3dbe4SHans de Goede .driver_data = (void *)&sipodev_desc
34509f3dbe4SHans de Goede },
34609f3dbe4SHans de Goede {
347be0aba82SKai-Heng Feng .ident = "Trekstor SURFBOOK E11B",
348be0aba82SKai-Heng Feng .matches = {
349be0aba82SKai-Heng Feng DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
350be0aba82SKai-Heng Feng DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"),
351be0aba82SKai-Heng Feng },
352be0aba82SKai-Heng Feng .driver_data = (void *)&sipodev_desc
353be0aba82SKai-Heng Feng },
354be0aba82SKai-Heng Feng {
3559ee3e066SJulian Sax .ident = "Direkt-Tek DTLAPY116-2",
3569ee3e066SJulian Sax .matches = {
3579ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"),
3589ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "DTLAPY116-2"),
3599ee3e066SJulian Sax },
3609ee3e066SJulian Sax .driver_data = (void *)&sipodev_desc
3619ee3e066SJulian Sax },
3629ee3e066SJulian Sax {
363399474e4SJulian Sax .ident = "Direkt-Tek DTLAPY133-1",
364399474e4SJulian Sax .matches = {
365399474e4SJulian Sax DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"),
366399474e4SJulian Sax DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "DTLAPY133-1"),
367399474e4SJulian Sax },
368399474e4SJulian Sax .driver_data = (void *)&sipodev_desc
369399474e4SJulian Sax },
370399474e4SJulian Sax {
3719ee3e066SJulian Sax .ident = "Mediacom Flexbook Edge 11",
3729ee3e066SJulian Sax .matches = {
3739ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"),
3749ee3e066SJulian Sax DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FlexBook edge11 - M-FBE11"),
3759ee3e066SJulian Sax },
3769ee3e066SJulian Sax .driver_data = (void *)&sipodev_desc
377b59dfdaeSLinus Torvalds },
378f8f80744SHans de Goede {
37943e666acSFederico Ricchiuto .ident = "Mediacom FlexBook edge 13",
38043e666acSFederico Ricchiuto .matches = {
38143e666acSFederico Ricchiuto DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"),
38243e666acSFederico Ricchiuto DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FlexBook_edge13-M-FBE13"),
38343e666acSFederico Ricchiuto },
38443e666acSFederico Ricchiuto .driver_data = (void *)&sipodev_desc
38543e666acSFederico Ricchiuto },
38643e666acSFederico Ricchiuto {
387f8f80744SHans de Goede .ident = "Odys Winbook 13",
388f8f80744SHans de Goede .matches = {
389f8f80744SHans de Goede DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AXDIA International GmbH"),
390f8f80744SHans de Goede DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "WINBOOK 13"),
391f8f80744SHans de Goede },
392f8f80744SHans de Goede .driver_data = (void *)&sipodev_desc
393f8f80744SHans de Goede },
394eb6964faSKai-Heng Feng {
395eb6964faSKai-Heng Feng .ident = "iBall Aer3",
396eb6964faSKai-Heng Feng .matches = {
397eb6964faSKai-Heng Feng DMI_EXACT_MATCH(DMI_SYS_VENDOR, "iBall"),
398eb6964faSKai-Heng Feng DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Aer3"),
399eb6964faSKai-Heng Feng },
400eb6964faSKai-Heng Feng .driver_data = (void *)&sipodev_desc
401eb6964faSKai-Heng Feng },
4026507ef10SJulian Sax {
4036507ef10SJulian Sax .ident = "Schneider SCL142ALM",
4046507ef10SJulian Sax .matches = {
4056507ef10SJulian Sax DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SCHNEIDER"),
4066507ef10SJulian Sax DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SCL142ALM"),
4076507ef10SJulian Sax },
4086507ef10SJulian Sax .driver_data = (void *)&sipodev_desc
4096507ef10SJulian Sax },
410c870d50cSJulian Sax {
411c870d50cSJulian Sax .ident = "Vero K147",
412c870d50cSJulian Sax .matches = {
413c870d50cSJulian Sax DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VERO"),
414c870d50cSJulian Sax DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "K147"),
415c870d50cSJulian Sax },
416c870d50cSJulian Sax .driver_data = (void *)&sipodev_desc
417c870d50cSJulian Sax },
418b59dfdaeSLinus Torvalds { } /* Terminate list */
4199ee3e066SJulian Sax };
4209ee3e066SJulian Sax
421*a2f416bfSAllen Ballway static const struct hid_device_id i2c_hid_elan_flipped_quirks = {
422*a2f416bfSAllen Ballway HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_ELAN, 0x2dcd),
423*a2f416bfSAllen Ballway HID_QUIRK_X_INVERT | HID_QUIRK_Y_INVERT
424*a2f416bfSAllen Ballway };
425*a2f416bfSAllen Ballway
426*a2f416bfSAllen Ballway /*
427*a2f416bfSAllen Ballway * This list contains devices which have specific issues based on the system
428*a2f416bfSAllen Ballway * they're on and not just the device itself. The driver_data will have a
429*a2f416bfSAllen Ballway * specific hid device to match against.
430*a2f416bfSAllen Ballway */
431*a2f416bfSAllen Ballway static const struct dmi_system_id i2c_hid_dmi_quirk_table[] = {
432*a2f416bfSAllen Ballway {
433*a2f416bfSAllen Ballway .ident = "DynaBook K50/FR",
434*a2f416bfSAllen Ballway .matches = {
435*a2f416bfSAllen Ballway DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dynabook Inc."),
436*a2f416bfSAllen Ballway DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "dynabook K50/FR"),
437*a2f416bfSAllen Ballway },
438*a2f416bfSAllen Ballway .driver_data = (void *)&i2c_hid_elan_flipped_quirks,
439*a2f416bfSAllen Ballway },
440*a2f416bfSAllen Ballway { } /* Terminate list */
441*a2f416bfSAllen Ballway };
442*a2f416bfSAllen Ballway
4439ee3e066SJulian Sax
i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t * i2c_name)4449ee3e066SJulian Sax struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name)
4459ee3e066SJulian Sax {
4469ee3e066SJulian Sax struct i2c_hid_desc_override *override;
4479ee3e066SJulian Sax const struct dmi_system_id *system_id;
4489ee3e066SJulian Sax
4499ee3e066SJulian Sax system_id = dmi_first_match(i2c_hid_dmi_desc_override_table);
4509ee3e066SJulian Sax if (!system_id)
4519ee3e066SJulian Sax return NULL;
4529ee3e066SJulian Sax
4539ee3e066SJulian Sax override = system_id->driver_data;
4549ee3e066SJulian Sax if (strcmp(override->i2c_name, i2c_name))
4559ee3e066SJulian Sax return NULL;
4569ee3e066SJulian Sax
4579ee3e066SJulian Sax return override->i2c_hid_desc;
4589ee3e066SJulian Sax }
4599ee3e066SJulian Sax
i2c_hid_get_dmi_hid_report_desc_override(uint8_t * i2c_name,unsigned int * size)4609ee3e066SJulian Sax char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name,
4619ee3e066SJulian Sax unsigned int *size)
4629ee3e066SJulian Sax {
4639ee3e066SJulian Sax struct i2c_hid_desc_override *override;
4649ee3e066SJulian Sax const struct dmi_system_id *system_id;
4659ee3e066SJulian Sax
4669ee3e066SJulian Sax system_id = dmi_first_match(i2c_hid_dmi_desc_override_table);
4679ee3e066SJulian Sax if (!system_id)
4689ee3e066SJulian Sax return NULL;
4699ee3e066SJulian Sax
4709ee3e066SJulian Sax override = system_id->driver_data;
4719ee3e066SJulian Sax if (strcmp(override->i2c_name, i2c_name))
4729ee3e066SJulian Sax return NULL;
4739ee3e066SJulian Sax
4749ee3e066SJulian Sax *size = override->hid_report_desc_size;
4759ee3e066SJulian Sax return override->hid_report_desc;
4769ee3e066SJulian Sax }
477*a2f416bfSAllen Ballway
i2c_hid_get_dmi_quirks(const u16 vendor,const u16 product)478*a2f416bfSAllen Ballway u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product)
479*a2f416bfSAllen Ballway {
480*a2f416bfSAllen Ballway u32 quirks = 0;
481*a2f416bfSAllen Ballway const struct dmi_system_id *system_id =
482*a2f416bfSAllen Ballway dmi_first_match(i2c_hid_dmi_quirk_table);
483*a2f416bfSAllen Ballway
484*a2f416bfSAllen Ballway if (system_id) {
485*a2f416bfSAllen Ballway const struct hid_device_id *device_id =
486*a2f416bfSAllen Ballway (struct hid_device_id *)(system_id->driver_data);
487*a2f416bfSAllen Ballway
488*a2f416bfSAllen Ballway if (device_id && device_id->vendor == vendor &&
489*a2f416bfSAllen Ballway device_id->product == product)
490*a2f416bfSAllen Ballway quirks = device_id->driver_data;
491*a2f416bfSAllen Ballway }
492*a2f416bfSAllen Ballway
493*a2f416bfSAllen Ballway return quirks;
494*a2f416bfSAllen Ballway }
495