1 /*
2  * Touchscreen driver DMI based configuration code
3  *
4  * Copyright (c) 2017 Red Hat Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Red Hat authors:
12  * Hans de Goede <hdegoede@redhat.com>
13  */
14 
15 #include <linux/acpi.h>
16 #include <linux/device.h>
17 #include <linux/dmi.h>
18 #include <linux/i2c.h>
19 #include <linux/notifier.h>
20 #include <linux/property.h>
21 #include <linux/string.h>
22 
23 struct ts_dmi_data {
24 	const char *acpi_name;
25 	const struct property_entry *properties;
26 };
27 
28 /* NOTE: Please keep all entries sorted alphabetically */
29 
30 static const struct property_entry chuwi_hi8_props[] = {
31 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
32 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
33 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
34 	PROPERTY_ENTRY_BOOL("silead,home-button"),
35 	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"),
36 	{ }
37 };
38 
39 static const struct ts_dmi_data chuwi_hi8_data = {
40 	.acpi_name      = "MSSL0001:00",
41 	.properties     = chuwi_hi8_props,
42 };
43 
44 static const struct property_entry chuwi_hi8_air_props[] = {
45 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
46 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
47 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
48 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-hi8-air.fw"),
49 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
50 	{ }
51 };
52 
53 static const struct ts_dmi_data chuwi_hi8_air_data = {
54 	.acpi_name	= "MSSL1680:00",
55 	.properties	= chuwi_hi8_air_props,
56 };
57 
58 static const struct property_entry chuwi_hi8_pro_props[] = {
59 	PROPERTY_ENTRY_U32("touchscreen-min-x", 6),
60 	PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
61 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
62 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
63 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
64 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-hi8-pro.fw"),
65 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
66 	PROPERTY_ENTRY_BOOL("silead,home-button"),
67 	{ }
68 };
69 
70 static const struct ts_dmi_data chuwi_hi8_pro_data = {
71 	.acpi_name	= "MSSL1680:00",
72 	.properties	= chuwi_hi8_pro_props,
73 };
74 
75 static const struct property_entry chuwi_hi10_air_props[] = {
76 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1981),
77 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1271),
78 	PROPERTY_ENTRY_U32("touchscreen-min-x", 99),
79 	PROPERTY_ENTRY_U32("touchscreen-min-y", 9),
80 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
81 	PROPERTY_ENTRY_U32("touchscreen-fuzz-x", 5),
82 	PROPERTY_ENTRY_U32("touchscreen-fuzz-y", 4),
83 	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10-air.fw"),
84 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
85 	PROPERTY_ENTRY_BOOL("silead,home-button"),
86 	{ }
87 };
88 
89 static const struct ts_dmi_data chuwi_hi10_air_data = {
90 	.acpi_name	= "MSSL1680:00",
91 	.properties	= chuwi_hi10_air_props,
92 };
93 
94 static const struct property_entry chuwi_vi8_props[] = {
95 	PROPERTY_ENTRY_U32("touchscreen-min-x", 4),
96 	PROPERTY_ENTRY_U32("touchscreen-min-y", 6),
97 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1724),
98 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
99 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
100 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-vi8.fw"),
101 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
102 	PROPERTY_ENTRY_BOOL("silead,home-button"),
103 	{ }
104 };
105 
106 static const struct ts_dmi_data chuwi_vi8_data = {
107 	.acpi_name      = "MSSL1680:00",
108 	.properties     = chuwi_vi8_props,
109 };
110 
111 static const struct property_entry chuwi_vi10_props[] = {
112 	PROPERTY_ENTRY_U32("touchscreen-min-x", 0),
113 	PROPERTY_ENTRY_U32("touchscreen-min-y", 4),
114 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1858),
115 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
116 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-vi10.fw"),
117 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
118 	PROPERTY_ENTRY_BOOL("silead,home-button"),
119 	{ }
120 };
121 
122 static const struct ts_dmi_data chuwi_vi10_data = {
123 	.acpi_name      = "MSSL0002:00",
124 	.properties     = chuwi_vi10_props,
125 };
126 
127 static const struct property_entry connect_tablet9_props[] = {
128 	PROPERTY_ENTRY_U32("touchscreen-min-x", 9),
129 	PROPERTY_ENTRY_U32("touchscreen-min-y", 10),
130 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1664),
131 	PROPERTY_ENTRY_U32("touchscreen-size-y", 880),
132 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
133 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
134 	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-connect-tablet9.fw"),
135 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
136 	{ }
137 };
138 
139 static const struct ts_dmi_data connect_tablet9_data = {
140 	.acpi_name      = "MSSL1680:00",
141 	.properties     = connect_tablet9_props,
142 };
143 
144 static const struct property_entry cube_iwork8_air_props[] = {
145 	PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
146 	PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
147 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1664),
148 	PROPERTY_ENTRY_U32("touchscreen-size-y", 896),
149 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
150 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-cube-iwork8-air.fw"),
151 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
152 	{ }
153 };
154 
155 static const struct ts_dmi_data cube_iwork8_air_data = {
156 	.acpi_name	= "MSSL1680:00",
157 	.properties	= cube_iwork8_air_props,
158 };
159 
160 static const struct property_entry cube_knote_i1101_props[] = {
161 	PROPERTY_ENTRY_U32("touchscreen-min-x", 20),
162 	PROPERTY_ENTRY_U32("touchscreen-min-y",  22),
163 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1961),
164 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1513),
165 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-cube-knote-i1101.fw"),
166 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
167 	PROPERTY_ENTRY_BOOL("silead,home-button"),
168 	{ }
169 };
170 
171 static const struct ts_dmi_data cube_knote_i1101_data = {
172 	.acpi_name	= "MSSL1680:00",
173 	.properties	= cube_knote_i1101_props,
174 };
175 
176 static const struct property_entry dexp_ursus_7w_props[] = {
177 	PROPERTY_ENTRY_U32("touchscreen-size-x", 890),
178 	PROPERTY_ENTRY_U32("touchscreen-size-y", 630),
179 	PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-dexp-ursus-7w.fw"),
180 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
181 	PROPERTY_ENTRY_BOOL("silead,home-button"),
182 	{ }
183 };
184 
185 static const struct ts_dmi_data dexp_ursus_7w_data = {
186 	.acpi_name	= "MSSL1680:00",
187 	.properties	= dexp_ursus_7w_props,
188 };
189 
190 static const struct property_entry digma_citi_e200_props[] = {
191 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
192 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
193 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
194 	PROPERTY_ENTRY_STRING("firmware-name",
195 			      "gsl1686-digma_citi_e200.fw"),
196 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
197 	PROPERTY_ENTRY_BOOL("silead,home-button"),
198 	{ }
199 };
200 
201 static const struct ts_dmi_data digma_citi_e200_data = {
202 	.acpi_name	= "MSSL1680:00",
203 	.properties	= digma_citi_e200_props,
204 };
205 
206 static const struct property_entry gp_electronic_t701_props[] = {
207 	PROPERTY_ENTRY_U32("touchscreen-size-x", 960),
208 	PROPERTY_ENTRY_U32("touchscreen-size-y", 640),
209 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
210 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
211 	PROPERTY_ENTRY_STRING("firmware-name",
212 			      "gsl1680-gp-electronic-t701.fw"),
213 	{ }
214 };
215 
216 static const struct ts_dmi_data gp_electronic_t701_data = {
217 	.acpi_name	= "MSSL1680:00",
218 	.properties	= gp_electronic_t701_props,
219 };
220 
221 static const struct property_entry itworks_tw891_props[] = {
222 	PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
223 	PROPERTY_ENTRY_U32("touchscreen-min-y", 5),
224 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
225 	PROPERTY_ENTRY_U32("touchscreen-size-y", 896),
226 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
227 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
228 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-itworks-tw891.fw"),
229 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
230 	{ }
231 };
232 
233 static const struct ts_dmi_data itworks_tw891_data = {
234 	.acpi_name	= "MSSL1680:00",
235 	.properties	= itworks_tw891_props,
236 };
237 
238 static const struct property_entry jumper_ezpad_6_pro_props[] = {
239 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
240 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
241 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro.fw"),
242 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
243 	PROPERTY_ENTRY_BOOL("silead,home-button"),
244 	{ }
245 };
246 
247 static const struct ts_dmi_data jumper_ezpad_6_pro_data = {
248 	.acpi_name	= "MSSL1680:00",
249 	.properties	= jumper_ezpad_6_pro_props,
250 };
251 
252 static const struct property_entry jumper_ezpad_6_pro_b_props[] = {
253 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
254 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
255 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro-b.fw"),
256 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
257 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
258 	PROPERTY_ENTRY_BOOL("silead,home-button"),
259 	{ }
260 };
261 
262 static const struct ts_dmi_data jumper_ezpad_6_pro_b_data = {
263 	.acpi_name      = "MSSL1680:00",
264 	.properties     = jumper_ezpad_6_pro_b_props,
265 };
266 
267 static const struct property_entry jumper_ezpad_mini3_props[] = {
268 	PROPERTY_ENTRY_U32("touchscreen-min-x", 23),
269 	PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
270 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1700),
271 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1138),
272 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
273 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-jumper-ezpad-mini3.fw"),
274 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
275 	{ }
276 };
277 
278 static const struct ts_dmi_data jumper_ezpad_mini3_data = {
279 	.acpi_name	= "MSSL1680:00",
280 	.properties	= jumper_ezpad_mini3_props,
281 };
282 
283 static const struct property_entry myria_my8307_props[] = {
284 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1720),
285 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
286 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
287 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
288 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
289 	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-myria-my8307.fw"),
290 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
291 	PROPERTY_ENTRY_BOOL("silead,home-button"),
292 	{ }
293 };
294 
295 static const struct ts_dmi_data myria_my8307_data = {
296 	.acpi_name	= "MSSL1680:00",
297 	.properties	= myria_my8307_props,
298 };
299 
300 static const struct property_entry onda_obook_20_plus_props[] = {
301 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
302 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
303 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
304 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
305 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
306 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-obook-20-plus.fw"),
307 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
308 	PROPERTY_ENTRY_BOOL("silead,home-button"),
309 	{ }
310 };
311 
312 static const struct ts_dmi_data onda_obook_20_plus_data = {
313 	.acpi_name	= "MSSL1680:00",
314 	.properties	= onda_obook_20_plus_props,
315 };
316 
317 static const struct property_entry onda_v80_plus_v3_props[] = {
318 	PROPERTY_ENTRY_U32("touchscreen-min-x", 22),
319 	PROPERTY_ENTRY_U32("touchscreen-min-y", 15),
320 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1698),
321 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
322 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
323 	PROPERTY_ENTRY_STRING("firmware-name",
324 			      "gsl3676-onda-v80-plus-v3.fw"),
325 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
326 	PROPERTY_ENTRY_BOOL("silead,home-button"),
327 	{ }
328 };
329 
330 static const struct ts_dmi_data onda_v80_plus_v3_data = {
331 	.acpi_name	= "MSSL1680:00",
332 	.properties	= onda_v80_plus_v3_props,
333 };
334 
335 static const struct property_entry onda_v820w_32g_props[] = {
336 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
337 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
338 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
339 	PROPERTY_ENTRY_STRING("firmware-name",
340 			      "gsl1680-onda-v820w-32g.fw"),
341 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
342 	PROPERTY_ENTRY_BOOL("silead,home-button"),
343 	{ }
344 };
345 
346 static const struct ts_dmi_data onda_v820w_32g_data = {
347 	.acpi_name	= "MSSL1680:00",
348 	.properties	= onda_v820w_32g_props,
349 };
350 
351 static const struct property_entry onda_v891w_v1_props[] = {
352 	PROPERTY_ENTRY_U32("touchscreen-min-x", 46),
353 	PROPERTY_ENTRY_U32("touchscreen-min-y",  8),
354 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1676),
355 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1130),
356 	PROPERTY_ENTRY_STRING("firmware-name",
357 			      "gsl3680-onda-v891w-v1.fw"),
358 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
359 	PROPERTY_ENTRY_BOOL("silead,home-button"),
360 	{ }
361 };
362 
363 static const struct ts_dmi_data onda_v891w_v1_data = {
364 	.acpi_name	= "MSSL1680:00",
365 	.properties	= onda_v891w_v1_props,
366 };
367 
368 static const struct property_entry onda_v891w_v3_props[] = {
369 	PROPERTY_ENTRY_U32("touchscreen-min-x", 35),
370 	PROPERTY_ENTRY_U32("touchscreen-min-y", 15),
371 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1625),
372 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1135),
373 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
374 	PROPERTY_ENTRY_STRING("firmware-name",
375 			      "gsl3676-onda-v891w-v3.fw"),
376 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
377 	PROPERTY_ENTRY_BOOL("silead,home-button"),
378 	{ }
379 };
380 
381 static const struct ts_dmi_data onda_v891w_v3_data = {
382 	.acpi_name	= "MSSL1680:00",
383 	.properties	= onda_v891w_v3_props,
384 };
385 
386 static const struct property_entry pipo_w2s_props[] = {
387 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
388 	PROPERTY_ENTRY_U32("touchscreen-size-y", 880),
389 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
390 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
391 	PROPERTY_ENTRY_STRING("firmware-name",
392 			      "gsl1680-pipo-w2s.fw"),
393 	{ }
394 };
395 
396 static const struct ts_dmi_data pipo_w2s_data = {
397 	.acpi_name	= "MSSL1680:00",
398 	.properties	= pipo_w2s_props,
399 };
400 
401 static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = {
402 	PROPERTY_ENTRY_U32("touchscreen-min-x", 32),
403 	PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
404 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1692),
405 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1146),
406 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
407 	PROPERTY_ENTRY_STRING("firmware-name",
408 			      "gsl3680-pov-mobii-wintab-p800w-v20.fw"),
409 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
410 	PROPERTY_ENTRY_BOOL("silead,home-button"),
411 	{ }
412 };
413 
414 static const struct ts_dmi_data pov_mobii_wintab_p800w_v20_data = {
415 	.acpi_name	= "MSSL1680:00",
416 	.properties	= pov_mobii_wintab_p800w_v20_props,
417 };
418 
419 static const struct property_entry pov_mobii_wintab_p800w_v21_props[] = {
420 	PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
421 	PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
422 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1794),
423 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
424 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
425 	PROPERTY_ENTRY_STRING("firmware-name",
426 			      "gsl3692-pov-mobii-wintab-p800w.fw"),
427 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
428 	PROPERTY_ENTRY_BOOL("silead,home-button"),
429 	{ }
430 };
431 
432 static const struct ts_dmi_data pov_mobii_wintab_p800w_v21_data = {
433 	.acpi_name	= "MSSL1680:00",
434 	.properties	= pov_mobii_wintab_p800w_v21_props,
435 };
436 
437 static const struct property_entry pov_mobii_wintab_p1006w_v10_props[] = {
438 	PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
439 	PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
440 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1984),
441 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1520),
442 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
443 	PROPERTY_ENTRY_STRING("firmware-name",
444 			      "gsl3692-pov-mobii-wintab-p1006w-v10.fw"),
445 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
446 	PROPERTY_ENTRY_BOOL("silead,home-button"),
447 	{ }
448 };
449 
450 static const struct ts_dmi_data pov_mobii_wintab_p1006w_v10_data = {
451 	.acpi_name	= "MSSL1680:00",
452 	.properties	= pov_mobii_wintab_p1006w_v10_props,
453 };
454 
455 static const struct property_entry teclast_x3_plus_props[] = {
456 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
457 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
458 	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-teclast-x3-plus.fw"),
459 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
460 	PROPERTY_ENTRY_BOOL("silead,home-button"),
461 	{ }
462 };
463 
464 static const struct ts_dmi_data teclast_x3_plus_data = {
465 	.acpi_name	= "MSSL1680:00",
466 	.properties	= teclast_x3_plus_props,
467 };
468 
469 static const struct property_entry teclast_x98plus2_props[] = {
470 	PROPERTY_ENTRY_U32("touchscreen-size-x", 2048),
471 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
472 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
473 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
474 	PROPERTY_ENTRY_STRING("firmware-name",
475 			      "gsl1686-teclast_x98plus2.fw"),
476 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
477 	{ }
478 };
479 
480 static const struct ts_dmi_data teclast_x98plus2_data = {
481 	.acpi_name	= "MSSL1680:00",
482 	.properties	= teclast_x98plus2_props,
483 };
484 
485 static const struct property_entry trekstor_primebook_c11_props[] = {
486 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1970),
487 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1530),
488 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
489 	PROPERTY_ENTRY_STRING("firmware-name",
490 			      "gsl1680-trekstor-primebook-c11.fw"),
491 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
492 	PROPERTY_ENTRY_BOOL("silead,home-button"),
493 	{ }
494 };
495 
496 static const struct ts_dmi_data trekstor_primebook_c11_data = {
497 	.acpi_name	= "MSSL1680:00",
498 	.properties	= trekstor_primebook_c11_props,
499 };
500 
501 static const struct property_entry trekstor_primebook_c13_props[] = {
502 	PROPERTY_ENTRY_U32("touchscreen-size-x", 2624),
503 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
504 	PROPERTY_ENTRY_STRING("firmware-name",
505 			      "gsl1680-trekstor-primebook-c13.fw"),
506 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
507 	PROPERTY_ENTRY_BOOL("silead,home-button"),
508 	{ }
509 };
510 
511 static const struct ts_dmi_data trekstor_primebook_c13_data = {
512 	.acpi_name	= "MSSL1680:00",
513 	.properties	= trekstor_primebook_c13_props,
514 };
515 
516 static const struct property_entry trekstor_primetab_t13b_props[] = {
517 	PROPERTY_ENTRY_U32("touchscreen-size-x", 2500),
518 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1900),
519 	PROPERTY_ENTRY_STRING("firmware-name",
520 			      "gsl1680-trekstor-primetab-t13b.fw"),
521 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
522 	PROPERTY_ENTRY_BOOL("silead,home-button"),
523 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
524 	{ }
525 };
526 
527 static const struct ts_dmi_data trekstor_primetab_t13b_data = {
528 	.acpi_name  = "MSSL1680:00",
529 	.properties = trekstor_primetab_t13b_props,
530 };
531 
532 static const struct property_entry trekstor_surftab_twin_10_1_props[] = {
533 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1900),
534 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
535 	PROPERTY_ENTRY_U32("touchscreen-inverted-y", 1),
536 	PROPERTY_ENTRY_STRING("firmware-name",
537 			      "gsl3670-surftab-twin-10-1-st10432-8.fw"),
538 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
539 	{ }
540 };
541 
542 static const struct ts_dmi_data trekstor_surftab_twin_10_1_data = {
543 	.acpi_name	= "MSSL1680:00",
544 	.properties	= trekstor_surftab_twin_10_1_props,
545 };
546 
547 static const struct property_entry trekstor_surftab_wintron70_props[] = {
548 	PROPERTY_ENTRY_U32("touchscreen-min-x", 12),
549 	PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
550 	PROPERTY_ENTRY_U32("touchscreen-size-x", 884),
551 	PROPERTY_ENTRY_U32("touchscreen-size-y", 632),
552 	PROPERTY_ENTRY_STRING("firmware-name",
553 			      "gsl1686-surftab-wintron70-st70416-6.fw"),
554 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
555 	PROPERTY_ENTRY_BOOL("silead,home-button"),
556 	{ }
557 };
558 
559 static const struct ts_dmi_data trekstor_surftab_wintron70_data = {
560 	.acpi_name	= "MSSL1680:00",
561 	.properties	= trekstor_surftab_wintron70_props,
562 };
563 
564 /* NOTE: Please keep this table sorted alphabetically */
565 static const struct dmi_system_id touchscreen_dmi_table[] = {
566 	{
567 		/* Chuwi Hi8 */
568 		.driver_data = (void *)&chuwi_hi8_data,
569 		.matches = {
570 			DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
571 			DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
572 		},
573 	},
574 	{
575 		/* Chuwi Hi8 (H1D_S806_206) */
576 		.driver_data = (void *)&chuwi_hi8_data,
577 		.matches = {
578 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
579 			DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
580 			DMI_MATCH(DMI_BIOS_VERSION, "H1D_S806_206"),
581 		},
582 	},
583 	{
584 		/* Chuwi Hi8 Air (CWI543) */
585 		.driver_data = (void *)&chuwi_hi8_air_data,
586 		.matches = {
587 			DMI_MATCH(DMI_BOARD_VENDOR, "Default string"),
588 			DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
589 			DMI_MATCH(DMI_PRODUCT_NAME, "Hi8 Air"),
590 		},
591 	},
592 	{
593 		/* Chuwi Hi8 Pro (CWI513) */
594 		.driver_data = (void *)&chuwi_hi8_pro_data,
595 		.matches = {
596 			DMI_MATCH(DMI_SYS_VENDOR, "Hampoo"),
597 			DMI_MATCH(DMI_PRODUCT_NAME, "X1D3_C806N"),
598 		},
599 	},
600 	{
601 		/* Chuwi Hi10 Air */
602 		.driver_data = (void *)&chuwi_hi10_air_data,
603 		.matches = {
604 			DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
605 			DMI_MATCH(DMI_PRODUCT_SKU, "P1W6_C109D_B"),
606 		},
607 	},
608 	{
609 		/* Chuwi Vi8 (CWI506) */
610 		.driver_data = (void *)&chuwi_vi8_data,
611 		.matches = {
612 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
613 			DMI_MATCH(DMI_PRODUCT_NAME, "i86"),
614 			DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
615 		},
616 	},
617 	{
618 		/* Chuwi Vi10 (CWI505) */
619 		.driver_data = (void *)&chuwi_vi10_data,
620 		.matches = {
621 			DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
622 			DMI_MATCH(DMI_BOARD_NAME, "BYT-PF02"),
623 			DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
624 			DMI_MATCH(DMI_PRODUCT_NAME, "S165"),
625 		},
626 	},
627 	{
628 		/* Connect Tablet 9 */
629 		.driver_data = (void *)&connect_tablet9_data,
630 		.matches = {
631 			DMI_MATCH(DMI_SYS_VENDOR, "Connect"),
632 			DMI_MATCH(DMI_PRODUCT_NAME, "Tablet 9"),
633 		},
634 	},
635 	{
636 		/* CUBE iwork8 Air */
637 		.driver_data = (void *)&cube_iwork8_air_data,
638 		.matches = {
639 			DMI_MATCH(DMI_SYS_VENDOR, "cube"),
640 			DMI_MATCH(DMI_PRODUCT_NAME, "i1-TF"),
641 			DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
642 		},
643 	},
644 	{
645 		/* Cube KNote i1101 */
646 		.driver_data = (void *)&cube_knote_i1101_data,
647 		.matches = {
648 			DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
649 			DMI_MATCH(DMI_BOARD_NAME, "L1W6_I1101"),
650 			DMI_MATCH(DMI_SYS_VENDOR, "ALLDOCUBE"),
651 			DMI_MATCH(DMI_PRODUCT_NAME, "i1101"),
652 		},
653 	},
654 	{
655 		/* DEXP Ursus 7W */
656 		.driver_data = (void *)&dexp_ursus_7w_data,
657 		.matches = {
658 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
659 			DMI_MATCH(DMI_PRODUCT_NAME, "7W"),
660 		},
661 	},
662 	{
663 		/* Digma Citi E200 */
664 		.driver_data = (void *)&digma_citi_e200_data,
665 		.matches = {
666 			DMI_MATCH(DMI_SYS_VENDOR, "Digma"),
667 			DMI_MATCH(DMI_PRODUCT_NAME, "CITI E200"),
668 			DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
669 		},
670 	},
671 	{
672 		/* GP-electronic T701 */
673 		.driver_data = (void *)&gp_electronic_t701_data,
674 		.matches = {
675 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
676 			DMI_MATCH(DMI_PRODUCT_NAME, "T701"),
677 			DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
678 		},
679 	},
680 	{
681 		/* I.T.Works TW701 (same hardware as the Trekstor ST70416-6) */
682 		.driver_data = (void *)&trekstor_surftab_wintron70_data,
683 		.matches = {
684 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
685 			DMI_MATCH(DMI_PRODUCT_NAME, "i71c"),
686 			DMI_MATCH(DMI_BIOS_VERSION, "itWORKS.G.WI71C.JGBMRB"),
687 		},
688 	},
689 	{
690 		/* I.T.Works TW891 */
691 		.driver_data = (void *)&itworks_tw891_data,
692 		.matches = {
693 			DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
694 			DMI_MATCH(DMI_PRODUCT_NAME, "TW891"),
695 		},
696 	},
697 	{
698 		/* Jumper EZpad 6 Pro */
699 		.driver_data = (void *)&jumper_ezpad_6_pro_data,
700 		.matches = {
701 			DMI_MATCH(DMI_SYS_VENDOR, "Jumper"),
702 			DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"),
703 			DMI_MATCH(DMI_BIOS_VERSION, "5.12"),
704 			/* Above matches are too generic, add bios-date match */
705 			DMI_MATCH(DMI_BIOS_DATE, "08/18/2017"),
706 		},
707 	},
708 	{
709 		/* Jumper EZpad 6 Pro B */
710 		.driver_data = (void *)&jumper_ezpad_6_pro_b_data,
711 		.matches = {
712 			DMI_MATCH(DMI_SYS_VENDOR, "Jumper"),
713 			DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"),
714 			DMI_MATCH(DMI_BIOS_VERSION, "5.12"),
715 			/* Above matches are too generic, add bios-date match */
716 			DMI_MATCH(DMI_BIOS_DATE, "04/24/2018"),
717 		},
718 	},
719 	{
720 		/* Jumper EZpad mini3 */
721 		.driver_data = (void *)&jumper_ezpad_mini3_data,
722 		.matches = {
723 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
724 			/* jumperx.T87.KFBNEEA02 with the version-nr dropped */
725 			DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
726 		},
727 	},
728 	{
729 		/* Mediacom Flexbook Edge 11 (same hw as TS Primebook C11) */
730 		.driver_data = (void *)&trekstor_primebook_c11_data,
731 		.matches = {
732 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIACOM"),
733 			DMI_MATCH(DMI_PRODUCT_NAME, "FlexBook edge11 - M-FBE11"),
734 		},
735 	},
736 	{
737 		/* Myria MY8307 */
738 		.driver_data = (void *)&myria_my8307_data,
739 		.matches = {
740 			DMI_MATCH(DMI_SYS_VENDOR, "Complet Electro Serv"),
741 			DMI_MATCH(DMI_PRODUCT_NAME, "MY8307"),
742 		},
743 	},
744 	{
745 		/* Onda oBook 20 Plus */
746 		.driver_data = (void *)&onda_obook_20_plus_data,
747 		.matches = {
748 			DMI_MATCH(DMI_SYS_VENDOR, "ONDA"),
749 			DMI_MATCH(DMI_PRODUCT_NAME, "OBOOK 20 PLUS"),
750 		},
751 	},
752 	{
753 		/* ONDA V80 plus v3 (P80PSBG9V3A01501) */
754 		.driver_data = (void *)&onda_v80_plus_v3_data,
755 		.matches = {
756 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ONDA"),
757 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "V80 PLUS")
758 		},
759 	},
760 	{
761 		/* ONDA V820w DualOS */
762 		.driver_data = (void *)&onda_v820w_32g_data,
763 		.matches = {
764 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ONDA"),
765 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "V820w DualOS")
766 		},
767 	},
768 	{
769 		/* ONDA V891w revision P891WBEBV1B00 aka v1 */
770 		.driver_data = (void *)&onda_v891w_v1_data,
771 		.matches = {
772 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ONDA"),
773 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONDA Tablet"),
774 			DMI_EXACT_MATCH(DMI_BOARD_VERSION, "V001"),
775 			/* Exact match, different versions need different fw */
776 			DMI_EXACT_MATCH(DMI_BIOS_VERSION, "ONDA.W89EBBN08"),
777 		},
778 	},
779 	{
780 		/* ONDA V891w Dual OS P891DCF2V1A01274 64GB */
781 		.driver_data = (void *)&onda_v891w_v3_data,
782 		.matches = {
783 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
784 			DMI_MATCH(DMI_PRODUCT_NAME, "ONDA Tablet"),
785 			DMI_MATCH(DMI_BIOS_VERSION, "ONDA.D890HBBNR0A"),
786 		},
787 	},
788 	{
789 		/* Pipo W2S */
790 		.driver_data = (void *)&pipo_w2s_data,
791 		.matches = {
792 			DMI_MATCH(DMI_SYS_VENDOR, "PIPO"),
793 			DMI_MATCH(DMI_PRODUCT_NAME, "W2S"),
794 		},
795 	},
796 	{
797 		/* Ployer Momo7w (same hardware as the Trekstor ST70416-6) */
798 		.driver_data = (void *)&trekstor_surftab_wintron70_data,
799 		.matches = {
800 			DMI_MATCH(DMI_SYS_VENDOR, "Shenzhen PLOYER"),
801 			DMI_MATCH(DMI_PRODUCT_NAME, "MOMO7W"),
802 			/* Exact match, different versions need different fw */
803 			DMI_MATCH(DMI_BIOS_VERSION, "MOMO.G.WI71C.MABMRBA02"),
804 		},
805 	},
806 	{
807 		/* Point of View mobii wintab p800w (v2.0) */
808 		.driver_data = (void *)&pov_mobii_wintab_p800w_v20_data,
809 		.matches = {
810 			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
811 			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
812 			DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
813 			/* Above matches are too generic, add bios-date match */
814 			DMI_MATCH(DMI_BIOS_DATE, "10/24/2014"),
815 		},
816 	},
817 	{
818 		/* Point of View mobii wintab p800w (v2.1) */
819 		.driver_data = (void *)&pov_mobii_wintab_p800w_v21_data,
820 		.matches = {
821 			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
822 			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
823 			DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
824 			/* Above matches are too generic, add bios-date match */
825 			DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
826 		},
827 	},
828 	{
829 		/* Point of View mobii wintab p1006w (v1.0) */
830 		.driver_data = (void *)&pov_mobii_wintab_p1006w_v10_data,
831 		.matches = {
832 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
833 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
834 			/* Note 105b is Foxcon's USB/PCI vendor id */
835 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "105B"),
836 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"),
837 		},
838 	},
839 	{
840 		/* Teclast X3 Plus */
841 		.driver_data = (void *)&teclast_x3_plus_data,
842 		.matches = {
843 			DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
844 			DMI_MATCH(DMI_PRODUCT_NAME, "X3 Plus"),
845 			DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"),
846 		},
847 	},
848 	{
849 		/* Teclast X98 Plus II */
850 		.driver_data = (void *)&teclast_x98plus2_data,
851 		.matches = {
852 			DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
853 			DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
854 		},
855 	},
856 	{
857 		/* Trekstor Primebook C11 */
858 		.driver_data = (void *)&trekstor_primebook_c11_data,
859 		.matches = {
860 			DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
861 			DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C11"),
862 		},
863 	},
864 	{
865 		/* Trekstor Primebook C13 */
866 		.driver_data = (void *)&trekstor_primebook_c13_data,
867 		.matches = {
868 			DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
869 			DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
870 		},
871 	},
872 	{
873 		/* Trekstor Primetab T13B */
874 		.driver_data = (void *)&trekstor_primetab_t13b_data,
875 		.matches = {
876 			DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
877 			DMI_MATCH(DMI_PRODUCT_NAME, "Primetab T13B"),
878 		},
879 	},
880 	{
881 		/* TrekStor SurfTab twin 10.1 ST10432-8 */
882 		.driver_data = (void *)&trekstor_surftab_twin_10_1_data,
883 		.matches = {
884 			DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
885 			DMI_MATCH(DMI_PRODUCT_NAME, "SurfTab twin 10.1"),
886 		},
887 	},
888 	{
889 		/* Trekstor Surftab Wintron 7.0 ST70416-6 */
890 		.driver_data = (void *)&trekstor_surftab_wintron70_data,
891 		.matches = {
892 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
893 			DMI_MATCH(DMI_PRODUCT_NAME, "ST70416-6"),
894 			/* Exact match, different versions need different fw */
895 			DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA04"),
896 		},
897 	},
898 	{
899 		/* Trekstor Surftab Wintron 7.0 ST70416-6, newer BIOS */
900 		.driver_data = (void *)&trekstor_surftab_wintron70_data,
901 		.matches = {
902 			DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
903 			DMI_MATCH(DMI_PRODUCT_NAME,
904 					     "SurfTab wintron 7.0 ST70416-6"),
905 			/* Exact match, different versions need different fw */
906 			DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA05"),
907 		},
908 	},
909 	{
910 		/* Yours Y8W81, same case and touchscreen as Chuwi Vi8 */
911 		.driver_data = (void *)&chuwi_vi8_data,
912 		.matches = {
913 			DMI_MATCH(DMI_SYS_VENDOR, "YOURS"),
914 			DMI_MATCH(DMI_PRODUCT_NAME, "Y8W81"),
915 		},
916 	},
917 	{ },
918 };
919 
920 static const struct ts_dmi_data *ts_data;
921 
922 static void ts_dmi_add_props(struct i2c_client *client)
923 {
924 	struct device *dev = &client->dev;
925 	int error;
926 
927 	if (has_acpi_companion(dev) &&
928 	    !strncmp(ts_data->acpi_name, client->name, I2C_NAME_SIZE)) {
929 		error = device_add_properties(dev, ts_data->properties);
930 		if (error)
931 			dev_err(dev, "failed to add properties: %d\n", error);
932 	}
933 }
934 
935 static int ts_dmi_notifier_call(struct notifier_block *nb,
936 				       unsigned long action, void *data)
937 {
938 	struct device *dev = data;
939 	struct i2c_client *client;
940 
941 	switch (action) {
942 	case BUS_NOTIFY_ADD_DEVICE:
943 		client = i2c_verify_client(dev);
944 		if (client)
945 			ts_dmi_add_props(client);
946 		break;
947 
948 	default:
949 		break;
950 	}
951 
952 	return 0;
953 }
954 
955 static struct notifier_block ts_dmi_notifier = {
956 	.notifier_call = ts_dmi_notifier_call,
957 };
958 
959 static int __init ts_dmi_init(void)
960 {
961 	const struct dmi_system_id *dmi_id;
962 	int error;
963 
964 	dmi_id = dmi_first_match(touchscreen_dmi_table);
965 	if (!dmi_id)
966 		return 0; /* Not an error */
967 
968 	ts_data = dmi_id->driver_data;
969 
970 	error = bus_register_notifier(&i2c_bus_type, &ts_dmi_notifier);
971 	if (error)
972 		pr_err("%s: failed to register i2c bus notifier: %d\n",
973 			__func__, error);
974 
975 	return error;
976 }
977 
978 /*
979  * We are registering out notifier after i2c core is initialized and i2c bus
980  * itself is ready (which happens at postcore initcall level), but before
981  * ACPI starts enumerating devices (at subsys initcall level).
982  */
983 arch_initcall(ts_dmi_init);
984