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 bool have_wifi; 247 static bool have_bluetooth; 248 static int leds_present; /* bitmask of leds present */ 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 = true; 258 else if (key->type == KE_BLUETOOTH) 259 have_bluetooth = true; 260 } 261 leds_present = 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_aopen_1557[] __initdata = { 615 { KE_KEY, 0x01, {KEY_HELP} }, 616 { KE_KEY, 0x11, {KEY_PROG1} }, 617 { KE_KEY, 0x12, {KEY_PROG2} }, 618 { KE_WIFI, 0x30 }, 619 { KE_KEY, 0x22, {KEY_REWIND} }, 620 { KE_KEY, 0x23, {KEY_FORWARD} }, 621 { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, 622 { KE_KEY, 0x25, {KEY_STOPCD} }, 623 { KE_KEY, 0x31, {KEY_MAIL} }, 624 { KE_KEY, 0x36, {KEY_WWW} }, 625 { KE_END, 0 } 626 }; 627 628 static struct key_entry keymap_prestigio[] __initdata = { 629 { KE_KEY, 0x11, {KEY_PROG1} }, 630 { KE_KEY, 0x12, {KEY_PROG2} }, 631 { KE_WIFI, 0x30 }, 632 { KE_KEY, 0x22, {KEY_REWIND} }, 633 { KE_KEY, 0x23, {KEY_FORWARD} }, 634 { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, 635 { KE_KEY, 0x25, {KEY_STOPCD} }, 636 { KE_KEY, 0x31, {KEY_MAIL} }, 637 { KE_KEY, 0x36, {KEY_WWW} }, 638 { KE_END, 0 } 639 }; 640 641 642 /* 643 * If your machine is not here (which is currently rather likely), please send 644 * a list of buttons and their key codes (reported when loading this module 645 * with force=1) and the output of dmidecode to $MODULE_AUTHOR. 646 */ 647 static struct dmi_system_id dmi_ids[] __initdata = { 648 { 649 .callback = dmi_matched, 650 .ident = "Fujitsu-Siemens Amilo Pro V2000", 651 .matches = { 652 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 653 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"), 654 }, 655 .driver_data = keymap_fs_amilo_pro_v2000 656 }, 657 { 658 .callback = dmi_matched, 659 .ident = "Fujitsu-Siemens Amilo Pro Edition V3505", 660 .matches = { 661 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 662 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"), 663 }, 664 .driver_data = keymap_fs_amilo_pro_v3505 665 }, 666 { 667 .callback = dmi_matched, 668 .ident = "Fujitsu-Siemens Amilo M7400", 669 .matches = { 670 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 671 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "), 672 }, 673 .driver_data = keymap_fs_amilo_pro_v2000 674 }, 675 { 676 .callback = dmi_matched, 677 .ident = "Maxdata Pro 7000 DX", 678 .matches = { 679 DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"), 680 DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"), 681 }, 682 .driver_data = keymap_fs_amilo_pro_v2000 683 }, 684 { 685 .callback = dmi_matched, 686 .ident = "Fujitsu N3510", 687 .matches = { 688 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 689 DMI_MATCH(DMI_PRODUCT_NAME, "N3510"), 690 }, 691 .driver_data = keymap_fujitsu_n3510 692 }, 693 { 694 .callback = dmi_matched, 695 .ident = "Acer Aspire 1500", 696 .matches = { 697 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 698 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"), 699 }, 700 .driver_data = keymap_acer_aspire_1500 701 }, 702 { 703 .callback = dmi_matched, 704 .ident = "Acer Aspire 1600", 705 .matches = { 706 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 707 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), 708 }, 709 .driver_data = keymap_acer_aspire_1600 710 }, 711 { 712 .callback = dmi_matched, 713 .ident = "Acer Aspire 3020", 714 .matches = { 715 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 716 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), 717 }, 718 .driver_data = keymap_acer_aspire_5020 719 }, 720 { 721 .callback = dmi_matched, 722 .ident = "Acer Aspire 5020", 723 .matches = { 724 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 725 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), 726 }, 727 .driver_data = keymap_acer_aspire_5020 728 }, 729 { 730 .callback = dmi_matched, 731 .ident = "Acer TravelMate 2100", 732 .matches = { 733 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 734 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), 735 }, 736 .driver_data = keymap_acer_aspire_5020 737 }, 738 { 739 .callback = dmi_matched, 740 .ident = "Acer TravelMate 2410", 741 .matches = { 742 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 743 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), 744 }, 745 .driver_data = keymap_acer_travelmate_2410 746 }, 747 { 748 .callback = dmi_matched, 749 .ident = "Acer TravelMate C300", 750 .matches = { 751 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 752 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), 753 }, 754 .driver_data = keymap_acer_travelmate_300 755 }, 756 { 757 .callback = dmi_matched, 758 .ident = "Acer TravelMate C100", 759 .matches = { 760 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 761 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), 762 }, 763 .driver_data = keymap_acer_travelmate_300 764 }, 765 { 766 .callback = dmi_matched, 767 .ident = "Acer TravelMate C110", 768 .matches = { 769 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 770 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), 771 }, 772 .driver_data = keymap_acer_travelmate_110 773 }, 774 { 775 .callback = dmi_matched, 776 .ident = "Acer TravelMate 380", 777 .matches = { 778 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 779 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), 780 }, 781 .driver_data = keymap_acer_travelmate_380 782 }, 783 { 784 .callback = dmi_matched, 785 .ident = "Acer TravelMate 370", 786 .matches = { 787 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 788 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), 789 }, 790 .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ 791 }, 792 { 793 .callback = dmi_matched, 794 .ident = "Acer TravelMate 220", 795 .matches = { 796 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 797 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), 798 }, 799 .driver_data = keymap_acer_travelmate_220 800 }, 801 { 802 .callback = dmi_matched, 803 .ident = "Acer TravelMate 260", 804 .matches = { 805 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 806 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), 807 }, 808 .driver_data = keymap_acer_travelmate_220 809 }, 810 { 811 .callback = dmi_matched, 812 .ident = "Acer TravelMate 230", 813 .matches = { 814 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 815 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), 816 /* acerhk looks for "TravelMate F4..." ?! */ 817 }, 818 .driver_data = keymap_acer_travelmate_230 819 }, 820 { 821 .callback = dmi_matched, 822 .ident = "Acer TravelMate 280", 823 .matches = { 824 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 825 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), 826 }, 827 .driver_data = keymap_acer_travelmate_230 828 }, 829 { 830 .callback = dmi_matched, 831 .ident = "Acer TravelMate 240", 832 .matches = { 833 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 834 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"), 835 }, 836 .driver_data = keymap_acer_travelmate_240 837 }, 838 { 839 .callback = dmi_matched, 840 .ident = "Acer TravelMate 250", 841 .matches = { 842 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 843 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), 844 }, 845 .driver_data = keymap_acer_travelmate_240 846 }, 847 { 848 .callback = dmi_matched, 849 .ident = "Acer TravelMate 2424NWXCi", 850 .matches = { 851 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 852 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"), 853 }, 854 .driver_data = keymap_acer_travelmate_240 855 }, 856 { 857 .callback = dmi_matched, 858 .ident = "Acer TravelMate 350", 859 .matches = { 860 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 861 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), 862 }, 863 .driver_data = keymap_acer_travelmate_350 864 }, 865 { 866 .callback = dmi_matched, 867 .ident = "Acer TravelMate 360", 868 .matches = { 869 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 870 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), 871 }, 872 .driver_data = keymap_acer_travelmate_360 873 }, 874 { 875 .callback = dmi_matched, 876 .ident = "Acer TravelMate 610", 877 .matches = { 878 DMI_MATCH(DMI_SYS_VENDOR, "ACER"), 879 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), 880 }, 881 .driver_data = keymap_acer_travelmate_610 882 }, 883 { 884 .callback = dmi_matched, 885 .ident = "Acer TravelMate 620", 886 .matches = { 887 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 888 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), 889 }, 890 .driver_data = keymap_acer_travelmate_630 891 }, 892 { 893 .callback = dmi_matched, 894 .ident = "Acer TravelMate 630", 895 .matches = { 896 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 897 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), 898 }, 899 .driver_data = keymap_acer_travelmate_630 900 }, 901 { 902 .callback = dmi_matched, 903 .ident = "AOpen 1559AS", 904 .matches = { 905 DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), 906 DMI_MATCH(DMI_BOARD_NAME, "E2U"), 907 }, 908 .driver_data = keymap_aopen_1559as 909 }, 910 { 911 .callback = dmi_matched, 912 .ident = "Medion MD 9783", 913 .matches = { 914 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 915 DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), 916 }, 917 .driver_data = keymap_wistron_ms2111 918 }, 919 { 920 .callback = dmi_matched, 921 .ident = "Medion MD 40100", 922 .matches = { 923 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 924 DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), 925 }, 926 .driver_data = keymap_wistron_md40100 927 }, 928 { 929 .callback = dmi_matched, 930 .ident = "Medion MD 2900", 931 .matches = { 932 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 933 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), 934 }, 935 .driver_data = keymap_wistron_md2900 936 }, 937 { 938 .callback = dmi_matched, 939 .ident = "Medion MD 96500", 940 .matches = { 941 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), 942 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), 943 }, 944 .driver_data = keymap_wistron_md96500 945 }, 946 { 947 .callback = dmi_matched, 948 .ident = "Medion MD 95400", 949 .matches = { 950 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), 951 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), 952 }, 953 .driver_data = keymap_wistron_md96500 954 }, 955 { 956 .callback = dmi_matched, 957 .ident = "Fujitsu Siemens Amilo D7820", 958 .matches = { 959 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ 960 DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), 961 }, 962 .driver_data = keymap_fs_amilo_d88x0 963 }, 964 { 965 .callback = dmi_matched, 966 .ident = "Fujitsu Siemens Amilo D88x0", 967 .matches = { 968 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 969 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"), 970 }, 971 .driver_data = keymap_fs_amilo_d88x0 972 }, 973 { NULL, } 974 }; 975 976 /* Copy the good keymap, as the original ones are free'd */ 977 static int __init copy_keymap(void) 978 { 979 const struct key_entry *key; 980 struct key_entry *new_keymap; 981 unsigned int length = 1; 982 983 for (key = keymap; key->type != KE_END; key++) 984 length++; 985 986 new_keymap = kmalloc(length * sizeof(struct key_entry), GFP_KERNEL); 987 if (!new_keymap) 988 return -ENOMEM; 989 990 memcpy(new_keymap, keymap, length * sizeof(struct key_entry)); 991 keymap = new_keymap; 992 993 return 0; 994 } 995 996 static int __init select_keymap(void) 997 { 998 dmi_check_system(dmi_ids); 999 if (keymap_name != NULL) { 1000 if (strcmp (keymap_name, "1557/MS2141") == 0) 1001 keymap = keymap_wistron_ms2141; 1002 else if (strcmp (keymap_name, "aopen1557") == 0) 1003 keymap = keymap_aopen_1557; 1004 else if (strcmp (keymap_name, "prestigio") == 0) 1005 keymap = keymap_prestigio; 1006 else if (strcmp (keymap_name, "generic") == 0) 1007 keymap = keymap_wistron_generic; 1008 else { 1009 printk(KERN_ERR "wistron_btns: Keymap unknown\n"); 1010 return -EINVAL; 1011 } 1012 } 1013 if (keymap == NULL) { 1014 if (!force) { 1015 printk(KERN_ERR "wistron_btns: System unknown\n"); 1016 return -ENODEV; 1017 } 1018 keymap = keymap_empty; 1019 } 1020 1021 return copy_keymap(); 1022 } 1023 1024 /* Input layer interface */ 1025 1026 static struct input_polled_dev *wistron_idev; 1027 static unsigned long jiffies_last_press; 1028 static bool wifi_enabled; 1029 static bool bluetooth_enabled; 1030 1031 static void report_key(struct input_dev *dev, unsigned int keycode) 1032 { 1033 input_report_key(dev, keycode, 1); 1034 input_sync(dev); 1035 input_report_key(dev, keycode, 0); 1036 input_sync(dev); 1037 } 1038 1039 static void report_switch(struct input_dev *dev, unsigned int code, int value) 1040 { 1041 input_report_switch(dev, code, value); 1042 input_sync(dev); 1043 } 1044 1045 1046 /* led management */ 1047 static void wistron_mail_led_set(struct led_classdev *led_cdev, 1048 enum led_brightness value) 1049 { 1050 bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0); 1051 } 1052 1053 /* same as setting up wifi card, but for laptops on which the led is managed */ 1054 static void wistron_wifi_led_set(struct led_classdev *led_cdev, 1055 enum led_brightness value) 1056 { 1057 bios_set_state(WIFI, (value != LED_OFF) ? 1 : 0); 1058 } 1059 1060 static struct led_classdev wistron_mail_led = { 1061 .name = "wistron:green:mail", 1062 .brightness_set = wistron_mail_led_set, 1063 }; 1064 1065 static struct led_classdev wistron_wifi_led = { 1066 .name = "wistron:red:wifi", 1067 .brightness_set = wistron_wifi_led_set, 1068 }; 1069 1070 static void __devinit wistron_led_init(struct device *parent) 1071 { 1072 if (leds_present & FE_WIFI_LED) { 1073 u16 wifi = bios_get_default_setting(WIFI); 1074 if (wifi & 1) { 1075 wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF; 1076 if (led_classdev_register(parent, &wistron_wifi_led)) 1077 leds_present &= ~FE_WIFI_LED; 1078 else 1079 bios_set_state(WIFI, wistron_wifi_led.brightness); 1080 1081 } else 1082 leds_present &= ~FE_WIFI_LED; 1083 } 1084 1085 if (leds_present & FE_MAIL_LED) { 1086 /* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */ 1087 wistron_mail_led.brightness = LED_OFF; 1088 if (led_classdev_register(parent, &wistron_mail_led)) 1089 leds_present &= ~FE_MAIL_LED; 1090 else 1091 bios_set_state(MAIL_LED, wistron_mail_led.brightness); 1092 } 1093 } 1094 1095 static void __devexit wistron_led_remove(void) 1096 { 1097 if (leds_present & FE_MAIL_LED) 1098 led_classdev_unregister(&wistron_mail_led); 1099 1100 if (leds_present & FE_WIFI_LED) 1101 led_classdev_unregister(&wistron_wifi_led); 1102 } 1103 1104 static inline void wistron_led_suspend(void) 1105 { 1106 if (leds_present & FE_MAIL_LED) 1107 led_classdev_suspend(&wistron_mail_led); 1108 1109 if (leds_present & FE_WIFI_LED) 1110 led_classdev_suspend(&wistron_wifi_led); 1111 } 1112 1113 static inline void wistron_led_resume(void) 1114 { 1115 if (leds_present & FE_MAIL_LED) 1116 led_classdev_resume(&wistron_mail_led); 1117 1118 if (leds_present & FE_WIFI_LED) 1119 led_classdev_resume(&wistron_wifi_led); 1120 } 1121 1122 static struct key_entry *wistron_get_entry_by_scancode(int code) 1123 { 1124 struct key_entry *key; 1125 1126 for (key = keymap; key->type != KE_END; key++) 1127 if (code == key->code) 1128 return key; 1129 1130 return NULL; 1131 } 1132 1133 static struct key_entry *wistron_get_entry_by_keycode(int keycode) 1134 { 1135 struct key_entry *key; 1136 1137 for (key = keymap; key->type != KE_END; key++) 1138 if (key->type == KE_KEY && keycode == key->keycode) 1139 return key; 1140 1141 return NULL; 1142 } 1143 1144 static void handle_key(u8 code) 1145 { 1146 const struct key_entry *key = wistron_get_entry_by_scancode(code); 1147 1148 if (key) { 1149 switch (key->type) { 1150 case KE_KEY: 1151 report_key(wistron_idev->input, key->keycode); 1152 break; 1153 1154 case KE_SW: 1155 report_switch(wistron_idev->input, 1156 key->sw.code, key->sw.value); 1157 break; 1158 1159 case KE_WIFI: 1160 if (have_wifi) { 1161 wifi_enabled = !wifi_enabled; 1162 bios_set_state(WIFI, wifi_enabled); 1163 } 1164 break; 1165 1166 case KE_BLUETOOTH: 1167 if (have_bluetooth) { 1168 bluetooth_enabled = !bluetooth_enabled; 1169 bios_set_state(BLUETOOTH, bluetooth_enabled); 1170 } 1171 break; 1172 1173 default: 1174 BUG(); 1175 } 1176 jiffies_last_press = jiffies; 1177 } else 1178 printk(KERN_NOTICE 1179 "wistron_btns: Unknown key code %02X\n", code); 1180 } 1181 1182 static void poll_bios(bool discard) 1183 { 1184 u8 qlen; 1185 u16 val; 1186 1187 for (;;) { 1188 qlen = CMOS_READ(cmos_address); 1189 if (qlen == 0) 1190 break; 1191 val = bios_pop_queue(); 1192 if (val != 0 && !discard) 1193 handle_key((u8)val); 1194 } 1195 } 1196 1197 static void wistron_flush(struct input_polled_dev *dev) 1198 { 1199 /* Flush stale event queue */ 1200 poll_bios(true); 1201 } 1202 1203 static void wistron_poll(struct input_polled_dev *dev) 1204 { 1205 poll_bios(false); 1206 1207 /* Increase poll frequency if user is currently pressing keys (< 2s ago) */ 1208 if (time_before(jiffies, jiffies_last_press + 2 * HZ)) 1209 dev->poll_interval = POLL_INTERVAL_BURST; 1210 else 1211 dev->poll_interval = POLL_INTERVAL_DEFAULT; 1212 } 1213 1214 static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode) 1215 { 1216 const struct key_entry *key = wistron_get_entry_by_scancode(scancode); 1217 1218 if (key && key->type == KE_KEY) { 1219 *keycode = key->keycode; 1220 return 0; 1221 } 1222 1223 return -EINVAL; 1224 } 1225 1226 static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) 1227 { 1228 struct key_entry *key; 1229 int old_keycode; 1230 1231 if (keycode < 0 || keycode > KEY_MAX) 1232 return -EINVAL; 1233 1234 key = wistron_get_entry_by_scancode(scancode); 1235 if (key && key->type == KE_KEY) { 1236 old_keycode = key->keycode; 1237 key->keycode = keycode; 1238 set_bit(keycode, dev->keybit); 1239 if (!wistron_get_entry_by_keycode(old_keycode)) 1240 clear_bit(old_keycode, dev->keybit); 1241 return 0; 1242 } 1243 1244 return -EINVAL; 1245 } 1246 1247 static int __devinit setup_input_dev(void) 1248 { 1249 struct key_entry *key; 1250 struct input_dev *input_dev; 1251 int error; 1252 1253 wistron_idev = input_allocate_polled_device(); 1254 if (!wistron_idev) 1255 return -ENOMEM; 1256 1257 wistron_idev->flush = wistron_flush; 1258 wistron_idev->poll = wistron_poll; 1259 wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT; 1260 1261 input_dev = wistron_idev->input; 1262 input_dev->name = "Wistron laptop buttons"; 1263 input_dev->phys = "wistron/input0"; 1264 input_dev->id.bustype = BUS_HOST; 1265 input_dev->dev.parent = &wistron_device->dev; 1266 1267 input_dev->getkeycode = wistron_getkeycode; 1268 input_dev->setkeycode = wistron_setkeycode; 1269 1270 for (key = keymap; key->type != KE_END; key++) { 1271 switch (key->type) { 1272 case KE_KEY: 1273 set_bit(EV_KEY, input_dev->evbit); 1274 set_bit(key->keycode, input_dev->keybit); 1275 break; 1276 1277 case KE_SW: 1278 set_bit(EV_SW, input_dev->evbit); 1279 set_bit(key->sw.code, input_dev->swbit); 1280 break; 1281 1282 /* if wifi or bluetooth are not available, create normal keys */ 1283 case KE_WIFI: 1284 if (!have_wifi) { 1285 key->type = KE_KEY; 1286 key->keycode = KEY_WLAN; 1287 key--; 1288 } 1289 break; 1290 1291 case KE_BLUETOOTH: 1292 if (!have_bluetooth) { 1293 key->type = KE_KEY; 1294 key->keycode = KEY_BLUETOOTH; 1295 key--; 1296 } 1297 break; 1298 1299 default: 1300 break; 1301 } 1302 } 1303 1304 /* reads information flags on KE_END */ 1305 if (key->code & FE_UNTESTED) 1306 printk(KERN_WARNING "Untested laptop multimedia keys, " 1307 "please report success or failure to eric.piel" 1308 "@tremplin-utc.net\n"); 1309 1310 error = input_register_polled_device(wistron_idev); 1311 if (error) { 1312 input_free_polled_device(wistron_idev); 1313 return error; 1314 } 1315 1316 return 0; 1317 } 1318 1319 /* Driver core */ 1320 1321 static int __devinit wistron_probe(struct platform_device *dev) 1322 { 1323 int err; 1324 1325 bios_attach(); 1326 cmos_address = bios_get_cmos_address(); 1327 1328 if (have_wifi) { 1329 u16 wifi = bios_get_default_setting(WIFI); 1330 if (wifi & 1) 1331 wifi_enabled = wifi & 2; 1332 else 1333 have_wifi = 0; 1334 1335 if (have_wifi) 1336 bios_set_state(WIFI, wifi_enabled); 1337 } 1338 1339 if (have_bluetooth) { 1340 u16 bt = bios_get_default_setting(BLUETOOTH); 1341 if (bt & 1) 1342 bluetooth_enabled = bt & 2; 1343 else 1344 have_bluetooth = false; 1345 1346 if (have_bluetooth) 1347 bios_set_state(BLUETOOTH, bluetooth_enabled); 1348 } 1349 1350 wistron_led_init(&dev->dev); 1351 1352 err = setup_input_dev(); 1353 if (err) { 1354 bios_detach(); 1355 return err; 1356 } 1357 1358 return 0; 1359 } 1360 1361 static int __devexit wistron_remove(struct platform_device *dev) 1362 { 1363 wistron_led_remove(); 1364 input_unregister_polled_device(wistron_idev); 1365 input_free_polled_device(wistron_idev); 1366 bios_detach(); 1367 1368 return 0; 1369 } 1370 1371 #ifdef CONFIG_PM 1372 static int wistron_suspend(struct device *dev) 1373 { 1374 if (have_wifi) 1375 bios_set_state(WIFI, 0); 1376 1377 if (have_bluetooth) 1378 bios_set_state(BLUETOOTH, 0); 1379 1380 wistron_led_suspend(); 1381 1382 return 0; 1383 } 1384 1385 static int wistron_resume(struct device *dev) 1386 { 1387 if (have_wifi) 1388 bios_set_state(WIFI, wifi_enabled); 1389 1390 if (have_bluetooth) 1391 bios_set_state(BLUETOOTH, bluetooth_enabled); 1392 1393 wistron_led_resume(); 1394 1395 poll_bios(true); 1396 1397 return 0; 1398 } 1399 1400 static const struct dev_pm_ops wistron_pm_ops = { 1401 .suspend = wistron_suspend, 1402 .resume = wistron_resume, 1403 .poweroff = wistron_suspend, 1404 .restore = wistron_resume, 1405 }; 1406 #endif 1407 1408 static struct platform_driver wistron_driver = { 1409 .driver = { 1410 .name = "wistron-bios", 1411 .owner = THIS_MODULE, 1412 #if CONFIG_PM 1413 .pm = &wistron_pm_ops, 1414 #endif 1415 }, 1416 .probe = wistron_probe, 1417 .remove = __devexit_p(wistron_remove), 1418 }; 1419 1420 static int __init wb_module_init(void) 1421 { 1422 int err; 1423 1424 err = select_keymap(); 1425 if (err) 1426 return err; 1427 1428 err = map_bios(); 1429 if (err) 1430 return err; 1431 1432 err = platform_driver_register(&wistron_driver); 1433 if (err) 1434 goto err_unmap_bios; 1435 1436 wistron_device = platform_device_alloc("wistron-bios", -1); 1437 if (!wistron_device) { 1438 err = -ENOMEM; 1439 goto err_unregister_driver; 1440 } 1441 1442 err = platform_device_add(wistron_device); 1443 if (err) 1444 goto err_free_device; 1445 1446 return 0; 1447 1448 err_free_device: 1449 platform_device_put(wistron_device); 1450 err_unregister_driver: 1451 platform_driver_unregister(&wistron_driver); 1452 err_unmap_bios: 1453 unmap_bios(); 1454 1455 return err; 1456 } 1457 1458 static void __exit wb_module_exit(void) 1459 { 1460 platform_device_unregister(wistron_device); 1461 platform_driver_unregister(&wistron_driver); 1462 unmap_bios(); 1463 kfree(keymap); 1464 } 1465 1466 module_init(wb_module_init); 1467 module_exit(wb_module_exit); 1468