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_mini3_props[] = {
253 	PROPERTY_ENTRY_U32("touchscreen-min-x", 23),
254 	PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
255 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1700),
256 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1138),
257 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
258 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-jumper-ezpad-mini3.fw"),
259 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
260 	{ }
261 };
262 
263 static const struct ts_dmi_data jumper_ezpad_mini3_data = {
264 	.acpi_name	= "MSSL1680:00",
265 	.properties	= jumper_ezpad_mini3_props,
266 };
267 
268 static const struct property_entry onda_obook_20_plus_props[] = {
269 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
270 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
271 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
272 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
273 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
274 	PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-obook-20-plus.fw"),
275 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
276 	PROPERTY_ENTRY_BOOL("silead,home-button"),
277 	{ }
278 };
279 
280 static const struct ts_dmi_data onda_obook_20_plus_data = {
281 	.acpi_name	= "MSSL1680:00",
282 	.properties	= onda_obook_20_plus_props,
283 };
284 
285 static const struct property_entry onda_v80_plus_v3_props[] = {
286 	PROPERTY_ENTRY_U32("touchscreen-min-x", 22),
287 	PROPERTY_ENTRY_U32("touchscreen-min-y", 15),
288 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1698),
289 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
290 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
291 	PROPERTY_ENTRY_STRING("firmware-name",
292 			      "gsl3676-onda-v80-plus-v3.fw"),
293 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
294 	PROPERTY_ENTRY_BOOL("silead,home-button"),
295 	{ }
296 };
297 
298 static const struct ts_dmi_data onda_v80_plus_v3_data = {
299 	.acpi_name	= "MSSL1680:00",
300 	.properties	= onda_v80_plus_v3_props,
301 };
302 
303 static const struct property_entry onda_v820w_32g_props[] = {
304 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
305 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
306 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
307 	PROPERTY_ENTRY_STRING("firmware-name",
308 			      "gsl1680-onda-v820w-32g.fw"),
309 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
310 	PROPERTY_ENTRY_BOOL("silead,home-button"),
311 	{ }
312 };
313 
314 static const struct ts_dmi_data onda_v820w_32g_data = {
315 	.acpi_name	= "MSSL1680:00",
316 	.properties	= onda_v820w_32g_props,
317 };
318 
319 static const struct property_entry onda_v891w_v1_props[] = {
320 	PROPERTY_ENTRY_U32("touchscreen-min-x", 46),
321 	PROPERTY_ENTRY_U32("touchscreen-min-y",  8),
322 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1676),
323 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1130),
324 	PROPERTY_ENTRY_STRING("firmware-name",
325 			      "gsl3680-onda-v891w-v1.fw"),
326 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
327 	PROPERTY_ENTRY_BOOL("silead,home-button"),
328 	{ }
329 };
330 
331 static const struct ts_dmi_data onda_v891w_v1_data = {
332 	.acpi_name	= "MSSL1680:00",
333 	.properties	= onda_v891w_v1_props,
334 };
335 
336 static const struct property_entry onda_v891w_v3_props[] = {
337 	PROPERTY_ENTRY_U32("touchscreen-min-x", 35),
338 	PROPERTY_ENTRY_U32("touchscreen-min-y", 15),
339 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1625),
340 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1135),
341 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
342 	PROPERTY_ENTRY_STRING("firmware-name",
343 			      "gsl3676-onda-v891w-v3.fw"),
344 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
345 	PROPERTY_ENTRY_BOOL("silead,home-button"),
346 	{ }
347 };
348 
349 static const struct ts_dmi_data onda_v891w_v3_data = {
350 	.acpi_name	= "MSSL1680:00",
351 	.properties	= onda_v891w_v3_props,
352 };
353 
354 static const struct property_entry pipo_w2s_props[] = {
355 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
356 	PROPERTY_ENTRY_U32("touchscreen-size-y", 880),
357 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
358 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
359 	PROPERTY_ENTRY_STRING("firmware-name",
360 			      "gsl1680-pipo-w2s.fw"),
361 	{ }
362 };
363 
364 static const struct ts_dmi_data pipo_w2s_data = {
365 	.acpi_name	= "MSSL1680:00",
366 	.properties	= pipo_w2s_props,
367 };
368 
369 static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = {
370 	PROPERTY_ENTRY_U32("touchscreen-min-x", 32),
371 	PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
372 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1692),
373 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1146),
374 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
375 	PROPERTY_ENTRY_STRING("firmware-name",
376 			      "gsl3680-pov-mobii-wintab-p800w-v20.fw"),
377 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
378 	PROPERTY_ENTRY_BOOL("silead,home-button"),
379 	{ }
380 };
381 
382 static const struct ts_dmi_data pov_mobii_wintab_p800w_v20_data = {
383 	.acpi_name	= "MSSL1680:00",
384 	.properties	= pov_mobii_wintab_p800w_v20_props,
385 };
386 
387 static const struct property_entry pov_mobii_wintab_p800w_v21_props[] = {
388 	PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
389 	PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
390 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1794),
391 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
392 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
393 	PROPERTY_ENTRY_STRING("firmware-name",
394 			      "gsl3692-pov-mobii-wintab-p800w.fw"),
395 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
396 	PROPERTY_ENTRY_BOOL("silead,home-button"),
397 	{ }
398 };
399 
400 static const struct ts_dmi_data pov_mobii_wintab_p800w_v21_data = {
401 	.acpi_name	= "MSSL1680:00",
402 	.properties	= pov_mobii_wintab_p800w_v21_props,
403 };
404 
405 static const struct property_entry pov_mobii_wintab_p1006w_v10_props[] = {
406 	PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
407 	PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
408 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1984),
409 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1520),
410 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
411 	PROPERTY_ENTRY_STRING("firmware-name",
412 			      "gsl3692-pov-mobii-wintab-p1006w-v10.fw"),
413 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
414 	PROPERTY_ENTRY_BOOL("silead,home-button"),
415 	{ }
416 };
417 
418 static const struct ts_dmi_data pov_mobii_wintab_p1006w_v10_data = {
419 	.acpi_name	= "MSSL1680:00",
420 	.properties	= pov_mobii_wintab_p1006w_v10_props,
421 };
422 
423 static const struct property_entry teclast_x3_plus_props[] = {
424 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
425 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
426 	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-teclast-x3-plus.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 teclast_x3_plus_data = {
433 	.acpi_name	= "MSSL1680:00",
434 	.properties	= teclast_x3_plus_props,
435 };
436 
437 static const struct property_entry teclast_x98plus2_props[] = {
438 	PROPERTY_ENTRY_U32("touchscreen-size-x", 2048),
439 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
440 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
441 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
442 	PROPERTY_ENTRY_STRING("firmware-name",
443 			      "gsl1686-teclast_x98plus2.fw"),
444 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
445 	{ }
446 };
447 
448 static const struct ts_dmi_data teclast_x98plus2_data = {
449 	.acpi_name	= "MSSL1680:00",
450 	.properties	= teclast_x98plus2_props,
451 };
452 
453 static const struct property_entry trekstor_primebook_c11_props[] = {
454 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1970),
455 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1530),
456 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
457 	PROPERTY_ENTRY_STRING("firmware-name",
458 			      "gsl1680-trekstor-primebook-c11.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 trekstor_primebook_c11_data = {
465 	.acpi_name	= "MSSL1680:00",
466 	.properties	= trekstor_primebook_c11_props,
467 };
468 
469 static const struct property_entry trekstor_primebook_c13_props[] = {
470 	PROPERTY_ENTRY_U32("touchscreen-size-x", 2624),
471 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
472 	PROPERTY_ENTRY_STRING("firmware-name",
473 			      "gsl1680-trekstor-primebook-c13.fw"),
474 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
475 	PROPERTY_ENTRY_BOOL("silead,home-button"),
476 	{ }
477 };
478 
479 static const struct ts_dmi_data trekstor_primebook_c13_data = {
480 	.acpi_name	= "MSSL1680:00",
481 	.properties	= trekstor_primebook_c13_props,
482 };
483 
484 static const struct property_entry trekstor_primetab_t13b_props[] = {
485 	PROPERTY_ENTRY_U32("touchscreen-size-x", 2500),
486 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1900),
487 	PROPERTY_ENTRY_STRING("firmware-name",
488 			      "gsl1680-trekstor-primetab-t13b.fw"),
489 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
490 	PROPERTY_ENTRY_BOOL("silead,home-button"),
491 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
492 	{ }
493 };
494 
495 static const struct ts_dmi_data trekstor_primetab_t13b_data = {
496 	.acpi_name  = "MSSL1680:00",
497 	.properties = trekstor_primetab_t13b_props,
498 };
499 
500 static const struct property_entry trekstor_surftab_twin_10_1_props[] = {
501 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1900),
502 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
503 	PROPERTY_ENTRY_U32("touchscreen-inverted-y", 1),
504 	PROPERTY_ENTRY_STRING("firmware-name",
505 			      "gsl3670-surftab-twin-10-1-st10432-8.fw"),
506 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
507 	{ }
508 };
509 
510 static const struct ts_dmi_data trekstor_surftab_twin_10_1_data = {
511 	.acpi_name	= "MSSL1680:00",
512 	.properties	= trekstor_surftab_twin_10_1_props,
513 };
514 
515 static const struct property_entry trekstor_surftab_wintron70_props[] = {
516 	PROPERTY_ENTRY_U32("touchscreen-min-x", 12),
517 	PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
518 	PROPERTY_ENTRY_U32("touchscreen-size-x", 884),
519 	PROPERTY_ENTRY_U32("touchscreen-size-y", 632),
520 	PROPERTY_ENTRY_STRING("firmware-name",
521 			      "gsl1686-surftab-wintron70-st70416-6.fw"),
522 	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
523 	PROPERTY_ENTRY_BOOL("silead,home-button"),
524 	{ }
525 };
526 
527 static const struct ts_dmi_data trekstor_surftab_wintron70_data = {
528 	.acpi_name	= "MSSL1680:00",
529 	.properties	= trekstor_surftab_wintron70_props,
530 };
531 
532 /* NOTE: Please keep this table sorted alphabetically */
533 static const struct dmi_system_id touchscreen_dmi_table[] = {
534 	{
535 		/* Chuwi Hi8 */
536 		.driver_data = (void *)&chuwi_hi8_data,
537 		.matches = {
538 			DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
539 			DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
540 		},
541 	},
542 	{
543 		/* Chuwi Hi8 (H1D_S806_206) */
544 		.driver_data = (void *)&chuwi_hi8_data,
545 		.matches = {
546 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
547 			DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
548 			DMI_MATCH(DMI_BIOS_VERSION, "H1D_S806_206"),
549 		},
550 	},
551 	{
552 		/* Chuwi Hi8 Air (CWI543) */
553 		.driver_data = (void *)&chuwi_hi8_air_data,
554 		.matches = {
555 			DMI_MATCH(DMI_BOARD_VENDOR, "Default string"),
556 			DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
557 			DMI_MATCH(DMI_PRODUCT_NAME, "Hi8 Air"),
558 		},
559 	},
560 	{
561 		/* Chuwi Hi8 Pro (CWI513) */
562 		.driver_data = (void *)&chuwi_hi8_pro_data,
563 		.matches = {
564 			DMI_MATCH(DMI_SYS_VENDOR, "Hampoo"),
565 			DMI_MATCH(DMI_PRODUCT_NAME, "X1D3_C806N"),
566 		},
567 	},
568 	{
569 		/* Chuwi Hi10 Air */
570 		.driver_data = (void *)&chuwi_hi10_air_data,
571 		.matches = {
572 			DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
573 			DMI_MATCH(DMI_PRODUCT_SKU, "P1W6_C109D_B"),
574 		},
575 	},
576 	{
577 		/* Chuwi Vi8 (CWI506) */
578 		.driver_data = (void *)&chuwi_vi8_data,
579 		.matches = {
580 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
581 			DMI_MATCH(DMI_PRODUCT_NAME, "i86"),
582 			DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
583 		},
584 	},
585 	{
586 		/* Chuwi Vi10 (CWI505) */
587 		.driver_data = (void *)&chuwi_vi10_data,
588 		.matches = {
589 			DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
590 			DMI_MATCH(DMI_BOARD_NAME, "BYT-PF02"),
591 			DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
592 			DMI_MATCH(DMI_PRODUCT_NAME, "S165"),
593 		},
594 	},
595 	{
596 		/* Connect Tablet 9 */
597 		.driver_data = (void *)&connect_tablet9_data,
598 		.matches = {
599 			DMI_MATCH(DMI_SYS_VENDOR, "Connect"),
600 			DMI_MATCH(DMI_PRODUCT_NAME, "Tablet 9"),
601 		},
602 	},
603 	{
604 		/* CUBE iwork8 Air */
605 		.driver_data = (void *)&cube_iwork8_air_data,
606 		.matches = {
607 			DMI_MATCH(DMI_SYS_VENDOR, "cube"),
608 			DMI_MATCH(DMI_PRODUCT_NAME, "i1-TF"),
609 			DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
610 		},
611 	},
612 	{
613 		/* Cube KNote i1101 */
614 		.driver_data = (void *)&cube_knote_i1101_data,
615 		.matches = {
616 			DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
617 			DMI_MATCH(DMI_BOARD_NAME, "L1W6_I1101"),
618 			DMI_MATCH(DMI_SYS_VENDOR, "ALLDOCUBE"),
619 			DMI_MATCH(DMI_PRODUCT_NAME, "i1101"),
620 		},
621 	},
622 	{
623 		/* DEXP Ursus 7W */
624 		.driver_data = (void *)&dexp_ursus_7w_data,
625 		.matches = {
626 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
627 			DMI_MATCH(DMI_PRODUCT_NAME, "7W"),
628 		},
629 	},
630 	{
631 		/* Digma Citi E200 */
632 		.driver_data = (void *)&digma_citi_e200_data,
633 		.matches = {
634 			DMI_MATCH(DMI_SYS_VENDOR, "Digma"),
635 			DMI_MATCH(DMI_PRODUCT_NAME, "CITI E200"),
636 			DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
637 		},
638 	},
639 	{
640 		/* GP-electronic T701 */
641 		.driver_data = (void *)&gp_electronic_t701_data,
642 		.matches = {
643 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
644 			DMI_MATCH(DMI_PRODUCT_NAME, "T701"),
645 			DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
646 		},
647 	},
648 	{
649 		/* I.T.Works TW701 (same hardware as the Trekstor ST70416-6) */
650 		.driver_data = (void *)&trekstor_surftab_wintron70_data,
651 		.matches = {
652 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
653 			DMI_MATCH(DMI_PRODUCT_NAME, "i71c"),
654 			DMI_MATCH(DMI_BIOS_VERSION, "itWORKS.G.WI71C.JGBMRB"),
655 		},
656 	},
657 	{
658 		/* I.T.Works TW891 */
659 		.driver_data = (void *)&itworks_tw891_data,
660 		.matches = {
661 			DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
662 			DMI_MATCH(DMI_PRODUCT_NAME, "TW891"),
663 		},
664 	},
665 	{
666 		/* Jumper EZpad 6 Pro */
667 		.driver_data = (void *)&jumper_ezpad_6_pro_data,
668 		.matches = {
669 			DMI_MATCH(DMI_SYS_VENDOR, "Jumper"),
670 			DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"),
671 			DMI_MATCH(DMI_BIOS_VERSION, "5.12"),
672 			/* Above matches are too generic, add bios-date match */
673 			DMI_MATCH(DMI_BIOS_DATE, "08/18/2017"),
674 		},
675 	},
676 	{
677 		/* Jumper EZpad mini3 */
678 		.driver_data = (void *)&jumper_ezpad_mini3_data,
679 		.matches = {
680 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
681 			/* jumperx.T87.KFBNEEA02 with the version-nr dropped */
682 			DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
683 		},
684 	},
685 	{
686 		/* Mediacom Flexbook Edge 11 (same hw as TS Primebook C11) */
687 		.driver_data = (void *)&trekstor_primebook_c11_data,
688 		.matches = {
689 			DMI_MATCH(DMI_SYS_VENDOR, "MEDIACOM"),
690 			DMI_MATCH(DMI_PRODUCT_NAME, "FlexBook edge11 - M-FBE11"),
691 		},
692 	},
693 	{
694 		/* Onda oBook 20 Plus */
695 		.driver_data = (void *)&onda_obook_20_plus_data,
696 		.matches = {
697 			DMI_MATCH(DMI_SYS_VENDOR, "ONDA"),
698 			DMI_MATCH(DMI_PRODUCT_NAME, "OBOOK 20 PLUS"),
699 		},
700 	},
701 	{
702 		/* ONDA V80 plus v3 (P80PSBG9V3A01501) */
703 		.driver_data = (void *)&onda_v80_plus_v3_data,
704 		.matches = {
705 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ONDA"),
706 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "V80 PLUS")
707 		},
708 	},
709 	{
710 		/* ONDA V820w DualOS */
711 		.driver_data = (void *)&onda_v820w_32g_data,
712 		.matches = {
713 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ONDA"),
714 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "V820w DualOS")
715 		},
716 	},
717 	{
718 		/* ONDA V891w revision P891WBEBV1B00 aka v1 */
719 		.driver_data = (void *)&onda_v891w_v1_data,
720 		.matches = {
721 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ONDA"),
722 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONDA Tablet"),
723 			DMI_EXACT_MATCH(DMI_BOARD_VERSION, "V001"),
724 			/* Exact match, different versions need different fw */
725 			DMI_EXACT_MATCH(DMI_BIOS_VERSION, "ONDA.W89EBBN08"),
726 		},
727 	},
728 	{
729 		/* ONDA V891w Dual OS P891DCF2V1A01274 64GB */
730 		.driver_data = (void *)&onda_v891w_v3_data,
731 		.matches = {
732 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
733 			DMI_MATCH(DMI_PRODUCT_NAME, "ONDA Tablet"),
734 			DMI_MATCH(DMI_BIOS_VERSION, "ONDA.D890HBBNR0A"),
735 		},
736 	},
737 	{
738 		/* Pipo W2S */
739 		.driver_data = (void *)&pipo_w2s_data,
740 		.matches = {
741 			DMI_MATCH(DMI_SYS_VENDOR, "PIPO"),
742 			DMI_MATCH(DMI_PRODUCT_NAME, "W2S"),
743 		},
744 	},
745 	{
746 		/* Ployer Momo7w (same hardware as the Trekstor ST70416-6) */
747 		.driver_data = (void *)&trekstor_surftab_wintron70_data,
748 		.matches = {
749 			DMI_MATCH(DMI_SYS_VENDOR, "Shenzhen PLOYER"),
750 			DMI_MATCH(DMI_PRODUCT_NAME, "MOMO7W"),
751 			/* Exact match, different versions need different fw */
752 			DMI_MATCH(DMI_BIOS_VERSION, "MOMO.G.WI71C.MABMRBA02"),
753 		},
754 	},
755 	{
756 		/* Point of View mobii wintab p800w (v2.0) */
757 		.driver_data = (void *)&pov_mobii_wintab_p800w_v20_data,
758 		.matches = {
759 			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
760 			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
761 			DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
762 			/* Above matches are too generic, add bios-date match */
763 			DMI_MATCH(DMI_BIOS_DATE, "10/24/2014"),
764 		},
765 	},
766 	{
767 		/* Point of View mobii wintab p800w (v2.1) */
768 		.driver_data = (void *)&pov_mobii_wintab_p800w_v21_data,
769 		.matches = {
770 			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
771 			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
772 			DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
773 			/* Above matches are too generic, add bios-date match */
774 			DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
775 		},
776 	},
777 	{
778 		/* Point of View mobii wintab p1006w (v1.0) */
779 		.driver_data = (void *)&pov_mobii_wintab_p1006w_v10_data,
780 		.matches = {
781 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
782 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
783 			/* Note 105b is Foxcon's USB/PCI vendor id */
784 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "105B"),
785 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"),
786 		},
787 	},
788 	{
789 		/* Teclast X3 Plus */
790 		.driver_data = (void *)&teclast_x3_plus_data,
791 		.matches = {
792 			DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
793 			DMI_MATCH(DMI_PRODUCT_NAME, "X3 Plus"),
794 			DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"),
795 		},
796 	},
797 	{
798 		/* Teclast X98 Plus II */
799 		.driver_data = (void *)&teclast_x98plus2_data,
800 		.matches = {
801 			DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
802 			DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
803 		},
804 	},
805 	{
806 		/* Trekstor Primebook C11 */
807 		.driver_data = (void *)&trekstor_primebook_c11_data,
808 		.matches = {
809 			DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
810 			DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C11"),
811 		},
812 	},
813 	{
814 		/* Trekstor Primebook C13 */
815 		.driver_data = (void *)&trekstor_primebook_c13_data,
816 		.matches = {
817 			DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
818 			DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
819 		},
820 	},
821 	{
822 		/* Trekstor Primetab T13B */
823 		.driver_data = (void *)&trekstor_primetab_t13b_data,
824 		.matches = {
825 			DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
826 			DMI_MATCH(DMI_PRODUCT_NAME, "Primetab T13B"),
827 		},
828 	},
829 	{
830 		/* TrekStor SurfTab twin 10.1 ST10432-8 */
831 		.driver_data = (void *)&trekstor_surftab_twin_10_1_data,
832 		.matches = {
833 			DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
834 			DMI_MATCH(DMI_PRODUCT_NAME, "SurfTab twin 10.1"),
835 		},
836 	},
837 	{
838 		/* Trekstor Surftab Wintron 7.0 ST70416-6 */
839 		.driver_data = (void *)&trekstor_surftab_wintron70_data,
840 		.matches = {
841 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
842 			DMI_MATCH(DMI_PRODUCT_NAME, "ST70416-6"),
843 			/* Exact match, different versions need different fw */
844 			DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA04"),
845 		},
846 	},
847 	{
848 		/* Trekstor Surftab Wintron 7.0 ST70416-6, newer BIOS */
849 		.driver_data = (void *)&trekstor_surftab_wintron70_data,
850 		.matches = {
851 			DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
852 			DMI_MATCH(DMI_PRODUCT_NAME,
853 					     "SurfTab wintron 7.0 ST70416-6"),
854 			/* Exact match, different versions need different fw */
855 			DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA05"),
856 		},
857 	},
858 	{
859 		/* Yours Y8W81, same case and touchscreen as Chuwi Vi8 */
860 		.driver_data = (void *)&chuwi_vi8_data,
861 		.matches = {
862 			DMI_MATCH(DMI_SYS_VENDOR, "YOURS"),
863 			DMI_MATCH(DMI_PRODUCT_NAME, "Y8W81"),
864 		},
865 	},
866 	{ },
867 };
868 
869 static const struct ts_dmi_data *ts_data;
870 
871 static void ts_dmi_add_props(struct i2c_client *client)
872 {
873 	struct device *dev = &client->dev;
874 	int error;
875 
876 	if (has_acpi_companion(dev) &&
877 	    !strncmp(ts_data->acpi_name, client->name, I2C_NAME_SIZE)) {
878 		error = device_add_properties(dev, ts_data->properties);
879 		if (error)
880 			dev_err(dev, "failed to add properties: %d\n", error);
881 	}
882 }
883 
884 static int ts_dmi_notifier_call(struct notifier_block *nb,
885 				       unsigned long action, void *data)
886 {
887 	struct device *dev = data;
888 	struct i2c_client *client;
889 
890 	switch (action) {
891 	case BUS_NOTIFY_ADD_DEVICE:
892 		client = i2c_verify_client(dev);
893 		if (client)
894 			ts_dmi_add_props(client);
895 		break;
896 
897 	default:
898 		break;
899 	}
900 
901 	return 0;
902 }
903 
904 static struct notifier_block ts_dmi_notifier = {
905 	.notifier_call = ts_dmi_notifier_call,
906 };
907 
908 static int __init ts_dmi_init(void)
909 {
910 	const struct dmi_system_id *dmi_id;
911 	int error;
912 
913 	dmi_id = dmi_first_match(touchscreen_dmi_table);
914 	if (!dmi_id)
915 		return 0; /* Not an error */
916 
917 	ts_data = dmi_id->driver_data;
918 
919 	error = bus_register_notifier(&i2c_bus_type, &ts_dmi_notifier);
920 	if (error)
921 		pr_err("%s: failed to register i2c bus notifier: %d\n",
922 			__func__, error);
923 
924 	return error;
925 }
926 
927 /*
928  * We are registering out notifier after i2c core is initialized and i2c bus
929  * itself is ready (which happens at postcore initcall level), but before
930  * ACPI starts enumerating devices (at subsys initcall level).
931  */
932 arch_initcall(ts_dmi_init);
933