1 #ifndef _I8042_X86IA64IO_H
2 #define _I8042_X86IA64IO_H
3 
4 /*
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 as published by
7  * the Free Software Foundation.
8  */
9 
10 #ifdef CONFIG_X86
11 #include <asm/x86_init.h>
12 #endif
13 
14 /*
15  * Names.
16  */
17 
18 #define I8042_KBD_PHYS_DESC "isa0060/serio0"
19 #define I8042_AUX_PHYS_DESC "isa0060/serio1"
20 #define I8042_MUX_PHYS_DESC "isa0060/serio%d"
21 
22 /*
23  * IRQs.
24  */
25 
26 #if defined(__ia64__)
27 # define I8042_MAP_IRQ(x)	isa_irq_to_vector((x))
28 #else
29 # define I8042_MAP_IRQ(x)	(x)
30 #endif
31 
32 #define I8042_KBD_IRQ	i8042_kbd_irq
33 #define I8042_AUX_IRQ	i8042_aux_irq
34 
35 static int i8042_kbd_irq;
36 static int i8042_aux_irq;
37 
38 /*
39  * Register numbers.
40  */
41 
42 #define I8042_COMMAND_REG	i8042_command_reg
43 #define I8042_STATUS_REG	i8042_command_reg
44 #define I8042_DATA_REG		i8042_data_reg
45 
46 static int i8042_command_reg = 0x64;
47 static int i8042_data_reg = 0x60;
48 
49 
i8042_read_data(void)50 static inline int i8042_read_data(void)
51 {
52 	return inb(I8042_DATA_REG);
53 }
54 
i8042_read_status(void)55 static inline int i8042_read_status(void)
56 {
57 	return inb(I8042_STATUS_REG);
58 }
59 
i8042_write_data(int val)60 static inline void i8042_write_data(int val)
61 {
62 	outb(val, I8042_DATA_REG);
63 }
64 
i8042_write_command(int val)65 static inline void i8042_write_command(int val)
66 {
67 	outb(val, I8042_COMMAND_REG);
68 }
69 
70 #ifdef CONFIG_X86
71 
72 #include <linux/dmi.h>
73 
74 static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
75 	{
76 		/*
77 		 * Arima-Rioworks HDAMB -
78 		 * AUX LOOP command does not raise AUX IRQ
79 		 */
80 		.matches = {
81 			DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
82 			DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
83 			DMI_MATCH(DMI_BOARD_VERSION, "Rev E"),
84 		},
85 	},
86 	{
87 		/* ASUS G1S */
88 		.matches = {
89 			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
90 			DMI_MATCH(DMI_BOARD_NAME, "G1S"),
91 			DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
92 		},
93 	},
94 	{
95 		/* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */
96 		.matches = {
97 			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
98 			DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"),
99 			DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X"),
100 		},
101 	},
102 	{
103 		.matches = {
104 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
105 			DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"),
106 		},
107 	},
108 	{
109 		.matches = {
110 			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
111 			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
112 			DMI_MATCH(DMI_PRODUCT_VERSION, "8500"),
113 		},
114 	},
115 	{
116 		.matches = {
117 			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
118 			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
119 			DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
120 		},
121 	},
122 	{
123 		/* OQO Model 01 */
124 		.matches = {
125 			DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
126 			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
127 			DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
128 		},
129 	},
130 	{
131 		/* ULI EV4873 - AUX LOOP does not work properly */
132 		.matches = {
133 			DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
134 			DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
135 			DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
136 		},
137 	},
138 	{
139 		/* Microsoft Virtual Machine */
140 		.matches = {
141 			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
142 			DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
143 			DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
144 		},
145 	},
146 	{
147 		/* Medion MAM 2070 */
148 		.matches = {
149 			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
150 			DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
151 			DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
152 		},
153 	},
154 	{
155 		/* Medion Akoya E7225 */
156 		.matches = {
157 			DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
158 			DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"),
159 			DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
160 		},
161 	},
162 	{
163 		/* Blue FB5601 */
164 		.matches = {
165 			DMI_MATCH(DMI_SYS_VENDOR, "blue"),
166 			DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
167 			DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
168 		},
169 	},
170 	{
171 		/* Gigabyte M912 */
172 		.matches = {
173 			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
174 			DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
175 			DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
176 		},
177 	},
178 	{
179 		/* Gigabyte M1022M netbook */
180 		.matches = {
181 			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."),
182 			DMI_MATCH(DMI_BOARD_NAME, "M1022E"),
183 			DMI_MATCH(DMI_BOARD_VERSION, "1.02"),
184 		},
185 	},
186 	{
187 		/* Gigabyte Spring Peak - defines wrong chassis type */
188 		.matches = {
189 			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
190 			DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"),
191 		},
192 	},
193 	{
194 		/* Gigabyte T1005 - defines wrong chassis type ("Other") */
195 		.matches = {
196 			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
197 			DMI_MATCH(DMI_PRODUCT_NAME, "T1005"),
198 		},
199 	},
200 	{
201 		/* Gigabyte T1005M/P - defines wrong chassis type ("Other") */
202 		.matches = {
203 			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
204 			DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"),
205 		},
206 	},
207 	{
208 		.matches = {
209 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
210 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
211 			DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
212 		},
213 	},
214 	{ }
215 };
216 
217 /*
218  * Some Fujitsu notebooks are having trouble with touchpads if
219  * active multiplexing mode is activated. Luckily they don't have
220  * external PS/2 ports so we can safely disable it.
221  * ... apparently some Toshibas don't like MUX mode either and
222  * die horrible death on reboot.
223  */
224 static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
225 	{
226 		/* Fujitsu Lifebook P7010/P7010D */
227 		.matches = {
228 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
229 			DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
230 		},
231 	},
232 	{
233 		/* Fujitsu Lifebook P7010 */
234 		.matches = {
235 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
236 			DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"),
237 		},
238 	},
239 	{
240 		/* Fujitsu Lifebook P5020D */
241 		.matches = {
242 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
243 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
244 		},
245 	},
246 	{
247 		/* Fujitsu Lifebook S2000 */
248 		.matches = {
249 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
250 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
251 		},
252 	},
253 	{
254 		/* Fujitsu Lifebook S6230 */
255 		.matches = {
256 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
257 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
258 		},
259 	},
260 	{
261 		/* Fujitsu Lifebook U745 */
262 		.matches = {
263 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
264 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"),
265 		},
266 	},
267 	{
268 		/* Fujitsu T70H */
269 		.matches = {
270 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
271 			DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
272 		},
273 	},
274 	{
275 		/* Fujitsu-Siemens Lifebook T3010 */
276 		.matches = {
277 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
278 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
279 		},
280 	},
281 	{
282 		/* Fujitsu-Siemens Lifebook E4010 */
283 		.matches = {
284 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
285 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
286 		},
287 	},
288 	{
289 		/* Fujitsu-Siemens Amilo Pro 2010 */
290 		.matches = {
291 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
292 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"),
293 		},
294 	},
295 	{
296 		/* Fujitsu-Siemens Amilo Pro 2030 */
297 		.matches = {
298 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
299 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
300 		},
301 	},
302 	{
303 		/*
304 		 * No data is coming from the touchscreen unless KBC
305 		 * is in legacy mode.
306 		 */
307 		/* Panasonic CF-29 */
308 		.matches = {
309 			DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
310 			DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
311 		},
312 	},
313 	{
314 		/*
315 		 * HP Pavilion DV4017EA -
316 		 * errors on MUX ports are reported without raising AUXDATA
317 		 * causing "spurious NAK" messages.
318 		 */
319 		.matches = {
320 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
321 			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
322 		},
323 	},
324 	{
325 		/*
326 		 * HP Pavilion ZT1000 -
327 		 * like DV4017EA does not raise AUXERR for errors on MUX ports.
328 		 */
329 		.matches = {
330 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
331 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
332 			DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"),
333 		},
334 	},
335 	{
336 		/*
337 		 * HP Pavilion DV4270ca -
338 		 * like DV4017EA does not raise AUXERR for errors on MUX ports.
339 		 */
340 		.matches = {
341 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
342 			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"),
343 		},
344 	},
345 	{
346 		.matches = {
347 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
348 			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
349 		},
350 	},
351 	{
352 		.matches = {
353 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
354 			DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
355 		},
356 	},
357 	{
358 		.matches = {
359 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
360 			DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"),
361 		},
362 	},
363 	{
364 		.matches = {
365 			DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
366 			DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
367 		},
368 	},
369 	{
370 		/* Sharp Actius MM20 */
371 		.matches = {
372 			DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
373 			DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
374 		},
375 	},
376 	{
377 		/* Sony Vaio FS-115b */
378 		.matches = {
379 			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
380 			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
381 		},
382 	},
383 	{
384 		/*
385 		 * Sony Vaio FZ-240E -
386 		 * reset and GET ID commands issued via KBD port are
387 		 * sometimes being delivered to AUX3.
388 		 */
389 		.matches = {
390 			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
391 			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
392 		},
393 	},
394 	{
395 		/*
396 		 * Most (all?) VAIOs do not have external PS/2 ports nor
397 		 * they implement active multiplexing properly, and
398 		 * MUX discovery usually messes up keyboard/touchpad.
399 		 */
400 		.matches = {
401 			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
402 			DMI_MATCH(DMI_BOARD_NAME, "VAIO"),
403 		},
404 	},
405 	{
406 		/* Amoi M636/A737 */
407 		.matches = {
408 			DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
409 			DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
410 		},
411 	},
412 	{
413 		/* Lenovo 3000 n100 */
414 		.matches = {
415 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
416 			DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
417 		},
418 	},
419 	{
420 		.matches = {
421 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
422 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
423 		},
424 	},
425 	{
426 		/* Acer Aspire 5710 */
427 		.matches = {
428 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
429 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"),
430 		},
431 	},
432 	{
433 		/* Acer Aspire 7738 */
434 		.matches = {
435 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
436 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"),
437 		},
438 	},
439 	{
440 		/* Gericom Bellagio */
441 		.matches = {
442 			DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
443 			DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
444 		},
445 	},
446 	{
447 		/* IBM 2656 */
448 		.matches = {
449 			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
450 			DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
451 		},
452 	},
453 	{
454 		/* Dell XPS M1530 */
455 		.matches = {
456 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
457 			DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
458 		},
459 	},
460 	{
461 		/* Compal HEL80I */
462 		.matches = {
463 			DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
464 			DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
465 		},
466 	},
467 	{
468 		/* Dell Vostro 1510 */
469 		.matches = {
470 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
471 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
472 		},
473 	},
474 	{
475 		/* Acer Aspire 5536 */
476 		.matches = {
477 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
478 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
479 			DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
480 		},
481 	},
482 	{
483 		/* Dell Vostro V13 */
484 		.matches = {
485 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
486 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
487 		},
488 	},
489 	{
490 		/* Newer HP Pavilion dv4 models */
491 		.matches = {
492 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
493 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
494 		},
495 	},
496 	{
497 		/* Asus X450LCP */
498 		.matches = {
499 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
500 			DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"),
501 		},
502 	},
503 	{
504 		/* Avatar AVIU-145A6 */
505 		.matches = {
506 			DMI_MATCH(DMI_SYS_VENDOR, "Intel"),
507 			DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"),
508 		},
509 	},
510 	{ }
511 };
512 
513 static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
514 	{
515 		/* MSI Wind U-100 */
516 		.matches = {
517 			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
518 			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
519 		},
520 	},
521 	{
522 		/* LG Electronics X110 */
523 		.matches = {
524 			DMI_MATCH(DMI_BOARD_NAME, "X110"),
525 			DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
526 		},
527 	},
528 	{
529 		/* Acer Aspire One 150 */
530 		.matches = {
531 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
532 			DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
533 		},
534 	},
535 	{
536 		/* Advent 4211 */
537 		.matches = {
538 			DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
539 			DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
540 		},
541 	},
542 	{
543 		/* Medion Akoya Mini E1210 */
544 		.matches = {
545 			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
546 			DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
547 		},
548 	},
549 	{
550 		/* Medion Akoya E1222 */
551 		.matches = {
552 			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
553 			DMI_MATCH(DMI_PRODUCT_NAME, "E122X"),
554 		},
555 	},
556 	{
557 		/* Mivvy M310 */
558 		.matches = {
559 			DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
560 			DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
561 		},
562 	},
563 	{
564 		/* Dell Vostro 1320 */
565 		.matches = {
566 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
567 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
568 		},
569 	},
570 	{
571 		/* Dell Vostro 1520 */
572 		.matches = {
573 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
574 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
575 		},
576 	},
577 	{
578 		/* Dell Vostro 1720 */
579 		.matches = {
580 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
581 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
582 		},
583 	},
584 	{
585 		/* Lenovo Ideapad U455 */
586 		.matches = {
587 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
588 			DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
589 		},
590 	},
591 	{ }
592 };
593 
594 #ifdef CONFIG_PNP
595 static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = {
596 	{
597 		/* Intel MBO Desktop D845PESV */
598 		.matches = {
599 			DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
600 			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
601 		},
602 	},
603 	{
604 		/*
605 		 * Intel NUC D54250WYK - does not have i8042 controller but
606 		 * declares PS/2 devices in DSDT.
607 		 */
608 		.matches = {
609 			DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"),
610 			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
611 		},
612 	},
613 	{
614 		/* MSI Wind U-100 */
615 		.matches = {
616 			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
617 			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
618 		},
619 	},
620 	{ }
621 };
622 
623 static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
624 	{
625 		.matches = {
626 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
627 		},
628 	},
629 	{
630 		.matches = {
631 			DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */
632 		},
633 	},
634 	{
635 		.matches = {
636 			DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
637 		},
638 	},
639 	{
640 		.matches = {
641 			DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
642 		},
643 	},
644 	{ }
645 };
646 #endif
647 
648 static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
649 	{
650 		/* Dell Vostro V13 */
651 		.matches = {
652 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
653 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
654 		},
655 	},
656 	{
657 		/* Newer HP Pavilion dv4 models */
658 		.matches = {
659 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
660 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
661 		},
662 	},
663 	{
664 		/* Fujitsu A544 laptop */
665 		/* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */
666 		.matches = {
667 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
668 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"),
669 		},
670 	},
671 	{
672 		/* Fujitsu AH544 laptop */
673 		/* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
674 		.matches = {
675 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
676 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"),
677 		},
678 	},
679 	{
680 		/* Fujitsu U574 laptop */
681 		/* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
682 		.matches = {
683 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
684 			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"),
685 		},
686 	},
687 	{ }
688 };
689 
690 /*
691  * Some Wistron based laptops need us to explicitly enable the 'Dritek
692  * keyboard extension' to make their extra keys start generating scancodes.
693  * Originally, this was just confined to older laptops, but a few Acer laptops
694  * have turned up in 2007 that also need this again.
695  */
696 static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
697 	{
698 		/* Acer Aspire 5100 */
699 		.matches = {
700 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
701 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
702 		},
703 	},
704 	{
705 		/* Acer Aspire 5610 */
706 		.matches = {
707 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
708 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
709 		},
710 	},
711 	{
712 		/* Acer Aspire 5630 */
713 		.matches = {
714 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
715 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
716 		},
717 	},
718 	{
719 		/* Acer Aspire 5650 */
720 		.matches = {
721 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
722 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
723 		},
724 	},
725 	{
726 		/* Acer Aspire 5680 */
727 		.matches = {
728 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
729 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
730 		},
731 	},
732 	{
733 		/* Acer Aspire 5720 */
734 		.matches = {
735 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
736 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
737 		},
738 	},
739 	{
740 		/* Acer Aspire 9110 */
741 		.matches = {
742 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
743 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
744 		},
745 	},
746 	{
747 		/* Acer TravelMate 660 */
748 		.matches = {
749 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
750 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
751 		},
752 	},
753 	{
754 		/* Acer TravelMate 2490 */
755 		.matches = {
756 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
757 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
758 		},
759 	},
760 	{
761 		/* Acer TravelMate 4280 */
762 		.matches = {
763 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
764 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
765 		},
766 	},
767 	{ }
768 };
769 
770 /*
771  * Some laptops need keyboard reset before probing for the trackpad to get
772  * it detected, initialised & finally work.
773  */
774 static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = {
775 	{
776 		/* Gigabyte P35 v2 - Elantech touchpad */
777 		.matches = {
778 			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
779 			DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"),
780 		},
781 	},
782 		{
783 		/* Aorus branded Gigabyte X3 Plus - Elantech touchpad */
784 		.matches = {
785 			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
786 			DMI_MATCH(DMI_PRODUCT_NAME, "X3"),
787 		},
788 	},
789 	{
790 		/* Gigabyte P34 - Elantech touchpad */
791 		.matches = {
792 			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
793 			DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
794 		},
795 	},
796 	{ }
797 };
798 
799 #endif /* CONFIG_X86 */
800 
801 #ifdef CONFIG_PNP
802 #include <linux/pnp.h>
803 
804 static bool i8042_pnp_kbd_registered;
805 static unsigned int i8042_pnp_kbd_devices;
806 static bool i8042_pnp_aux_registered;
807 static unsigned int i8042_pnp_aux_devices;
808 
809 static int i8042_pnp_command_reg;
810 static int i8042_pnp_data_reg;
811 static int i8042_pnp_kbd_irq;
812 static int i8042_pnp_aux_irq;
813 
814 static char i8042_pnp_kbd_name[32];
815 static char i8042_pnp_aux_name[32];
816 
i8042_pnp_id_to_string(struct pnp_id * id,char * dst,int dst_size)817 static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size)
818 {
819 	strlcpy(dst, "PNP:", dst_size);
820 
821 	while (id) {
822 		strlcat(dst, " ", dst_size);
823 		strlcat(dst, id->id, dst_size);
824 		id = id->next;
825 	}
826 }
827 
i8042_pnp_kbd_probe(struct pnp_dev * dev,const struct pnp_device_id * did)828 static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
829 {
830 	if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
831 		i8042_pnp_data_reg = pnp_port_start(dev,0);
832 
833 	if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
834 		i8042_pnp_command_reg = pnp_port_start(dev, 1);
835 
836 	if (pnp_irq_valid(dev,0))
837 		i8042_pnp_kbd_irq = pnp_irq(dev, 0);
838 
839 	strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name));
840 	if (strlen(pnp_dev_name(dev))) {
841 		strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name));
842 		strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
843 	}
844 	i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id,
845 			       sizeof(i8042_kbd_firmware_id));
846 
847 	/* Keyboard ports are always supposed to be wakeup-enabled */
848 	device_set_wakeup_enable(&dev->dev, true);
849 
850 	i8042_pnp_kbd_devices++;
851 	return 0;
852 }
853 
i8042_pnp_aux_probe(struct pnp_dev * dev,const struct pnp_device_id * did)854 static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
855 {
856 	if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
857 		i8042_pnp_data_reg = pnp_port_start(dev,0);
858 
859 	if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
860 		i8042_pnp_command_reg = pnp_port_start(dev, 1);
861 
862 	if (pnp_irq_valid(dev, 0))
863 		i8042_pnp_aux_irq = pnp_irq(dev, 0);
864 
865 	strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name));
866 	if (strlen(pnp_dev_name(dev))) {
867 		strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name));
868 		strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name));
869 	}
870 	i8042_pnp_id_to_string(dev->id, i8042_aux_firmware_id,
871 			       sizeof(i8042_aux_firmware_id));
872 
873 	i8042_pnp_aux_devices++;
874 	return 0;
875 }
876 
877 static struct pnp_device_id pnp_kbd_devids[] = {
878 	{ .id = "PNP0300", .driver_data = 0 },
879 	{ .id = "PNP0301", .driver_data = 0 },
880 	{ .id = "PNP0302", .driver_data = 0 },
881 	{ .id = "PNP0303", .driver_data = 0 },
882 	{ .id = "PNP0304", .driver_data = 0 },
883 	{ .id = "PNP0305", .driver_data = 0 },
884 	{ .id = "PNP0306", .driver_data = 0 },
885 	{ .id = "PNP0309", .driver_data = 0 },
886 	{ .id = "PNP030a", .driver_data = 0 },
887 	{ .id = "PNP030b", .driver_data = 0 },
888 	{ .id = "PNP0320", .driver_data = 0 },
889 	{ .id = "PNP0343", .driver_data = 0 },
890 	{ .id = "PNP0344", .driver_data = 0 },
891 	{ .id = "PNP0345", .driver_data = 0 },
892 	{ .id = "CPQA0D7", .driver_data = 0 },
893 	{ .id = "", },
894 };
895 MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids);
896 
897 static struct pnp_driver i8042_pnp_kbd_driver = {
898 	.name           = "i8042 kbd",
899 	.id_table       = pnp_kbd_devids,
900 	.probe          = i8042_pnp_kbd_probe,
901 };
902 
903 static struct pnp_device_id pnp_aux_devids[] = {
904 	{ .id = "AUI0200", .driver_data = 0 },
905 	{ .id = "FJC6000", .driver_data = 0 },
906 	{ .id = "FJC6001", .driver_data = 0 },
907 	{ .id = "PNP0f03", .driver_data = 0 },
908 	{ .id = "PNP0f0b", .driver_data = 0 },
909 	{ .id = "PNP0f0e", .driver_data = 0 },
910 	{ .id = "PNP0f12", .driver_data = 0 },
911 	{ .id = "PNP0f13", .driver_data = 0 },
912 	{ .id = "PNP0f19", .driver_data = 0 },
913 	{ .id = "PNP0f1c", .driver_data = 0 },
914 	{ .id = "SYN0801", .driver_data = 0 },
915 	{ .id = "", },
916 };
917 MODULE_DEVICE_TABLE(pnp, pnp_aux_devids);
918 
919 static struct pnp_driver i8042_pnp_aux_driver = {
920 	.name           = "i8042 aux",
921 	.id_table       = pnp_aux_devids,
922 	.probe          = i8042_pnp_aux_probe,
923 };
924 
i8042_pnp_exit(void)925 static void i8042_pnp_exit(void)
926 {
927 	if (i8042_pnp_kbd_registered) {
928 		i8042_pnp_kbd_registered = false;
929 		pnp_unregister_driver(&i8042_pnp_kbd_driver);
930 	}
931 
932 	if (i8042_pnp_aux_registered) {
933 		i8042_pnp_aux_registered = false;
934 		pnp_unregister_driver(&i8042_pnp_aux_driver);
935 	}
936 }
937 
i8042_pnp_init(void)938 static int __init i8042_pnp_init(void)
939 {
940 	char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
941 	bool pnp_data_busted = false;
942 	int err;
943 
944 #ifdef CONFIG_X86
945 	if (dmi_check_system(i8042_dmi_nopnp_table))
946 		i8042_nopnp = true;
947 #endif
948 
949 	if (i8042_nopnp) {
950 		pr_info("PNP detection disabled\n");
951 		return 0;
952 	}
953 
954 	err = pnp_register_driver(&i8042_pnp_kbd_driver);
955 	if (!err)
956 		i8042_pnp_kbd_registered = true;
957 
958 	err = pnp_register_driver(&i8042_pnp_aux_driver);
959 	if (!err)
960 		i8042_pnp_aux_registered = true;
961 
962 	if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) {
963 		i8042_pnp_exit();
964 #if defined(__ia64__)
965 		return -ENODEV;
966 #else
967 		pr_info("PNP: No PS/2 controller found. Probing ports directly.\n");
968 		return 0;
969 #endif
970 	}
971 
972 	if (i8042_pnp_kbd_devices)
973 		snprintf(kbd_irq_str, sizeof(kbd_irq_str),
974 			"%d", i8042_pnp_kbd_irq);
975 	if (i8042_pnp_aux_devices)
976 		snprintf(aux_irq_str, sizeof(aux_irq_str),
977 			"%d", i8042_pnp_aux_irq);
978 
979 	pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",
980 		i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
981 		i8042_pnp_aux_name,
982 		i8042_pnp_data_reg, i8042_pnp_command_reg,
983 		kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
984 		aux_irq_str);
985 
986 #if defined(__ia64__)
987 	if (!i8042_pnp_kbd_devices)
988 		i8042_nokbd = true;
989 	if (!i8042_pnp_aux_devices)
990 		i8042_noaux = true;
991 #endif
992 
993 	if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&
994 	      i8042_pnp_data_reg != i8042_data_reg) ||
995 	    !i8042_pnp_data_reg) {
996 		pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n",
997 			i8042_pnp_data_reg, i8042_data_reg);
998 		i8042_pnp_data_reg = i8042_data_reg;
999 		pnp_data_busted = true;
1000 	}
1001 
1002 	if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) &&
1003 	      i8042_pnp_command_reg != i8042_command_reg) ||
1004 	    !i8042_pnp_command_reg) {
1005 		pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n",
1006 			i8042_pnp_command_reg, i8042_command_reg);
1007 		i8042_pnp_command_reg = i8042_command_reg;
1008 		pnp_data_busted = true;
1009 	}
1010 
1011 	if (!i8042_nokbd && !i8042_pnp_kbd_irq) {
1012 		pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n",
1013 			i8042_kbd_irq);
1014 		i8042_pnp_kbd_irq = i8042_kbd_irq;
1015 		pnp_data_busted = true;
1016 	}
1017 
1018 	if (!i8042_noaux && !i8042_pnp_aux_irq) {
1019 		if (!pnp_data_busted && i8042_pnp_kbd_irq) {
1020 			pr_warn("PNP: PS/2 appears to have AUX port disabled, "
1021 				"if this is incorrect please boot with i8042.nopnp\n");
1022 			i8042_noaux = true;
1023 		} else {
1024 			pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n",
1025 				i8042_aux_irq);
1026 			i8042_pnp_aux_irq = i8042_aux_irq;
1027 		}
1028 	}
1029 
1030 	i8042_data_reg = i8042_pnp_data_reg;
1031 	i8042_command_reg = i8042_pnp_command_reg;
1032 	i8042_kbd_irq = i8042_pnp_kbd_irq;
1033 	i8042_aux_irq = i8042_pnp_aux_irq;
1034 
1035 #ifdef CONFIG_X86
1036 	i8042_bypass_aux_irq_test = !pnp_data_busted &&
1037 				    dmi_check_system(i8042_dmi_laptop_table);
1038 #endif
1039 
1040 	return 0;
1041 }
1042 
1043 #else
i8042_pnp_init(void)1044 static inline int i8042_pnp_init(void) { return 0; }
i8042_pnp_exit(void)1045 static inline void i8042_pnp_exit(void) { }
1046 #endif
1047 
i8042_platform_init(void)1048 static int __init i8042_platform_init(void)
1049 {
1050 	int retval;
1051 
1052 #ifdef CONFIG_X86
1053 	u8 a20_on = 0xdf;
1054 	/* Just return if pre-detection shows no i8042 controller exist */
1055 	if (!x86_platform.i8042_detect())
1056 		return -ENODEV;
1057 #endif
1058 
1059 /*
1060  * On ix86 platforms touching the i8042 data register region can do really
1061  * bad things. Because of this the region is always reserved on ix86 boxes.
1062  *
1063  *	if (!request_region(I8042_DATA_REG, 16, "i8042"))
1064  *		return -EBUSY;
1065  */
1066 
1067 	i8042_kbd_irq = I8042_MAP_IRQ(1);
1068 	i8042_aux_irq = I8042_MAP_IRQ(12);
1069 
1070 	retval = i8042_pnp_init();
1071 	if (retval)
1072 		return retval;
1073 
1074 #if defined(__ia64__)
1075         i8042_reset = true;
1076 #endif
1077 
1078 #ifdef CONFIG_X86
1079 	if (dmi_check_system(i8042_dmi_reset_table))
1080 		i8042_reset = true;
1081 
1082 	if (dmi_check_system(i8042_dmi_noloop_table))
1083 		i8042_noloop = true;
1084 
1085 	if (dmi_check_system(i8042_dmi_nomux_table))
1086 		i8042_nomux = true;
1087 
1088 	if (dmi_check_system(i8042_dmi_notimeout_table))
1089 		i8042_notimeout = true;
1090 
1091 	if (dmi_check_system(i8042_dmi_dritek_table))
1092 		i8042_dritek = true;
1093 
1094 	if (dmi_check_system(i8042_dmi_kbdreset_table))
1095 		i8042_kbdreset = true;
1096 
1097 	/*
1098 	 * A20 was already enabled during early kernel init. But some buggy
1099 	 * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to
1100 	 * resume from S3. So we do it here and hope that nothing breaks.
1101 	 */
1102 	i8042_command(&a20_on, 0x10d1);
1103 	i8042_command(NULL, 0x00ff);	/* Null command for SMM firmware */
1104 #endif /* CONFIG_X86 */
1105 
1106 	return retval;
1107 }
1108 
i8042_platform_exit(void)1109 static inline void i8042_platform_exit(void)
1110 {
1111 	i8042_pnp_exit();
1112 }
1113 
1114 #endif /* _I8042_X86IA64IO_H */
1115