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
35static int i8042_kbd_irq;
36static 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
46static int i8042_command_reg = 0x64;
47static int i8042_data_reg = 0x60;
48
49
50static inline int i8042_read_data(void)
51{
52	return inb(I8042_DATA_REG);
53}
54
55static inline int i8042_read_status(void)
56{
57	return inb(I8042_STATUS_REG);
58}
59
60static inline void i8042_write_data(int val)
61{
62	outb(val, I8042_DATA_REG);
63}
64
65static 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
74static 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 */
224static 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
513static 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
595static 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
623static 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
648static 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 */
696static 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 */
774static 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
804static bool i8042_pnp_kbd_registered;
805static unsigned int i8042_pnp_kbd_devices;
806static bool i8042_pnp_aux_registered;
807static unsigned int i8042_pnp_aux_devices;
808
809static int i8042_pnp_command_reg;
810static int i8042_pnp_data_reg;
811static int i8042_pnp_kbd_irq;
812static int i8042_pnp_aux_irq;
813
814static char i8042_pnp_kbd_name[32];
815static char i8042_pnp_aux_name[32];
816
817static 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
828static 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
854static 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
877static 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};
895MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids);
896
897static 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
903static 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};
917MODULE_DEVICE_TABLE(pnp, pnp_aux_devids);
918
919static 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
925static 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
938static 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
1044static inline int i8042_pnp_init(void) { return 0; }
1045static inline void i8042_pnp_exit(void) { }
1046#endif
1047
1048static 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
1109static inline void i8042_platform_exit(void)
1110{
1111	i8042_pnp_exit();
1112}
1113
1114#endif /* _I8042_X86IA64IO_H */
1115