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 50 static bool 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 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 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 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 }, /* satellite 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, 0 } 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 dmi_ids[] __initconst = { 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 MODULE_DEVICE_TABLE(dmi, dmi_ids); 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