Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.26 615 lines 15 kB view raw
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/* 11 * Names. 12 */ 13 14#define I8042_KBD_PHYS_DESC "isa0060/serio0" 15#define I8042_AUX_PHYS_DESC "isa0060/serio1" 16#define I8042_MUX_PHYS_DESC "isa0060/serio%d" 17 18/* 19 * IRQs. 20 */ 21 22#if defined(__ia64__) 23# define I8042_MAP_IRQ(x) isa_irq_to_vector((x)) 24#else 25# define I8042_MAP_IRQ(x) (x) 26#endif 27 28#define I8042_KBD_IRQ i8042_kbd_irq 29#define I8042_AUX_IRQ i8042_aux_irq 30 31static int i8042_kbd_irq; 32static int i8042_aux_irq; 33 34/* 35 * Register numbers. 36 */ 37 38#define I8042_COMMAND_REG i8042_command_reg 39#define I8042_STATUS_REG i8042_command_reg 40#define I8042_DATA_REG i8042_data_reg 41 42static int i8042_command_reg = 0x64; 43static int i8042_data_reg = 0x60; 44 45 46static inline int i8042_read_data(void) 47{ 48 return inb(I8042_DATA_REG); 49} 50 51static inline int i8042_read_status(void) 52{ 53 return inb(I8042_STATUS_REG); 54} 55 56static inline void i8042_write_data(int val) 57{ 58 outb(val, I8042_DATA_REG); 59} 60 61static inline void i8042_write_command(int val) 62{ 63 outb(val, I8042_COMMAND_REG); 64} 65 66#if defined(__i386__) || defined(__x86_64__) 67 68#include <linux/dmi.h> 69 70static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { 71 { 72 /* AUX LOOP command does not raise AUX IRQ */ 73 .ident = "ASUS P65UP5", 74 .matches = { 75 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), 76 DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"), 77 DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X"), 78 }, 79 }, 80 { 81 .ident = "Compaq Proliant 8500", 82 .matches = { 83 DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), 84 DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), 85 DMI_MATCH(DMI_PRODUCT_VERSION, "8500"), 86 }, 87 }, 88 { 89 .ident = "Compaq Proliant DL760", 90 .matches = { 91 DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), 92 DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), 93 DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"), 94 }, 95 }, 96 { 97 .ident = "OQO Model 01", 98 .matches = { 99 DMI_MATCH(DMI_SYS_VENDOR, "OQO"), 100 DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), 101 DMI_MATCH(DMI_PRODUCT_VERSION, "00"), 102 }, 103 }, 104 { 105 /* AUX LOOP does not work properly */ 106 .ident = "ULI EV4873", 107 .matches = { 108 DMI_MATCH(DMI_SYS_VENDOR, "ULI"), 109 DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"), 110 DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), 111 }, 112 }, 113 { 114 .ident = "Microsoft Virtual Machine", 115 .matches = { 116 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), 117 DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), 118 DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"), 119 }, 120 }, 121 { } 122}; 123 124/* 125 * Some Fujitsu notebooks are having trouble with touchpads if 126 * active multiplexing mode is activated. Luckily they don't have 127 * external PS/2 ports so we can safely disable it. 128 * ... apparently some Toshibas don't like MUX mode either and 129 * die horrible death on reboot. 130 */ 131static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { 132 { 133 .ident = "Fujitsu Lifebook P7010/P7010D", 134 .matches = { 135 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 136 DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), 137 }, 138 }, 139 { 140 .ident = "Fujitsu Lifebook P7010", 141 .matches = { 142 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 143 DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), 144 }, 145 }, 146 { 147 .ident = "Fujitsu Lifebook P5020D", 148 .matches = { 149 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 150 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), 151 }, 152 }, 153 { 154 .ident = "Fujitsu Lifebook S2000", 155 .matches = { 156 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 157 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), 158 }, 159 }, 160 { 161 .ident = "Fujitsu Lifebook S6230", 162 .matches = { 163 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 164 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), 165 }, 166 }, 167 { 168 .ident = "Fujitsu T70H", 169 .matches = { 170 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 171 DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), 172 }, 173 }, 174 { 175 .ident = "Fujitsu-Siemens Lifebook T3010", 176 .matches = { 177 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 178 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), 179 }, 180 }, 181 { 182 .ident = "Fujitsu-Siemens Lifebook E4010", 183 .matches = { 184 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 185 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), 186 }, 187 }, 188 { 189 .ident = "Fujitsu-Siemens Amilo Pro 2010", 190 .matches = { 191 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 192 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), 193 }, 194 }, 195 { 196 .ident = "Fujitsu-Siemens Amilo Pro 2030", 197 .matches = { 198 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 199 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), 200 }, 201 }, 202 { 203 /* 204 * No data is coming from the touchscreen unless KBC 205 * is in legacy mode. 206 */ 207 .ident = "Panasonic CF-29", 208 .matches = { 209 DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), 210 DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), 211 }, 212 }, 213 { 214 /* 215 * Errors on MUX ports are reported without raising AUXDATA 216 * causing "spurious NAK" messages. 217 */ 218 .ident = "HP Pavilion DV4017EA", 219 .matches = { 220 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 221 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), 222 }, 223 }, 224 { 225 /* 226 * Like DV4017EA does not raise AUXERR for errors on MUX ports. 227 */ 228 .ident = "HP Pavilion ZT1000", 229 .matches = { 230 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 231 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), 232 DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"), 233 }, 234 }, 235 { 236 /* 237 * Like DV4017EA does not raise AUXERR for errors on MUX ports. 238 */ 239 .ident = "HP Pavilion DV4270ca", 240 .matches = { 241 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 242 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), 243 }, 244 }, 245 { 246 .ident = "Toshiba P10", 247 .matches = { 248 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 249 DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), 250 }, 251 }, 252 { 253 .ident = "Toshiba Equium A110", 254 .matches = { 255 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 256 DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), 257 }, 258 }, 259 { 260 .ident = "Alienware Sentia", 261 .matches = { 262 DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), 263 DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), 264 }, 265 }, 266 { 267 .ident = "Sharp Actius MM20", 268 .matches = { 269 DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), 270 DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), 271 }, 272 }, 273 { 274 .ident = "Sony Vaio FS-115b", 275 .matches = { 276 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 277 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), 278 }, 279 }, 280 { 281 .ident = "Amoi M636/A737", 282 .matches = { 283 DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), 284 DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), 285 }, 286 }, 287 { 288 .ident = "Lenovo 3000 n100", 289 .matches = { 290 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 291 DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), 292 }, 293 }, 294 { } 295}; 296 297 298 299#endif 300 301#ifdef CONFIG_X86 302 303#include <linux/dmi.h> 304 305/* 306 * Some Wistron based laptops need us to explicitly enable the 'Dritek 307 * keyboard extension' to make their extra keys start generating scancodes. 308 * Originally, this was just confined to older laptops, but a few Acer laptops 309 * have turned up in 2007 that also need this again. 310 */ 311static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = { 312 { 313 .ident = "Acer Aspire 5630", 314 .matches = { 315 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 316 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), 317 }, 318 }, 319 { 320 .ident = "Acer Aspire 5650", 321 .matches = { 322 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 323 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), 324 }, 325 }, 326 { 327 .ident = "Acer Aspire 5680", 328 .matches = { 329 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 330 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), 331 }, 332 }, 333 { 334 .ident = "Acer Aspire 9110", 335 .matches = { 336 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 337 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), 338 }, 339 }, 340 { 341 .ident = "Acer TravelMate 660", 342 .matches = { 343 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 344 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), 345 }, 346 }, 347 { 348 .ident = "Acer TravelMate 2490", 349 .matches = { 350 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 351 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), 352 }, 353 }, 354 { } 355}; 356 357#endif /* CONFIG_X86 */ 358 359 360#ifdef CONFIG_PNP 361#include <linux/pnp.h> 362 363static int i8042_pnp_kbd_registered; 364static unsigned int i8042_pnp_kbd_devices; 365static int i8042_pnp_aux_registered; 366static unsigned int i8042_pnp_aux_devices; 367 368static int i8042_pnp_command_reg; 369static int i8042_pnp_data_reg; 370static int i8042_pnp_kbd_irq; 371static int i8042_pnp_aux_irq; 372 373static char i8042_pnp_kbd_name[32]; 374static char i8042_pnp_aux_name[32]; 375 376static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did) 377{ 378 if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) 379 i8042_pnp_data_reg = pnp_port_start(dev,0); 380 381 if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1) 382 i8042_pnp_command_reg = pnp_port_start(dev, 1); 383 384 if (pnp_irq_valid(dev,0)) 385 i8042_pnp_kbd_irq = pnp_irq(dev, 0); 386 387 strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); 388 if (strlen(pnp_dev_name(dev))) { 389 strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); 390 strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); 391 } 392 393 i8042_pnp_kbd_devices++; 394 return 0; 395} 396 397static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did) 398{ 399 if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) 400 i8042_pnp_data_reg = pnp_port_start(dev,0); 401 402 if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1) 403 i8042_pnp_command_reg = pnp_port_start(dev, 1); 404 405 if (pnp_irq_valid(dev, 0)) 406 i8042_pnp_aux_irq = pnp_irq(dev, 0); 407 408 strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); 409 if (strlen(pnp_dev_name(dev))) { 410 strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); 411 strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); 412 } 413 414 i8042_pnp_aux_devices++; 415 return 0; 416} 417 418static struct pnp_device_id pnp_kbd_devids[] = { 419 { .id = "PNP0303", .driver_data = 0 }, 420 { .id = "PNP030b", .driver_data = 0 }, 421 { .id = "", }, 422}; 423 424static struct pnp_driver i8042_pnp_kbd_driver = { 425 .name = "i8042 kbd", 426 .id_table = pnp_kbd_devids, 427 .probe = i8042_pnp_kbd_probe, 428}; 429 430static struct pnp_device_id pnp_aux_devids[] = { 431 { .id = "FJC6000", .driver_data = 0 }, 432 { .id = "FJC6001", .driver_data = 0 }, 433 { .id = "PNP0f03", .driver_data = 0 }, 434 { .id = "PNP0f0b", .driver_data = 0 }, 435 { .id = "PNP0f0e", .driver_data = 0 }, 436 { .id = "PNP0f12", .driver_data = 0 }, 437 { .id = "PNP0f13", .driver_data = 0 }, 438 { .id = "PNP0f19", .driver_data = 0 }, 439 { .id = "PNP0f1c", .driver_data = 0 }, 440 { .id = "SYN0801", .driver_data = 0 }, 441 { .id = "", }, 442}; 443 444static struct pnp_driver i8042_pnp_aux_driver = { 445 .name = "i8042 aux", 446 .id_table = pnp_aux_devids, 447 .probe = i8042_pnp_aux_probe, 448}; 449 450static void i8042_pnp_exit(void) 451{ 452 if (i8042_pnp_kbd_registered) { 453 i8042_pnp_kbd_registered = 0; 454 pnp_unregister_driver(&i8042_pnp_kbd_driver); 455 } 456 457 if (i8042_pnp_aux_registered) { 458 i8042_pnp_aux_registered = 0; 459 pnp_unregister_driver(&i8042_pnp_aux_driver); 460 } 461} 462 463static int __init i8042_pnp_init(void) 464{ 465 char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; 466 int pnp_data_busted = 0; 467 int err; 468 469 if (i8042_nopnp) { 470 printk(KERN_INFO "i8042: PNP detection disabled\n"); 471 return 0; 472 } 473 474 err = pnp_register_driver(&i8042_pnp_kbd_driver); 475 if (!err) 476 i8042_pnp_kbd_registered = 1; 477 478 err = pnp_register_driver(&i8042_pnp_aux_driver); 479 if (!err) 480 i8042_pnp_aux_registered = 1; 481 482 if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) { 483 i8042_pnp_exit(); 484#if defined(__ia64__) 485 return -ENODEV; 486#else 487 printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n"); 488 return 0; 489#endif 490 } 491 492 if (i8042_pnp_kbd_devices) 493 snprintf(kbd_irq_str, sizeof(kbd_irq_str), 494 "%d", i8042_pnp_kbd_irq); 495 if (i8042_pnp_aux_devices) 496 snprintf(aux_irq_str, sizeof(aux_irq_str), 497 "%d", i8042_pnp_aux_irq); 498 499 printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", 500 i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", 501 i8042_pnp_aux_name, 502 i8042_pnp_data_reg, i8042_pnp_command_reg, 503 kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", 504 aux_irq_str); 505 506#if defined(__ia64__) 507 if (!i8042_pnp_kbd_devices) 508 i8042_nokbd = 1; 509 if (!i8042_pnp_aux_devices) 510 i8042_noaux = 1; 511#endif 512 513 if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && 514 i8042_pnp_data_reg != i8042_data_reg) || 515 !i8042_pnp_data_reg) { 516 printk(KERN_WARNING 517 "PNP: PS/2 controller has invalid data port %#x; " 518 "using default %#x\n", 519 i8042_pnp_data_reg, i8042_data_reg); 520 i8042_pnp_data_reg = i8042_data_reg; 521 pnp_data_busted = 1; 522 } 523 524 if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && 525 i8042_pnp_command_reg != i8042_command_reg) || 526 !i8042_pnp_command_reg) { 527 printk(KERN_WARNING 528 "PNP: PS/2 controller has invalid command port %#x; " 529 "using default %#x\n", 530 i8042_pnp_command_reg, i8042_command_reg); 531 i8042_pnp_command_reg = i8042_command_reg; 532 pnp_data_busted = 1; 533 } 534 535 if (!i8042_nokbd && !i8042_pnp_kbd_irq) { 536 printk(KERN_WARNING 537 "PNP: PS/2 controller doesn't have KBD irq; " 538 "using default %d\n", i8042_kbd_irq); 539 i8042_pnp_kbd_irq = i8042_kbd_irq; 540 pnp_data_busted = 1; 541 } 542 543 if (!i8042_noaux && !i8042_pnp_aux_irq) { 544 if (!pnp_data_busted && i8042_pnp_kbd_irq) { 545 printk(KERN_WARNING 546 "PNP: PS/2 appears to have AUX port disabled, " 547 "if this is incorrect please boot with " 548 "i8042.nopnp\n"); 549 i8042_noaux = 1; 550 } else { 551 printk(KERN_WARNING 552 "PNP: PS/2 controller doesn't have AUX irq; " 553 "using default %d\n", i8042_aux_irq); 554 i8042_pnp_aux_irq = i8042_aux_irq; 555 } 556 } 557 558 i8042_data_reg = i8042_pnp_data_reg; 559 i8042_command_reg = i8042_pnp_command_reg; 560 i8042_kbd_irq = i8042_pnp_kbd_irq; 561 i8042_aux_irq = i8042_pnp_aux_irq; 562 563 return 0; 564} 565 566#else 567static inline int i8042_pnp_init(void) { return 0; } 568static inline void i8042_pnp_exit(void) { } 569#endif 570 571static int __init i8042_platform_init(void) 572{ 573 int retval; 574 575/* 576 * On ix86 platforms touching the i8042 data register region can do really 577 * bad things. Because of this the region is always reserved on ix86 boxes. 578 * 579 * if (!request_region(I8042_DATA_REG, 16, "i8042")) 580 * return -EBUSY; 581 */ 582 583 i8042_kbd_irq = I8042_MAP_IRQ(1); 584 i8042_aux_irq = I8042_MAP_IRQ(12); 585 586 retval = i8042_pnp_init(); 587 if (retval) 588 return retval; 589 590#if defined(__ia64__) 591 i8042_reset = 1; 592#endif 593 594#if defined(__i386__) || defined(__x86_64__) 595 if (dmi_check_system(i8042_dmi_noloop_table)) 596 i8042_noloop = 1; 597 598 if (dmi_check_system(i8042_dmi_nomux_table)) 599 i8042_nomux = 1; 600#endif 601 602#ifdef CONFIG_X86 603 if (dmi_check_system(i8042_dmi_dritek_table)) 604 i8042_dritek = 1; 605#endif /* CONFIG_X86 */ 606 607 return retval; 608} 609 610static inline void i8042_platform_exit(void) 611{ 612 i8042_pnp_exit(); 613} 614 615#endif /* _I8042_X86IA64IO_H */