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-polldev.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/types.h> 32 #include <linux/platform_device.h> 33 #include <linux/leds.h> 34 35 /* How often we poll keys - msecs */ 36 #define POLL_INTERVAL_DEFAULT 500 /* when idle */ 37 #define POLL_INTERVAL_BURST 100 /* when a key was recently pressed */ 38 39 /* BIOS subsystem IDs */ 40 #define WIFI 0x35 41 #define BLUETOOTH 0x34 42 #define MAIL_LED 0x31 43 44 MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); 45 MODULE_DESCRIPTION("Wistron laptop button driver"); 46 MODULE_LICENSE("GPL v2"); 47 MODULE_VERSION("0.3"); 48 49 static int force; /* = 0; */ 50 module_param(force, bool, 0); 51 MODULE_PARM_DESC(force, "Load even if computer is not in database"); 52 53 static char *keymap_name; /* = NULL; */ 54 module_param_named(keymap, keymap_name, charp, 0); 55 MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected [generic, 1557/MS2141]"); 56 57 static struct platform_device *wistron_device; 58 59 /* BIOS interface implementation */ 60 61 static void __iomem *bios_entry_point; /* BIOS routine entry point */ 62 static void __iomem *bios_code_map_base; 63 static void __iomem *bios_data_map_base; 64 65 static u8 cmos_address; 66 67 struct regs { 68 u32 eax, ebx, ecx; 69 }; 70 71 static void call_bios(struct regs *regs) 72 { 73 unsigned long flags; 74 75 preempt_disable(); 76 local_irq_save(flags); 77 asm volatile ("pushl %%ebp;" 78 "movl %7, %%ebp;" 79 "call *%6;" 80 "popl %%ebp" 81 : "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx) 82 : "0" (regs->eax), "1" (regs->ebx), "2" (regs->ecx), 83 "m" (bios_entry_point), "m" (bios_data_map_base) 84 : "edx", "edi", "esi", "memory"); 85 local_irq_restore(flags); 86 preempt_enable(); 87 } 88 89 static ssize_t __init locate_wistron_bios(void __iomem *base) 90 { 91 static unsigned char __initdata signature[] = 92 { 0x42, 0x21, 0x55, 0x30 }; 93 ssize_t offset; 94 95 for (offset = 0; offset < 0x10000; offset += 0x10) { 96 if (check_signature(base + offset, signature, 97 sizeof(signature)) != 0) 98 return offset; 99 } 100 return -1; 101 } 102 103 static int __init map_bios(void) 104 { 105 void __iomem *base; 106 ssize_t offset; 107 u32 entry_point; 108 109 base = ioremap(0xF0000, 0x10000); /* Can't fail */ 110 offset = locate_wistron_bios(base); 111 if (offset < 0) { 112 printk(KERN_ERR "wistron_btns: BIOS entry point not found\n"); 113 iounmap(base); 114 return -ENODEV; 115 } 116 117 entry_point = readl(base + offset + 5); 118 printk(KERN_DEBUG 119 "wistron_btns: BIOS signature found at %p, entry point %08X\n", 120 base + offset, entry_point); 121 122 if (entry_point >= 0xF0000) { 123 bios_code_map_base = base; 124 bios_entry_point = bios_code_map_base + (entry_point & 0xFFFF); 125 } else { 126 iounmap(base); 127 bios_code_map_base = ioremap(entry_point & ~0x3FFF, 0x4000); 128 if (bios_code_map_base == NULL) { 129 printk(KERN_ERR 130 "wistron_btns: Can't map BIOS code at %08X\n", 131 entry_point & ~0x3FFF); 132 goto err; 133 } 134 bios_entry_point = bios_code_map_base + (entry_point & 0x3FFF); 135 } 136 /* The Windows driver maps 0x10000 bytes, we keep only one page... */ 137 bios_data_map_base = ioremap(0x400, 0xc00); 138 if (bios_data_map_base == NULL) { 139 printk(KERN_ERR "wistron_btns: Can't map BIOS data\n"); 140 goto err_code; 141 } 142 return 0; 143 144 err_code: 145 iounmap(bios_code_map_base); 146 err: 147 return -ENOMEM; 148 } 149 150 static inline void unmap_bios(void) 151 { 152 iounmap(bios_code_map_base); 153 iounmap(bios_data_map_base); 154 } 155 156 /* BIOS calls */ 157 158 static u16 bios_pop_queue(void) 159 { 160 struct regs regs; 161 162 memset(®s, 0, sizeof (regs)); 163 regs.eax = 0x9610; 164 regs.ebx = 0x061C; 165 regs.ecx = 0x0000; 166 call_bios(®s); 167 168 return regs.eax; 169 } 170 171 static void __devinit bios_attach(void) 172 { 173 struct regs regs; 174 175 memset(®s, 0, sizeof (regs)); 176 regs.eax = 0x9610; 177 regs.ebx = 0x012E; 178 call_bios(®s); 179 } 180 181 static void bios_detach(void) 182 { 183 struct regs regs; 184 185 memset(®s, 0, sizeof (regs)); 186 regs.eax = 0x9610; 187 regs.ebx = 0x002E; 188 call_bios(®s); 189 } 190 191 static u8 __devinit bios_get_cmos_address(void) 192 { 193 struct regs regs; 194 195 memset(®s, 0, sizeof (regs)); 196 regs.eax = 0x9610; 197 regs.ebx = 0x051C; 198 call_bios(®s); 199 200 return regs.ecx; 201 } 202 203 static u16 __devinit bios_get_default_setting(u8 subsys) 204 { 205 struct regs regs; 206 207 memset(®s, 0, sizeof (regs)); 208 regs.eax = 0x9610; 209 regs.ebx = 0x0200 | subsys; 210 call_bios(®s); 211 212 return regs.eax; 213 } 214 215 static void bios_set_state(u8 subsys, int enable) 216 { 217 struct regs regs; 218 219 memset(®s, 0, sizeof (regs)); 220 regs.eax = 0x9610; 221 regs.ebx = (enable ? 0x0100 : 0x0000) | subsys; 222 call_bios(®s); 223 } 224 225 /* Hardware database */ 226 227 struct key_entry { 228 char type; /* See KE_* below */ 229 u8 code; 230 union { 231 u16 keycode; /* For KE_KEY */ 232 struct { /* For KE_SW */ 233 u8 code; 234 u8 value; 235 } sw; 236 }; 237 }; 238 239 enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; 240 241 #define FE_MAIL_LED 0x01 242 #define FE_WIFI_LED 0x02 243 #define FE_UNTESTED 0x80 244 245 static struct key_entry *keymap; /* = NULL; Current key map */ 246 static int have_wifi; 247 static int have_bluetooth; 248 static int have_leds; 249 250 static int __init dmi_matched(const struct dmi_system_id *dmi) 251 { 252 const struct key_entry *key; 253 254 keymap = dmi->driver_data; 255 for (key = keymap; key->type != KE_END; key++) { 256 if (key->type == KE_WIFI) 257 have_wifi = 1; 258 else if (key->type == KE_BLUETOOTH) 259 have_bluetooth = 1; 260 } 261 have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED); 262 263 return 1; 264 } 265 266 static struct key_entry keymap_empty[] __initdata = { 267 { KE_END, 0 } 268 }; 269 270 static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { 271 { KE_KEY, 0x01, {KEY_HELP} }, 272 { KE_KEY, 0x11, {KEY_PROG1} }, 273 { KE_KEY, 0x12, {KEY_PROG2} }, 274 { KE_WIFI, 0x30 }, 275 { KE_KEY, 0x31, {KEY_MAIL} }, 276 { KE_KEY, 0x36, {KEY_WWW} }, 277 { KE_END, 0 } 278 }; 279 280 static struct key_entry keymap_fs_amilo_pro_v3505[] __initdata = { 281 { KE_KEY, 0x01, {KEY_HELP} }, /* Fn+F1 */ 282 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Fn+F4 */ 283 { KE_BLUETOOTH, 0x30 }, /* Fn+F10 */ 284 { KE_KEY, 0x31, {KEY_MAIL} }, /* mail button */ 285 { KE_KEY, 0x36, {KEY_WWW} }, /* www button */ 286 { KE_WIFI, 0x78 }, /* satelite dish button */ 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 static struct key_entry keymap_prestigio[] __initdata = { 615 { KE_KEY, 0x11, {KEY_PROG1} }, 616 { KE_KEY, 0x12, {KEY_PROG2} }, 617 { KE_WIFI, 0x30 }, 618 { KE_KEY, 0x22, {KEY_REWIND} }, 619 { KE_KEY, 0x23, {KEY_FORWARD} }, 620 { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, 621 { KE_KEY, 0x25, {KEY_STOPCD} }, 622 { KE_KEY, 0x31, {KEY_MAIL} }, 623 { KE_KEY, 0x36, {KEY_WWW} }, 624 { KE_END, 0 } 625 }; 626 627 628 /* 629 * If your machine is not here (which is currently rather likely), please send 630 * a list of buttons and their key codes (reported when loading this module 631 * with force=1) and the output of dmidecode to $MODULE_AUTHOR. 632 */ 633 static struct dmi_system_id dmi_ids[] __initdata = { 634 { 635 .callback = dmi_matched, 636 .ident = "Fujitsu-Siemens Amilo Pro V2000", 637 .matches = { 638 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 639 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"), 640 }, 641 .driver_data = keymap_fs_amilo_pro_v2000 642 }, 643 { 644 .callback = dmi_matched, 645 .ident = "Fujitsu-Siemens Amilo Pro Edition V3505", 646 .matches = { 647 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 648 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"), 649 }, 650 .driver_data = keymap_fs_amilo_pro_v3505 651 }, 652 { 653 .callback = dmi_matched, 654 .ident = "Fujitsu-Siemens Amilo M7400", 655 .matches = { 656 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 657 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "), 658 }, 659 .driver_data = keymap_fs_amilo_pro_v2000 660 }, 661 { 662 .callback = dmi_matched, 663 .ident = "Maxdata Pro 7000 DX", 664 .matches = { 665 DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"), 666 DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"), 667 }, 668 .driver_data = keymap_fs_amilo_pro_v2000 669 }, 670 { 671 .callback = dmi_matched, 672 .ident = "Fujitsu N3510", 673 .matches = { 674 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 675 DMI_MATCH(DMI_PRODUCT_NAME, "N3510"), 676 }, 677 .driver_data = keymap_fujitsu_n3510 678 }, 679 { 680 .callback = dmi_matched, 681 .ident = "Acer Aspire 1500", 682 .matches = { 683 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 684 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"), 685 }, 686 .driver_data = keymap_acer_aspire_1500 687 }, 688 { 689 .callback = dmi_matched, 690 .ident = "Acer Aspire 1600", 691 .matches = { 692 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 693 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), 694 }, 695 .driver_data = keymap_acer_aspire_1600 696 }, 697 { 698 .callback = dmi_matched, 699 .ident = "Acer Aspire 3020", 700 .matches = { 701 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 702 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), 703 }, 704 .driver_data = keymap_acer_aspire_5020 705 }, 706 { 707 .callback = dmi_matched, 708 .ident = "Acer Aspire 5020", 709 .matches = { 710 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 711 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), 712 }, 713 .driver_data = keymap_acer_aspire_5020 714 }, 715 { 716 .callback = dmi_matched, 717 .ident = "Acer TravelMate 2100", 718 .matches = { 719 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 720 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), 721 }, 722 .driver_data = keymap_acer_aspire_5020 723 }, 724 { 725 .callback = dmi_matched, 726 .ident = "Acer TravelMate 2410", 727 .matches = { 728 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 729 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), 730 }, 731 .driver_data = keymap_acer_travelmate_2410 732 }, 733 { 734 .callback = dmi_matched, 735 .ident = "Acer TravelMate C300", 736 .matches = { 737 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 738 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), 739 }, 740 .driver_data = keymap_acer_travelmate_300 741 }, 742 { 743 .callback = dmi_matched, 744 .ident = "Acer TravelMate C100", 745 .matches = { 746 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 747 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), 748 }, 749 .driver_data = keymap_acer_travelmate_300 750 }, 751 { 752 .callback = dmi_matched, 753 .ident = "Acer TravelMate C110", 754 .matches = { 755 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 756 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), 757 }, 758 .driver_data = keymap_acer_travelmate_110 759 }, 760 { 761 .callback = dmi_matched, 762 .ident = "Acer TravelMate 380", 763 .matches = { 764 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 765 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), 766 }, 767 .driver_data = keymap_acer_travelmate_380 768 }, 769 { 770 .callback = dmi_matched, 771 .ident = "Acer TravelMate 370", 772 .matches = { 773 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 774 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), 775 }, 776 .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ 777 }, 778 { 779 .callback = dmi_matched, 780 .ident = "Acer TravelMate 220", 781 .matches = { 782 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 783 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), 784 }, 785 .driver_data = keymap_acer_travelmate_220 786 }, 787 { 788 .callback = dmi_matched, 789 .ident = "Acer TravelMate 260", 790 .matches = { 791 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 792 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), 793 }, 794 .driver_data = keymap_acer_travelmate_220 795 }, 796 { 797 .callback = dmi_matched, 798 .ident = "Acer TravelMate 230", 799 .matches = { 800 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 801 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), 802 /* acerhk looks for "TravelMate F4..." ?! */ 803 }, 804 .driver_data = keymap_acer_travelmate_230 805 }, 806 { 807 .callback = dmi_matched, 808 .ident = "Acer TravelMate 280", 809 .matches = { 810 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 811 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), 812 }, 813 .driver_data = keymap_acer_travelmate_230 814 }, 815 { 816 .callback = dmi_matched, 817 .ident = "Acer TravelMate 240", 818 .matches = { 819 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 820 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"), 821 }, 822 .driver_data = keymap_acer_travelmate_240 823 }, 824 { 825 .callback = dmi_matched, 826 .ident = "Acer TravelMate 250", 827 .matches = { 828 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 829 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), 830 }, 831 .driver_data = keymap_acer_travelmate_240 832 }, 833 { 834 .callback = dmi_matched, 835 .ident = "Acer TravelMate 2424NWXCi", 836 .matches = { 837 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 838 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"), 839 }, 840 .driver_data = keymap_acer_travelmate_240 841 }, 842 { 843 .callback = dmi_matched, 844 .ident = "Acer TravelMate 350", 845 .matches = { 846 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 847 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), 848 }, 849 .driver_data = keymap_acer_travelmate_350 850 }, 851 { 852 .callback = dmi_matched, 853 .ident = "Acer TravelMate 360", 854 .matches = { 855 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 856 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), 857 }, 858 .driver_data = keymap_acer_travelmate_360 859 }, 860 { 861 .callback = dmi_matched, 862 .ident = "Acer TravelMate 610", 863 .matches = { 864 DMI_MATCH(DMI_SYS_VENDOR, "ACER"), 865 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), 866 }, 867 .driver_data = keymap_acer_travelmate_610 868 }, 869 { 870 .callback = dmi_matched, 871 .ident = "Acer TravelMate 620", 872 .matches = { 873 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 874 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), 875 }, 876 .driver_data = keymap_acer_travelmate_630 877 }, 878 { 879 .callback = dmi_matched, 880 .ident = "Acer TravelMate 630", 881 .matches = { 882 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 883 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), 884 }, 885 .driver_data = keymap_acer_travelmate_630 886 }, 887 { 888 .callback = dmi_matched, 889 .ident = "AOpen 1559AS", 890 .matches = { 891 DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), 892 DMI_MATCH(DMI_BOARD_NAME, "E2U"), 893 }, 894 .driver_data = keymap_aopen_1559as 895 }, 896 { 897 .callback = dmi_matched, 898 .ident = "Medion MD 9783", 899 .matches = { 900 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 901 DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), 902 }, 903 .driver_data = keymap_wistron_ms2111 904 }, 905 { 906 .callback = dmi_matched, 907 .ident = "Medion MD 40100", 908 .matches = { 909 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 910 DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), 911 }, 912 .driver_data = keymap_wistron_md40100 913 }, 914 { 915 .callback = dmi_matched, 916 .ident = "Medion MD 2900", 917 .matches = { 918 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 919 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), 920 }, 921 .driver_data = keymap_wistron_md2900 922 }, 923 { 924 .callback = dmi_matched, 925 .ident = "Medion MD 96500", 926 .matches = { 927 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), 928 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), 929 }, 930 .driver_data = keymap_wistron_md96500 931 }, 932 { 933 .callback = dmi_matched, 934 .ident = "Medion MD 95400", 935 .matches = { 936 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), 937 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), 938 }, 939 .driver_data = keymap_wistron_md96500 940 }, 941 { 942 .callback = dmi_matched, 943 .ident = "Fujitsu Siemens Amilo D7820", 944 .matches = { 945 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ 946 DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), 947 }, 948 .driver_data = keymap_fs_amilo_d88x0 949 }, 950 { 951 .callback = dmi_matched, 952 .ident = "Fujitsu Siemens Amilo D88x0", 953 .matches = { 954 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 955 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"), 956 }, 957 .driver_data = keymap_fs_amilo_d88x0 958 }, 959 { NULL, } 960 }; 961 962 /* Copy the good keymap, as the original ones are free'd */ 963 static int __init copy_keymap(void) 964 { 965 const struct key_entry *key; 966 struct key_entry *new_keymap; 967 unsigned int length = 1; 968 969 for (key = keymap; key->type != KE_END; key++) 970 length++; 971 972 new_keymap = kmalloc(length * sizeof(struct key_entry), GFP_KERNEL); 973 if (!new_keymap) 974 return -ENOMEM; 975 976 memcpy(new_keymap, keymap, length * sizeof(struct key_entry)); 977 keymap = new_keymap; 978 979 return 0; 980 } 981 982 static int __init select_keymap(void) 983 { 984 dmi_check_system(dmi_ids); 985 if (keymap_name != NULL) { 986 if (strcmp (keymap_name, "1557/MS2141") == 0) 987 keymap = keymap_wistron_ms2141; 988 else if (strcmp (keymap_name, "prestigio") == 0) 989 keymap = keymap_prestigio; 990 else if (strcmp (keymap_name, "generic") == 0) 991 keymap = keymap_wistron_generic; 992 else { 993 printk(KERN_ERR "wistron_btns: Keymap unknown\n"); 994 return -EINVAL; 995 } 996 } 997 if (keymap == NULL) { 998 if (!force) { 999 printk(KERN_ERR "wistron_btns: System unknown\n"); 1000 return -ENODEV; 1001 } 1002 keymap = keymap_empty; 1003 } 1004 1005 return copy_keymap(); 1006 } 1007 1008 /* Input layer interface */ 1009 1010 static struct input_polled_dev *wistron_idev; 1011 static unsigned long jiffies_last_press; 1012 static int wifi_enabled; 1013 static int bluetooth_enabled; 1014 1015 static void report_key(struct input_dev *dev, unsigned int keycode) 1016 { 1017 input_report_key(dev, keycode, 1); 1018 input_sync(dev); 1019 input_report_key(dev, keycode, 0); 1020 input_sync(dev); 1021 } 1022 1023 static void report_switch(struct input_dev *dev, unsigned int code, int value) 1024 { 1025 input_report_switch(dev, code, value); 1026 input_sync(dev); 1027 } 1028 1029 1030 /* led management */ 1031 static void wistron_mail_led_set(struct led_classdev *led_cdev, 1032 enum led_brightness value) 1033 { 1034 bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0); 1035 } 1036 1037 /* same as setting up wifi card, but for laptops on which the led is managed */ 1038 static void wistron_wifi_led_set(struct led_classdev *led_cdev, 1039 enum led_brightness value) 1040 { 1041 bios_set_state(WIFI, (value != LED_OFF) ? 1 : 0); 1042 } 1043 1044 static struct led_classdev wistron_mail_led = { 1045 .name = "wistron:green:mail", 1046 .brightness_set = wistron_mail_led_set, 1047 }; 1048 1049 static struct led_classdev wistron_wifi_led = { 1050 .name = "wistron:red:wifi", 1051 .brightness_set = wistron_wifi_led_set, 1052 }; 1053 1054 static void __devinit wistron_led_init(struct device *parent) 1055 { 1056 if (have_leds & FE_WIFI_LED) { 1057 u16 wifi = bios_get_default_setting(WIFI); 1058 if (wifi & 1) { 1059 wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF; 1060 if (led_classdev_register(parent, &wistron_wifi_led)) 1061 have_leds &= ~FE_WIFI_LED; 1062 else 1063 bios_set_state(WIFI, wistron_wifi_led.brightness); 1064 1065 } else 1066 have_leds &= ~FE_WIFI_LED; 1067 } 1068 1069 if (have_leds & FE_MAIL_LED) { 1070 /* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */ 1071 wistron_mail_led.brightness = LED_OFF; 1072 if (led_classdev_register(parent, &wistron_mail_led)) 1073 have_leds &= ~FE_MAIL_LED; 1074 else 1075 bios_set_state(MAIL_LED, wistron_mail_led.brightness); 1076 } 1077 } 1078 1079 static void __devexit wistron_led_remove(void) 1080 { 1081 if (have_leds & FE_MAIL_LED) 1082 led_classdev_unregister(&wistron_mail_led); 1083 1084 if (have_leds & FE_WIFI_LED) 1085 led_classdev_unregister(&wistron_wifi_led); 1086 } 1087 1088 static inline void wistron_led_suspend(void) 1089 { 1090 if (have_leds & FE_MAIL_LED) 1091 led_classdev_suspend(&wistron_mail_led); 1092 1093 if (have_leds & FE_WIFI_LED) 1094 led_classdev_suspend(&wistron_wifi_led); 1095 } 1096 1097 static inline void wistron_led_resume(void) 1098 { 1099 if (have_leds & FE_MAIL_LED) 1100 led_classdev_resume(&wistron_mail_led); 1101 1102 if (have_leds & FE_WIFI_LED) 1103 led_classdev_resume(&wistron_wifi_led); 1104 } 1105 1106 static struct key_entry *wistron_get_entry_by_scancode(int code) 1107 { 1108 struct key_entry *key; 1109 1110 for (key = keymap; key->type != KE_END; key++) 1111 if (code == key->code) 1112 return key; 1113 1114 return NULL; 1115 } 1116 1117 static struct key_entry *wistron_get_entry_by_keycode(int keycode) 1118 { 1119 struct key_entry *key; 1120 1121 for (key = keymap; key->type != KE_END; key++) 1122 if (key->type == KE_KEY && keycode == key->keycode) 1123 return key; 1124 1125 return NULL; 1126 } 1127 1128 static void handle_key(u8 code) 1129 { 1130 const struct key_entry *key = wistron_get_entry_by_scancode(code); 1131 1132 if (key) { 1133 switch (key->type) { 1134 case KE_KEY: 1135 report_key(wistron_idev->input, key->keycode); 1136 break; 1137 1138 case KE_SW: 1139 report_switch(wistron_idev->input, 1140 key->sw.code, key->sw.value); 1141 break; 1142 1143 case KE_WIFI: 1144 if (have_wifi) { 1145 wifi_enabled = !wifi_enabled; 1146 bios_set_state(WIFI, wifi_enabled); 1147 } 1148 break; 1149 1150 case KE_BLUETOOTH: 1151 if (have_bluetooth) { 1152 bluetooth_enabled = !bluetooth_enabled; 1153 bios_set_state(BLUETOOTH, bluetooth_enabled); 1154 } 1155 break; 1156 1157 default: 1158 BUG(); 1159 } 1160 jiffies_last_press = jiffies; 1161 } else 1162 printk(KERN_NOTICE 1163 "wistron_btns: Unknown key code %02X\n", code); 1164 } 1165 1166 static void poll_bios(bool discard) 1167 { 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 } 1179 } 1180 1181 static void wistron_flush(struct input_polled_dev *dev) 1182 { 1183 /* Flush stale event queue */ 1184 poll_bios(true); 1185 } 1186 1187 static void wistron_poll(struct input_polled_dev *dev) 1188 { 1189 poll_bios(false); 1190 1191 /* Increase poll frequency if user is currently pressing keys (< 2s ago) */ 1192 if (time_before(jiffies, jiffies_last_press + 2 * HZ)) 1193 dev->poll_interval = POLL_INTERVAL_BURST; 1194 else 1195 dev->poll_interval = POLL_INTERVAL_DEFAULT; 1196 } 1197 1198 static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) 1199 { 1200 const struct key_entry *key = wistron_get_entry_by_scancode(scancode); 1201 1202 if (key && key->type == KE_KEY) { 1203 *keycode = key->keycode; 1204 return 0; 1205 } 1206 1207 return -EINVAL; 1208 } 1209 1210 static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) 1211 { 1212 struct key_entry *key; 1213 int old_keycode; 1214 1215 if (keycode < 0 || keycode > KEY_MAX) 1216 return -EINVAL; 1217 1218 key = wistron_get_entry_by_scancode(scancode); 1219 if (key && key->type == KE_KEY) { 1220 old_keycode = key->keycode; 1221 key->keycode = keycode; 1222 set_bit(keycode, dev->keybit); 1223 if (!wistron_get_entry_by_keycode(old_keycode)) 1224 clear_bit(old_keycode, dev->keybit); 1225 return 0; 1226 } 1227 1228 return -EINVAL; 1229 } 1230 1231 static int __devinit setup_input_dev(void) 1232 { 1233 struct key_entry *key; 1234 struct input_dev *input_dev; 1235 int error; 1236 1237 wistron_idev = input_allocate_polled_device(); 1238 if (!wistron_idev) 1239 return -ENOMEM; 1240 1241 wistron_idev->flush = wistron_flush; 1242 wistron_idev->poll = wistron_poll; 1243 wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; 1244 1245 input_dev = wistron_idev->input; 1246 input_dev->name = "Wistron laptop buttons"; 1247 input_dev->phys = "wistron/input0"; 1248 input_dev->id.bustype = BUS_HOST; 1249 input_dev->dev.parent = &wistron_device->dev; 1250 1251 input_dev->getkeycode = wistron_getkeycode; 1252 input_dev->setkeycode = wistron_setkeycode; 1253 1254 for (key = keymap; key->type != KE_END; key++) { 1255 switch (key->type) { 1256 case KE_KEY: 1257 set_bit(EV_KEY, input_dev->evbit); 1258 set_bit(key->keycode, input_dev->keybit); 1259 break; 1260 1261 case KE_SW: 1262 set_bit(EV_SW, input_dev->evbit); 1263 set_bit(key->sw.code, input_dev->swbit); 1264 break; 1265 1266 /* if wifi or bluetooth are not available, create normal keys */ 1267 case KE_WIFI: 1268 if (!have_wifi) { 1269 key->type = KE_KEY; 1270 key->keycode = KEY_WLAN; 1271 key--; 1272 } 1273 break; 1274 1275 case KE_BLUETOOTH: 1276 if (!have_bluetooth) { 1277 key->type = KE_KEY; 1278 key->keycode = KEY_BLUETOOTH; 1279 key--; 1280 } 1281 break; 1282 1283 default: 1284 break; 1285 } 1286 } 1287 1288 /* reads information flags on KE_END */ 1289 if (key->code & FE_UNTESTED) 1290 printk(KERN_WARNING "Untested laptop multimedia keys, " 1291 "please report success or failure to eric.piel" 1292 "@tremplin-utc.net\n"); 1293 1294 error = input_register_polled_device(wistron_idev); 1295 if (error) { 1296 input_free_polled_device(wistron_idev); 1297 return error; 1298 } 1299 1300 return 0; 1301 } 1302 1303 /* Driver core */ 1304 1305 static int __devinit wistron_probe(struct platform_device *dev) 1306 { 1307 int err; 1308 1309 bios_attach(); 1310 cmos_address = bios_get_cmos_address(); 1311 1312 if (have_wifi) { 1313 u16 wifi = bios_get_default_setting(WIFI); 1314 if (wifi & 1) 1315 wifi_enabled = (wifi & 2) ? 1 : 0; 1316 else 1317 have_wifi = 0; 1318 1319 if (have_wifi) 1320 bios_set_state(WIFI, wifi_enabled); 1321 } 1322 1323 if (have_bluetooth) { 1324 u16 bt = bios_get_default_setting(BLUETOOTH); 1325 if (bt & 1) 1326 bluetooth_enabled = (bt & 2) ? 1 : 0; 1327 else 1328 have_bluetooth = 0; 1329 1330 if (have_bluetooth) 1331 bios_set_state(BLUETOOTH, bluetooth_enabled); 1332 } 1333 1334 wistron_led_init(&dev->dev); 1335 err = setup_input_dev(); 1336 if (err) { 1337 bios_detach(); 1338 return err; 1339 } 1340 1341 return 0; 1342 } 1343 1344 static int __devexit wistron_remove(struct platform_device *dev) 1345 { 1346 wistron_led_remove(); 1347 input_unregister_polled_device(wistron_idev); 1348 input_free_polled_device(wistron_idev); 1349 bios_detach(); 1350 1351 return 0; 1352 } 1353 1354 #ifdef CONFIG_PM 1355 static int wistron_suspend(struct platform_device *dev, pm_message_t state) 1356 { 1357 if (have_wifi) 1358 bios_set_state(WIFI, 0); 1359 1360 if (have_bluetooth) 1361 bios_set_state(BLUETOOTH, 0); 1362 1363 wistron_led_suspend(); 1364 return 0; 1365 } 1366 1367 static int wistron_resume(struct platform_device *dev) 1368 { 1369 if (have_wifi) 1370 bios_set_state(WIFI, wifi_enabled); 1371 1372 if (have_bluetooth) 1373 bios_set_state(BLUETOOTH, bluetooth_enabled); 1374 1375 wistron_led_resume(); 1376 poll_bios(true); 1377 1378 return 0; 1379 } 1380 #else 1381 #define wistron_suspend NULL 1382 #define wistron_resume NULL 1383 #endif 1384 1385 static struct platform_driver wistron_driver = { 1386 .driver = { 1387 .name = "wistron-bios", 1388 .owner = THIS_MODULE, 1389 }, 1390 .probe = wistron_probe, 1391 .remove = __devexit_p(wistron_remove), 1392 .suspend = wistron_suspend, 1393 .resume = wistron_resume, 1394 }; 1395 1396 static int __init wb_module_init(void) 1397 { 1398 int err; 1399 1400 err = select_keymap(); 1401 if (err) 1402 return err; 1403 1404 err = map_bios(); 1405 if (err) 1406 return err; 1407 1408 err = platform_driver_register(&wistron_driver); 1409 if (err) 1410 goto err_unmap_bios; 1411 1412 wistron_device = platform_device_alloc("wistron-bios", -1); 1413 if (!wistron_device) { 1414 err = -ENOMEM; 1415 goto err_unregister_driver; 1416 } 1417 1418 err = platform_device_add(wistron_device); 1419 if (err) 1420 goto err_free_device; 1421 1422 return 0; 1423 1424 err_free_device: 1425 platform_device_put(wistron_device); 1426 err_unregister_driver: 1427 platform_driver_unregister(&wistron_driver); 1428 err_unmap_bios: 1429 unmap_bios(); 1430 1431 return err; 1432 } 1433 1434 static void __exit wb_module_exit(void) 1435 { 1436 platform_device_unregister(wistron_device); 1437 platform_driver_unregister(&wistron_driver); 1438 unmap_bios(); 1439 kfree(keymap); 1440 } 1441 1442 module_init(wb_module_init); 1443 module_exit(wb_module_exit); 1444