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