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.23-rc9 523 lines 13 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__) 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}; 115 116/* 117 * Some Fujitsu notebooks are having trouble with touchpads if 118 * active multiplexing mode is activated. Luckily they don't have 119 * external PS/2 ports so we can safely disable it. 120 * ... apparently some Toshibas don't like MUX mode either and 121 * die horrible death on reboot. 122 */ 123static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { 124 { 125 .ident = "Fujitsu Lifebook P7010/P7010D", 126 .matches = { 127 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 128 DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), 129 }, 130 }, 131 { 132 .ident = "Fujitsu Lifebook P7010", 133 .matches = { 134 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 135 DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), 136 }, 137 }, 138 { 139 .ident = "Fujitsu Lifebook P5020D", 140 .matches = { 141 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 142 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), 143 }, 144 }, 145 { 146 .ident = "Fujitsu Lifebook S2000", 147 .matches = { 148 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 149 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), 150 }, 151 }, 152 { 153 .ident = "Fujitsu Lifebook S6230", 154 .matches = { 155 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 156 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), 157 }, 158 }, 159 { 160 .ident = "Fujitsu T70H", 161 .matches = { 162 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 163 DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), 164 }, 165 }, 166 { 167 .ident = "Fujitsu-Siemens Lifebook T3010", 168 .matches = { 169 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 170 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), 171 }, 172 }, 173 { 174 .ident = "Fujitsu-Siemens Lifebook E4010", 175 .matches = { 176 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 177 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), 178 }, 179 }, 180 { 181 /* 182 * No data is coming from the touchscreen unless KBC 183 * is in legacy mode. 184 */ 185 .ident = "Panasonic CF-29", 186 .matches = { 187 DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), 188 DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), 189 }, 190 }, 191 { 192 /* 193 * Errors on MUX ports are reported without raising AUXDATA 194 * causing "spurious NAK" messages. 195 */ 196 .ident = "HP Pavilion DV4017EA", 197 .matches = { 198 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 199 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), 200 }, 201 }, 202 { 203 /* 204 * Like DV4017EA does not raise AUXERR for errors on MUX ports. 205 */ 206 .ident = "HP Pavilion ZT1000", 207 .matches = { 208 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 209 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), 210 DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"), 211 }, 212 }, 213 { 214 /* 215 * Like DV4017EA does not raise AUXERR for errors on MUX ports. 216 */ 217 .ident = "HP Pavilion DV4270ca", 218 .matches = { 219 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 220 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), 221 }, 222 }, 223 { 224 .ident = "Toshiba P10", 225 .matches = { 226 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 227 DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), 228 }, 229 }, 230 { 231 .ident = "Toshiba Equium A110", 232 .matches = { 233 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 234 DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), 235 }, 236 }, 237 { 238 .ident = "Alienware Sentia", 239 .matches = { 240 DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), 241 DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), 242 }, 243 }, 244 { 245 .ident = "Sharp Actius MM20", 246 .matches = { 247 DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), 248 DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), 249 }, 250 }, 251 { 252 .ident = "Sony Vaio FS-115b", 253 .matches = { 254 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 255 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), 256 }, 257 }, 258 { 259 .ident = "Amoi M636/A737", 260 .matches = { 261 DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), 262 DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), 263 }, 264 }, 265 { } 266}; 267 268 269 270#endif 271 272 273#ifdef CONFIG_PNP 274#include <linux/pnp.h> 275 276static int i8042_pnp_kbd_registered; 277static unsigned int i8042_pnp_kbd_devices; 278static int i8042_pnp_aux_registered; 279static unsigned int i8042_pnp_aux_devices; 280 281static int i8042_pnp_command_reg; 282static int i8042_pnp_data_reg; 283static int i8042_pnp_kbd_irq; 284static int i8042_pnp_aux_irq; 285 286static char i8042_pnp_kbd_name[32]; 287static char i8042_pnp_aux_name[32]; 288 289static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did) 290{ 291 if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) 292 i8042_pnp_data_reg = pnp_port_start(dev,0); 293 294 if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1) 295 i8042_pnp_command_reg = pnp_port_start(dev, 1); 296 297 if (pnp_irq_valid(dev,0)) 298 i8042_pnp_kbd_irq = pnp_irq(dev, 0); 299 300 strncpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); 301 if (strlen(pnp_dev_name(dev))) { 302 strncat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); 303 strncat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); 304 } 305 306 i8042_pnp_kbd_devices++; 307 return 0; 308} 309 310static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did) 311{ 312 if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) 313 i8042_pnp_data_reg = pnp_port_start(dev,0); 314 315 if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1) 316 i8042_pnp_command_reg = pnp_port_start(dev, 1); 317 318 if (pnp_irq_valid(dev, 0)) 319 i8042_pnp_aux_irq = pnp_irq(dev, 0); 320 321 strncpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); 322 if (strlen(pnp_dev_name(dev))) { 323 strncat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); 324 strncat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); 325 } 326 327 i8042_pnp_aux_devices++; 328 return 0; 329} 330 331static struct pnp_device_id pnp_kbd_devids[] = { 332 { .id = "PNP0303", .driver_data = 0 }, 333 { .id = "PNP030b", .driver_data = 0 }, 334 { .id = "", }, 335}; 336 337static struct pnp_driver i8042_pnp_kbd_driver = { 338 .name = "i8042 kbd", 339 .id_table = pnp_kbd_devids, 340 .probe = i8042_pnp_kbd_probe, 341}; 342 343static struct pnp_device_id pnp_aux_devids[] = { 344 { .id = "FJC6000", .driver_data = 0 }, 345 { .id = "FJC6001", .driver_data = 0 }, 346 { .id = "PNP0f03", .driver_data = 0 }, 347 { .id = "PNP0f0b", .driver_data = 0 }, 348 { .id = "PNP0f0e", .driver_data = 0 }, 349 { .id = "PNP0f12", .driver_data = 0 }, 350 { .id = "PNP0f13", .driver_data = 0 }, 351 { .id = "PNP0f19", .driver_data = 0 }, 352 { .id = "PNP0f1c", .driver_data = 0 }, 353 { .id = "SYN0801", .driver_data = 0 }, 354 { .id = "", }, 355}; 356 357static struct pnp_driver i8042_pnp_aux_driver = { 358 .name = "i8042 aux", 359 .id_table = pnp_aux_devids, 360 .probe = i8042_pnp_aux_probe, 361}; 362 363static void i8042_pnp_exit(void) 364{ 365 if (i8042_pnp_kbd_registered) { 366 i8042_pnp_kbd_registered = 0; 367 pnp_unregister_driver(&i8042_pnp_kbd_driver); 368 } 369 370 if (i8042_pnp_aux_registered) { 371 i8042_pnp_aux_registered = 0; 372 pnp_unregister_driver(&i8042_pnp_aux_driver); 373 } 374} 375 376static int __init i8042_pnp_init(void) 377{ 378 char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; 379 int pnp_data_busted = 0; 380 int err; 381 382 if (i8042_nopnp) { 383 printk(KERN_INFO "i8042: PNP detection disabled\n"); 384 return 0; 385 } 386 387 err = pnp_register_driver(&i8042_pnp_kbd_driver); 388 if (!err) 389 i8042_pnp_kbd_registered = 1; 390 391 err = pnp_register_driver(&i8042_pnp_aux_driver); 392 if (!err) 393 i8042_pnp_aux_registered = 1; 394 395 if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) { 396 i8042_pnp_exit(); 397#if defined(__ia64__) 398 return -ENODEV; 399#else 400 printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n"); 401 return 0; 402#endif 403 } 404 405 if (i8042_pnp_kbd_devices) 406 snprintf(kbd_irq_str, sizeof(kbd_irq_str), 407 "%d", i8042_pnp_kbd_irq); 408 if (i8042_pnp_aux_devices) 409 snprintf(aux_irq_str, sizeof(aux_irq_str), 410 "%d", i8042_pnp_aux_irq); 411 412 printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", 413 i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", 414 i8042_pnp_aux_name, 415 i8042_pnp_data_reg, i8042_pnp_command_reg, 416 kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", 417 aux_irq_str); 418 419#if defined(__ia64__) 420 if (!i8042_pnp_kbd_devices) 421 i8042_nokbd = 1; 422 if (!i8042_pnp_aux_devices) 423 i8042_noaux = 1; 424#endif 425 426 if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && 427 i8042_pnp_data_reg != i8042_data_reg) || 428 !i8042_pnp_data_reg) { 429 printk(KERN_WARNING 430 "PNP: PS/2 controller has invalid data port %#x; " 431 "using default %#x\n", 432 i8042_pnp_data_reg, i8042_data_reg); 433 i8042_pnp_data_reg = i8042_data_reg; 434 pnp_data_busted = 1; 435 } 436 437 if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && 438 i8042_pnp_command_reg != i8042_command_reg) || 439 !i8042_pnp_command_reg) { 440 printk(KERN_WARNING 441 "PNP: PS/2 controller has invalid command port %#x; " 442 "using default %#x\n", 443 i8042_pnp_command_reg, i8042_command_reg); 444 i8042_pnp_command_reg = i8042_command_reg; 445 pnp_data_busted = 1; 446 } 447 448 if (!i8042_nokbd && !i8042_pnp_kbd_irq) { 449 printk(KERN_WARNING 450 "PNP: PS/2 controller doesn't have KBD irq; " 451 "using default %d\n", i8042_kbd_irq); 452 i8042_pnp_kbd_irq = i8042_kbd_irq; 453 pnp_data_busted = 1; 454 } 455 456 if (!i8042_noaux && !i8042_pnp_aux_irq) { 457 if (!pnp_data_busted && i8042_pnp_kbd_irq) { 458 printk(KERN_WARNING 459 "PNP: PS/2 appears to have AUX port disabled, " 460 "if this is incorrect please boot with " 461 "i8042.nopnp\n"); 462 i8042_noaux = 1; 463 } else { 464 printk(KERN_WARNING 465 "PNP: PS/2 controller doesn't have AUX irq; " 466 "using default %d\n", i8042_aux_irq); 467 i8042_pnp_aux_irq = i8042_aux_irq; 468 } 469 } 470 471 i8042_data_reg = i8042_pnp_data_reg; 472 i8042_command_reg = i8042_pnp_command_reg; 473 i8042_kbd_irq = i8042_pnp_kbd_irq; 474 i8042_aux_irq = i8042_pnp_aux_irq; 475 476 return 0; 477} 478 479#else 480static inline int i8042_pnp_init(void) { return 0; } 481static inline void i8042_pnp_exit(void) { } 482#endif 483 484static int __init i8042_platform_init(void) 485{ 486 int retval; 487 488/* 489 * On ix86 platforms touching the i8042 data register region can do really 490 * bad things. Because of this the region is always reserved on ix86 boxes. 491 * 492 * if (!request_region(I8042_DATA_REG, 16, "i8042")) 493 * return -EBUSY; 494 */ 495 496 i8042_kbd_irq = I8042_MAP_IRQ(1); 497 i8042_aux_irq = I8042_MAP_IRQ(12); 498 499 retval = i8042_pnp_init(); 500 if (retval) 501 return retval; 502 503#if defined(__ia64__) 504 i8042_reset = 1; 505#endif 506 507#if defined(__i386__) 508 if (dmi_check_system(i8042_dmi_noloop_table)) 509 i8042_noloop = 1; 510 511 if (dmi_check_system(i8042_dmi_nomux_table)) 512 i8042_nomux = 1; 513#endif 514 515 return retval; 516} 517 518static inline void i8042_platform_exit(void) 519{ 520 i8042_pnp_exit(); 521} 522 523#endif /* _I8042_X86IA64IO_H */