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