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