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