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