Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i8042-x86ia64io.h
Go to the documentation of this file.
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 
50 static inline int i8042_read_data(void)
51 {
52  return inb(I8042_DATA_REG);
53 }
54 
55 static inline int i8042_read_status(void)
56 {
57  return inb(I8042_STATUS_REG);
58 }
59 
60 static inline void i8042_write_data(int val)
61 {
62  outb(val, I8042_DATA_REG);
63 }
64 
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"),
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, "Compaq"),
105  DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
107  },
108  },
109  {
110  .matches = {
111  DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
112  DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
113  DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
114  },
115  },
116  {
117  /* OQO Model 01 */
118  .matches = {
119  DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
120  DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
122  },
123  },
124  {
125  /* ULI EV4873 - AUX LOOP does not work properly */
126  .matches = {
127  DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
128  DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
130  },
131  },
132  {
133  /* Microsoft Virtual Machine */
134  .matches = {
135  DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
136  DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
137  DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
138  },
139  },
140  {
141  /* Medion MAM 2070 */
142  .matches = {
143  DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
144  DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
146  },
147  },
148  {
149  /* Blue FB5601 */
150  .matches = {
151  DMI_MATCH(DMI_SYS_VENDOR, "blue"),
152  DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
154  },
155  },
156  {
157  /* Gigabyte M912 */
158  .matches = {
159  DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
160  DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
162  },
163  },
164  {
165  /* Gigabyte M1022M netbook */
166  .matches = {
167  DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."),
168  DMI_MATCH(DMI_BOARD_NAME, "M1022E"),
169  DMI_MATCH(DMI_BOARD_VERSION, "1.02"),
170  },
171  },
172  {
173  /* Gigabyte Spring Peak - defines wrong chassis type */
174  .matches = {
175  DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
176  DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"),
177  },
178  },
179  {
180  /* Gigabyte T1005 - defines wrong chassis type ("Other") */
181  .matches = {
182  DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
183  DMI_MATCH(DMI_PRODUCT_NAME, "T1005"),
184  },
185  },
186  {
187  /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */
188  .matches = {
189  DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
190  DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"),
191  },
192  },
193  {
194  .matches = {
195  DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
196  DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
197  DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
198  },
199  },
200  { }
201 };
202 
203 /*
204  * Some Fujitsu notebooks are having trouble with touchpads if
205  * active multiplexing mode is activated. Luckily they don't have
206  * external PS/2 ports so we can safely disable it.
207  * ... apparently some Toshibas don't like MUX mode either and
208  * die horrible death on reboot.
209  */
210 static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
211  {
212  /* Fujitsu Lifebook P7010/P7010D */
213  .matches = {
214  DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
215  DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
216  },
217  },
218  {
219  /* Fujitsu Lifebook P7010 */
220  .matches = {
221  DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
222  DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"),
223  },
224  },
225  {
226  /* Fujitsu Lifebook P5020D */
227  .matches = {
228  DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
229  DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
230  },
231  },
232  {
233  /* Fujitsu Lifebook S2000 */
234  .matches = {
235  DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
236  DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
237  },
238  },
239  {
240  /* Fujitsu Lifebook S6230 */
241  .matches = {
242  DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
243  DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
244  },
245  },
246  {
247  /* Fujitsu T70H */
248  .matches = {
249  DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
250  DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
251  },
252  },
253  {
254  /* Fujitsu-Siemens Lifebook T3010 */
255  .matches = {
256  DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
257  DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
258  },
259  },
260  {
261  /* Fujitsu-Siemens Lifebook E4010 */
262  .matches = {
263  DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
264  DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
265  },
266  },
267  {
268  /* Fujitsu-Siemens Amilo Pro 2010 */
269  .matches = {
270  DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
271  DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"),
272  },
273  },
274  {
275  /* Fujitsu-Siemens Amilo Pro 2030 */
276  .matches = {
277  DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
278  DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
279  },
280  },
281  {
282  /*
283  * No data is coming from the touchscreen unless KBC
284  * is in legacy mode.
285  */
286  /* Panasonic CF-29 */
287  .matches = {
288  DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
289  DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
290  },
291  },
292  {
293  /*
294  * HP Pavilion DV4017EA -
295  * errors on MUX ports are reported without raising AUXDATA
296  * causing "spurious NAK" messages.
297  */
298  .matches = {
299  DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
300  DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
301  },
302  },
303  {
304  /*
305  * HP Pavilion ZT1000 -
306  * like DV4017EA does not raise AUXERR for errors on MUX ports.
307  */
308  .matches = {
309  DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
310  DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
311  DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"),
312  },
313  },
314  {
315  /*
316  * HP Pavilion DV4270ca -
317  * like DV4017EA does not raise AUXERR for errors on MUX ports.
318  */
319  .matches = {
320  DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
321  DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"),
322  },
323  },
324  {
325  .matches = {
326  DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
327  DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
328  },
329  },
330  {
331  .matches = {
332  DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
333  DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
334  },
335  },
336  {
337  .matches = {
338  DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
339  DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"),
340  },
341  },
342  {
343  .matches = {
344  DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
345  DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
346  },
347  },
348  {
349  /* Sharp Actius MM20 */
350  .matches = {
351  DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
352  DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
353  },
354  },
355  {
356  /* Sony Vaio FS-115b */
357  .matches = {
358  DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
359  DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
360  },
361  },
362  {
363  /*
364  * Sony Vaio FZ-240E -
365  * reset and GET ID commands issued via KBD port are
366  * sometimes being delivered to AUX3.
367  */
368  .matches = {
369  DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
370  DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
371  },
372  },
373  {
374  /*
375  * Most (all?) VAIOs do not have external PS/2 ports nor
376  * they implement active multiplexing properly, and
377  * MUX discovery usually messes up keyboard/touchpad.
378  */
379  .matches = {
380  DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
381  DMI_MATCH(DMI_BOARD_NAME, "VAIO"),
382  },
383  },
384  {
385  /* Amoi M636/A737 */
386  .matches = {
387  DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
388  DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
389  },
390  },
391  {
392  /* Lenovo 3000 n100 */
393  .matches = {
394  DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
395  DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
396  },
397  },
398  {
399  .matches = {
400  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
401  DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
402  },
403  },
404  {
405  /* Gericom Bellagio */
406  .matches = {
407  DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
408  DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
409  },
410  },
411  {
412  /* IBM 2656 */
413  .matches = {
414  DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
415  DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
416  },
417  },
418  {
419  /* Dell XPS M1530 */
420  .matches = {
421  DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
422  DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
423  },
424  },
425  {
426  /* Compal HEL80I */
427  .matches = {
428  DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
429  DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
430  },
431  },
432  {
433  /* Dell Vostro 1510 */
434  .matches = {
435  DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
436  DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
437  },
438  },
439  {
440  /* Acer Aspire 5536 */
441  .matches = {
442  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
443  DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
445  },
446  },
447  {
448  /* Dell Vostro V13 */
449  .matches = {
450  DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
451  DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
452  },
453  },
454  {
455  /* Newer HP Pavilion dv4 models */
456  .matches = {
457  DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
458  DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
459  },
460  },
461  { }
462 };
463 
464 static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
465  {
466  /* MSI Wind U-100 */
467  .matches = {
468  DMI_MATCH(DMI_BOARD_NAME, "U-100"),
469  DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
470  },
471  },
472  {
473  /* LG Electronics X110 */
474  .matches = {
475  DMI_MATCH(DMI_BOARD_NAME, "X110"),
476  DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
477  },
478  },
479  {
480  /* Acer Aspire One 150 */
481  .matches = {
482  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
483  DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
484  },
485  },
486  {
487  /* Advent 4211 */
488  .matches = {
489  DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
490  DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
491  },
492  },
493  {
494  /* Medion Akoya Mini E1210 */
495  .matches = {
496  DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
497  DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
498  },
499  },
500  {
501  /* Medion Akoya E1222 */
502  .matches = {
503  DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
504  DMI_MATCH(DMI_PRODUCT_NAME, "E122X"),
505  },
506  },
507  {
508  /* Mivvy M310 */
509  .matches = {
510  DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
511  DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
512  },
513  },
514  {
515  /* Dell Vostro 1320 */
516  .matches = {
517  DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
518  DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
519  },
520  },
521  {
522  /* Dell Vostro 1520 */
523  .matches = {
524  DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
525  DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
526  },
527  },
528  {
529  /* Dell Vostro 1720 */
530  .matches = {
531  DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
532  DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
533  },
534  },
535  {
536  /* Lenovo Ideapad U455 */
537  .matches = {
538  DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
539  DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
540  },
541  },
542  { }
543 };
544 
545 #ifdef CONFIG_PNP
546 static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = {
547  {
548  /* Intel MBO Desktop D845PESV */
549  .matches = {
550  DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
551  DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
552  },
553  },
554  {
555  /* MSI Wind U-100 */
556  .matches = {
557  DMI_MATCH(DMI_BOARD_NAME, "U-100"),
558  DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
559  },
560  },
561  { }
562 };
563 
564 static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
565  {
566  .matches = {
567  DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
568  },
569  },
570  {
571  .matches = {
572  DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */
573  },
574  },
575  {
576  .matches = {
577  DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
578  },
579  },
580  {
581  .matches = {
582  DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
583  },
584  },
585  { }
586 };
587 #endif
588 
589 static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
590  {
591  /* Dell Vostro V13 */
592  .matches = {
593  DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
594  DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
595  },
596  },
597  {
598  /* Newer HP Pavilion dv4 models */
599  .matches = {
600  DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
601  DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
602  },
603  },
604  { }
605 };
606 
607 /*
608  * Some Wistron based laptops need us to explicitly enable the 'Dritek
609  * keyboard extension' to make their extra keys start generating scancodes.
610  * Originally, this was just confined to older laptops, but a few Acer laptops
611  * have turned up in 2007 that also need this again.
612  */
613 static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
614  {
615  /* Acer Aspire 5100 */
616  .matches = {
617  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
618  DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
619  },
620  },
621  {
622  /* Acer Aspire 5610 */
623  .matches = {
624  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
625  DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
626  },
627  },
628  {
629  /* Acer Aspire 5630 */
630  .matches = {
631  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
632  DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
633  },
634  },
635  {
636  /* Acer Aspire 5650 */
637  .matches = {
638  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
639  DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
640  },
641  },
642  {
643  /* Acer Aspire 5680 */
644  .matches = {
645  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
646  DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
647  },
648  },
649  {
650  /* Acer Aspire 5720 */
651  .matches = {
652  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
653  DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
654  },
655  },
656  {
657  /* Acer Aspire 9110 */
658  .matches = {
659  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
660  DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
661  },
662  },
663  {
664  /* Acer TravelMate 660 */
665  .matches = {
666  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
667  DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
668  },
669  },
670  {
671  /* Acer TravelMate 2490 */
672  .matches = {
673  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
674  DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
675  },
676  },
677  {
678  /* Acer TravelMate 4280 */
679  .matches = {
680  DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
681  DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
682  },
683  },
684  { }
685 };
686 
687 #endif /* CONFIG_X86 */
688 
689 #ifdef CONFIG_PNP
690 #include <linux/pnp.h>
691 
692 static bool i8042_pnp_kbd_registered;
693 static unsigned int i8042_pnp_kbd_devices;
694 static bool i8042_pnp_aux_registered;
695 static unsigned int i8042_pnp_aux_devices;
696 
697 static int i8042_pnp_command_reg;
698 static int i8042_pnp_data_reg;
699 static int i8042_pnp_kbd_irq;
700 static int i8042_pnp_aux_irq;
701 
702 static char i8042_pnp_kbd_name[32];
703 static char i8042_pnp_aux_name[32];
704 
705 static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
706 {
707  if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
708  i8042_pnp_data_reg = pnp_port_start(dev,0);
709 
710  if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
711  i8042_pnp_command_reg = pnp_port_start(dev, 1);
712 
713  if (pnp_irq_valid(dev,0))
714  i8042_pnp_kbd_irq = pnp_irq(dev, 0);
715 
716  strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name));
717  if (strlen(pnp_dev_name(dev))) {
718  strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name));
719  strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
720  }
721 
722  /* Keyboard ports are always supposed to be wakeup-enabled */
723  device_set_wakeup_enable(&dev->dev, true);
724 
725  i8042_pnp_kbd_devices++;
726  return 0;
727 }
728 
729 static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
730 {
731  if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
732  i8042_pnp_data_reg = pnp_port_start(dev,0);
733 
734  if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
735  i8042_pnp_command_reg = pnp_port_start(dev, 1);
736 
737  if (pnp_irq_valid(dev, 0))
738  i8042_pnp_aux_irq = pnp_irq(dev, 0);
739 
740  strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name));
741  if (strlen(pnp_dev_name(dev))) {
742  strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name));
743  strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name));
744  }
745 
746  i8042_pnp_aux_devices++;
747  return 0;
748 }
749 
750 static struct pnp_device_id pnp_kbd_devids[] = {
751  { .id = "PNP0300", .driver_data = 0 },
752  { .id = "PNP0301", .driver_data = 0 },
753  { .id = "PNP0302", .driver_data = 0 },
754  { .id = "PNP0303", .driver_data = 0 },
755  { .id = "PNP0304", .driver_data = 0 },
756  { .id = "PNP0305", .driver_data = 0 },
757  { .id = "PNP0306", .driver_data = 0 },
758  { .id = "PNP0309", .driver_data = 0 },
759  { .id = "PNP030a", .driver_data = 0 },
760  { .id = "PNP030b", .driver_data = 0 },
761  { .id = "PNP0320", .driver_data = 0 },
762  { .id = "PNP0343", .driver_data = 0 },
763  { .id = "PNP0344", .driver_data = 0 },
764  { .id = "PNP0345", .driver_data = 0 },
765  { .id = "CPQA0D7", .driver_data = 0 },
766  { .id = "", },
767 };
768 
769 static struct pnp_driver i8042_pnp_kbd_driver = {
770  .name = "i8042 kbd",
771  .id_table = pnp_kbd_devids,
772  .probe = i8042_pnp_kbd_probe,
773 };
774 
775 static struct pnp_device_id pnp_aux_devids[] = {
776  { .id = "AUI0200", .driver_data = 0 },
777  { .id = "FJC6000", .driver_data = 0 },
778  { .id = "FJC6001", .driver_data = 0 },
779  { .id = "PNP0f03", .driver_data = 0 },
780  { .id = "PNP0f0b", .driver_data = 0 },
781  { .id = "PNP0f0e", .driver_data = 0 },
782  { .id = "PNP0f12", .driver_data = 0 },
783  { .id = "PNP0f13", .driver_data = 0 },
784  { .id = "PNP0f19", .driver_data = 0 },
785  { .id = "PNP0f1c", .driver_data = 0 },
786  { .id = "SYN0801", .driver_data = 0 },
787  { .id = "", },
788 };
789 
790 static struct pnp_driver i8042_pnp_aux_driver = {
791  .name = "i8042 aux",
792  .id_table = pnp_aux_devids,
793  .probe = i8042_pnp_aux_probe,
794 };
795 
796 static void i8042_pnp_exit(void)
797 {
798  if (i8042_pnp_kbd_registered) {
799  i8042_pnp_kbd_registered = false;
800  pnp_unregister_driver(&i8042_pnp_kbd_driver);
801  }
802 
803  if (i8042_pnp_aux_registered) {
804  i8042_pnp_aux_registered = false;
805  pnp_unregister_driver(&i8042_pnp_aux_driver);
806  }
807 }
808 
809 static int __init i8042_pnp_init(void)
810 {
811  char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
812  bool pnp_data_busted = false;
813  int err;
814 
815 #ifdef CONFIG_X86
816  if (dmi_check_system(i8042_dmi_nopnp_table))
817  i8042_nopnp = true;
818 #endif
819 
820  if (i8042_nopnp) {
821  pr_info("PNP detection disabled\n");
822  return 0;
823  }
824 
825  err = pnp_register_driver(&i8042_pnp_kbd_driver);
826  if (!err)
827  i8042_pnp_kbd_registered = true;
828 
829  err = pnp_register_driver(&i8042_pnp_aux_driver);
830  if (!err)
831  i8042_pnp_aux_registered = true;
832 
833  if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) {
834  i8042_pnp_exit();
835 #if defined(__ia64__)
836  return -ENODEV;
837 #else
838  pr_info("PNP: No PS/2 controller found. Probing ports directly.\n");
839  return 0;
840 #endif
841  }
842 
843  if (i8042_pnp_kbd_devices)
844  snprintf(kbd_irq_str, sizeof(kbd_irq_str),
845  "%d", i8042_pnp_kbd_irq);
846  if (i8042_pnp_aux_devices)
847  snprintf(aux_irq_str, sizeof(aux_irq_str),
848  "%d", i8042_pnp_aux_irq);
849 
850  pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",
851  i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
852  i8042_pnp_aux_name,
853  i8042_pnp_data_reg, i8042_pnp_command_reg,
854  kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
855  aux_irq_str);
856 
857 #if defined(__ia64__)
858  if (!i8042_pnp_kbd_devices)
859  i8042_nokbd = true;
860  if (!i8042_pnp_aux_devices)
861  i8042_noaux = true;
862 #endif
863 
864  if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&
865  i8042_pnp_data_reg != i8042_data_reg) ||
866  !i8042_pnp_data_reg) {
867  pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n",
868  i8042_pnp_data_reg, i8042_data_reg);
869  i8042_pnp_data_reg = i8042_data_reg;
870  pnp_data_busted = true;
871  }
872 
873  if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) &&
874  i8042_pnp_command_reg != i8042_command_reg) ||
875  !i8042_pnp_command_reg) {
876  pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n",
877  i8042_pnp_command_reg, i8042_command_reg);
878  i8042_pnp_command_reg = i8042_command_reg;
879  pnp_data_busted = true;
880  }
881 
882  if (!i8042_nokbd && !i8042_pnp_kbd_irq) {
883  pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n",
884  i8042_kbd_irq);
885  i8042_pnp_kbd_irq = i8042_kbd_irq;
886  pnp_data_busted = true;
887  }
888 
889  if (!i8042_noaux && !i8042_pnp_aux_irq) {
890  if (!pnp_data_busted && i8042_pnp_kbd_irq) {
891  pr_warn("PNP: PS/2 appears to have AUX port disabled, "
892  "if this is incorrect please boot with i8042.nopnp\n");
893  i8042_noaux = true;
894  } else {
895  pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n",
896  i8042_aux_irq);
897  i8042_pnp_aux_irq = i8042_aux_irq;
898  }
899  }
900 
901  i8042_data_reg = i8042_pnp_data_reg;
902  i8042_command_reg = i8042_pnp_command_reg;
903  i8042_kbd_irq = i8042_pnp_kbd_irq;
904  i8042_aux_irq = i8042_pnp_aux_irq;
905 
906 #ifdef CONFIG_X86
907  i8042_bypass_aux_irq_test = !pnp_data_busted &&
908  dmi_check_system(i8042_dmi_laptop_table);
909 #endif
910 
911  return 0;
912 }
913 
914 #else
915 static inline int i8042_pnp_init(void) { return 0; }
916 static inline void i8042_pnp_exit(void) { }
917 #endif
918 
919 static int __init i8042_platform_init(void)
920 {
921  int retval;
922 
923 #ifdef CONFIG_X86
924  /* Just return if pre-detection shows no i8042 controller exist */
925  if (!x86_platform.i8042_detect())
926  return -ENODEV;
927 #endif
928 
929 /*
930  * On ix86 platforms touching the i8042 data register region can do really
931  * bad things. Because of this the region is always reserved on ix86 boxes.
932  *
933  * if (!request_region(I8042_DATA_REG, 16, "i8042"))
934  * return -EBUSY;
935  */
936 
937  i8042_kbd_irq = I8042_MAP_IRQ(1);
938  i8042_aux_irq = I8042_MAP_IRQ(12);
939 
940  retval = i8042_pnp_init();
941  if (retval)
942  return retval;
943 
944 #if defined(__ia64__)
945  i8042_reset = true;
946 #endif
947 
948 #ifdef CONFIG_X86
949  if (dmi_check_system(i8042_dmi_reset_table))
950  i8042_reset = true;
951 
952  if (dmi_check_system(i8042_dmi_noloop_table))
953  i8042_noloop = true;
954 
955  if (dmi_check_system(i8042_dmi_nomux_table))
956  i8042_nomux = true;
957 
958  if (dmi_check_system(i8042_dmi_notimeout_table))
959  i8042_notimeout = true;
960 
961  if (dmi_check_system(i8042_dmi_dritek_table))
962  i8042_dritek = true;
963 #endif /* CONFIG_X86 */
964 
965  return retval;
966 }
967 
968 static inline void i8042_platform_exit(void)
969 {
970  i8042_pnp_exit();
971 }
972 
973 #endif /* _I8042_X86IA64IO_H */