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_pro_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", "gsl3680-chuwi-hi8-pro.fw"),
49 PROPERTY_ENTRY_BOOL("silead,home-button"),
50 { }
51 };
52
53 static const struct ts_dmi_data chuwi_hi8_pro_data = {
54 .acpi_name = "MSSL1680:00",
55 .properties = chuwi_hi8_pro_props,
56 };
57
58 static const struct property_entry chuwi_vi8_props[] = {
59 PROPERTY_ENTRY_U32("touchscreen-size-x", 1724),
60 PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
61 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
62 PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-vi8.fw"),
63 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
64 PROPERTY_ENTRY_BOOL("silead,home-button"),
65 { }
66 };
67
68 static const struct ts_dmi_data chuwi_vi8_data = {
69 .acpi_name = "MSSL1680:00",
70 .properties = chuwi_vi8_props,
71 };
72
73 static const struct property_entry chuwi_vi10_props[] = {
74 PROPERTY_ENTRY_U32("touchscreen-min-x", 0),
75 PROPERTY_ENTRY_U32("touchscreen-min-y", 4),
76 PROPERTY_ENTRY_U32("touchscreen-size-x", 1858),
77 PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
78 PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-vi10.fw"),
79 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
80 PROPERTY_ENTRY_BOOL("silead,home-button"),
81 { }
82 };
83
84 static const struct ts_dmi_data chuwi_vi10_data = {
85 .acpi_name = "MSSL0002:00",
86 .properties = chuwi_vi10_props,
87 };
88
89 static const struct property_entry connect_tablet9_props[] = {
90 PROPERTY_ENTRY_U32("touchscreen-min-x", 9),
91 PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
92 PROPERTY_ENTRY_U32("touchscreen-size-x", 1664),
93 PROPERTY_ENTRY_U32("touchscreen-size-y", 878),
94 PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
95 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
96 PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-connect-tablet9.fw"),
97 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
98 { }
99 };
100
101 static const struct ts_dmi_data connect_tablet9_data = {
102 .acpi_name = "MSSL1680:00",
103 .properties = connect_tablet9_props,
104 };
105
106 static const struct property_entry cube_iwork8_air_props[] = {
107 PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
108 PROPERTY_ENTRY_U32("touchscreen-size-y", 900),
109 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
110 PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-cube-iwork8-air.fw"),
111 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
112 { }
113 };
114
115 static const struct ts_dmi_data cube_iwork8_air_data = {
116 .acpi_name = "MSSL1680:00",
117 .properties = cube_iwork8_air_props,
118 };
119
120 static const struct property_entry cube_knote_i1101_props[] = {
121 PROPERTY_ENTRY_U32("touchscreen-min-x", 20),
122 PROPERTY_ENTRY_U32("touchscreen-min-y", 22),
123 PROPERTY_ENTRY_U32("touchscreen-size-x", 1961),
124 PROPERTY_ENTRY_U32("touchscreen-size-y", 1513),
125 PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-cube-knote-i1101.fw"),
126 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
127 PROPERTY_ENTRY_BOOL("silead,home-button"),
128 { }
129 };
130
131 static const struct ts_dmi_data cube_knote_i1101_data = {
132 .acpi_name = "MSSL1680:00",
133 .properties = cube_knote_i1101_props,
134 };
135
136 static const struct property_entry dexp_ursus_7w_props[] = {
137 PROPERTY_ENTRY_U32("touchscreen-size-x", 890),
138 PROPERTY_ENTRY_U32("touchscreen-size-y", 630),
139 PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-dexp-ursus-7w.fw"),
140 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
141 PROPERTY_ENTRY_BOOL("silead,home-button"),
142 { }
143 };
144
145 static const struct ts_dmi_data dexp_ursus_7w_data = {
146 .acpi_name = "MSSL1680:00",
147 .properties = dexp_ursus_7w_props,
148 };
149
150 static const struct property_entry digma_citi_e200_props[] = {
151 PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
152 PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
153 PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
154 PROPERTY_ENTRY_STRING("firmware-name",
155 "gsl1686-digma_citi_e200.fw"),
156 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
157 PROPERTY_ENTRY_BOOL("silead,home-button"),
158 { }
159 };
160
161 static const struct ts_dmi_data digma_citi_e200_data = {
162 .acpi_name = "MSSL1680:00",
163 .properties = digma_citi_e200_props,
164 };
165
166 static const struct property_entry gp_electronic_t701_props[] = {
167 PROPERTY_ENTRY_U32("touchscreen-size-x", 960),
168 PROPERTY_ENTRY_U32("touchscreen-size-y", 640),
169 PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
170 PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
171 PROPERTY_ENTRY_STRING("firmware-name",
172 "gsl1680-gp-electronic-t701.fw"),
173 { }
174 };
175
176 static const struct ts_dmi_data gp_electronic_t701_data = {
177 .acpi_name = "MSSL1680:00",
178 .properties = gp_electronic_t701_props,
179 };
180
181 static const struct property_entry itworks_tw891_props[] = {
182 PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
183 PROPERTY_ENTRY_U32("touchscreen-size-y", 890),
184 PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
185 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
186 PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-itworks-tw891.fw"),
187 { }
188 };
189
190 static const struct ts_dmi_data itworks_tw891_data = {
191 .acpi_name = "MSSL1680:00",
192 .properties = itworks_tw891_props,
193 };
194
195 static const struct property_entry jumper_ezpad_6_pro_props[] = {
196 PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
197 PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
198 PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro.fw"),
199 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
200 PROPERTY_ENTRY_BOOL("silead,home-button"),
201 { }
202 };
203
204 static const struct ts_dmi_data jumper_ezpad_6_pro_data = {
205 .acpi_name = "MSSL1680:00",
206 .properties = jumper_ezpad_6_pro_props,
207 };
208
209 static const struct property_entry jumper_ezpad_mini3_props[] = {
210 PROPERTY_ENTRY_U32("touchscreen-size-x", 1700),
211 PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
212 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
213 PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-jumper-ezpad-mini3.fw"),
214 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
215 { }
216 };
217
218 static const struct ts_dmi_data jumper_ezpad_mini3_data = {
219 .acpi_name = "MSSL1680:00",
220 .properties = jumper_ezpad_mini3_props,
221 };
222
223 static const struct property_entry onda_obook_20_plus_props[] = {
224 PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
225 PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
226 PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
227 PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
228 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
229 PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-obook-20-plus.fw"),
230 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
231 PROPERTY_ENTRY_BOOL("silead,home-button"),
232 { }
233 };
234
235 static const struct ts_dmi_data onda_obook_20_plus_data = {
236 .acpi_name = "MSSL1680:00",
237 .properties = onda_obook_20_plus_props,
238 };
239
240 static const struct property_entry onda_v820w_32g_props[] = {
241 PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
242 PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
243 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
244 PROPERTY_ENTRY_STRING("firmware-name",
245 "gsl1680-onda-v820w-32g.fw"),
246 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
247 PROPERTY_ENTRY_BOOL("silead,home-button"),
248 { }
249 };
250
251 static const struct ts_dmi_data onda_v820w_32g_data = {
252 .acpi_name = "MSSL1680:00",
253 .properties = onda_v820w_32g_props,
254 };
255
256 static const struct property_entry onda_v891w_v1_props[] = {
257 PROPERTY_ENTRY_U32("touchscreen-min-x", 46),
258 PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
259 PROPERTY_ENTRY_U32("touchscreen-size-x", 1676),
260 PROPERTY_ENTRY_U32("touchscreen-size-y", 1130),
261 PROPERTY_ENTRY_STRING("firmware-name",
262 "gsl3680-onda-v891w-v1.fw"),
263 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
264 PROPERTY_ENTRY_BOOL("silead,home-button"),
265 { }
266 };
267
268 static const struct ts_dmi_data onda_v891w_v1_data = {
269 .acpi_name = "MSSL1680:00",
270 .properties = onda_v891w_v1_props,
271 };
272
273 static const struct property_entry onda_v891w_v3_props[] = {
274 PROPERTY_ENTRY_U32("touchscreen-min-x", 35),
275 PROPERTY_ENTRY_U32("touchscreen-min-y", 15),
276 PROPERTY_ENTRY_U32("touchscreen-size-x", 1625),
277 PROPERTY_ENTRY_U32("touchscreen-size-y", 1135),
278 PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
279 PROPERTY_ENTRY_STRING("firmware-name",
280 "gsl3676-onda-v891w-v3.fw"),
281 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
282 PROPERTY_ENTRY_BOOL("silead,home-button"),
283 { }
284 };
285
286 static const struct ts_dmi_data onda_v891w_v3_data = {
287 .acpi_name = "MSSL1680:00",
288 .properties = onda_v891w_v3_props,
289 };
290
291 static const struct property_entry pipo_w2s_props[] = {
292 PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
293 PROPERTY_ENTRY_U32("touchscreen-size-y", 880),
294 PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
295 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
296 PROPERTY_ENTRY_STRING("firmware-name",
297 "gsl1680-pipo-w2s.fw"),
298 { }
299 };
300
301 static const struct ts_dmi_data pipo_w2s_data = {
302 .acpi_name = "MSSL1680:00",
303 .properties = pipo_w2s_props,
304 };
305
306 static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = {
307 PROPERTY_ENTRY_U32("touchscreen-min-x", 32),
308 PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
309 PROPERTY_ENTRY_U32("touchscreen-size-x", 1692),
310 PROPERTY_ENTRY_U32("touchscreen-size-y", 1146),
311 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
312 PROPERTY_ENTRY_STRING("firmware-name",
313 "gsl3680-pov-mobii-wintab-p800w-v20.fw"),
314 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
315 PROPERTY_ENTRY_BOOL("silead,home-button"),
316 { }
317 };
318
319 static const struct ts_dmi_data pov_mobii_wintab_p800w_v20_data = {
320 .acpi_name = "MSSL1680:00",
321 .properties = pov_mobii_wintab_p800w_v20_props,
322 };
323
324 static const struct property_entry pov_mobii_wintab_p800w_v21_props[] = {
325 PROPERTY_ENTRY_U32("touchscreen-size-x", 1800),
326 PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
327 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
328 PROPERTY_ENTRY_STRING("firmware-name",
329 "gsl3692-pov-mobii-wintab-p800w.fw"),
330 PROPERTY_ENTRY_BOOL("silead,home-button"),
331 { }
332 };
333
334 static const struct ts_dmi_data pov_mobii_wintab_p800w_v21_data = {
335 .acpi_name = "MSSL1680:00",
336 .properties = pov_mobii_wintab_p800w_v21_props,
337 };
338
339 static const struct property_entry teclast_x3_plus_props[] = {
340 PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
341 PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
342 PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-teclast-x3-plus.fw"),
343 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
344 PROPERTY_ENTRY_BOOL("silead,home-button"),
345 { }
346 };
347
348 static const struct ts_dmi_data teclast_x3_plus_data = {
349 .acpi_name = "MSSL1680:00",
350 .properties = teclast_x3_plus_props,
351 };
352
353 static const struct property_entry teclast_x98plus2_props[] = {
354 PROPERTY_ENTRY_U32("touchscreen-size-x", 2048),
355 PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
356 PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
357 PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
358 PROPERTY_ENTRY_STRING("firmware-name",
359 "gsl1686-teclast_x98plus2.fw"),
360 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
361 { }
362 };
363
364 static const struct ts_dmi_data teclast_x98plus2_data = {
365 .acpi_name = "MSSL1680:00",
366 .properties = teclast_x98plus2_props,
367 };
368
369 static const struct property_entry trekstor_primebook_c13_props[] = {
370 PROPERTY_ENTRY_U32("touchscreen-size-x", 2624),
371 PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
372 PROPERTY_ENTRY_STRING("firmware-name",
373 "gsl1680-trekstor-primebook-c13.fw"),
374 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
375 PROPERTY_ENTRY_BOOL("silead,home-button"),
376 { }
377 };
378
379 static const struct ts_dmi_data trekstor_primebook_c13_data = {
380 .acpi_name = "MSSL1680:00",
381 .properties = trekstor_primebook_c13_props,
382 };
383
384 static const struct property_entry trekstor_surftab_twin_10_1_props[] = {
385 PROPERTY_ENTRY_U32("touchscreen-size-x", 1900),
386 PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
387 PROPERTY_ENTRY_U32("touchscreen-inverted-y", 1),
388 PROPERTY_ENTRY_STRING("firmware-name",
389 "gsl3670-surftab-twin-10-1-st10432-8.fw"),
390 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
391 { }
392 };
393
394 static const struct ts_dmi_data trekstor_surftab_twin_10_1_data = {
395 .acpi_name = "MSSL1680:00",
396 .properties = trekstor_surftab_twin_10_1_props,
397 };
398
399 static const struct property_entry trekstor_surftab_wintron70_props[] = {
400 PROPERTY_ENTRY_U32("touchscreen-size-x", 884),
401 PROPERTY_ENTRY_U32("touchscreen-size-y", 632),
402 PROPERTY_ENTRY_STRING("firmware-name",
403 "gsl1686-surftab-wintron70-st70416-6.fw"),
404 PROPERTY_ENTRY_U32("silead,max-fingers", 10),
405 PROPERTY_ENTRY_BOOL("silead,home-button"),
406 { }
407 };
408
409 static const struct ts_dmi_data trekstor_surftab_wintron70_data = {
410 .acpi_name = "MSSL1680:00",
411 .properties = trekstor_surftab_wintron70_props,
412 };
413
414 /* NOTE: Please keep this table sorted alphabetically */
415 static const struct dmi_system_id touchscreen_dmi_table[] = {
416 {
417 /* Chuwi Hi8 */
418 .driver_data = (void *)&chuwi_hi8_data,
419 .matches = {
420 DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
421 DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
422 },
423 },
424 {
425 /* Chuwi Hi8 (H1D_S806_206) */
426 .driver_data = (void *)&chuwi_hi8_data,
427 .matches = {
428 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
429 DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
430 DMI_MATCH(DMI_BIOS_VERSION, "H1D_S806_206"),
431 },
432 },
433 {
434 /* Chuwi Hi8 Pro (CWI513) */
435 .driver_data = (void *)&chuwi_hi8_pro_data,
436 .matches = {
437 DMI_MATCH(DMI_SYS_VENDOR, "Hampoo"),
438 DMI_MATCH(DMI_PRODUCT_NAME, "X1D3_C806N"),
439 },
440 },
441 {
442 /* Chuwi Vi8 (CWI506) */
443 .driver_data = (void *)&chuwi_vi8_data,
444 .matches = {
445 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
446 DMI_MATCH(DMI_PRODUCT_NAME, "i86"),
447 DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
448 },
449 },
450 {
451 /* Chuwi Vi10 (CWI505) */
452 .driver_data = (void *)&chuwi_vi10_data,
453 .matches = {
454 DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
455 DMI_MATCH(DMI_BOARD_NAME, "BYT-PF02"),
456 DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
457 DMI_MATCH(DMI_PRODUCT_NAME, "S165"),
458 },
459 },
460 {
461 /* Connect Tablet 9 */
462 .driver_data = (void *)&connect_tablet9_data,
463 .matches = {
464 DMI_MATCH(DMI_SYS_VENDOR, "Connect"),
465 DMI_MATCH(DMI_PRODUCT_NAME, "Tablet 9"),
466 },
467 },
468 {
469 /* CUBE iwork8 Air */
470 .driver_data = (void *)&cube_iwork8_air_data,
471 .matches = {
472 DMI_MATCH(DMI_SYS_VENDOR, "cube"),
473 DMI_MATCH(DMI_PRODUCT_NAME, "i1-TF"),
474 DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
475 },
476 },
477 {
478 /* Cube KNote i1101 */
479 .driver_data = (void *)&cube_knote_i1101_data,
480 .matches = {
481 DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
482 DMI_MATCH(DMI_BOARD_NAME, "L1W6_I1101"),
483 DMI_MATCH(DMI_SYS_VENDOR, "ALLDOCUBE"),
484 DMI_MATCH(DMI_PRODUCT_NAME, "i1101"),
485 },
486 },
487 {
488 /* DEXP Ursus 7W */
489 .driver_data = (void *)&dexp_ursus_7w_data,
490 .matches = {
491 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
492 DMI_MATCH(DMI_PRODUCT_NAME, "7W"),
493 },
494 },
495 {
496 /* Digma Citi E200 */
497 .driver_data = (void *)&digma_citi_e200_data,
498 .matches = {
499 DMI_MATCH(DMI_SYS_VENDOR, "Digma"),
500 DMI_MATCH(DMI_PRODUCT_NAME, "CITI E200"),
501 DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
502 },
503 },
504 {
505 /* GP-electronic T701 */
506 .driver_data = (void *)&gp_electronic_t701_data,
507 .matches = {
508 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
509 DMI_MATCH(DMI_PRODUCT_NAME, "T701"),
510 DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
511 },
512 },
513 {
514 /* I.T.Works TW701 (same hardware as the Trekstor ST70416-6) */
515 .driver_data = (void *)&trekstor_surftab_wintron70_data,
516 .matches = {
517 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
518 DMI_MATCH(DMI_PRODUCT_NAME, "i71c"),
519 DMI_MATCH(DMI_BIOS_VERSION, "itWORKS.G.WI71C.JGBMRB"),
520 },
521 },
522 {
523 /* I.T.Works TW891 */
524 .driver_data = (void *)&itworks_tw891_data,
525 .matches = {
526 DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
527 DMI_MATCH(DMI_PRODUCT_NAME, "TW891"),
528 },
529 },
530 {
531 /* Jumper EZpad 6 Pro */
532 .driver_data = (void *)&jumper_ezpad_6_pro_data,
533 .matches = {
534 DMI_MATCH(DMI_SYS_VENDOR, "Jumper"),
535 DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"),
536 DMI_MATCH(DMI_BIOS_VERSION, "5.12"),
537 /* Above matches are too generic, add bios-date match */
538 DMI_MATCH(DMI_BIOS_DATE, "08/18/2017"),
539 },
540 },
541 {
542 /* Jumper EZpad mini3 */
543 .driver_data = (void *)&jumper_ezpad_mini3_data,
544 .matches = {
545 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
546 /* jumperx.T87.KFBNEEA02 with the version-nr dropped */
547 DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
548 },
549 },
550 {
551 /* Onda oBook 20 Plus */
552 .driver_data = (void *)&onda_obook_20_plus_data,
553 .matches = {
554 DMI_MATCH(DMI_SYS_VENDOR, "ONDA"),
555 DMI_MATCH(DMI_PRODUCT_NAME, "OBOOK 20 PLUS"),
556 },
557 },
558 {
559 /* ONDA V820w DualOS */
560 .driver_data = (void *)&onda_v820w_32g_data,
561 .matches = {
562 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ONDA"),
563 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "V820w DualOS")
564 },
565 },
566 {
567 /* ONDA V891w revision P891WBEBV1B00 aka v1 */
568 .driver_data = (void *)&onda_v891w_v1_data,
569 .matches = {
570 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ONDA"),
571 DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONDA Tablet"),
572 DMI_EXACT_MATCH(DMI_BOARD_VERSION, "V001"),
573 /* Exact match, different versions need different fw */
574 DMI_EXACT_MATCH(DMI_BIOS_VERSION, "ONDA.W89EBBN08"),
575 },
576 },
577 {
578 /* ONDA V891w Dual OS P891DCF2V1A01274 64GB */
579 .driver_data = (void *)&onda_v891w_v3_data,
580 .matches = {
581 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
582 DMI_MATCH(DMI_PRODUCT_NAME, "ONDA Tablet"),
583 DMI_MATCH(DMI_BIOS_VERSION, "ONDA.D890HBBNR0A"),
584 },
585 },
586 {
587 /* Pipo W2S */
588 .driver_data = (void *)&pipo_w2s_data,
589 .matches = {
590 DMI_MATCH(DMI_SYS_VENDOR, "PIPO"),
591 DMI_MATCH(DMI_PRODUCT_NAME, "W2S"),
592 },
593 },
594 {
595 /* Ployer Momo7w (same hardware as the Trekstor ST70416-6) */
596 .driver_data = (void *)&trekstor_surftab_wintron70_data,
597 .matches = {
598 DMI_MATCH(DMI_SYS_VENDOR, "Shenzhen PLOYER"),
599 DMI_MATCH(DMI_PRODUCT_NAME, "MOMO7W"),
600 /* Exact match, different versions need different fw */
601 DMI_MATCH(DMI_BIOS_VERSION, "MOMO.G.WI71C.MABMRBA02"),
602 },
603 },
604 {
605 /* Point of View mobii wintab p800w (v2.0) */
606 .driver_data = (void *)&pov_mobii_wintab_p800w_v20_data,
607 .matches = {
608 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
609 DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
610 DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
611 /* Above matches are too generic, add bios-date match */
612 DMI_MATCH(DMI_BIOS_DATE, "10/24/2014"),
613 },
614 },
615 {
616 /* Point of View mobii wintab p800w (v2.1) */
617 .driver_data = (void *)&pov_mobii_wintab_p800w_v21_data,
618 .matches = {
619 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
620 DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
621 DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
622 /* Above matches are too generic, add bios-date match */
623 DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
624 },
625 },
626 {
627 /* Teclast X3 Plus */
628 .driver_data = (void *)&teclast_x3_plus_data,
629 .matches = {
630 DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
631 DMI_MATCH(DMI_PRODUCT_NAME, "X3 Plus"),
632 DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"),
633 },
634 },
635 {
636 /* Teclast X98 Plus II */
637 .driver_data = (void *)&teclast_x98plus2_data,
638 .matches = {
639 DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
640 DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
641 },
642 },
643 {
644 /* Trekstor Primebook C13 */
645 .driver_data = (void *)&trekstor_primebook_c13_data,
646 .matches = {
647 DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
648 DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
649 },
650 },
651 {
652 /* TrekStor SurfTab twin 10.1 ST10432-8 */
653 .driver_data = (void *)&trekstor_surftab_twin_10_1_data,
654 .matches = {
655 DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
656 DMI_MATCH(DMI_PRODUCT_NAME, "SurfTab twin 10.1"),
657 },
658 },
659 {
660 /* Trekstor Surftab Wintron 7.0 ST70416-6 */
661 .driver_data = (void *)&trekstor_surftab_wintron70_data,
662 .matches = {
663 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
664 DMI_MATCH(DMI_PRODUCT_NAME, "ST70416-6"),
665 /* Exact match, different versions need different fw */
666 DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA04"),
667 },
668 },
669 {
670 /* Trekstor Surftab Wintron 7.0 ST70416-6, newer BIOS */
671 .driver_data = (void *)&trekstor_surftab_wintron70_data,
672 .matches = {
673 DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
674 DMI_MATCH(DMI_PRODUCT_NAME,
675 "SurfTab wintron 7.0 ST70416-6"),
676 /* Exact match, different versions need different fw */
677 DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA05"),
678 },
679 },
680 {
681 /* Yours Y8W81, same case and touchscreen as Chuwi Vi8 */
682 .driver_data = (void *)&chuwi_vi8_data,
683 .matches = {
684 DMI_MATCH(DMI_SYS_VENDOR, "YOURS"),
685 DMI_MATCH(DMI_PRODUCT_NAME, "Y8W81"),
686 },
687 },
688 { },
689 };
690
691 static const struct ts_dmi_data *ts_data;
692
ts_dmi_add_props(struct i2c_client * client)693 static void ts_dmi_add_props(struct i2c_client *client)
694 {
695 struct device *dev = &client->dev;
696 int error;
697
698 if (has_acpi_companion(dev) &&
699 !strncmp(ts_data->acpi_name, client->name, I2C_NAME_SIZE)) {
700 error = device_add_properties(dev, ts_data->properties);
701 if (error)
702 dev_err(dev, "failed to add properties: %d\n", error);
703 }
704 }
705
ts_dmi_notifier_call(struct notifier_block * nb,unsigned long action,void * data)706 static int ts_dmi_notifier_call(struct notifier_block *nb,
707 unsigned long action, void *data)
708 {
709 struct device *dev = data;
710 struct i2c_client *client;
711
712 switch (action) {
713 case BUS_NOTIFY_ADD_DEVICE:
714 client = i2c_verify_client(dev);
715 if (client)
716 ts_dmi_add_props(client);
717 break;
718
719 default:
720 break;
721 }
722
723 return 0;
724 }
725
726 static struct notifier_block ts_dmi_notifier = {
727 .notifier_call = ts_dmi_notifier_call,
728 };
729
ts_dmi_init(void)730 static int __init ts_dmi_init(void)
731 {
732 const struct dmi_system_id *dmi_id;
733 int error;
734
735 dmi_id = dmi_first_match(touchscreen_dmi_table);
736 if (!dmi_id)
737 return 0; /* Not an error */
738
739 ts_data = dmi_id->driver_data;
740
741 error = bus_register_notifier(&i2c_bus_type, &ts_dmi_notifier);
742 if (error)
743 pr_err("%s: failed to register i2c bus notifier: %d\n",
744 __func__, error);
745
746 return error;
747 }
748
749 /*
750 * We are registering out notifier after i2c core is initialized and i2c bus
751 * itself is ready (which happens at postcore initcall level), but before
752 * ACPI starts enumerating devices (at subsys initcall level).
753 */
754 arch_initcall(ts_dmi_init);
755