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