1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | #ifndef _I8042_ACPIPNPIO_H |
3 | #define _I8042_ACPIPNPIO_H |
4 | |
5 | #include <linux/acpi.h> |
6 | |
7 | #ifdef CONFIG_X86 |
8 | #include <asm/x86_init.h> |
9 | #endif |
10 | |
11 | /* |
12 | * Names. |
13 | */ |
14 | |
15 | #define I8042_KBD_PHYS_DESC "isa0060/serio0" |
16 | #define I8042_AUX_PHYS_DESC "isa0060/serio1" |
17 | #define I8042_MUX_PHYS_DESC "isa0060/serio%d" |
18 | |
19 | /* |
20 | * IRQs. |
21 | */ |
22 | |
23 | #if defined(__ia64__) |
24 | # define I8042_MAP_IRQ(x) isa_irq_to_vector((x)) |
25 | #else |
26 | # define I8042_MAP_IRQ(x) (x) |
27 | #endif |
28 | |
29 | #define I8042_KBD_IRQ i8042_kbd_irq |
30 | #define I8042_AUX_IRQ i8042_aux_irq |
31 | |
32 | static int i8042_kbd_irq; |
33 | static int i8042_aux_irq; |
34 | |
35 | /* |
36 | * Register numbers. |
37 | */ |
38 | |
39 | #define I8042_COMMAND_REG i8042_command_reg |
40 | #define I8042_STATUS_REG i8042_command_reg |
41 | #define I8042_DATA_REG i8042_data_reg |
42 | |
43 | static int i8042_command_reg = 0x64; |
44 | static int i8042_data_reg = 0x60; |
45 | |
46 | |
47 | static inline int i8042_read_data(void) |
48 | { |
49 | return inb(I8042_DATA_REG); |
50 | } |
51 | |
52 | static inline int i8042_read_status(void) |
53 | { |
54 | return inb(I8042_STATUS_REG); |
55 | } |
56 | |
57 | static inline void i8042_write_data(int val) |
58 | { |
59 | outb(value: val, I8042_DATA_REG); |
60 | } |
61 | |
62 | static inline void i8042_write_command(int val) |
63 | { |
64 | outb(value: val, I8042_COMMAND_REG); |
65 | } |
66 | |
67 | #ifdef CONFIG_X86 |
68 | |
69 | #include <linux/dmi.h> |
70 | |
71 | #define SERIO_QUIRK_NOKBD BIT(0) |
72 | #define SERIO_QUIRK_NOAUX BIT(1) |
73 | #define SERIO_QUIRK_NOMUX BIT(2) |
74 | #define SERIO_QUIRK_FORCEMUX BIT(3) |
75 | #define SERIO_QUIRK_UNLOCK BIT(4) |
76 | #define SERIO_QUIRK_PROBE_DEFER BIT(5) |
77 | #define SERIO_QUIRK_RESET_ALWAYS BIT(6) |
78 | #define SERIO_QUIRK_RESET_NEVER BIT(7) |
79 | #define SERIO_QUIRK_DIECT BIT(8) |
80 | #define SERIO_QUIRK_DUMBKBD BIT(9) |
81 | #define SERIO_QUIRK_NOLOOP BIT(10) |
82 | #define SERIO_QUIRK_NOTIMEOUT BIT(11) |
83 | #define SERIO_QUIRK_KBDRESET BIT(12) |
84 | #define SERIO_QUIRK_DRITEK BIT(13) |
85 | #define SERIO_QUIRK_NOPNP BIT(14) |
86 | |
87 | /* Quirk table for different mainboards. Options similar or identical to i8042 |
88 | * module parameters. |
89 | * ORDERING IS IMPORTANT! The first match will be apllied and the rest ignored. |
90 | * This allows entries to overwrite vendor wide quirks on a per device basis. |
91 | * Where this is irrelevant, entries are sorted case sensitive by DMI_SYS_VENDOR |
92 | * and/or DMI_BOARD_VENDOR to make it easier to avoid dublicate entries. |
93 | */ |
94 | static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { |
95 | { |
96 | .matches = { |
97 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE" ), |
98 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia" ), |
99 | }, |
100 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
101 | }, |
102 | { |
103 | .matches = { |
104 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC." ), |
105 | DMI_MATCH(DMI_PRODUCT_NAME, "X750LN" ), |
106 | }, |
107 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
108 | }, |
109 | { |
110 | /* Asus X450LCP */ |
111 | .matches = { |
112 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC." ), |
113 | DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP" ), |
114 | }, |
115 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER) |
116 | }, |
117 | { |
118 | /* ASUS ZenBook UX425UA/QA */ |
119 | .matches = { |
120 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC." ), |
121 | DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425" ), |
122 | }, |
123 | .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) |
124 | }, |
125 | { |
126 | /* ASUS ZenBook UM325UA/QA */ |
127 | .matches = { |
128 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC." ), |
129 | DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325" ), |
130 | }, |
131 | .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) |
132 | }, |
133 | /* |
134 | * On some Asus laptops, just running self tests cause problems. |
135 | */ |
136 | { |
137 | .matches = { |
138 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC." ), |
139 | DMI_MATCH(DMI_CHASSIS_TYPE, "10" ), /* Notebook */ |
140 | }, |
141 | .driver_data = (void *)(SERIO_QUIRK_RESET_NEVER) |
142 | }, |
143 | { |
144 | .matches = { |
145 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC." ), |
146 | DMI_MATCH(DMI_CHASSIS_TYPE, "31" ), /* Convertible Notebook */ |
147 | }, |
148 | .driver_data = (void *)(SERIO_QUIRK_RESET_NEVER) |
149 | }, |
150 | { |
151 | /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */ |
152 | .matches = { |
153 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC." ), |
154 | DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5" ), |
155 | DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X" ), |
156 | }, |
157 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
158 | }, |
159 | { |
160 | /* ASUS G1S */ |
161 | .matches = { |
162 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc." ), |
163 | DMI_MATCH(DMI_BOARD_NAME, "G1S" ), |
164 | DMI_MATCH(DMI_BOARD_VERSION, "1.0" ), |
165 | }, |
166 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
167 | }, |
168 | { |
169 | .matches = { |
170 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
171 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360" ), |
172 | }, |
173 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
174 | }, |
175 | { |
176 | /* Acer Aspire 5710 */ |
177 | .matches = { |
178 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
179 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710" ), |
180 | }, |
181 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
182 | }, |
183 | { |
184 | /* Acer Aspire 7738 */ |
185 | .matches = { |
186 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
187 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738" ), |
188 | }, |
189 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
190 | }, |
191 | { |
192 | /* Acer Aspire 5536 */ |
193 | .matches = { |
194 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
195 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536" ), |
196 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100" ), |
197 | }, |
198 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
199 | }, |
200 | { |
201 | /* |
202 | * Acer Aspire 5738z |
203 | * Touchpad stops working in mux mode when dis- + re-enabled |
204 | * with the touchpad enable/disable toggle hotkey |
205 | */ |
206 | .matches = { |
207 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
208 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738" ), |
209 | }, |
210 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
211 | }, |
212 | { |
213 | /* Acer Aspire One 150 */ |
214 | .matches = { |
215 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
216 | DMI_MATCH(DMI_PRODUCT_NAME, "AOA150" ), |
217 | }, |
218 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
219 | }, |
220 | { |
221 | /* Acer Aspire One 532h */ |
222 | .matches = { |
223 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
224 | DMI_MATCH(DMI_PRODUCT_NAME, "AO532h" ), |
225 | }, |
226 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
227 | }, |
228 | { |
229 | .matches = { |
230 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
231 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A114-31" ), |
232 | }, |
233 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
234 | }, |
235 | { |
236 | .matches = { |
237 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
238 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A314-31" ), |
239 | }, |
240 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
241 | }, |
242 | { |
243 | .matches = { |
244 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
245 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-31" ), |
246 | }, |
247 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
248 | }, |
249 | { |
250 | .matches = { |
251 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
252 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132" ), |
253 | }, |
254 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
255 | }, |
256 | { |
257 | .matches = { |
258 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
259 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-332" ), |
260 | }, |
261 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
262 | }, |
263 | { |
264 | .matches = { |
265 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
266 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-432" ), |
267 | }, |
268 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
269 | }, |
270 | { |
271 | .matches = { |
272 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
273 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate Spin B118-RN" ), |
274 | }, |
275 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
276 | }, |
277 | /* |
278 | * Some Wistron based laptops need us to explicitly enable the 'Dritek |
279 | * keyboard extension' to make their extra keys start generating scancodes. |
280 | * Originally, this was just confined to older laptops, but a few Acer laptops |
281 | * have turned up in 2007 that also need this again. |
282 | */ |
283 | { |
284 | /* Acer Aspire 5100 */ |
285 | .matches = { |
286 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
287 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100" ), |
288 | }, |
289 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
290 | }, |
291 | { |
292 | /* Acer Aspire 5610 */ |
293 | .matches = { |
294 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
295 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610" ), |
296 | }, |
297 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
298 | }, |
299 | { |
300 | /* Acer Aspire 5630 */ |
301 | .matches = { |
302 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
303 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630" ), |
304 | }, |
305 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
306 | }, |
307 | { |
308 | /* Acer Aspire 5650 */ |
309 | .matches = { |
310 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
311 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650" ), |
312 | }, |
313 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
314 | }, |
315 | { |
316 | /* Acer Aspire 5680 */ |
317 | .matches = { |
318 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
319 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680" ), |
320 | }, |
321 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
322 | }, |
323 | { |
324 | /* Acer Aspire 5720 */ |
325 | .matches = { |
326 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
327 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720" ), |
328 | }, |
329 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
330 | }, |
331 | { |
332 | /* Acer Aspire 9110 */ |
333 | .matches = { |
334 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
335 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110" ), |
336 | }, |
337 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
338 | }, |
339 | { |
340 | /* Acer TravelMate 660 */ |
341 | .matches = { |
342 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
343 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660" ), |
344 | }, |
345 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
346 | }, |
347 | { |
348 | /* Acer TravelMate 2490 */ |
349 | .matches = { |
350 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
351 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490" ), |
352 | }, |
353 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
354 | }, |
355 | { |
356 | /* Acer TravelMate 4280 */ |
357 | .matches = { |
358 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
359 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280" ), |
360 | }, |
361 | .driver_data = (void *)(SERIO_QUIRK_DRITEK) |
362 | }, |
363 | { |
364 | /* Acer TravelMate P459-G2-M */ |
365 | .matches = { |
366 | DMI_MATCH(DMI_SYS_VENDOR, "Acer" ), |
367 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate P459-G2-M" ), |
368 | }, |
369 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
370 | }, |
371 | { |
372 | /* Amoi M636/A737 */ |
373 | .matches = { |
374 | DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD." ), |
375 | DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform" ), |
376 | }, |
377 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
378 | }, |
379 | { |
380 | .matches = { |
381 | DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC" ), |
382 | DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B" ), |
383 | }, |
384 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
385 | }, |
386 | { |
387 | /* Compal HEL80I */ |
388 | .matches = { |
389 | DMI_MATCH(DMI_SYS_VENDOR, "COMPAL" ), |
390 | DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I" ), |
391 | }, |
392 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
393 | }, |
394 | { |
395 | .matches = { |
396 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq" ), |
397 | DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant" ), |
398 | DMI_MATCH(DMI_PRODUCT_VERSION, "8500" ), |
399 | }, |
400 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
401 | }, |
402 | { |
403 | .matches = { |
404 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq" ), |
405 | DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant" ), |
406 | DMI_MATCH(DMI_PRODUCT_VERSION, "DL760" ), |
407 | }, |
408 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
409 | }, |
410 | { |
411 | /* Advent 4211 */ |
412 | .matches = { |
413 | DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP" ), |
414 | DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211" ), |
415 | }, |
416 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
417 | }, |
418 | { |
419 | /* Dell Embedded Box PC 3000 */ |
420 | .matches = { |
421 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
422 | DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000" ), |
423 | }, |
424 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
425 | }, |
426 | { |
427 | /* Dell XPS M1530 */ |
428 | .matches = { |
429 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
430 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530" ), |
431 | }, |
432 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
433 | }, |
434 | { |
435 | /* Dell Vostro 1510 */ |
436 | .matches = { |
437 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
438 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510" ), |
439 | }, |
440 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
441 | }, |
442 | { |
443 | /* Dell Vostro V13 */ |
444 | .matches = { |
445 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
446 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13" ), |
447 | }, |
448 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) |
449 | }, |
450 | { |
451 | /* Dell Vostro 1320 */ |
452 | .matches = { |
453 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
454 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320" ), |
455 | }, |
456 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
457 | }, |
458 | { |
459 | /* Dell Vostro 1520 */ |
460 | .matches = { |
461 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
462 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520" ), |
463 | }, |
464 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
465 | }, |
466 | { |
467 | /* Dell Vostro 1720 */ |
468 | .matches = { |
469 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc." ), |
470 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720" ), |
471 | }, |
472 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
473 | }, |
474 | { |
475 | /* Entroware Proteus */ |
476 | .matches = { |
477 | DMI_MATCH(DMI_SYS_VENDOR, "Entroware" ), |
478 | DMI_MATCH(DMI_PRODUCT_NAME, "Proteus" ), |
479 | DMI_MATCH(DMI_PRODUCT_VERSION, "EL07R4" ), |
480 | }, |
481 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS) |
482 | }, |
483 | /* |
484 | * Some Fujitsu notebooks are having trouble with touchpads if |
485 | * active multiplexing mode is activated. Luckily they don't have |
486 | * external PS/2 ports so we can safely disable it. |
487 | * ... apparently some Toshibas don't like MUX mode either and |
488 | * die horrible death on reboot. |
489 | */ |
490 | { |
491 | /* Fujitsu Lifebook P7010/P7010D */ |
492 | .matches = { |
493 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
494 | DMI_MATCH(DMI_PRODUCT_NAME, "P7010" ), |
495 | }, |
496 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
497 | }, |
498 | { |
499 | /* Fujitsu Lifebook P5020D */ |
500 | .matches = { |
501 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
502 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series" ), |
503 | }, |
504 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
505 | }, |
506 | { |
507 | /* Fujitsu Lifebook S2000 */ |
508 | .matches = { |
509 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
510 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series" ), |
511 | }, |
512 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
513 | }, |
514 | { |
515 | /* Fujitsu Lifebook S6230 */ |
516 | .matches = { |
517 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
518 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230" ), |
519 | }, |
520 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
521 | }, |
522 | { |
523 | /* Fujitsu Lifebook T725 laptop */ |
524 | .matches = { |
525 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
526 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725" ), |
527 | }, |
528 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) |
529 | }, |
530 | { |
531 | /* Fujitsu Lifebook U745 */ |
532 | .matches = { |
533 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
534 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745" ), |
535 | }, |
536 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
537 | }, |
538 | { |
539 | /* Fujitsu T70H */ |
540 | .matches = { |
541 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
542 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H" ), |
543 | }, |
544 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
545 | }, |
546 | { |
547 | /* Fujitsu A544 laptop */ |
548 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */ |
549 | .matches = { |
550 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
551 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544" ), |
552 | }, |
553 | .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) |
554 | }, |
555 | { |
556 | /* Fujitsu AH544 laptop */ |
557 | /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ |
558 | .matches = { |
559 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
560 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544" ), |
561 | }, |
562 | .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) |
563 | }, |
564 | { |
565 | /* Fujitsu U574 laptop */ |
566 | /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ |
567 | .matches = { |
568 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
569 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574" ), |
570 | }, |
571 | .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) |
572 | }, |
573 | { |
574 | /* Fujitsu UH554 laptop */ |
575 | .matches = { |
576 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
577 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544" ), |
578 | }, |
579 | .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) |
580 | }, |
581 | { |
582 | /* Fujitsu Lifebook P7010 */ |
583 | .matches = { |
584 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS" ), |
585 | DMI_MATCH(DMI_PRODUCT_NAME, "0000000000" ), |
586 | }, |
587 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
588 | }, |
589 | { |
590 | /* Fujitsu-Siemens Lifebook T3010 */ |
591 | .matches = { |
592 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS" ), |
593 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010" ), |
594 | }, |
595 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
596 | }, |
597 | { |
598 | /* Fujitsu-Siemens Lifebook E4010 */ |
599 | .matches = { |
600 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS" ), |
601 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010" ), |
602 | }, |
603 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
604 | }, |
605 | { |
606 | /* Fujitsu-Siemens Amilo Pro 2010 */ |
607 | .matches = { |
608 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS" ), |
609 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010" ), |
610 | }, |
611 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
612 | }, |
613 | { |
614 | /* Fujitsu-Siemens Amilo Pro 2030 */ |
615 | .matches = { |
616 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS" ), |
617 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030" ), |
618 | }, |
619 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
620 | }, |
621 | { |
622 | /* Fujitsu Lifebook A574/H */ |
623 | .matches = { |
624 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
625 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVA0501PZ" ), |
626 | }, |
627 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
628 | }, |
629 | { |
630 | /* Fujitsu Lifebook E5411 */ |
631 | .matches = { |
632 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU CLIENT COMPUTING LIMITED" ), |
633 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E5411" ), |
634 | }, |
635 | .driver_data = (void *)(SERIO_QUIRK_NOAUX) |
636 | }, |
637 | { |
638 | /* Fujitsu Lifebook U728 */ |
639 | .matches = { |
640 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU" ), |
641 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U728" ), |
642 | }, |
643 | .driver_data = (void *)(SERIO_QUIRK_NOAUX) |
644 | }, |
645 | { |
646 | /* Gigabyte M912 */ |
647 | .matches = { |
648 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE" ), |
649 | DMI_MATCH(DMI_PRODUCT_NAME, "M912" ), |
650 | DMI_MATCH(DMI_PRODUCT_VERSION, "01" ), |
651 | }, |
652 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
653 | }, |
654 | { |
655 | /* Gigabyte Spring Peak - defines wrong chassis type */ |
656 | .matches = { |
657 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE" ), |
658 | DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak" ), |
659 | }, |
660 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
661 | }, |
662 | { |
663 | /* Gigabyte T1005 - defines wrong chassis type ("Other") */ |
664 | .matches = { |
665 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE" ), |
666 | DMI_MATCH(DMI_PRODUCT_NAME, "T1005" ), |
667 | }, |
668 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
669 | }, |
670 | { |
671 | /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ |
672 | .matches = { |
673 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE" ), |
674 | DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P" ), |
675 | }, |
676 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
677 | }, |
678 | /* |
679 | * Some laptops need keyboard reset before probing for the trackpad to get |
680 | * it detected, initialised & finally work. |
681 | */ |
682 | { |
683 | /* Gigabyte P35 v2 - Elantech touchpad */ |
684 | .matches = { |
685 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE" ), |
686 | DMI_MATCH(DMI_PRODUCT_NAME, "P35V2" ), |
687 | }, |
688 | .driver_data = (void *)(SERIO_QUIRK_KBDRESET) |
689 | }, |
690 | { |
691 | /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */ |
692 | .matches = { |
693 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE" ), |
694 | DMI_MATCH(DMI_PRODUCT_NAME, "X3" ), |
695 | }, |
696 | .driver_data = (void *)(SERIO_QUIRK_KBDRESET) |
697 | }, |
698 | { |
699 | /* Gigabyte P34 - Elantech touchpad */ |
700 | .matches = { |
701 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE" ), |
702 | DMI_MATCH(DMI_PRODUCT_NAME, "P34" ), |
703 | }, |
704 | .driver_data = (void *)(SERIO_QUIRK_KBDRESET) |
705 | }, |
706 | { |
707 | /* Gigabyte P57 - Elantech touchpad */ |
708 | .matches = { |
709 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE" ), |
710 | DMI_MATCH(DMI_PRODUCT_NAME, "P57" ), |
711 | }, |
712 | .driver_data = (void *)(SERIO_QUIRK_KBDRESET) |
713 | }, |
714 | { |
715 | /* Gericom Bellagio */ |
716 | .matches = { |
717 | DMI_MATCH(DMI_SYS_VENDOR, "Gericom" ), |
718 | DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6" ), |
719 | }, |
720 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
721 | }, |
722 | { |
723 | /* Gigabyte M1022M netbook */ |
724 | .matches = { |
725 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd." ), |
726 | DMI_MATCH(DMI_BOARD_NAME, "M1022E" ), |
727 | DMI_MATCH(DMI_BOARD_VERSION, "1.02" ), |
728 | }, |
729 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
730 | }, |
731 | { |
732 | .matches = { |
733 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard" ), |
734 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700" ), |
735 | DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1" ), |
736 | }, |
737 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
738 | }, |
739 | { |
740 | /* |
741 | * HP Pavilion DV4017EA - |
742 | * errors on MUX ports are reported without raising AUXDATA |
743 | * causing "spurious NAK" messages. |
744 | */ |
745 | .matches = { |
746 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard" ), |
747 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)" ), |
748 | }, |
749 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
750 | }, |
751 | { |
752 | /* |
753 | * HP Pavilion ZT1000 - |
754 | * like DV4017EA does not raise AUXERR for errors on MUX ports. |
755 | */ |
756 | .matches = { |
757 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard" ), |
758 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC" ), |
759 | DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000" ), |
760 | }, |
761 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
762 | }, |
763 | { |
764 | /* |
765 | * HP Pavilion DV4270ca - |
766 | * like DV4017EA does not raise AUXERR for errors on MUX ports. |
767 | */ |
768 | .matches = { |
769 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard" ), |
770 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)" ), |
771 | }, |
772 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
773 | }, |
774 | { |
775 | /* Newer HP Pavilion dv4 models */ |
776 | .matches = { |
777 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard" ), |
778 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC" ), |
779 | }, |
780 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) |
781 | }, |
782 | { |
783 | /* IBM 2656 */ |
784 | .matches = { |
785 | DMI_MATCH(DMI_SYS_VENDOR, "IBM" ), |
786 | DMI_MATCH(DMI_PRODUCT_NAME, "2656" ), |
787 | }, |
788 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
789 | }, |
790 | { |
791 | /* Avatar AVIU-145A6 */ |
792 | .matches = { |
793 | DMI_MATCH(DMI_SYS_VENDOR, "Intel" ), |
794 | DMI_MATCH(DMI_PRODUCT_NAME, "IC4I" ), |
795 | }, |
796 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
797 | }, |
798 | { |
799 | /* Intel MBO Desktop D845PESV */ |
800 | .matches = { |
801 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation" ), |
802 | DMI_MATCH(DMI_BOARD_NAME, "D845PESV" ), |
803 | }, |
804 | .driver_data = (void *)(SERIO_QUIRK_NOPNP) |
805 | }, |
806 | { |
807 | /* |
808 | * Intel NUC D54250WYK - does not have i8042 controller but |
809 | * declares PS/2 devices in DSDT. |
810 | */ |
811 | .matches = { |
812 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation" ), |
813 | DMI_MATCH(DMI_BOARD_NAME, "D54250WYK" ), |
814 | }, |
815 | .driver_data = (void *)(SERIO_QUIRK_NOPNP) |
816 | }, |
817 | { |
818 | /* Lenovo 3000 n100 */ |
819 | .matches = { |
820 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO" ), |
821 | DMI_MATCH(DMI_PRODUCT_NAME, "076804U" ), |
822 | }, |
823 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
824 | }, |
825 | { |
826 | /* Lenovo XiaoXin Air 12 */ |
827 | .matches = { |
828 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO" ), |
829 | DMI_MATCH(DMI_PRODUCT_NAME, "80UN" ), |
830 | }, |
831 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
832 | }, |
833 | { |
834 | /* Lenovo LaVie Z */ |
835 | .matches = { |
836 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO" ), |
837 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z" ), |
838 | }, |
839 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
840 | }, |
841 | { |
842 | /* Lenovo Ideapad U455 */ |
843 | .matches = { |
844 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO" ), |
845 | DMI_MATCH(DMI_PRODUCT_NAME, "20046" ), |
846 | }, |
847 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
848 | }, |
849 | { |
850 | /* Lenovo ThinkPad L460 */ |
851 | .matches = { |
852 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO" ), |
853 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460" ), |
854 | }, |
855 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
856 | }, |
857 | { |
858 | /* Lenovo ThinkPad Twist S230u */ |
859 | .matches = { |
860 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO" ), |
861 | DMI_MATCH(DMI_PRODUCT_NAME, "33474HU" ), |
862 | }, |
863 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
864 | }, |
865 | { |
866 | /* LG Electronics X110 */ |
867 | .matches = { |
868 | DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc." ), |
869 | DMI_MATCH(DMI_BOARD_NAME, "X110" ), |
870 | }, |
871 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
872 | }, |
873 | { |
874 | /* Medion Akoya Mini E1210 */ |
875 | .matches = { |
876 | DMI_MATCH(DMI_SYS_VENDOR, "MEDION" ), |
877 | DMI_MATCH(DMI_PRODUCT_NAME, "E1210" ), |
878 | }, |
879 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
880 | }, |
881 | { |
882 | /* Medion Akoya E1222 */ |
883 | .matches = { |
884 | DMI_MATCH(DMI_SYS_VENDOR, "MEDION" ), |
885 | DMI_MATCH(DMI_PRODUCT_NAME, "E122X" ), |
886 | }, |
887 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
888 | }, |
889 | { |
890 | /* MSI Wind U-100 */ |
891 | .matches = { |
892 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD" ), |
893 | DMI_MATCH(DMI_BOARD_NAME, "U-100" ), |
894 | }, |
895 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOPNP) |
896 | }, |
897 | { |
898 | /* |
899 | * No data is coming from the touchscreen unless KBC |
900 | * is in legacy mode. |
901 | */ |
902 | /* Panasonic CF-29 */ |
903 | .matches = { |
904 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita" ), |
905 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29" ), |
906 | }, |
907 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
908 | }, |
909 | { |
910 | /* Medion Akoya E7225 */ |
911 | .matches = { |
912 | DMI_MATCH(DMI_SYS_VENDOR, "Medion" ), |
913 | DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225" ), |
914 | DMI_MATCH(DMI_PRODUCT_VERSION, "1.0" ), |
915 | }, |
916 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
917 | }, |
918 | { |
919 | /* Microsoft Virtual Machine */ |
920 | .matches = { |
921 | DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation" ), |
922 | DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine" ), |
923 | DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2" ), |
924 | }, |
925 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
926 | }, |
927 | { |
928 | /* Medion MAM 2070 */ |
929 | .matches = { |
930 | DMI_MATCH(DMI_SYS_VENDOR, "Notebook" ), |
931 | DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070" ), |
932 | DMI_MATCH(DMI_PRODUCT_VERSION, "5a" ), |
933 | }, |
934 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
935 | }, |
936 | { |
937 | /* TUXEDO BU1406 */ |
938 | .matches = { |
939 | DMI_MATCH(DMI_SYS_VENDOR, "Notebook" ), |
940 | DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU" ), |
941 | }, |
942 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
943 | }, |
944 | { |
945 | /* OQO Model 01 */ |
946 | .matches = { |
947 | DMI_MATCH(DMI_SYS_VENDOR, "OQO" ), |
948 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO" ), |
949 | DMI_MATCH(DMI_PRODUCT_VERSION, "00" ), |
950 | }, |
951 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
952 | }, |
953 | { |
954 | .matches = { |
955 | DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION" ), |
956 | DMI_MATCH(DMI_PRODUCT_NAME, "C15B" ), |
957 | }, |
958 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
959 | }, |
960 | { |
961 | /* Acer Aspire 5 A515 */ |
962 | .matches = { |
963 | DMI_MATCH(DMI_BOARD_VENDOR, "PK" ), |
964 | DMI_MATCH(DMI_BOARD_NAME, "Grumpy_PK" ), |
965 | }, |
966 | .driver_data = (void *)(SERIO_QUIRK_NOPNP) |
967 | }, |
968 | { |
969 | /* ULI EV4873 - AUX LOOP does not work properly */ |
970 | .matches = { |
971 | DMI_MATCH(DMI_SYS_VENDOR, "ULI" ), |
972 | DMI_MATCH(DMI_PRODUCT_NAME, "EV4873" ), |
973 | DMI_MATCH(DMI_PRODUCT_VERSION, "5a" ), |
974 | }, |
975 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
976 | }, |
977 | { |
978 | /* |
979 | * Arima-Rioworks HDAMB - |
980 | * AUX LOOP command does not raise AUX IRQ |
981 | */ |
982 | .matches = { |
983 | DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS" ), |
984 | DMI_MATCH(DMI_BOARD_NAME, "HDAMB" ), |
985 | DMI_MATCH(DMI_BOARD_VERSION, "Rev E" ), |
986 | }, |
987 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
988 | }, |
989 | { |
990 | /* Sharp Actius MM20 */ |
991 | .matches = { |
992 | DMI_MATCH(DMI_SYS_VENDOR, "SHARP" ), |
993 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series" ), |
994 | }, |
995 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
996 | }, |
997 | { |
998 | /* |
999 | * Sony Vaio FZ-240E - |
1000 | * reset and GET ID commands issued via KBD port are |
1001 | * sometimes being delivered to AUX3. |
1002 | */ |
1003 | .matches = { |
1004 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation" ), |
1005 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E" ), |
1006 | }, |
1007 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
1008 | }, |
1009 | { |
1010 | /* |
1011 | * Most (all?) VAIOs do not have external PS/2 ports nor |
1012 | * they implement active multiplexing properly, and |
1013 | * MUX discovery usually messes up keyboard/touchpad. |
1014 | */ |
1015 | .matches = { |
1016 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation" ), |
1017 | DMI_MATCH(DMI_BOARD_NAME, "VAIO" ), |
1018 | }, |
1019 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
1020 | }, |
1021 | { |
1022 | /* Sony Vaio FS-115b */ |
1023 | .matches = { |
1024 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation" ), |
1025 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B" ), |
1026 | }, |
1027 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
1028 | }, |
1029 | { |
1030 | /* |
1031 | * Sony Vaio VGN-CS series require MUX or the touch sensor |
1032 | * buttons will disturb touchpad operation |
1033 | */ |
1034 | .matches = { |
1035 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation" ), |
1036 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS" ), |
1037 | }, |
1038 | .driver_data = (void *)(SERIO_QUIRK_FORCEMUX) |
1039 | }, |
1040 | { |
1041 | .matches = { |
1042 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA" ), |
1043 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10" ), |
1044 | }, |
1045 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
1046 | }, |
1047 | { |
1048 | .matches = { |
1049 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA" ), |
1050 | DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110" ), |
1051 | }, |
1052 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
1053 | }, |
1054 | { |
1055 | .matches = { |
1056 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA" ), |
1057 | DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D" ), |
1058 | }, |
1059 | .driver_data = (void *)(SERIO_QUIRK_NOMUX) |
1060 | }, |
1061 | /* |
1062 | * A lot of modern Clevo barebones have touchpad and/or keyboard issues |
1063 | * after suspend fixable with nomux + reset + noloop + nopnp. Luckily, |
1064 | * none of them have an external PS/2 port so this can safely be set for |
1065 | * all of them. These two are based on a Clevo design, but have the |
1066 | * board_name changed. |
1067 | */ |
1068 | { |
1069 | .matches = { |
1070 | DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO" ), |
1071 | DMI_MATCH(DMI_BOARD_NAME, "AURA1501" ), |
1072 | }, |
1073 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1074 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1075 | }, |
1076 | { |
1077 | .matches = { |
1078 | DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO" ), |
1079 | DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502" ), |
1080 | }, |
1081 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1082 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1083 | }, |
1084 | { |
1085 | /* Mivvy M310 */ |
1086 | .matches = { |
1087 | DMI_MATCH(DMI_SYS_VENDOR, "VIOOO" ), |
1088 | DMI_MATCH(DMI_PRODUCT_NAME, "N10" ), |
1089 | }, |
1090 | .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) |
1091 | }, |
1092 | /* |
1093 | * Some laptops need keyboard reset before probing for the trackpad to get |
1094 | * it detected, initialised & finally work. |
1095 | */ |
1096 | { |
1097 | /* Schenker XMG C504 - Elantech touchpad */ |
1098 | .matches = { |
1099 | DMI_MATCH(DMI_SYS_VENDOR, "XMG" ), |
1100 | DMI_MATCH(DMI_PRODUCT_NAME, "C504" ), |
1101 | }, |
1102 | .driver_data = (void *)(SERIO_QUIRK_KBDRESET) |
1103 | }, |
1104 | { |
1105 | /* Blue FB5601 */ |
1106 | .matches = { |
1107 | DMI_MATCH(DMI_SYS_VENDOR, "blue" ), |
1108 | DMI_MATCH(DMI_PRODUCT_NAME, "FB5601" ), |
1109 | DMI_MATCH(DMI_PRODUCT_VERSION, "M606" ), |
1110 | }, |
1111 | .driver_data = (void *)(SERIO_QUIRK_NOLOOP) |
1112 | }, |
1113 | /* |
1114 | * A lot of modern Clevo barebones have touchpad and/or keyboard issues |
1115 | * after suspend fixable with nomux + reset + noloop + nopnp. Luckily, |
1116 | * none of them have an external PS/2 port so this can safely be set for |
1117 | * all of them. |
1118 | * Clevo barebones come with board_vendor and/or system_vendor set to |
1119 | * either the very generic string "Notebook" and/or a different value |
1120 | * for each individual reseller. The only somewhat universal way to |
1121 | * identify them is by board_name. |
1122 | */ |
1123 | { |
1124 | .matches = { |
1125 | DMI_MATCH(DMI_BOARD_NAME, "LAPQC71A" ), |
1126 | }, |
1127 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1128 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1129 | }, |
1130 | { |
1131 | .matches = { |
1132 | DMI_MATCH(DMI_BOARD_NAME, "LAPQC71B" ), |
1133 | }, |
1134 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1135 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1136 | }, |
1137 | { |
1138 | .matches = { |
1139 | DMI_MATCH(DMI_BOARD_NAME, "N140CU" ), |
1140 | }, |
1141 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1142 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1143 | }, |
1144 | { |
1145 | .matches = { |
1146 | DMI_MATCH(DMI_BOARD_NAME, "N141CU" ), |
1147 | }, |
1148 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1149 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1150 | }, |
1151 | { |
1152 | /* |
1153 | * Setting SERIO_QUIRK_NOMUX or SERIO_QUIRK_RESET_ALWAYS makes |
1154 | * the keyboard very laggy for ~5 seconds after boot and |
1155 | * sometimes also after resume. |
1156 | * However both are required for the keyboard to not fail |
1157 | * completely sometimes after boot or resume. |
1158 | */ |
1159 | .matches = { |
1160 | DMI_MATCH(DMI_BOARD_NAME, "N150CU" ), |
1161 | }, |
1162 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1163 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1164 | }, |
1165 | { |
1166 | .matches = { |
1167 | DMI_MATCH(DMI_BOARD_NAME, "NH5xAx" ), |
1168 | }, |
1169 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1170 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1171 | }, |
1172 | { |
1173 | /* |
1174 | * Setting SERIO_QUIRK_NOMUX or SERIO_QUIRK_RESET_ALWAYS makes |
1175 | * the keyboard very laggy for ~5 seconds after boot and |
1176 | * sometimes also after resume. |
1177 | * However both are required for the keyboard to not fail |
1178 | * completely sometimes after boot or resume. |
1179 | */ |
1180 | .matches = { |
1181 | DMI_MATCH(DMI_BOARD_NAME, "NHxxRZQ" ), |
1182 | }, |
1183 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1184 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1185 | }, |
1186 | { |
1187 | .matches = { |
1188 | DMI_MATCH(DMI_BOARD_NAME, "NL5xRU" ), |
1189 | }, |
1190 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1191 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1192 | }, |
1193 | /* |
1194 | * At least one modern Clevo barebone has the touchpad connected both |
1195 | * via PS/2 and i2c interface. This causes a race condition between the |
1196 | * psmouse and i2c-hid driver. Since the full capability of the touchpad |
1197 | * is available via the i2c interface and the device has no external |
1198 | * PS/2 port, it is safe to just ignore all ps2 mouses here to avoid |
1199 | * this issue. The known affected device is the |
1200 | * TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU which comes with one of |
1201 | * the two different dmi strings below. NS50MU is not a typo! |
1202 | */ |
1203 | { |
1204 | .matches = { |
1205 | DMI_MATCH(DMI_BOARD_NAME, "NS50MU" ), |
1206 | }, |
1207 | .driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX | |
1208 | SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | |
1209 | SERIO_QUIRK_NOPNP) |
1210 | }, |
1211 | { |
1212 | .matches = { |
1213 | DMI_MATCH(DMI_BOARD_NAME, "NS50_70MU" ), |
1214 | }, |
1215 | .driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX | |
1216 | SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | |
1217 | SERIO_QUIRK_NOPNP) |
1218 | }, |
1219 | { |
1220 | .matches = { |
1221 | DMI_MATCH(DMI_BOARD_NAME, "NS5x_7xPU" ), |
1222 | }, |
1223 | .driver_data = (void *)(SERIO_QUIRK_NOAUX) |
1224 | }, |
1225 | { |
1226 | .matches = { |
1227 | DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU" ), |
1228 | }, |
1229 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1230 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1231 | }, |
1232 | { |
1233 | /* |
1234 | * This is only a partial board_name and might be followed by |
1235 | * another letter or number. DMI_MATCH however does do partial |
1236 | * matching. |
1237 | */ |
1238 | .matches = { |
1239 | DMI_MATCH(DMI_PRODUCT_NAME, "P65xH" ), |
1240 | }, |
1241 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1242 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1243 | }, |
1244 | { |
1245 | /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */ |
1246 | .matches = { |
1247 | DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP" ), |
1248 | }, |
1249 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1250 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1251 | }, |
1252 | { |
1253 | /* |
1254 | * This is only a partial board_name and might be followed by |
1255 | * another letter or number. DMI_MATCH however does do partial |
1256 | * matching. |
1257 | */ |
1258 | .matches = { |
1259 | DMI_MATCH(DMI_PRODUCT_NAME, "P65_P67H" ), |
1260 | }, |
1261 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1262 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1263 | }, |
1264 | { |
1265 | /* |
1266 | * This is only a partial board_name and might be followed by |
1267 | * another letter or number. DMI_MATCH however does do partial |
1268 | * matching. |
1269 | */ |
1270 | .matches = { |
1271 | DMI_MATCH(DMI_PRODUCT_NAME, "P65_67RP" ), |
1272 | }, |
1273 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1274 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1275 | }, |
1276 | { |
1277 | /* |
1278 | * This is only a partial board_name and might be followed by |
1279 | * another letter or number. DMI_MATCH however does do partial |
1280 | * matching. |
1281 | */ |
1282 | .matches = { |
1283 | DMI_MATCH(DMI_PRODUCT_NAME, "P65_67RS" ), |
1284 | }, |
1285 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1286 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1287 | }, |
1288 | { |
1289 | /* |
1290 | * This is only a partial board_name and might be followed by |
1291 | * another letter or number. DMI_MATCH however does do partial |
1292 | * matching. |
1293 | */ |
1294 | .matches = { |
1295 | DMI_MATCH(DMI_PRODUCT_NAME, "P67xRP" ), |
1296 | }, |
1297 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1298 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1299 | }, |
1300 | { |
1301 | .matches = { |
1302 | DMI_MATCH(DMI_BOARD_NAME, "PB50_70DFx,DDx" ), |
1303 | }, |
1304 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1305 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1306 | }, |
1307 | { |
1308 | .matches = { |
1309 | DMI_MATCH(DMI_BOARD_NAME, "PCX0DX" ), |
1310 | }, |
1311 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1312 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1313 | }, |
1314 | /* See comment on TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU above */ |
1315 | { |
1316 | .matches = { |
1317 | DMI_MATCH(DMI_BOARD_NAME, "PD5x_7xPNP_PNR_PNN_PNT" ), |
1318 | }, |
1319 | .driver_data = (void *)(SERIO_QUIRK_NOAUX) |
1320 | }, |
1321 | { |
1322 | .matches = { |
1323 | DMI_MATCH(DMI_BOARD_NAME, "X170SM" ), |
1324 | }, |
1325 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1326 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1327 | }, |
1328 | { |
1329 | .matches = { |
1330 | DMI_MATCH(DMI_BOARD_NAME, "X170KM-G" ), |
1331 | }, |
1332 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | |
1333 | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) |
1334 | }, |
1335 | { } |
1336 | }; |
1337 | |
1338 | #ifdef CONFIG_PNP |
1339 | static const struct dmi_system_id i8042_dmi_laptop_table[] __initconst = { |
1340 | { |
1341 | .matches = { |
1342 | DMI_MATCH(DMI_CHASSIS_TYPE, "8" ), /* Portable */ |
1343 | }, |
1344 | }, |
1345 | { |
1346 | .matches = { |
1347 | DMI_MATCH(DMI_CHASSIS_TYPE, "9" ), /* Laptop */ |
1348 | }, |
1349 | }, |
1350 | { |
1351 | .matches = { |
1352 | DMI_MATCH(DMI_CHASSIS_TYPE, "10" ), /* Notebook */ |
1353 | }, |
1354 | }, |
1355 | { |
1356 | .matches = { |
1357 | DMI_MATCH(DMI_CHASSIS_TYPE, "14" ), /* Sub-Notebook */ |
1358 | }, |
1359 | }, |
1360 | { } |
1361 | }; |
1362 | #endif |
1363 | |
1364 | #endif /* CONFIG_X86 */ |
1365 | |
1366 | #ifdef CONFIG_PNP |
1367 | #include <linux/pnp.h> |
1368 | |
1369 | static bool i8042_pnp_kbd_registered; |
1370 | static unsigned int i8042_pnp_kbd_devices; |
1371 | static bool i8042_pnp_aux_registered; |
1372 | static unsigned int i8042_pnp_aux_devices; |
1373 | |
1374 | static int i8042_pnp_command_reg; |
1375 | static int i8042_pnp_data_reg; |
1376 | static int i8042_pnp_kbd_irq; |
1377 | static int i8042_pnp_aux_irq; |
1378 | |
1379 | static char i8042_pnp_kbd_name[32]; |
1380 | static char i8042_pnp_aux_name[32]; |
1381 | |
1382 | static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size) |
1383 | { |
1384 | strscpy(dst, "PNP:" , dst_size); |
1385 | |
1386 | while (id) { |
1387 | strlcat(p: dst, q: " " , avail: dst_size); |
1388 | strlcat(p: dst, q: id->id, avail: dst_size); |
1389 | id = id->next; |
1390 | } |
1391 | } |
1392 | |
1393 | static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did) |
1394 | { |
1395 | if (pnp_port_valid(dev, bar: 0) && pnp_port_len(dev, bar: 0) == 1) |
1396 | i8042_pnp_data_reg = pnp_port_start(dev,bar: 0); |
1397 | |
1398 | if (pnp_port_valid(dev, bar: 1) && pnp_port_len(dev, bar: 1) == 1) |
1399 | i8042_pnp_command_reg = pnp_port_start(dev, bar: 1); |
1400 | |
1401 | if (pnp_irq_valid(dev,bar: 0)) |
1402 | i8042_pnp_kbd_irq = pnp_irq(dev, bar: 0); |
1403 | |
1404 | strscpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); |
1405 | if (strlen(pnp_dev_name(dev))) { |
1406 | strlcat(p: i8042_pnp_kbd_name, q: ":" , avail: sizeof(i8042_pnp_kbd_name)); |
1407 | strlcat(p: i8042_pnp_kbd_name, pnp_dev_name(dev), avail: sizeof(i8042_pnp_kbd_name)); |
1408 | } |
1409 | i8042_pnp_id_to_string(id: dev->id, dst: i8042_kbd_firmware_id, |
1410 | dst_size: sizeof(i8042_kbd_firmware_id)); |
1411 | i8042_kbd_fwnode = dev_fwnode(&dev->dev); |
1412 | |
1413 | /* Keyboard ports are always supposed to be wakeup-enabled */ |
1414 | device_set_wakeup_enable(dev: &dev->dev, enable: true); |
1415 | |
1416 | i8042_pnp_kbd_devices++; |
1417 | return 0; |
1418 | } |
1419 | |
1420 | static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did) |
1421 | { |
1422 | if (pnp_port_valid(dev, bar: 0) && pnp_port_len(dev, bar: 0) == 1) |
1423 | i8042_pnp_data_reg = pnp_port_start(dev,bar: 0); |
1424 | |
1425 | if (pnp_port_valid(dev, bar: 1) && pnp_port_len(dev, bar: 1) == 1) |
1426 | i8042_pnp_command_reg = pnp_port_start(dev, bar: 1); |
1427 | |
1428 | if (pnp_irq_valid(dev, bar: 0)) |
1429 | i8042_pnp_aux_irq = pnp_irq(dev, bar: 0); |
1430 | |
1431 | strscpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); |
1432 | if (strlen(pnp_dev_name(dev))) { |
1433 | strlcat(p: i8042_pnp_aux_name, q: ":" , avail: sizeof(i8042_pnp_aux_name)); |
1434 | strlcat(p: i8042_pnp_aux_name, pnp_dev_name(dev), avail: sizeof(i8042_pnp_aux_name)); |
1435 | } |
1436 | i8042_pnp_id_to_string(id: dev->id, dst: i8042_aux_firmware_id, |
1437 | dst_size: sizeof(i8042_aux_firmware_id)); |
1438 | |
1439 | i8042_pnp_aux_devices++; |
1440 | return 0; |
1441 | } |
1442 | |
1443 | static const struct pnp_device_id pnp_kbd_devids[] = { |
1444 | { .id = "PNP0300" , .driver_data = 0 }, |
1445 | { .id = "PNP0301" , .driver_data = 0 }, |
1446 | { .id = "PNP0302" , .driver_data = 0 }, |
1447 | { .id = "PNP0303" , .driver_data = 0 }, |
1448 | { .id = "PNP0304" , .driver_data = 0 }, |
1449 | { .id = "PNP0305" , .driver_data = 0 }, |
1450 | { .id = "PNP0306" , .driver_data = 0 }, |
1451 | { .id = "PNP0309" , .driver_data = 0 }, |
1452 | { .id = "PNP030a" , .driver_data = 0 }, |
1453 | { .id = "PNP030b" , .driver_data = 0 }, |
1454 | { .id = "PNP0320" , .driver_data = 0 }, |
1455 | { .id = "PNP0343" , .driver_data = 0 }, |
1456 | { .id = "PNP0344" , .driver_data = 0 }, |
1457 | { .id = "PNP0345" , .driver_data = 0 }, |
1458 | { .id = "CPQA0D7" , .driver_data = 0 }, |
1459 | { .id = "" , }, |
1460 | }; |
1461 | MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids); |
1462 | |
1463 | static struct pnp_driver i8042_pnp_kbd_driver = { |
1464 | .name = "i8042 kbd" , |
1465 | .id_table = pnp_kbd_devids, |
1466 | .probe = i8042_pnp_kbd_probe, |
1467 | .driver = { |
1468 | .probe_type = PROBE_FORCE_SYNCHRONOUS, |
1469 | .suppress_bind_attrs = true, |
1470 | }, |
1471 | }; |
1472 | |
1473 | static const struct pnp_device_id pnp_aux_devids[] = { |
1474 | { .id = "AUI0200" , .driver_data = 0 }, |
1475 | { .id = "FJC6000" , .driver_data = 0 }, |
1476 | { .id = "FJC6001" , .driver_data = 0 }, |
1477 | { .id = "PNP0f03" , .driver_data = 0 }, |
1478 | { .id = "PNP0f0b" , .driver_data = 0 }, |
1479 | { .id = "PNP0f0e" , .driver_data = 0 }, |
1480 | { .id = "PNP0f12" , .driver_data = 0 }, |
1481 | { .id = "PNP0f13" , .driver_data = 0 }, |
1482 | { .id = "PNP0f19" , .driver_data = 0 }, |
1483 | { .id = "PNP0f1c" , .driver_data = 0 }, |
1484 | { .id = "SYN0801" , .driver_data = 0 }, |
1485 | { .id = "" , }, |
1486 | }; |
1487 | MODULE_DEVICE_TABLE(pnp, pnp_aux_devids); |
1488 | |
1489 | static struct pnp_driver i8042_pnp_aux_driver = { |
1490 | .name = "i8042 aux" , |
1491 | .id_table = pnp_aux_devids, |
1492 | .probe = i8042_pnp_aux_probe, |
1493 | .driver = { |
1494 | .probe_type = PROBE_FORCE_SYNCHRONOUS, |
1495 | .suppress_bind_attrs = true, |
1496 | }, |
1497 | }; |
1498 | |
1499 | static void i8042_pnp_exit(void) |
1500 | { |
1501 | if (i8042_pnp_kbd_registered) { |
1502 | i8042_pnp_kbd_registered = false; |
1503 | pnp_unregister_driver(drv: &i8042_pnp_kbd_driver); |
1504 | } |
1505 | |
1506 | if (i8042_pnp_aux_registered) { |
1507 | i8042_pnp_aux_registered = false; |
1508 | pnp_unregister_driver(drv: &i8042_pnp_aux_driver); |
1509 | } |
1510 | } |
1511 | |
1512 | static int __init i8042_pnp_init(void) |
1513 | { |
1514 | char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; |
1515 | bool pnp_data_busted = false; |
1516 | int err; |
1517 | |
1518 | if (i8042_nopnp) { |
1519 | pr_info("PNP detection disabled\n" ); |
1520 | return 0; |
1521 | } |
1522 | |
1523 | err = pnp_register_driver(drv: &i8042_pnp_kbd_driver); |
1524 | if (!err) |
1525 | i8042_pnp_kbd_registered = true; |
1526 | |
1527 | err = pnp_register_driver(drv: &i8042_pnp_aux_driver); |
1528 | if (!err) |
1529 | i8042_pnp_aux_registered = true; |
1530 | |
1531 | if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) { |
1532 | i8042_pnp_exit(); |
1533 | #if defined(__ia64__) |
1534 | return -ENODEV; |
1535 | #else |
1536 | pr_info("PNP: No PS/2 controller found.\n" ); |
1537 | #if defined(__loongarch__) |
1538 | if (acpi_disabled == 0) |
1539 | return -ENODEV; |
1540 | #else |
1541 | if (x86_platform.legacy.i8042 != |
1542 | X86_LEGACY_I8042_EXPECTED_PRESENT) |
1543 | return -ENODEV; |
1544 | #endif |
1545 | pr_info("Probing ports directly.\n" ); |
1546 | return 0; |
1547 | #endif |
1548 | } |
1549 | |
1550 | if (i8042_pnp_kbd_devices) |
1551 | snprintf(buf: kbd_irq_str, size: sizeof(kbd_irq_str), |
1552 | fmt: "%d" , i8042_pnp_kbd_irq); |
1553 | if (i8042_pnp_aux_devices) |
1554 | snprintf(buf: aux_irq_str, size: sizeof(aux_irq_str), |
1555 | fmt: "%d" , i8042_pnp_aux_irq); |
1556 | |
1557 | pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n" , |
1558 | i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "" , |
1559 | i8042_pnp_aux_name, |
1560 | i8042_pnp_data_reg, i8042_pnp_command_reg, |
1561 | kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "" , |
1562 | aux_irq_str); |
1563 | |
1564 | #if defined(__ia64__) |
1565 | if (!i8042_pnp_kbd_devices) |
1566 | i8042_nokbd = true; |
1567 | if (!i8042_pnp_aux_devices) |
1568 | i8042_noaux = true; |
1569 | #endif |
1570 | |
1571 | if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && |
1572 | i8042_pnp_data_reg != i8042_data_reg) || |
1573 | !i8042_pnp_data_reg) { |
1574 | pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n" , |
1575 | i8042_pnp_data_reg, i8042_data_reg); |
1576 | i8042_pnp_data_reg = i8042_data_reg; |
1577 | pnp_data_busted = true; |
1578 | } |
1579 | |
1580 | if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && |
1581 | i8042_pnp_command_reg != i8042_command_reg) || |
1582 | !i8042_pnp_command_reg) { |
1583 | pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n" , |
1584 | i8042_pnp_command_reg, i8042_command_reg); |
1585 | i8042_pnp_command_reg = i8042_command_reg; |
1586 | pnp_data_busted = true; |
1587 | } |
1588 | |
1589 | if (!i8042_nokbd && !i8042_pnp_kbd_irq) { |
1590 | pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n" , |
1591 | i8042_kbd_irq); |
1592 | i8042_pnp_kbd_irq = i8042_kbd_irq; |
1593 | pnp_data_busted = true; |
1594 | } |
1595 | |
1596 | if (!i8042_noaux && !i8042_pnp_aux_irq) { |
1597 | if (!pnp_data_busted && i8042_pnp_kbd_irq) { |
1598 | pr_warn("PNP: PS/2 appears to have AUX port disabled, " |
1599 | "if this is incorrect please boot with i8042.nopnp\n" ); |
1600 | i8042_noaux = true; |
1601 | } else { |
1602 | pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n" , |
1603 | i8042_aux_irq); |
1604 | i8042_pnp_aux_irq = i8042_aux_irq; |
1605 | } |
1606 | } |
1607 | |
1608 | i8042_data_reg = i8042_pnp_data_reg; |
1609 | i8042_command_reg = i8042_pnp_command_reg; |
1610 | i8042_kbd_irq = i8042_pnp_kbd_irq; |
1611 | i8042_aux_irq = i8042_pnp_aux_irq; |
1612 | |
1613 | #ifdef CONFIG_X86 |
1614 | i8042_bypass_aux_irq_test = !pnp_data_busted && |
1615 | dmi_check_system(list: i8042_dmi_laptop_table); |
1616 | #endif |
1617 | |
1618 | return 0; |
1619 | } |
1620 | |
1621 | #else /* !CONFIG_PNP */ |
1622 | static inline int i8042_pnp_init(void) { return 0; } |
1623 | static inline void i8042_pnp_exit(void) { } |
1624 | #endif /* CONFIG_PNP */ |
1625 | |
1626 | |
1627 | #ifdef CONFIG_X86 |
1628 | static void __init i8042_check_quirks(void) |
1629 | { |
1630 | const struct dmi_system_id *device_quirk_info; |
1631 | uintptr_t quirks; |
1632 | |
1633 | device_quirk_info = dmi_first_match(list: i8042_dmi_quirk_table); |
1634 | if (!device_quirk_info) |
1635 | return; |
1636 | |
1637 | quirks = (uintptr_t)device_quirk_info->driver_data; |
1638 | |
1639 | if (quirks & SERIO_QUIRK_NOKBD) |
1640 | i8042_nokbd = true; |
1641 | if (quirks & SERIO_QUIRK_NOAUX) |
1642 | i8042_noaux = true; |
1643 | if (quirks & SERIO_QUIRK_NOMUX) |
1644 | i8042_nomux = true; |
1645 | if (quirks & SERIO_QUIRK_FORCEMUX) |
1646 | i8042_nomux = false; |
1647 | if (quirks & SERIO_QUIRK_UNLOCK) |
1648 | i8042_unlock = true; |
1649 | if (quirks & SERIO_QUIRK_PROBE_DEFER) |
1650 | i8042_probe_defer = true; |
1651 | /* Honor module parameter when value is not default */ |
1652 | if (i8042_reset == I8042_RESET_DEFAULT) { |
1653 | if (quirks & SERIO_QUIRK_RESET_ALWAYS) |
1654 | i8042_reset = I8042_RESET_ALWAYS; |
1655 | if (quirks & SERIO_QUIRK_RESET_NEVER) |
1656 | i8042_reset = I8042_RESET_NEVER; |
1657 | } |
1658 | if (quirks & SERIO_QUIRK_DIECT) |
1659 | i8042_direct = true; |
1660 | if (quirks & SERIO_QUIRK_DUMBKBD) |
1661 | i8042_dumbkbd = true; |
1662 | if (quirks & SERIO_QUIRK_NOLOOP) |
1663 | i8042_noloop = true; |
1664 | if (quirks & SERIO_QUIRK_NOTIMEOUT) |
1665 | i8042_notimeout = true; |
1666 | if (quirks & SERIO_QUIRK_KBDRESET) |
1667 | i8042_kbdreset = true; |
1668 | if (quirks & SERIO_QUIRK_DRITEK) |
1669 | i8042_dritek = true; |
1670 | #ifdef CONFIG_PNP |
1671 | if (quirks & SERIO_QUIRK_NOPNP) |
1672 | i8042_nopnp = true; |
1673 | #endif |
1674 | } |
1675 | #else |
1676 | static inline void i8042_check_quirks(void) {} |
1677 | #endif |
1678 | |
1679 | static int __init i8042_platform_init(void) |
1680 | { |
1681 | int retval; |
1682 | |
1683 | #ifdef CONFIG_X86 |
1684 | u8 a20_on = 0xdf; |
1685 | /* Just return if platform does not have i8042 controller */ |
1686 | if (x86_platform.legacy.i8042 == X86_LEGACY_I8042_PLATFORM_ABSENT) |
1687 | return -ENODEV; |
1688 | #endif |
1689 | |
1690 | /* |
1691 | * On ix86 platforms touching the i8042 data register region can do really |
1692 | * bad things. Because of this the region is always reserved on ix86 boxes. |
1693 | * |
1694 | * if (!request_region(I8042_DATA_REG, 16, "i8042")) |
1695 | * return -EBUSY; |
1696 | */ |
1697 | |
1698 | i8042_kbd_irq = I8042_MAP_IRQ(1); |
1699 | i8042_aux_irq = I8042_MAP_IRQ(12); |
1700 | |
1701 | #if defined(__ia64__) |
1702 | i8042_reset = I8042_RESET_ALWAYS; |
1703 | #endif |
1704 | |
1705 | i8042_check_quirks(); |
1706 | |
1707 | pr_debug("Active quirks (empty means none):%s%s%s%s%s%s%s%s%s%s%s%s%s\n" , |
1708 | i8042_nokbd ? " nokbd" : "" , |
1709 | i8042_noaux ? " noaux" : "" , |
1710 | i8042_nomux ? " nomux" : "" , |
1711 | i8042_unlock ? " unlock" : "" , |
1712 | i8042_probe_defer ? "probe_defer" : "" , |
1713 | i8042_reset == I8042_RESET_DEFAULT ? |
1714 | "" : i8042_reset == I8042_RESET_ALWAYS ? |
1715 | " reset_always" : " reset_never" , |
1716 | i8042_direct ? " direct" : "" , |
1717 | i8042_dumbkbd ? " dumbkbd" : "" , |
1718 | i8042_noloop ? " noloop" : "" , |
1719 | i8042_notimeout ? " notimeout" : "" , |
1720 | i8042_kbdreset ? " kbdreset" : "" , |
1721 | #ifdef CONFIG_X86 |
1722 | i8042_dritek ? " dritek" : "" , |
1723 | #else |
1724 | "" , |
1725 | #endif |
1726 | #ifdef CONFIG_PNP |
1727 | i8042_nopnp ? " nopnp" : "" ); |
1728 | #else |
1729 | "" ); |
1730 | #endif |
1731 | |
1732 | retval = i8042_pnp_init(); |
1733 | if (retval) |
1734 | return retval; |
1735 | |
1736 | #ifdef CONFIG_X86 |
1737 | /* |
1738 | * A20 was already enabled during early kernel init. But some buggy |
1739 | * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to |
1740 | * resume from S3. So we do it here and hope that nothing breaks. |
1741 | */ |
1742 | i8042_command(param: &a20_on, command: 0x10d1); |
1743 | i8042_command(NULL, command: 0x00ff); /* Null command for SMM firmware */ |
1744 | #endif /* CONFIG_X86 */ |
1745 | |
1746 | return retval; |
1747 | } |
1748 | |
1749 | static inline void i8042_platform_exit(void) |
1750 | { |
1751 | i8042_pnp_exit(); |
1752 | } |
1753 | |
1754 | #endif /* _I8042_ACPIPNPIO_H */ |
1755 | |