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