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