xref: /linux/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c (revision d2c9a99135da931377240942d44f3dea104cedb8)
1 // SPDX-License-Identifier: GPL-2.0+
2 
3 /*
4  * Quirks for I2C-HID devices that do not supply proper descriptors
5  *
6  * Copyright (c) 2018 Julian Sax <jsbc@gmx.de>
7  *
8  */
9 
10 #include <linux/types.h>
11 #include <linux/dmi.h>
12 #include <linux/hid.h>
13 
14 #include "i2c-hid.h"
15 #include "../hid-ids.h"
16 
17 
18 struct i2c_hid_desc_override {
19 	union {
20 		struct i2c_hid_desc *i2c_hid_desc;
21 		uint8_t             *i2c_hid_desc_buffer;
22 	};
23 	uint8_t              *hid_report_desc;
24 	unsigned int          hid_report_desc_size;
25 	uint8_t              *i2c_name;
26 };
27 
28 
29 /*
30  * descriptors for the SIPODEV SP1064 touchpad
31  *
32  * This device does not supply any descriptors and on windows a filter
33  * driver operates between the i2c-hid layer and the device and injects
34  * these descriptors when the device is prompted. The descriptors were
35  * extracted by listening to the i2c-hid traffic that occurs between the
36  * windows filter driver and the windows i2c-hid driver.
37  */
38 
39 static const struct i2c_hid_desc_override sipodev_desc = {
40 	.i2c_hid_desc_buffer = (uint8_t [])
41 	{0x1e, 0x00,                  /* Length of descriptor                 */
42 	 0x00, 0x01,                  /* Version of descriptor                */
43 	 0xdb, 0x01,                  /* Length of report descriptor          */
44 	 0x21, 0x00,                  /* Location of report descriptor        */
45 	 0x24, 0x00,                  /* Location of input report             */
46 	 0x1b, 0x00,                  /* Max input report length              */
47 	 0x25, 0x00,                  /* Location of output report            */
48 	 0x11, 0x00,                  /* Max output report length             */
49 	 0x22, 0x00,                  /* Location of command register         */
50 	 0x23, 0x00,                  /* Location of data register            */
51 	 0x11, 0x09,                  /* Vendor ID                            */
52 	 0x88, 0x52,                  /* Product ID                           */
53 	 0x06, 0x00,                  /* Version ID                           */
54 	 0x00, 0x00, 0x00, 0x00       /* Reserved                             */
55 	},
56 
57 	.hid_report_desc = (uint8_t [])
58 	{0x05, 0x01,                  /* Usage Page (Desktop),                */
59 	 0x09, 0x02,                  /* Usage (Mouse),                       */
60 	 0xA1, 0x01,                  /* Collection (Application),            */
61 	 0x85, 0x01,                  /*     Report ID (1),                   */
62 	 0x09, 0x01,                  /*     Usage (Pointer),                 */
63 	 0xA1, 0x00,                  /*     Collection (Physical),           */
64 	 0x05, 0x09,                  /*         Usage Page (Button),         */
65 	 0x19, 0x01,                  /*         Usage Minimum (01h),         */
66 	 0x29, 0x02,                  /*         Usage Maximum (02h),         */
67 	 0x25, 0x01,                  /*         Logical Maximum (1),         */
68 	 0x75, 0x01,                  /*         Report Size (1),             */
69 	 0x95, 0x02,                  /*         Report Count (2),            */
70 	 0x81, 0x02,                  /*         Input (Variable),            */
71 	 0x95, 0x06,                  /*         Report Count (6),            */
72 	 0x81, 0x01,                  /*         Input (Constant),            */
73 	 0x05, 0x01,                  /*         Usage Page (Desktop),        */
74 	 0x09, 0x30,                  /*         Usage (X),                   */
75 	 0x09, 0x31,                  /*         Usage (Y),                   */
76 	 0x15, 0x81,                  /*         Logical Minimum (-127),      */
77 	 0x25, 0x7F,                  /*         Logical Maximum (127),       */
78 	 0x75, 0x08,                  /*         Report Size (8),             */
79 	 0x95, 0x02,                  /*         Report Count (2),            */
80 	 0x81, 0x06,                  /*         Input (Variable, Relative),  */
81 	 0xC0,                        /*     End Collection,                  */
82 	 0xC0,                        /* End Collection,                      */
83 	 0x05, 0x0D,                  /* Usage Page (Digitizer),              */
84 	 0x09, 0x05,                  /* Usage (Touchpad),                    */
85 	 0xA1, 0x01,                  /* Collection (Application),            */
86 	 0x85, 0x04,                  /*     Report ID (4),                   */
87 	 0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
88 	 0x09, 0x22,                  /*     Usage (Finger),                  */
89 	 0xA1, 0x02,                  /*     Collection (Logical),            */
90 	 0x15, 0x00,                  /*         Logical Minimum (0),         */
91 	 0x25, 0x01,                  /*         Logical Maximum (1),         */
92 	 0x09, 0x47,                  /*         Usage (Touch Valid),         */
93 	 0x09, 0x42,                  /*         Usage (Tip Switch),          */
94 	 0x95, 0x02,                  /*         Report Count (2),            */
95 	 0x75, 0x01,                  /*         Report Size (1),             */
96 	 0x81, 0x02,                  /*         Input (Variable),            */
97 	 0x95, 0x01,                  /*         Report Count (1),            */
98 	 0x75, 0x03,                  /*         Report Size (3),             */
99 	 0x25, 0x05,                  /*         Logical Maximum (5),         */
100 	 0x09, 0x51,                  /*         Usage (Contact Identifier),  */
101 	 0x81, 0x02,                  /*         Input (Variable),            */
102 	 0x75, 0x01,                  /*         Report Size (1),             */
103 	 0x95, 0x03,                  /*         Report Count (3),            */
104 	 0x81, 0x03,                  /*         Input (Constant, Variable),  */
105 	 0x05, 0x01,                  /*         Usage Page (Desktop),        */
106 	 0x26, 0x44, 0x0A,            /*         Logical Maximum (2628),      */
107 	 0x75, 0x10,                  /*         Report Size (16),            */
108 	 0x55, 0x0E,                  /*         Unit Exponent (14),          */
109 	 0x65, 0x11,                  /*         Unit (Centimeter),           */
110 	 0x09, 0x30,                  /*         Usage (X),                   */
111 	 0x46, 0x1A, 0x04,            /*         Physical Maximum (1050),     */
112 	 0x95, 0x01,                  /*         Report Count (1),            */
113 	 0x81, 0x02,                  /*         Input (Variable),            */
114 	 0x46, 0xBC, 0x02,            /*         Physical Maximum (700),      */
115 	 0x26, 0x34, 0x05,            /*         Logical Maximum (1332),      */
116 	 0x09, 0x31,                  /*         Usage (Y),                   */
117 	 0x81, 0x02,                  /*         Input (Variable),            */
118 	 0xC0,                        /*     End Collection,                  */
119 	 0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
120 	 0x09, 0x22,                  /*     Usage (Finger),                  */
121 	 0xA1, 0x02,                  /*     Collection (Logical),            */
122 	 0x25, 0x01,                  /*         Logical Maximum (1),         */
123 	 0x09, 0x47,                  /*         Usage (Touch Valid),         */
124 	 0x09, 0x42,                  /*         Usage (Tip Switch),          */
125 	 0x95, 0x02,                  /*         Report Count (2),            */
126 	 0x75, 0x01,                  /*         Report Size (1),             */
127 	 0x81, 0x02,                  /*         Input (Variable),            */
128 	 0x95, 0x01,                  /*         Report Count (1),            */
129 	 0x75, 0x03,                  /*         Report Size (3),             */
130 	 0x25, 0x05,                  /*         Logical Maximum (5),         */
131 	 0x09, 0x51,                  /*         Usage (Contact Identifier),  */
132 	 0x81, 0x02,                  /*         Input (Variable),            */
133 	 0x75, 0x01,                  /*         Report Size (1),             */
134 	 0x95, 0x03,                  /*         Report Count (3),            */
135 	 0x81, 0x03,                  /*         Input (Constant, Variable),  */
136 	 0x05, 0x01,                  /*         Usage Page (Desktop),        */
137 	 0x26, 0x44, 0x0A,            /*         Logical Maximum (2628),      */
138 	 0x75, 0x10,                  /*         Report Size (16),            */
139 	 0x09, 0x30,                  /*         Usage (X),                   */
140 	 0x46, 0x1A, 0x04,            /*         Physical Maximum (1050),     */
141 	 0x95, 0x01,                  /*         Report Count (1),            */
142 	 0x81, 0x02,                  /*         Input (Variable),            */
143 	 0x46, 0xBC, 0x02,            /*         Physical Maximum (700),      */
144 	 0x26, 0x34, 0x05,            /*         Logical Maximum (1332),      */
145 	 0x09, 0x31,                  /*         Usage (Y),                   */
146 	 0x81, 0x02,                  /*         Input (Variable),            */
147 	 0xC0,                        /*     End Collection,                  */
148 	 0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
149 	 0x09, 0x22,                  /*     Usage (Finger),                  */
150 	 0xA1, 0x02,                  /*     Collection (Logical),            */
151 	 0x25, 0x01,                  /*         Logical Maximum (1),         */
152 	 0x09, 0x47,                  /*         Usage (Touch Valid),         */
153 	 0x09, 0x42,                  /*         Usage (Tip Switch),          */
154 	 0x95, 0x02,                  /*         Report Count (2),            */
155 	 0x75, 0x01,                  /*         Report Size (1),             */
156 	 0x81, 0x02,                  /*         Input (Variable),            */
157 	 0x95, 0x01,                  /*         Report Count (1),            */
158 	 0x75, 0x03,                  /*         Report Size (3),             */
159 	 0x25, 0x05,                  /*         Logical Maximum (5),         */
160 	 0x09, 0x51,                  /*         Usage (Contact Identifier),  */
161 	 0x81, 0x02,                  /*         Input (Variable),            */
162 	 0x75, 0x01,                  /*         Report Size (1),             */
163 	 0x95, 0x03,                  /*         Report Count (3),            */
164 	 0x81, 0x03,                  /*         Input (Constant, Variable),  */
165 	 0x05, 0x01,                  /*         Usage Page (Desktop),        */
166 	 0x26, 0x44, 0x0A,            /*         Logical Maximum (2628),      */
167 	 0x75, 0x10,                  /*         Report Size (16),            */
168 	 0x09, 0x30,                  /*         Usage (X),                   */
169 	 0x46, 0x1A, 0x04,            /*         Physical Maximum (1050),     */
170 	 0x95, 0x01,                  /*         Report Count (1),            */
171 	 0x81, 0x02,                  /*         Input (Variable),            */
172 	 0x46, 0xBC, 0x02,            /*         Physical Maximum (700),      */
173 	 0x26, 0x34, 0x05,            /*         Logical Maximum (1332),      */
174 	 0x09, 0x31,                  /*         Usage (Y),                   */
175 	 0x81, 0x02,                  /*         Input (Variable),            */
176 	 0xC0,                        /*     End Collection,                  */
177 	 0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
178 	 0x09, 0x22,                  /*     Usage (Finger),                  */
179 	 0xA1, 0x02,                  /*     Collection (Logical),            */
180 	 0x25, 0x01,                  /*         Logical Maximum (1),         */
181 	 0x09, 0x47,                  /*         Usage (Touch Valid),         */
182 	 0x09, 0x42,                  /*         Usage (Tip Switch),          */
183 	 0x95, 0x02,                  /*         Report Count (2),            */
184 	 0x75, 0x01,                  /*         Report Size (1),             */
185 	 0x81, 0x02,                  /*         Input (Variable),            */
186 	 0x95, 0x01,                  /*         Report Count (1),            */
187 	 0x75, 0x03,                  /*         Report Size (3),             */
188 	 0x25, 0x05,                  /*         Logical Maximum (5),         */
189 	 0x09, 0x51,                  /*         Usage (Contact Identifier),  */
190 	 0x81, 0x02,                  /*         Input (Variable),            */
191 	 0x75, 0x01,                  /*         Report Size (1),             */
192 	 0x95, 0x03,                  /*         Report Count (3),            */
193 	 0x81, 0x03,                  /*         Input (Constant, Variable),  */
194 	 0x05, 0x01,                  /*         Usage Page (Desktop),        */
195 	 0x26, 0x44, 0x0A,            /*         Logical Maximum (2628),      */
196 	 0x75, 0x10,                  /*         Report Size (16),            */
197 	 0x09, 0x30,                  /*         Usage (X),                   */
198 	 0x46, 0x1A, 0x04,            /*         Physical Maximum (1050),     */
199 	 0x95, 0x01,                  /*         Report Count (1),            */
200 	 0x81, 0x02,                  /*         Input (Variable),            */
201 	 0x46, 0xBC, 0x02,            /*         Physical Maximum (700),      */
202 	 0x26, 0x34, 0x05,            /*         Logical Maximum (1332),      */
203 	 0x09, 0x31,                  /*         Usage (Y),                   */
204 	 0x81, 0x02,                  /*         Input (Variable),            */
205 	 0xC0,                        /*     End Collection,                  */
206 	 0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
207 	 0x55, 0x0C,                  /*     Unit Exponent (12),              */
208 	 0x66, 0x01, 0x10,            /*     Unit (Seconds),                  */
209 	 0x47, 0xFF, 0xFF, 0x00, 0x00,/*     Physical Maximum (65535),        */
210 	 0x27, 0xFF, 0xFF, 0x00, 0x00,/*     Logical Maximum (65535),         */
211 	 0x75, 0x10,                  /*     Report Size (16),                */
212 	 0x95, 0x01,                  /*     Report Count (1),                */
213 	 0x09, 0x56,                  /*     Usage (Scan Time),               */
214 	 0x81, 0x02,                  /*     Input (Variable),                */
215 	 0x09, 0x54,                  /*     Usage (Contact Count),           */
216 	 0x25, 0x7F,                  /*     Logical Maximum (127),           */
217 	 0x75, 0x08,                  /*     Report Size (8),                 */
218 	 0x81, 0x02,                  /*     Input (Variable),                */
219 	 0x05, 0x09,                  /*     Usage Page (Button),             */
220 	 0x09, 0x01,                  /*     Usage (01h),                     */
221 	 0x25, 0x01,                  /*     Logical Maximum (1),             */
222 	 0x75, 0x01,                  /*     Report Size (1),                 */
223 	 0x95, 0x01,                  /*     Report Count (1),                */
224 	 0x81, 0x02,                  /*     Input (Variable),                */
225 	 0x95, 0x07,                  /*     Report Count (7),                */
226 	 0x81, 0x03,                  /*     Input (Constant, Variable),      */
227 	 0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
228 	 0x85, 0x02,                  /*     Report ID (2),                   */
229 	 0x09, 0x55,                  /*     Usage (Contact Count Maximum),   */
230 	 0x09, 0x59,                  /*     Usage (59h),                     */
231 	 0x75, 0x04,                  /*     Report Size (4),                 */
232 	 0x95, 0x02,                  /*     Report Count (2),                */
233 	 0x25, 0x0F,                  /*     Logical Maximum (15),            */
234 	 0xB1, 0x02,                  /*     Feature (Variable),              */
235 	 0x05, 0x0D,                  /*     Usage Page (Digitizer),          */
236 	 0x85, 0x07,                  /*     Report ID (7),                   */
237 	 0x09, 0x60,                  /*     Usage (60h),                     */
238 	 0x75, 0x01,                  /*     Report Size (1),                 */
239 	 0x95, 0x01,                  /*     Report Count (1),                */
240 	 0x25, 0x01,                  /*     Logical Maximum (1),             */
241 	 0xB1, 0x02,                  /*     Feature (Variable),              */
242 	 0x95, 0x07,                  /*     Report Count (7),                */
243 	 0xB1, 0x03,                  /*     Feature (Constant, Variable),    */
244 	 0x85, 0x06,                  /*     Report ID (6),                   */
245 	 0x06, 0x00, 0xFF,            /*     Usage Page (FF00h),              */
246 	 0x09, 0xC5,                  /*     Usage (C5h),                     */
247 	 0x26, 0xFF, 0x00,            /*     Logical Maximum (255),           */
248 	 0x75, 0x08,                  /*     Report Size (8),                 */
249 	 0x96, 0x00, 0x01,            /*     Report Count (256),              */
250 	 0xB1, 0x02,                  /*     Feature (Variable),              */
251 	 0xC0,                        /* End Collection,                      */
252 	 0x06, 0x00, 0xFF,            /* Usage Page (FF00h),                  */
253 	 0x09, 0x01,                  /* Usage (01h),                         */
254 	 0xA1, 0x01,                  /* Collection (Application),            */
255 	 0x85, 0x0D,                  /*     Report ID (13),                  */
256 	 0x26, 0xFF, 0x00,            /*     Logical Maximum (255),           */
257 	 0x19, 0x01,                  /*     Usage Minimum (01h),             */
258 	 0x29, 0x02,                  /*     Usage Maximum (02h),             */
259 	 0x75, 0x08,                  /*     Report Size (8),                 */
260 	 0x95, 0x02,                  /*     Report Count (2),                */
261 	 0xB1, 0x02,                  /*     Feature (Variable),              */
262 	 0xC0,                        /* End Collection,                      */
263 	 0x05, 0x0D,                  /* Usage Page (Digitizer),              */
264 	 0x09, 0x0E,                  /* Usage (Configuration),               */
265 	 0xA1, 0x01,                  /* Collection (Application),            */
266 	 0x85, 0x03,                  /*     Report ID (3),                   */
267 	 0x09, 0x22,                  /*     Usage (Finger),                  */
268 	 0xA1, 0x02,                  /*     Collection (Logical),            */
269 	 0x09, 0x52,                  /*         Usage (Device Mode),         */
270 	 0x25, 0x0A,                  /*         Logical Maximum (10),        */
271 	 0x95, 0x01,                  /*         Report Count (1),            */
272 	 0xB1, 0x02,                  /*         Feature (Variable),          */
273 	 0xC0,                        /*     End Collection,                  */
274 	 0x09, 0x22,                  /*     Usage (Finger),                  */
275 	 0xA1, 0x00,                  /*     Collection (Physical),           */
276 	 0x85, 0x05,                  /*         Report ID (5),               */
277 	 0x09, 0x57,                  /*         Usage (57h),                 */
278 	 0x09, 0x58,                  /*         Usage (58h),                 */
279 	 0x75, 0x01,                  /*         Report Size (1),             */
280 	 0x95, 0x02,                  /*         Report Count (2),            */
281 	 0x25, 0x01,                  /*         Logical Maximum (1),         */
282 	 0xB1, 0x02,                  /*         Feature (Variable),          */
283 	 0x95, 0x06,                  /*         Report Count (6),            */
284 	 0xB1, 0x03,                  /*         Feature (Constant, Variable),*/
285 	 0xC0,                        /*     End Collection,                  */
286 	 0xC0                         /* End Collection                       */
287 	},
288 	.hid_report_desc_size = 475,
289 	.i2c_name = "SYNA3602:00"
290 };
291 
292 
293 static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
294 	{
295 		.ident = "Teclast F6 Pro",
296 		.matches = {
297 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TECLAST"),
298 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "F6 Pro"),
299 		},
300 		.driver_data = (void *)&sipodev_desc
301 	},
302 	{
303 		.ident = "Teclast F7",
304 		.matches = {
305 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TECLAST"),
306 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "F7"),
307 		},
308 		.driver_data = (void *)&sipodev_desc
309 	},
310 	{
311 		.ident = "Trekstor Primebook C13",
312 		.matches = {
313 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
314 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
315 		},
316 		.driver_data = (void *)&sipodev_desc
317 	},
318 	{
319 		.ident = "Trekstor Primebook C11",
320 		.matches = {
321 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
322 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11"),
323 		},
324 		.driver_data = (void *)&sipodev_desc
325 	},
326 	{
327 		/*
328 		 * There are at least 2 Primebook C11B versions, the older
329 		 * version has a product-name of "Primebook C11B", and a
330 		 * bios version / release / firmware revision of:
331 		 * V2.1.2 / 05/03/2018 / 18.2
332 		 * The new version has "PRIMEBOOK C11B" as product-name and a
333 		 * bios version / release / firmware revision of:
334 		 * CFALKSW05_BIOS_V1.1.2 / 11/19/2018 / 19.2
335 		 * Only the older version needs this quirk, note the newer
336 		 * version will not match as it has a different product-name.
337 		 */
338 		.ident = "Trekstor Primebook C11B",
339 		.matches = {
340 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
341 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11B"),
342 		},
343 		.driver_data = (void *)&sipodev_desc
344 	},
345 	{
346 		.ident = "Trekstor SURFBOOK E11B",
347 		.matches = {
348 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
349 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"),
350 		},
351 		.driver_data = (void *)&sipodev_desc
352 	},
353 	{
354 		.ident = "Direkt-Tek DTLAPY116-2",
355 		.matches = {
356 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"),
357 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "DTLAPY116-2"),
358 		},
359 		.driver_data = (void *)&sipodev_desc
360 	},
361 	{
362 		.ident = "Direkt-Tek DTLAPY133-1",
363 		.matches = {
364 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"),
365 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "DTLAPY133-1"),
366 		},
367 		.driver_data = (void *)&sipodev_desc
368 	},
369 	{
370 		.ident = "Mediacom Flexbook Edge 11",
371 		.matches = {
372 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"),
373 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FlexBook edge11 - M-FBE11"),
374 		},
375 		.driver_data = (void *)&sipodev_desc
376 	},
377 	{
378 		.ident = "Mediacom FlexBook edge 13",
379 		.matches = {
380 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"),
381 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FlexBook_edge13-M-FBE13"),
382 		},
383 		.driver_data = (void *)&sipodev_desc
384 	},
385 	{
386 		.ident = "Odys Winbook 13",
387 		.matches = {
388 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AXDIA International GmbH"),
389 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "WINBOOK 13"),
390 		},
391 		.driver_data = (void *)&sipodev_desc
392 	},
393 	{
394 		.ident = "iBall Aer3",
395 		.matches = {
396 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "iBall"),
397 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Aer3"),
398 		},
399 		.driver_data = (void *)&sipodev_desc
400 	},
401 	{
402 		.ident = "Schneider SCL142ALM",
403 		.matches = {
404 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SCHNEIDER"),
405 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SCL142ALM"),
406 		},
407 		.driver_data = (void *)&sipodev_desc
408 	},
409 	{
410 		.ident = "Vero K147",
411 		.matches = {
412 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VERO"),
413 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "K147"),
414 		},
415 		.driver_data = (void *)&sipodev_desc
416 	},
417 	{ }	/* Terminate list */
418 };
419 
420 static const struct hid_device_id i2c_hid_elan_flipped_quirks = {
421 	HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_ELAN, 0x2dcd),
422 		HID_QUIRK_X_INVERT | HID_QUIRK_Y_INVERT
423 };
424 
425 /*
426  * This list contains devices which have specific issues based on the system
427  * they're on and not just the device itself. The driver_data will have a
428  * specific hid device to match against.
429  */
430 static const struct dmi_system_id i2c_hid_dmi_quirk_table[] = {
431 	{
432 		.ident = "DynaBook K50/FR",
433 		.matches = {
434 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dynabook Inc."),
435 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "dynabook K50/FR"),
436 		},
437 		.driver_data = (void *)&i2c_hid_elan_flipped_quirks,
438 	},
439 	{ }	/* Terminate list */
440 };
441 
442 
i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t * i2c_name)443 struct i2c_hid_desc *i2c_hid_get_dmi_i2c_hid_desc_override(uint8_t *i2c_name)
444 {
445 	struct i2c_hid_desc_override *override;
446 	const struct dmi_system_id *system_id;
447 
448 	system_id = dmi_first_match(i2c_hid_dmi_desc_override_table);
449 	if (!system_id)
450 		return NULL;
451 
452 	override = system_id->driver_data;
453 	if (strcmp(override->i2c_name, i2c_name))
454 		return NULL;
455 
456 	return override->i2c_hid_desc;
457 }
458 
i2c_hid_get_dmi_hid_report_desc_override(uint8_t * i2c_name,unsigned int * size)459 char *i2c_hid_get_dmi_hid_report_desc_override(uint8_t *i2c_name,
460 					       unsigned int *size)
461 {
462 	struct i2c_hid_desc_override *override;
463 	const struct dmi_system_id *system_id;
464 
465 	system_id = dmi_first_match(i2c_hid_dmi_desc_override_table);
466 	if (!system_id)
467 		return NULL;
468 
469 	override = system_id->driver_data;
470 	if (strcmp(override->i2c_name, i2c_name))
471 		return NULL;
472 
473 	*size = override->hid_report_desc_size;
474 	return override->hid_report_desc;
475 }
476 
i2c_hid_get_dmi_quirks(const u16 vendor,const u16 product)477 u32 i2c_hid_get_dmi_quirks(const u16 vendor, const u16 product)
478 {
479 	u32 quirks = 0;
480 	const struct dmi_system_id *system_id =
481 			dmi_first_match(i2c_hid_dmi_quirk_table);
482 
483 	if (system_id) {
484 		const struct hid_device_id *device_id =
485 				(struct hid_device_id *)(system_id->driver_data);
486 
487 		if (device_id && device_id->vendor == vendor &&
488 		    device_id->product == product)
489 			quirks = device_id->driver_data;
490 	}
491 
492 	return quirks;
493 }
494