1 /* 2 * Wistron laptop button driver 3 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz> 4 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org> 5 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru> 6 * 7 * You can redistribute and/or modify this program under the terms of the 8 * GNU General Public License version 2 as published by the Free Software 9 * Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 14 * Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA. 19 */ 20 #include <linux/io.h> 21 #include <linux/dmi.h> 22 #include <linux/init.h> 23 #include <linux/input.h> 24 #include <linux/interrupt.h> 25 #include <linux/jiffies.h> 26 #include <linux/kernel.h> 27 #include <linux/mc146818rtc.h> 28 #include <linux/module.h> 29 #include <linux/preempt.h> 30 #include <linux/string.h> 31 #include <linux/timer.h> 32 #include <linux/types.h> 33 #include <linux/platform_device.h> 34 #include <linux/leds.h> 35 36 /* 37 * Number of attempts to read data from queue per poll; 38 * the queue can hold up to 31 entries 39 */ 40 #define MAX_POLL_ITERATIONS 64 41 42 #define POLL_FREQUENCY 2 /* Number of polls per second when idle */ 43 #define POLL_FREQUENCY_BURST 10 /* Polls per second when a key was recently pressed */ 44 45 #if POLL_FREQUENCY_BURST > HZ 46 #error "POLL_FREQUENCY too high" 47 #endif 48 49 /* BIOS subsystem IDs */ 50 #define WIFI 0x35 51 #define BLUETOOTH 0x34 52 #define MAIL_LED 0x31 53 54 MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); 55 MODULE_DESCRIPTION("Wistron laptop button driver"); 56 MODULE_LICENSE("GPL v2"); 57 MODULE_VERSION("0.3"); 58 59 static int force; /* = 0; */ 60 module_param(force, bool, 0); 61 MODULE_PARM_DESC(force, "Load even if computer is not in database"); 62 63 static char *keymap_name; /* = NULL; */ 64 module_param_named(keymap, keymap_name, charp, 0); 65 MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected [generic, 1557/MS2141]"); 66 67 static struct platform_device *wistron_device; 68 69 /* BIOS interface implementation */ 70 71 static void __iomem *bios_entry_point; /* BIOS routine entry point */ 72 static void __iomem *bios_code_map_base; 73 static void __iomem *bios_data_map_base; 74 75 static u8 cmos_address; 76 77 struct regs { 78 u32 eax, ebx, ecx; 79 }; 80 81 static void call_bios(struct regs *regs) 82 { 83 unsigned long flags; 84 85 preempt_disable(); 86 local_irq_save(flags); 87 asm volatile ("pushl %%ebp;" 88 "movl %7, %%ebp;" 89 "call *%6;" 90 "popl %%ebp" 91 : "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx) 92 : "0" (regs->eax), "1" (regs->ebx), "2" (regs->ecx), 93 "m" (bios_entry_point), "m" (bios_data_map_base) 94 : "edx", "edi", "esi", "memory"); 95 local_irq_restore(flags); 96 preempt_enable(); 97 } 98 99 static ssize_t __init locate_wistron_bios(void __iomem *base) 100 { 101 static unsigned char __initdata signature[] = 102 { 0x42, 0x21, 0x55, 0x30 }; 103 ssize_t offset; 104 105 for (offset = 0; offset < 0x10000; offset += 0x10) { 106 if (check_signature(base + offset, signature, 107 sizeof(signature)) != 0) 108 return offset; 109 } 110 return -1; 111 } 112 113 static int __init map_bios(void) 114 { 115 void __iomem *base; 116 ssize_t offset; 117 u32 entry_point; 118 119 base = ioremap(0xF0000, 0x10000); /* Can't fail */ 120 offset = locate_wistron_bios(base); 121 if (offset < 0) { 122 printk(KERN_ERR "wistron_btns: BIOS entry point not found\n"); 123 iounmap(base); 124 return -ENODEV; 125 } 126 127 entry_point = readl(base + offset + 5); 128 printk(KERN_DEBUG 129 "wistron_btns: BIOS signature found at %p, entry point %08X\n", 130 base + offset, entry_point); 131 132 if (entry_point >= 0xF0000) { 133 bios_code_map_base = base; 134 bios_entry_point = bios_code_map_base + (entry_point & 0xFFFF); 135 } else { 136 iounmap(base); 137 bios_code_map_base = ioremap(entry_point & ~0x3FFF, 0x4000); 138 if (bios_code_map_base == NULL) { 139 printk(KERN_ERR 140 "wistron_btns: Can't map BIOS code at %08X\n", 141 entry_point & ~0x3FFF); 142 goto err; 143 } 144 bios_entry_point = bios_code_map_base + (entry_point & 0x3FFF); 145 } 146 /* The Windows driver maps 0x10000 bytes, we keep only one page... */ 147 bios_data_map_base = ioremap(0x400, 0xc00); 148 if (bios_data_map_base == NULL) { 149 printk(KERN_ERR "wistron_btns: Can't map BIOS data\n"); 150 goto err_code; 151 } 152 return 0; 153 154 err_code: 155 iounmap(bios_code_map_base); 156 err: 157 return -ENOMEM; 158 } 159 160 static inline void unmap_bios(void) 161 { 162 iounmap(bios_code_map_base); 163 iounmap(bios_data_map_base); 164 } 165 166 /* BIOS calls */ 167 168 static u16 bios_pop_queue(void) 169 { 170 struct regs regs; 171 172 memset(®s, 0, sizeof (regs)); 173 regs.eax = 0x9610; 174 regs.ebx = 0x061C; 175 regs.ecx = 0x0000; 176 call_bios(®s); 177 178 return regs.eax; 179 } 180 181 static void __devinit bios_attach(void) 182 { 183 struct regs regs; 184 185 memset(®s, 0, sizeof (regs)); 186 regs.eax = 0x9610; 187 regs.ebx = 0x012E; 188 call_bios(®s); 189 } 190 191 static void bios_detach(void) 192 { 193 struct regs regs; 194 195 memset(®s, 0, sizeof (regs)); 196 regs.eax = 0x9610; 197 regs.ebx = 0x002E; 198 call_bios(®s); 199 } 200 201 static u8 __devinit bios_get_cmos_address(void) 202 { 203 struct regs regs; 204 205 memset(®s, 0, sizeof (regs)); 206 regs.eax = 0x9610; 207 regs.ebx = 0x051C; 208 call_bios(®s); 209 210 return regs.ecx; 211 } 212 213 static u16 __devinit bios_get_default_setting(u8 subsys) 214 { 215 struct regs regs; 216 217 memset(®s, 0, sizeof (regs)); 218 regs.eax = 0x9610; 219 regs.ebx = 0x0200 | subsys; 220 call_bios(®s); 221 222 return regs.eax; 223 } 224 225 static void bios_set_state(u8 subsys, int enable) 226 { 227 struct regs regs; 228 229 memset(®s, 0, sizeof (regs)); 230 regs.eax = 0x9610; 231 regs.ebx = (enable ? 0x0100 : 0x0000) | subsys; 232 call_bios(®s); 233 } 234 235 /* Hardware database */ 236 237 struct key_entry { 238 char type; /* See KE_* below */ 239 u8 code; 240 union { 241 u16 keycode; /* For KE_KEY */ 242 struct { /* For KE_SW */ 243 u8 code; 244 u8 value; 245 } sw; 246 }; 247 }; 248 249 enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; 250 251 #define FE_MAIL_LED 0x01 252 #define FE_WIFI_LED 0x02 253 #define FE_UNTESTED 0x80 254 255 static const struct key_entry *keymap; /* = NULL; Current key map */ 256 static int have_wifi; 257 static int have_bluetooth; 258 static int have_leds; 259 260 static int __init dmi_matched(struct dmi_system_id *dmi) 261 { 262 const struct key_entry *key; 263 264 keymap = dmi->driver_data; 265 for (key = keymap; key->type != KE_END; key++) { 266 if (key->type == KE_WIFI) 267 have_wifi = 1; 268 else if (key->type == KE_BLUETOOTH) 269 have_bluetooth = 1; 270 } 271 have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED); 272 273 return 1; 274 } 275 276 static struct key_entry keymap_empty[] __initdata = { 277 { KE_END, 0 } 278 }; 279 280 static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { 281 { KE_KEY, 0x01, {KEY_HELP} }, 282 { KE_KEY, 0x11, {KEY_PROG1} }, 283 { KE_KEY, 0x12, {KEY_PROG2} }, 284 { KE_WIFI, 0x30 }, 285 { KE_KEY, 0x31, {KEY_MAIL} }, 286 { KE_KEY, 0x36, {KEY_WWW} }, 287 { KE_END, 0 } 288 }; 289 290 static struct key_entry keymap_fujitsu_n3510[] __initdata = { 291 { KE_KEY, 0x11, {KEY_PROG1} }, 292 { KE_KEY, 0x12, {KEY_PROG2} }, 293 { KE_KEY, 0x36, {KEY_WWW} }, 294 { KE_KEY, 0x31, {KEY_MAIL} }, 295 { KE_KEY, 0x71, {KEY_STOPCD} }, 296 { KE_KEY, 0x72, {KEY_PLAYPAUSE} }, 297 { KE_KEY, 0x74, {KEY_REWIND} }, 298 { KE_KEY, 0x78, {KEY_FORWARD} }, 299 { KE_END, 0 } 300 }; 301 302 static struct key_entry keymap_wistron_ms2111[] __initdata = { 303 { KE_KEY, 0x11, {KEY_PROG1} }, 304 { KE_KEY, 0x12, {KEY_PROG2} }, 305 { KE_KEY, 0x13, {KEY_PROG3} }, 306 { KE_KEY, 0x31, {KEY_MAIL} }, 307 { KE_KEY, 0x36, {KEY_WWW} }, 308 { KE_END, FE_MAIL_LED } 309 }; 310 311 static struct key_entry keymap_wistron_md40100[] __initdata = { 312 { KE_KEY, 0x01, {KEY_HELP} }, 313 { KE_KEY, 0x02, {KEY_CONFIG} }, 314 { KE_KEY, 0x31, {KEY_MAIL} }, 315 { KE_KEY, 0x36, {KEY_WWW} }, 316 { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ 317 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } 318 }; 319 320 static struct key_entry keymap_wistron_ms2141[] __initdata = { 321 { KE_KEY, 0x11, {KEY_PROG1} }, 322 { KE_KEY, 0x12, {KEY_PROG2} }, 323 { KE_WIFI, 0x30 }, 324 { KE_KEY, 0x22, {KEY_REWIND} }, 325 { KE_KEY, 0x23, {KEY_FORWARD} }, 326 { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, 327 { KE_KEY, 0x25, {KEY_STOPCD} }, 328 { KE_KEY, 0x31, {KEY_MAIL} }, 329 { KE_KEY, 0x36, {KEY_WWW} }, 330 { KE_END, 0 } 331 }; 332 333 static struct key_entry keymap_acer_aspire_1500[] __initdata = { 334 { KE_KEY, 0x01, {KEY_HELP} }, 335 { KE_KEY, 0x03, {KEY_POWER} }, 336 { KE_KEY, 0x11, {KEY_PROG1} }, 337 { KE_KEY, 0x12, {KEY_PROG2} }, 338 { KE_WIFI, 0x30 }, 339 { KE_KEY, 0x31, {KEY_MAIL} }, 340 { KE_KEY, 0x36, {KEY_WWW} }, 341 { KE_KEY, 0x49, {KEY_CONFIG} }, 342 { KE_BLUETOOTH, 0x44 }, 343 { KE_END, FE_UNTESTED } 344 }; 345 346 static struct key_entry keymap_acer_aspire_1600[] __initdata = { 347 { KE_KEY, 0x01, {KEY_HELP} }, 348 { KE_KEY, 0x03, {KEY_POWER} }, 349 { KE_KEY, 0x08, {KEY_MUTE} }, 350 { KE_KEY, 0x11, {KEY_PROG1} }, 351 { KE_KEY, 0x12, {KEY_PROG2} }, 352 { KE_KEY, 0x13, {KEY_PROG3} }, 353 { KE_KEY, 0x31, {KEY_MAIL} }, 354 { KE_KEY, 0x36, {KEY_WWW} }, 355 { KE_KEY, 0x49, {KEY_CONFIG} }, 356 { KE_WIFI, 0x30 }, 357 { KE_BLUETOOTH, 0x44 }, 358 { KE_END, FE_MAIL_LED | FE_UNTESTED } 359 }; 360 361 /* 3020 has been tested */ 362 static struct key_entry keymap_acer_aspire_5020[] __initdata = { 363 { KE_KEY, 0x01, {KEY_HELP} }, 364 { KE_KEY, 0x03, {KEY_POWER} }, 365 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ 366 { KE_KEY, 0x11, {KEY_PROG1} }, 367 { KE_KEY, 0x12, {KEY_PROG2} }, 368 { KE_KEY, 0x31, {KEY_MAIL} }, 369 { KE_KEY, 0x36, {KEY_WWW} }, 370 { KE_KEY, 0x6a, {KEY_CONFIG} }, 371 { KE_WIFI, 0x30 }, 372 { KE_BLUETOOTH, 0x44 }, 373 { KE_END, FE_MAIL_LED | FE_UNTESTED } 374 }; 375 376 static struct key_entry keymap_acer_travelmate_2410[] __initdata = { 377 { KE_KEY, 0x01, {KEY_HELP} }, 378 { KE_KEY, 0x6d, {KEY_POWER} }, 379 { KE_KEY, 0x11, {KEY_PROG1} }, 380 { KE_KEY, 0x12, {KEY_PROG2} }, 381 { KE_KEY, 0x31, {KEY_MAIL} }, 382 { KE_KEY, 0x36, {KEY_WWW} }, 383 { KE_KEY, 0x6a, {KEY_CONFIG} }, 384 { KE_WIFI, 0x30 }, 385 { KE_BLUETOOTH, 0x44 }, 386 { KE_END, FE_MAIL_LED | FE_UNTESTED } 387 }; 388 389 static struct key_entry keymap_acer_travelmate_110[] __initdata = { 390 { KE_KEY, 0x01, {KEY_HELP} }, 391 { KE_KEY, 0x02, {KEY_CONFIG} }, 392 { KE_KEY, 0x03, {KEY_POWER} }, 393 { KE_KEY, 0x08, {KEY_MUTE} }, 394 { KE_KEY, 0x11, {KEY_PROG1} }, 395 { KE_KEY, 0x12, {KEY_PROG2} }, 396 { KE_KEY, 0x20, {KEY_VOLUMEUP} }, 397 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, 398 { KE_KEY, 0x31, {KEY_MAIL} }, 399 { KE_KEY, 0x36, {KEY_WWW} }, 400 { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */ 401 { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */ 402 { KE_WIFI, 0x30 }, 403 { KE_END, FE_MAIL_LED | FE_UNTESTED } 404 }; 405 406 static struct key_entry keymap_acer_travelmate_300[] __initdata = { 407 { KE_KEY, 0x01, {KEY_HELP} }, 408 { KE_KEY, 0x02, {KEY_CONFIG} }, 409 { KE_KEY, 0x03, {KEY_POWER} }, 410 { KE_KEY, 0x08, {KEY_MUTE} }, 411 { KE_KEY, 0x11, {KEY_PROG1} }, 412 { KE_KEY, 0x12, {KEY_PROG2} }, 413 { KE_KEY, 0x20, {KEY_VOLUMEUP} }, 414 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, 415 { KE_KEY, 0x31, {KEY_MAIL} }, 416 { KE_KEY, 0x36, {KEY_WWW} }, 417 { KE_WIFI, 0x30 }, 418 { KE_BLUETOOTH, 0x44 }, 419 { KE_END, FE_MAIL_LED | FE_UNTESTED } 420 }; 421 422 static struct key_entry keymap_acer_travelmate_380[] __initdata = { 423 { KE_KEY, 0x01, {KEY_HELP} }, 424 { KE_KEY, 0x02, {KEY_CONFIG} }, 425 { KE_KEY, 0x03, {KEY_POWER} }, /* not 370 */ 426 { KE_KEY, 0x11, {KEY_PROG1} }, 427 { KE_KEY, 0x12, {KEY_PROG2} }, 428 { KE_KEY, 0x13, {KEY_PROG3} }, 429 { KE_KEY, 0x31, {KEY_MAIL} }, 430 { KE_KEY, 0x36, {KEY_WWW} }, 431 { KE_WIFI, 0x30 }, 432 { KE_END, FE_MAIL_LED | FE_UNTESTED } 433 }; 434 435 /* unusual map */ 436 static struct key_entry keymap_acer_travelmate_220[] __initdata = { 437 { KE_KEY, 0x01, {KEY_HELP} }, 438 { KE_KEY, 0x02, {KEY_CONFIG} }, 439 { KE_KEY, 0x11, {KEY_MAIL} }, 440 { KE_KEY, 0x12, {KEY_WWW} }, 441 { KE_KEY, 0x13, {KEY_PROG2} }, 442 { KE_KEY, 0x31, {KEY_PROG1} }, 443 { KE_END, FE_WIFI_LED | FE_UNTESTED } 444 }; 445 446 static struct key_entry keymap_acer_travelmate_230[] __initdata = { 447 { KE_KEY, 0x01, {KEY_HELP} }, 448 { KE_KEY, 0x02, {KEY_CONFIG} }, 449 { KE_KEY, 0x11, {KEY_PROG1} }, 450 { KE_KEY, 0x12, {KEY_PROG2} }, 451 { KE_KEY, 0x31, {KEY_MAIL} }, 452 { KE_KEY, 0x36, {KEY_WWW} }, 453 { KE_END, FE_WIFI_LED | FE_UNTESTED } 454 }; 455 456 static struct key_entry keymap_acer_travelmate_240[] __initdata = { 457 { KE_KEY, 0x01, {KEY_HELP} }, 458 { KE_KEY, 0x02, {KEY_CONFIG} }, 459 { KE_KEY, 0x03, {KEY_POWER} }, 460 { KE_KEY, 0x08, {KEY_MUTE} }, 461 { KE_KEY, 0x31, {KEY_MAIL} }, 462 { KE_KEY, 0x36, {KEY_WWW} }, 463 { KE_KEY, 0x11, {KEY_PROG1} }, 464 { KE_KEY, 0x12, {KEY_PROG2} }, 465 { KE_BLUETOOTH, 0x44 }, 466 { KE_WIFI, 0x30 }, 467 { KE_END, FE_UNTESTED } 468 }; 469 470 static struct key_entry keymap_acer_travelmate_350[] __initdata = { 471 { KE_KEY, 0x01, {KEY_HELP} }, 472 { KE_KEY, 0x02, {KEY_CONFIG} }, 473 { KE_KEY, 0x11, {KEY_PROG1} }, 474 { KE_KEY, 0x12, {KEY_PROG2} }, 475 { KE_KEY, 0x13, {KEY_MAIL} }, 476 { KE_KEY, 0x14, {KEY_PROG3} }, 477 { KE_KEY, 0x15, {KEY_WWW} }, 478 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } 479 }; 480 481 static struct key_entry keymap_acer_travelmate_360[] __initdata = { 482 { KE_KEY, 0x01, {KEY_HELP} }, 483 { KE_KEY, 0x02, {KEY_CONFIG} }, 484 { KE_KEY, 0x11, {KEY_PROG1} }, 485 { KE_KEY, 0x12, {KEY_PROG2} }, 486 { KE_KEY, 0x13, {KEY_MAIL} }, 487 { KE_KEY, 0x14, {KEY_PROG3} }, 488 { KE_KEY, 0x15, {KEY_WWW} }, 489 { KE_KEY, 0x40, {KEY_WLAN} }, 490 { KE_END, FE_WIFI_LED | FE_UNTESTED } /* no mail led */ 491 }; 492 493 /* Wifi subsystem only activates the led. Therefore we need to pass 494 * wifi event as a normal key, then userspace can really change the wifi state. 495 * TODO we need to export led state to userspace (wifi and mail) */ 496 static struct key_entry keymap_acer_travelmate_610[] __initdata = { 497 { KE_KEY, 0x01, {KEY_HELP} }, 498 { KE_KEY, 0x02, {KEY_CONFIG} }, 499 { KE_KEY, 0x11, {KEY_PROG1} }, 500 { KE_KEY, 0x12, {KEY_PROG2} }, 501 { KE_KEY, 0x13, {KEY_PROG3} }, 502 { KE_KEY, 0x14, {KEY_MAIL} }, 503 { KE_KEY, 0x15, {KEY_WWW} }, 504 { KE_KEY, 0x40, {KEY_WLAN} }, 505 { KE_END, FE_MAIL_LED | FE_WIFI_LED } 506 }; 507 508 static struct key_entry keymap_acer_travelmate_630[] __initdata = { 509 { KE_KEY, 0x01, {KEY_HELP} }, 510 { KE_KEY, 0x02, {KEY_CONFIG} }, 511 { KE_KEY, 0x03, {KEY_POWER} }, 512 { KE_KEY, 0x08, {KEY_MUTE} }, /* not 620 */ 513 { KE_KEY, 0x11, {KEY_PROG1} }, 514 { KE_KEY, 0x12, {KEY_PROG2} }, 515 { KE_KEY, 0x13, {KEY_PROG3} }, 516 { KE_KEY, 0x20, {KEY_VOLUMEUP} }, 517 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, 518 { KE_KEY, 0x31, {KEY_MAIL} }, 519 { KE_KEY, 0x36, {KEY_WWW} }, 520 { KE_WIFI, 0x30 }, 521 { KE_END, FE_MAIL_LED | FE_UNTESTED } 522 }; 523 524 static struct key_entry keymap_aopen_1559as[] __initdata = { 525 { KE_KEY, 0x01, {KEY_HELP} }, 526 { KE_KEY, 0x06, {KEY_PROG3} }, 527 { KE_KEY, 0x11, {KEY_PROG1} }, 528 { KE_KEY, 0x12, {KEY_PROG2} }, 529 { KE_WIFI, 0x30 }, 530 { KE_KEY, 0x31, {KEY_MAIL} }, 531 { KE_KEY, 0x36, {KEY_WWW} }, 532 { KE_END, 0 }, 533 }; 534 535 static struct key_entry keymap_fs_amilo_d88x0[] __initdata = { 536 { KE_KEY, 0x01, {KEY_HELP} }, 537 { KE_KEY, 0x08, {KEY_MUTE} }, 538 { KE_KEY, 0x31, {KEY_MAIL} }, 539 { KE_KEY, 0x36, {KEY_WWW} }, 540 { KE_KEY, 0x11, {KEY_PROG1} }, 541 { KE_KEY, 0x12, {KEY_PROG2} }, 542 { KE_KEY, 0x13, {KEY_PROG3} }, 543 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } 544 }; 545 546 static struct key_entry keymap_wistron_md2900[] __initdata = { 547 { KE_KEY, 0x01, {KEY_HELP} }, 548 { KE_KEY, 0x02, {KEY_CONFIG} }, 549 { KE_KEY, 0x11, {KEY_PROG1} }, 550 { KE_KEY, 0x12, {KEY_PROG2} }, 551 { KE_KEY, 0x31, {KEY_MAIL} }, 552 { KE_KEY, 0x36, {KEY_WWW} }, 553 { KE_WIFI, 0x30 }, 554 { KE_END, FE_MAIL_LED | FE_UNTESTED } 555 }; 556 557 static struct key_entry keymap_wistron_md96500[] __initdata = { 558 { KE_KEY, 0x01, {KEY_HELP} }, 559 { KE_KEY, 0x02, {KEY_CONFIG} }, 560 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ 561 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ 562 { KE_KEY, 0x08, {KEY_MUTE} }, 563 { KE_KEY, 0x11, {KEY_PROG1} }, 564 { KE_KEY, 0x12, {KEY_PROG2} }, 565 { KE_KEY, 0x20, {KEY_VOLUMEUP} }, 566 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, 567 { KE_KEY, 0x22, {KEY_REWIND} }, 568 { KE_KEY, 0x23, {KEY_FORWARD} }, 569 { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, 570 { KE_KEY, 0x25, {KEY_STOPCD} }, 571 { KE_KEY, 0x31, {KEY_MAIL} }, 572 { KE_KEY, 0x36, {KEY_WWW} }, 573 { KE_WIFI, 0x30 }, 574 { KE_BLUETOOTH, 0x44 }, 575 { KE_END, FE_UNTESTED } 576 }; 577 578 static struct key_entry keymap_wistron_generic[] __initdata = { 579 { KE_KEY, 0x01, {KEY_HELP} }, 580 { KE_KEY, 0x02, {KEY_CONFIG} }, 581 { KE_KEY, 0x03, {KEY_POWER} }, 582 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ 583 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ 584 { KE_KEY, 0x08, {KEY_MUTE} }, 585 { KE_KEY, 0x11, {KEY_PROG1} }, 586 { KE_KEY, 0x12, {KEY_PROG2} }, 587 { KE_KEY, 0x13, {KEY_PROG3} }, 588 { KE_KEY, 0x14, {KEY_MAIL} }, 589 { KE_KEY, 0x15, {KEY_WWW} }, 590 { KE_KEY, 0x20, {KEY_VOLUMEUP} }, 591 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, 592 { KE_KEY, 0x22, {KEY_REWIND} }, 593 { KE_KEY, 0x23, {KEY_FORWARD} }, 594 { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, 595 { KE_KEY, 0x25, {KEY_STOPCD} }, 596 { KE_KEY, 0x31, {KEY_MAIL} }, 597 { KE_KEY, 0x36, {KEY_WWW} }, 598 { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ 599 { KE_KEY, 0x40, {KEY_WLAN} }, 600 { KE_KEY, 0x49, {KEY_CONFIG} }, 601 { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */ 602 { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */ 603 { KE_KEY, 0x6a, {KEY_CONFIG} }, 604 { KE_KEY, 0x6d, {KEY_POWER} }, 605 { KE_KEY, 0x71, {KEY_STOPCD} }, 606 { KE_KEY, 0x72, {KEY_PLAYPAUSE} }, 607 { KE_KEY, 0x74, {KEY_REWIND} }, 608 { KE_KEY, 0x78, {KEY_FORWARD} }, 609 { KE_WIFI, 0x30 }, 610 { KE_BLUETOOTH, 0x44 }, 611 { KE_END, 0 } 612 }; 613 614 /* 615 * If your machine is not here (which is currently rather likely), please send 616 * a list of buttons and their key codes (reported when loading this module 617 * with force=1) and the output of dmidecode to $MODULE_AUTHOR. 618 */ 619 static struct dmi_system_id dmi_ids[] __initdata = { 620 { 621 .callback = dmi_matched, 622 .ident = "Fujitsu-Siemens Amilo Pro V2000", 623 .matches = { 624 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 625 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"), 626 }, 627 .driver_data = keymap_fs_amilo_pro_v2000 628 }, 629 { 630 .callback = dmi_matched, 631 .ident = "Fujitsu-Siemens Amilo M7400", 632 .matches = { 633 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 634 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "), 635 }, 636 .driver_data = keymap_fs_amilo_pro_v2000 637 }, 638 { 639 .callback = dmi_matched, 640 .ident = "Fujitsu N3510", 641 .matches = { 642 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 643 DMI_MATCH(DMI_PRODUCT_NAME, "N3510"), 644 }, 645 .driver_data = keymap_fujitsu_n3510 646 }, 647 { 648 .callback = dmi_matched, 649 .ident = "Acer Aspire 1500", 650 .matches = { 651 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 652 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"), 653 }, 654 .driver_data = keymap_acer_aspire_1500 655 }, 656 { 657 .callback = dmi_matched, 658 .ident = "Acer Aspire 1600", 659 .matches = { 660 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 661 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), 662 }, 663 .driver_data = keymap_acer_aspire_1600 664 }, 665 { 666 .callback = dmi_matched, 667 .ident = "Acer Aspire 3020", 668 .matches = { 669 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 670 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), 671 }, 672 .driver_data = keymap_acer_aspire_5020 673 }, 674 { 675 .callback = dmi_matched, 676 .ident = "Acer Aspire 5020", 677 .matches = { 678 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 679 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), 680 }, 681 .driver_data = keymap_acer_aspire_5020 682 }, 683 { 684 .callback = dmi_matched, 685 .ident = "Acer TravelMate 2100", 686 .matches = { 687 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 688 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), 689 }, 690 .driver_data = keymap_acer_aspire_5020 691 }, 692 { 693 .callback = dmi_matched, 694 .ident = "Acer TravelMate 2410", 695 .matches = { 696 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 697 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), 698 }, 699 .driver_data = keymap_acer_travelmate_2410 700 }, 701 { 702 .callback = dmi_matched, 703 .ident = "Acer TravelMate C300", 704 .matches = { 705 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 706 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), 707 }, 708 .driver_data = keymap_acer_travelmate_300 709 }, 710 { 711 .callback = dmi_matched, 712 .ident = "Acer TravelMate C100", 713 .matches = { 714 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 715 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), 716 }, 717 .driver_data = keymap_acer_travelmate_300 718 }, 719 { 720 .callback = dmi_matched, 721 .ident = "Acer TravelMate C110", 722 .matches = { 723 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 724 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), 725 }, 726 .driver_data = keymap_acer_travelmate_110 727 }, 728 { 729 .callback = dmi_matched, 730 .ident = "Acer TravelMate 380", 731 .matches = { 732 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 733 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), 734 }, 735 .driver_data = keymap_acer_travelmate_380 736 }, 737 { 738 .callback = dmi_matched, 739 .ident = "Acer TravelMate 370", 740 .matches = { 741 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 742 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), 743 }, 744 .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ 745 }, 746 { 747 .callback = dmi_matched, 748 .ident = "Acer TravelMate 220", 749 .matches = { 750 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 751 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), 752 }, 753 .driver_data = keymap_acer_travelmate_220 754 }, 755 { 756 .callback = dmi_matched, 757 .ident = "Acer TravelMate 260", 758 .matches = { 759 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 760 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), 761 }, 762 .driver_data = keymap_acer_travelmate_220 763 }, 764 { 765 .callback = dmi_matched, 766 .ident = "Acer TravelMate 230", 767 .matches = { 768 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 769 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), 770 /* acerhk looks for "TravelMate F4..." ?! */ 771 }, 772 .driver_data = keymap_acer_travelmate_230 773 }, 774 { 775 .callback = dmi_matched, 776 .ident = "Acer TravelMate 280", 777 .matches = { 778 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 779 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), 780 }, 781 .driver_data = keymap_acer_travelmate_230 782 }, 783 { 784 .callback = dmi_matched, 785 .ident = "Acer TravelMate 240", 786 .matches = { 787 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 788 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"), 789 }, 790 .driver_data = keymap_acer_travelmate_240 791 }, 792 { 793 .callback = dmi_matched, 794 .ident = "Acer TravelMate 250", 795 .matches = { 796 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 797 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), 798 }, 799 .driver_data = keymap_acer_travelmate_240 800 }, 801 { 802 .callback = dmi_matched, 803 .ident = "Acer TravelMate 2424NWXCi", 804 .matches = { 805 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 806 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"), 807 }, 808 .driver_data = keymap_acer_travelmate_240 809 }, 810 { 811 .callback = dmi_matched, 812 .ident = "Acer TravelMate 350", 813 .matches = { 814 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 815 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), 816 }, 817 .driver_data = keymap_acer_travelmate_350 818 }, 819 { 820 .callback = dmi_matched, 821 .ident = "Acer TravelMate 360", 822 .matches = { 823 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 824 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), 825 }, 826 .driver_data = keymap_acer_travelmate_360 827 }, 828 { 829 .callback = dmi_matched, 830 .ident = "Acer TravelMate 610", 831 .matches = { 832 DMI_MATCH(DMI_SYS_VENDOR, "ACER"), 833 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), 834 }, 835 .driver_data = keymap_acer_travelmate_610 836 }, 837 { 838 .callback = dmi_matched, 839 .ident = "Acer TravelMate 620", 840 .matches = { 841 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 842 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), 843 }, 844 .driver_data = keymap_acer_travelmate_630 845 }, 846 { 847 .callback = dmi_matched, 848 .ident = "Acer TravelMate 630", 849 .matches = { 850 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 851 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), 852 }, 853 .driver_data = keymap_acer_travelmate_630 854 }, 855 { 856 .callback = dmi_matched, 857 .ident = "AOpen 1559AS", 858 .matches = { 859 DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), 860 DMI_MATCH(DMI_BOARD_NAME, "E2U"), 861 }, 862 .driver_data = keymap_aopen_1559as 863 }, 864 { 865 .callback = dmi_matched, 866 .ident = "Medion MD 9783", 867 .matches = { 868 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 869 DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), 870 }, 871 .driver_data = keymap_wistron_ms2111 872 }, 873 { 874 .callback = dmi_matched, 875 .ident = "Medion MD 40100", 876 .matches = { 877 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 878 DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), 879 }, 880 .driver_data = keymap_wistron_md40100 881 }, 882 { 883 .callback = dmi_matched, 884 .ident = "Medion MD 2900", 885 .matches = { 886 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 887 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), 888 }, 889 .driver_data = keymap_wistron_md2900 890 }, 891 { 892 .callback = dmi_matched, 893 .ident = "Medion MD 96500", 894 .matches = { 895 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), 896 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), 897 }, 898 .driver_data = keymap_wistron_md96500 899 }, 900 { 901 .callback = dmi_matched, 902 .ident = "Medion MD 95400", 903 .matches = { 904 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), 905 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), 906 }, 907 .driver_data = keymap_wistron_md96500 908 }, 909 { 910 .callback = dmi_matched, 911 .ident = "Fujitsu Siemens Amilo D7820", 912 .matches = { 913 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ 914 DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), 915 }, 916 .driver_data = keymap_fs_amilo_d88x0 917 }, 918 { 919 .callback = dmi_matched, 920 .ident = "Fujitsu Siemens Amilo D88x0", 921 .matches = { 922 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 923 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"), 924 }, 925 .driver_data = keymap_fs_amilo_d88x0 926 }, 927 { NULL, } 928 }; 929 930 /* Copy the good keymap, as the original ones are free'd */ 931 static int __init copy_keymap(void) 932 { 933 const struct key_entry *key; 934 struct key_entry *new_keymap; 935 unsigned int length = 1; 936 937 for (key = keymap; key->type != KE_END; key++) 938 length++; 939 940 new_keymap = kmalloc(length * sizeof(struct key_entry), GFP_KERNEL); 941 if (!new_keymap) 942 return -ENOMEM; 943 944 memcpy(new_keymap, keymap, length * sizeof(struct key_entry)); 945 keymap = new_keymap; 946 947 return 0; 948 } 949 950 static int __init select_keymap(void) 951 { 952 dmi_check_system(dmi_ids); 953 if (keymap_name != NULL) { 954 if (strcmp (keymap_name, "1557/MS2141") == 0) 955 keymap = keymap_wistron_ms2141; 956 else if (strcmp (keymap_name, "generic") == 0) 957 keymap = keymap_wistron_generic; 958 else { 959 printk(KERN_ERR "wistron_btns: Keymap unknown\n"); 960 return -EINVAL; 961 } 962 } 963 if (keymap == NULL) { 964 if (!force) { 965 printk(KERN_ERR "wistron_btns: System unknown\n"); 966 return -ENODEV; 967 } 968 keymap = keymap_empty; 969 } 970 971 return copy_keymap(); 972 } 973 974 /* Input layer interface */ 975 976 static struct input_dev *input_dev; 977 978 static int __devinit setup_input_dev(void) 979 { 980 const struct key_entry *key; 981 int error; 982 983 input_dev = input_allocate_device(); 984 if (!input_dev) 985 return -ENOMEM; 986 987 input_dev->name = "Wistron laptop buttons"; 988 input_dev->phys = "wistron/input0"; 989 input_dev->id.bustype = BUS_HOST; 990 input_dev->cdev.dev = &wistron_device->dev; 991 992 for (key = keymap; key->type != KE_END; key++) { 993 switch (key->type) { 994 case KE_KEY: 995 set_bit(EV_KEY, input_dev->evbit); 996 set_bit(key->keycode, input_dev->keybit); 997 break; 998 999 case KE_SW: 1000 set_bit(EV_SW, input_dev->evbit); 1001 set_bit(key->sw.code, input_dev->swbit); 1002 break; 1003 1004 default: 1005 ; 1006 } 1007 } 1008 1009 /* reads information flags on KE_END */ 1010 if (key->code & FE_UNTESTED) 1011 printk(KERN_WARNING "Untested laptop multimedia keys, " 1012 "please report success or failure to eric.piel" 1013 "@tremplin-utc.net\n"); 1014 1015 error = input_register_device(input_dev); 1016 if (error) { 1017 input_free_device(input_dev); 1018 return error; 1019 } 1020 1021 return 0; 1022 } 1023 1024 static void report_key(unsigned keycode) 1025 { 1026 input_report_key(input_dev, keycode, 1); 1027 input_sync(input_dev); 1028 input_report_key(input_dev, keycode, 0); 1029 input_sync(input_dev); 1030 } 1031 1032 static void report_switch(unsigned code, int value) 1033 { 1034 input_report_switch(input_dev, code, value); 1035 input_sync(input_dev); 1036 } 1037 1038 1039 /* led management */ 1040 static void wistron_mail_led_set(struct led_classdev *led_cdev, 1041 enum led_brightness value) 1042 { 1043 bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0); 1044 } 1045 1046 /* same as setting up wifi card, but for laptops on which the led is managed */ 1047 static void wistron_wifi_led_set(struct led_classdev *led_cdev, 1048 enum led_brightness value) 1049 { 1050 bios_set_state(WIFI, (value != LED_OFF) ? 1 : 0); 1051 } 1052 1053 static struct led_classdev wistron_mail_led = { 1054 .name = "mail:green", 1055 .brightness_set = wistron_mail_led_set, 1056 }; 1057 1058 static struct led_classdev wistron_wifi_led = { 1059 .name = "wifi:red", 1060 .brightness_set = wistron_wifi_led_set, 1061 }; 1062 1063 static void __devinit wistron_led_init(struct device *parent) 1064 { 1065 if (have_leds & FE_WIFI_LED) { 1066 u16 wifi = bios_get_default_setting(WIFI); 1067 if (wifi & 1) { 1068 wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF; 1069 if (led_classdev_register(parent, &wistron_wifi_led)) 1070 have_leds &= ~FE_WIFI_LED; 1071 else 1072 bios_set_state(WIFI, wistron_wifi_led.brightness); 1073 1074 } else 1075 have_leds &= ~FE_WIFI_LED; 1076 } 1077 1078 if (have_leds & FE_MAIL_LED) { 1079 /* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */ 1080 wistron_mail_led.brightness = LED_OFF; 1081 if (led_classdev_register(parent, &wistron_mail_led)) 1082 have_leds &= ~FE_MAIL_LED; 1083 else 1084 bios_set_state(MAIL_LED, wistron_mail_led.brightness); 1085 } 1086 } 1087 1088 static void __devexit wistron_led_remove(void) 1089 { 1090 if (have_leds & FE_MAIL_LED) 1091 led_classdev_unregister(&wistron_mail_led); 1092 1093 if (have_leds & FE_WIFI_LED) 1094 led_classdev_unregister(&wistron_wifi_led); 1095 } 1096 1097 static inline void wistron_led_suspend(void) 1098 { 1099 if (have_leds & FE_MAIL_LED) 1100 led_classdev_suspend(&wistron_mail_led); 1101 1102 if (have_leds & FE_WIFI_LED) 1103 led_classdev_suspend(&wistron_wifi_led); 1104 } 1105 1106 static inline void wistron_led_resume(void) 1107 { 1108 if (have_leds & FE_MAIL_LED) 1109 led_classdev_resume(&wistron_mail_led); 1110 1111 if (have_leds & FE_WIFI_LED) 1112 led_classdev_resume(&wistron_wifi_led); 1113 } 1114 1115 /* Driver core */ 1116 1117 static int wifi_enabled; 1118 static int bluetooth_enabled; 1119 1120 static void poll_bios(unsigned long); 1121 1122 static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0); 1123 1124 static void handle_key(u8 code) 1125 { 1126 const struct key_entry *key; 1127 1128 for (key = keymap; key->type != KE_END; key++) { 1129 if (code == key->code) { 1130 switch (key->type) { 1131 case KE_KEY: 1132 report_key(key->keycode); 1133 break; 1134 1135 case KE_SW: 1136 report_switch(key->sw.code, key->sw.value); 1137 break; 1138 1139 case KE_WIFI: 1140 if (have_wifi) { 1141 wifi_enabled = !wifi_enabled; 1142 bios_set_state(WIFI, wifi_enabled); 1143 } 1144 break; 1145 1146 case KE_BLUETOOTH: 1147 if (have_bluetooth) { 1148 bluetooth_enabled = !bluetooth_enabled; 1149 bios_set_state(BLUETOOTH, bluetooth_enabled); 1150 } 1151 break; 1152 1153 case KE_END: 1154 break; 1155 default: 1156 BUG(); 1157 } 1158 return; 1159 } 1160 } 1161 printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code); 1162 } 1163 1164 static void poll_bios(unsigned long discard) 1165 { 1166 static unsigned long jiffies_last_press; 1167 unsigned long jiffies_now = jiffies; 1168 u8 qlen; 1169 u16 val; 1170 1171 for (;;) { 1172 qlen = CMOS_READ(cmos_address); 1173 if (qlen == 0) 1174 break; 1175 val = bios_pop_queue(); 1176 if (val != 0 && !discard) { 1177 handle_key((u8)val); 1178 jiffies_last_press = jiffies_now; 1179 } 1180 } 1181 1182 /* Increase precision if user is currently pressing keys (< 2s ago) */ 1183 if (time_after(jiffies_last_press, jiffies_now - (HZ * 2))) 1184 mod_timer(&poll_timer, jiffies_now + HZ / POLL_FREQUENCY_BURST); 1185 else 1186 mod_timer(&poll_timer, jiffies_now + HZ / POLL_FREQUENCY); 1187 } 1188 1189 static int __devinit wistron_probe(struct platform_device *dev) 1190 { 1191 int err = setup_input_dev(); 1192 if (err) 1193 return err; 1194 1195 bios_attach(); 1196 cmos_address = bios_get_cmos_address(); 1197 1198 if (have_wifi) { 1199 u16 wifi = bios_get_default_setting(WIFI); 1200 if (wifi & 1) 1201 wifi_enabled = (wifi & 2) ? 1 : 0; 1202 else 1203 have_wifi = 0; 1204 1205 if (have_wifi) 1206 bios_set_state(WIFI, wifi_enabled); 1207 } 1208 1209 if (have_bluetooth) { 1210 u16 bt = bios_get_default_setting(BLUETOOTH); 1211 if (bt & 1) 1212 bluetooth_enabled = (bt & 2) ? 1 : 0; 1213 else 1214 have_bluetooth = 0; 1215 1216 if (have_bluetooth) 1217 bios_set_state(BLUETOOTH, bluetooth_enabled); 1218 } 1219 1220 wistron_led_init(&dev->dev); 1221 poll_bios(1); /* Flush stale event queue and arm timer */ 1222 1223 return 0; 1224 } 1225 1226 static int __devexit wistron_remove(struct platform_device *dev) 1227 { 1228 del_timer_sync(&poll_timer); 1229 wistron_led_remove(); 1230 input_unregister_device(input_dev); 1231 bios_detach(); 1232 1233 return 0; 1234 } 1235 1236 #ifdef CONFIG_PM 1237 static int wistron_suspend(struct platform_device *dev, pm_message_t state) 1238 { 1239 del_timer_sync(&poll_timer); 1240 1241 if (have_wifi) 1242 bios_set_state(WIFI, 0); 1243 1244 if (have_bluetooth) 1245 bios_set_state(BLUETOOTH, 0); 1246 1247 wistron_led_suspend(); 1248 return 0; 1249 } 1250 1251 static int wistron_resume(struct platform_device *dev) 1252 { 1253 if (have_wifi) 1254 bios_set_state(WIFI, wifi_enabled); 1255 1256 if (have_bluetooth) 1257 bios_set_state(BLUETOOTH, bluetooth_enabled); 1258 1259 wistron_led_resume(); 1260 poll_bios(1); 1261 1262 return 0; 1263 } 1264 #else 1265 #define wistron_suspend NULL 1266 #define wistron_resume NULL 1267 #endif 1268 1269 static struct platform_driver wistron_driver = { 1270 .driver = { 1271 .name = "wistron-bios", 1272 .owner = THIS_MODULE, 1273 }, 1274 .probe = wistron_probe, 1275 .remove = __devexit_p(wistron_remove), 1276 .suspend = wistron_suspend, 1277 .resume = wistron_resume, 1278 }; 1279 1280 static int __init wb_module_init(void) 1281 { 1282 int err; 1283 1284 err = select_keymap(); 1285 if (err) 1286 return err; 1287 1288 err = map_bios(); 1289 if (err) 1290 return err; 1291 1292 err = platform_driver_register(&wistron_driver); 1293 if (err) 1294 goto err_unmap_bios; 1295 1296 wistron_device = platform_device_alloc("wistron-bios", -1); 1297 if (!wistron_device) { 1298 err = -ENOMEM; 1299 goto err_unregister_driver; 1300 } 1301 1302 err = platform_device_add(wistron_device); 1303 if (err) 1304 goto err_free_device; 1305 1306 return 0; 1307 1308 err_free_device: 1309 platform_device_put(wistron_device); 1310 err_unregister_driver: 1311 platform_driver_unregister(&wistron_driver); 1312 err_unmap_bios: 1313 unmap_bios(); 1314 1315 return err; 1316 } 1317 1318 static void __exit wb_module_exit(void) 1319 { 1320 platform_device_unregister(wistron_device); 1321 platform_driver_unregister(&wistron_driver); 1322 unmap_bios(); 1323 kfree(keymap); 1324 } 1325 1326 module_init(wb_module_init); 1327 module_exit(wb_module_exit); 1328