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