aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/wistron_btns.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/misc/wistron_btns.c')
-rw-r--r--drivers/input/misc/wistron_btns.c685
1 files changed, 610 insertions, 75 deletions
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index e1183aeb8ed5..961aad7a0476 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -50,7 +50,7 @@
50MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); 50MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
51MODULE_DESCRIPTION("Wistron laptop button driver"); 51MODULE_DESCRIPTION("Wistron laptop button driver");
52MODULE_LICENSE("GPL v2"); 52MODULE_LICENSE("GPL v2");
53MODULE_VERSION("0.1"); 53MODULE_VERSION("0.2");
54 54
55static int force; /* = 0; */ 55static int force; /* = 0; */
56module_param(force, bool, 0); 56module_param(force, bool, 0);
@@ -58,7 +58,7 @@ MODULE_PARM_DESC(force, "Load even if computer is not in database");
58 58
59static char *keymap_name; /* = NULL; */ 59static char *keymap_name; /* = NULL; */
60module_param_named(keymap, keymap_name, charp, 0); 60module_param_named(keymap, keymap_name, charp, 0);
61MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected"); 61MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected [generic, 1557/MS2141]");
62 62
63static struct platform_device *wistron_device; 63static struct platform_device *wistron_device;
64 64
@@ -233,10 +233,20 @@ static void bios_set_state(u8 subsys, int enable)
233struct key_entry { 233struct key_entry {
234 char type; /* See KE_* below */ 234 char type; /* See KE_* below */
235 u8 code; 235 u8 code;
236 unsigned keycode; /* For KE_KEY */ 236 union {
237 u16 keycode; /* For KE_KEY */
238 struct { /* For KE_SW */
239 u8 code;
240 u8 value;
241 } sw;
242 };
237}; 243};
238 244
239enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH }; 245enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
246
247#define FE_MAIL_LED 0x01
248#define FE_WIFI_LED 0x02
249#define FE_UNTESTED 0x80
240 250
241static const struct key_entry *keymap; /* = NULL; Current key map */ 251static const struct key_entry *keymap; /* = NULL; Current key map */
242static int have_wifi; 252static int have_wifi;
@@ -256,93 +266,341 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
256 return 1; 266 return 1;
257} 267}
258 268
259static struct key_entry keymap_empty[] = { 269static struct key_entry keymap_empty[] __initdata = {
260 { KE_END, 0 } 270 { KE_END, 0 }
261}; 271};
262 272
263static struct key_entry keymap_fs_amilo_pro_v2000[] = { 273static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
264 { KE_KEY, 0x01, KEY_HELP }, 274 { KE_KEY, 0x01, {KEY_HELP} },
265 { KE_KEY, 0x11, KEY_PROG1 }, 275 { KE_KEY, 0x11, {KEY_PROG1} },
266 { KE_KEY, 0x12, KEY_PROG2 }, 276 { KE_KEY, 0x12, {KEY_PROG2} },
267 { KE_WIFI, 0x30, 0 }, 277 { KE_WIFI, 0x30 },
268 { KE_KEY, 0x31, KEY_MAIL }, 278 { KE_KEY, 0x31, {KEY_MAIL} },
269 { KE_KEY, 0x36, KEY_WWW }, 279 { KE_KEY, 0x36, {KEY_WWW} },
270 { KE_END, 0 } 280 { KE_END, 0 }
271}; 281};
272 282
273static struct key_entry keymap_fujitsu_n3510[] = { 283static struct key_entry keymap_fujitsu_n3510[] __initdata = {
274 { KE_KEY, 0x11, KEY_PROG1 }, 284 { KE_KEY, 0x11, {KEY_PROG1} },
275 { KE_KEY, 0x12, KEY_PROG2 }, 285 { KE_KEY, 0x12, {KEY_PROG2} },
276 { KE_KEY, 0x36, KEY_WWW }, 286 { KE_KEY, 0x36, {KEY_WWW} },
277 { KE_KEY, 0x31, KEY_MAIL }, 287 { KE_KEY, 0x31, {KEY_MAIL} },
278 { KE_KEY, 0x71, KEY_STOPCD }, 288 { KE_KEY, 0x71, {KEY_STOPCD} },
279 { KE_KEY, 0x72, KEY_PLAYPAUSE }, 289 { KE_KEY, 0x72, {KEY_PLAYPAUSE} },
280 { KE_KEY, 0x74, KEY_REWIND }, 290 { KE_KEY, 0x74, {KEY_REWIND} },
281 { KE_KEY, 0x78, KEY_FORWARD }, 291 { KE_KEY, 0x78, {KEY_FORWARD} },
282 { KE_END, 0 } 292 { KE_END, 0 }
283}; 293};
284 294
285static struct key_entry keymap_wistron_ms2111[] = { 295static struct key_entry keymap_wistron_ms2111[] __initdata = {
286 { KE_KEY, 0x11, KEY_PROG1 }, 296 { KE_KEY, 0x11, {KEY_PROG1} },
287 { KE_KEY, 0x12, KEY_PROG2 }, 297 { KE_KEY, 0x12, {KEY_PROG2} },
288 { KE_KEY, 0x13, KEY_PROG3 }, 298 { KE_KEY, 0x13, {KEY_PROG3} },
289 { KE_KEY, 0x31, KEY_MAIL }, 299 { KE_KEY, 0x31, {KEY_MAIL} },
290 { KE_KEY, 0x36, KEY_WWW }, 300 { KE_KEY, 0x36, {KEY_WWW} },
291 { KE_END, 0 } 301 { KE_END, FE_MAIL_LED }
302};
303
304static struct key_entry keymap_wistron_md40100[] __initdata = {
305 { KE_KEY, 0x01, {KEY_HELP} },
306 { KE_KEY, 0x02, {KEY_CONFIG} },
307 { KE_KEY, 0x31, {KEY_MAIL} },
308 { KE_KEY, 0x36, {KEY_WWW} },
309 { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */
310 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED }
292}; 311};
293 312
294static struct key_entry keymap_wistron_ms2141[] = { 313static struct key_entry keymap_wistron_ms2141[] __initdata = {
295 { KE_KEY, 0x11, KEY_PROG1 }, 314 { KE_KEY, 0x11, {KEY_PROG1} },
296 { KE_KEY, 0x12, KEY_PROG2 }, 315 { KE_KEY, 0x12, {KEY_PROG2} },
297 { KE_WIFI, 0x30, 0 }, 316 { KE_WIFI, 0x30 },
298 { KE_KEY, 0x22, KEY_REWIND }, 317 { KE_KEY, 0x22, {KEY_REWIND} },
299 { KE_KEY, 0x23, KEY_FORWARD }, 318 { KE_KEY, 0x23, {KEY_FORWARD} },
300 { KE_KEY, 0x24, KEY_PLAYPAUSE }, 319 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
301 { KE_KEY, 0x25, KEY_STOPCD }, 320 { KE_KEY, 0x25, {KEY_STOPCD} },
302 { KE_KEY, 0x31, KEY_MAIL }, 321 { KE_KEY, 0x31, {KEY_MAIL} },
303 { KE_KEY, 0x36, KEY_WWW }, 322 { KE_KEY, 0x36, {KEY_WWW} },
304 { KE_END, 0 } 323 { KE_END, 0 }
305}; 324};
306 325
307static struct key_entry keymap_acer_aspire_1500[] = { 326static struct key_entry keymap_acer_aspire_1500[] __initdata = {
308 { KE_KEY, 0x11, KEY_PROG1 }, 327 { KE_KEY, 0x01, {KEY_HELP} },
309 { KE_KEY, 0x12, KEY_PROG2 }, 328 { KE_KEY, 0x03, {KEY_POWER} },
310 { KE_WIFI, 0x30, 0 }, 329 { KE_KEY, 0x11, {KEY_PROG1} },
311 { KE_KEY, 0x31, KEY_MAIL }, 330 { KE_KEY, 0x12, {KEY_PROG2} },
312 { KE_KEY, 0x36, KEY_WWW }, 331 { KE_WIFI, 0x30 },
313 { KE_BLUETOOTH, 0x44, 0 }, 332 { KE_KEY, 0x31, {KEY_MAIL} },
314 { KE_END, 0 } 333 { KE_KEY, 0x36, {KEY_WWW} },
334 { KE_KEY, 0x49, {KEY_CONFIG} },
335 { KE_BLUETOOTH, 0x44 },
336 { KE_END, FE_UNTESTED }
315}; 337};
316 338
317static struct key_entry keymap_acer_travelmate_240[] = { 339static struct key_entry keymap_acer_aspire_1600[] __initdata = {
318 { KE_KEY, 0x31, KEY_MAIL }, 340 { KE_KEY, 0x01, {KEY_HELP} },
319 { KE_KEY, 0x36, KEY_WWW }, 341 { KE_KEY, 0x03, {KEY_POWER} },
320 { KE_KEY, 0x11, KEY_PROG1 }, 342 { KE_KEY, 0x08, {KEY_MUTE} },
321 { KE_KEY, 0x12, KEY_PROG2 }, 343 { KE_KEY, 0x11, {KEY_PROG1} },
322 { KE_BLUETOOTH, 0x44, 0 }, 344 { KE_KEY, 0x12, {KEY_PROG2} },
323 { KE_WIFI, 0x30, 0 }, 345 { KE_KEY, 0x13, {KEY_PROG3} },
324 { KE_END, 0 } 346 { KE_KEY, 0x31, {KEY_MAIL} },
347 { KE_KEY, 0x36, {KEY_WWW} },
348 { KE_KEY, 0x49, {KEY_CONFIG} },
349 { KE_WIFI, 0x30 },
350 { KE_BLUETOOTH, 0x44 },
351 { KE_END, FE_MAIL_LED | FE_UNTESTED }
352};
353
354/* 3020 has been tested */
355static struct key_entry keymap_acer_aspire_5020[] __initdata = {
356 { KE_KEY, 0x01, {KEY_HELP} },
357 { KE_KEY, 0x03, {KEY_POWER} },
358 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */
359 { KE_KEY, 0x11, {KEY_PROG1} },
360 { KE_KEY, 0x12, {KEY_PROG2} },
361 { KE_KEY, 0x31, {KEY_MAIL} },
362 { KE_KEY, 0x36, {KEY_WWW} },
363 { KE_KEY, 0x6a, {KEY_CONFIG} },
364 { KE_WIFI, 0x30 },
365 { KE_BLUETOOTH, 0x44 },
366 { KE_END, FE_MAIL_LED | FE_UNTESTED }
367};
368
369static struct key_entry keymap_acer_travelmate_2410[] __initdata = {
370 { KE_KEY, 0x01, {KEY_HELP} },
371 { KE_KEY, 0x6d, {KEY_POWER} },
372 { KE_KEY, 0x11, {KEY_PROG1} },
373 { KE_KEY, 0x12, {KEY_PROG2} },
374 { KE_KEY, 0x31, {KEY_MAIL} },
375 { KE_KEY, 0x36, {KEY_WWW} },
376 { KE_KEY, 0x6a, {KEY_CONFIG} },
377 { KE_WIFI, 0x30 },
378 { KE_BLUETOOTH, 0x44 },
379 { KE_END, FE_MAIL_LED | FE_UNTESTED }
380};
381
382static struct key_entry keymap_acer_travelmate_110[] __initdata = {
383 { KE_KEY, 0x01, {KEY_HELP} },
384 { KE_KEY, 0x02, {KEY_CONFIG} },
385 { KE_KEY, 0x03, {KEY_POWER} },
386 { KE_KEY, 0x08, {KEY_MUTE} },
387 { KE_KEY, 0x11, {KEY_PROG1} },
388 { KE_KEY, 0x12, {KEY_PROG2} },
389 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
390 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
391 { KE_KEY, 0x31, {KEY_MAIL} },
392 { KE_KEY, 0x36, {KEY_WWW} },
393 { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */
394 { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */
395 { KE_WIFI, 0x30 },
396 { KE_END, FE_MAIL_LED | FE_UNTESTED }
397};
398
399static struct key_entry keymap_acer_travelmate_300[] __initdata = {
400 { KE_KEY, 0x01, {KEY_HELP} },
401 { KE_KEY, 0x02, {KEY_CONFIG} },
402 { KE_KEY, 0x03, {KEY_POWER} },
403 { KE_KEY, 0x08, {KEY_MUTE} },
404 { KE_KEY, 0x11, {KEY_PROG1} },
405 { KE_KEY, 0x12, {KEY_PROG2} },
406 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
407 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
408 { KE_KEY, 0x31, {KEY_MAIL} },
409 { KE_KEY, 0x36, {KEY_WWW} },
410 { KE_WIFI, 0x30 },
411 { KE_BLUETOOTH, 0x44 },
412 { KE_END, FE_MAIL_LED | FE_UNTESTED }
325}; 413};
326 414
327static struct key_entry keymap_aopen_1559as[] = { 415static struct key_entry keymap_acer_travelmate_380[] __initdata = {
328 { KE_KEY, 0x01, KEY_HELP }, 416 { KE_KEY, 0x01, {KEY_HELP} },
329 { KE_KEY, 0x06, KEY_PROG3 }, 417 { KE_KEY, 0x02, {KEY_CONFIG} },
330 { KE_KEY, 0x11, KEY_PROG1 }, 418 { KE_KEY, 0x03, {KEY_POWER} }, /* not 370 */
331 { KE_KEY, 0x12, KEY_PROG2 }, 419 { KE_KEY, 0x11, {KEY_PROG1} },
332 { KE_WIFI, 0x30, 0 }, 420 { KE_KEY, 0x12, {KEY_PROG2} },
333 { KE_KEY, 0x31, KEY_MAIL }, 421 { KE_KEY, 0x13, {KEY_PROG3} },
334 { KE_KEY, 0x36, KEY_WWW }, 422 { KE_KEY, 0x31, {KEY_MAIL} },
423 { KE_KEY, 0x36, {KEY_WWW} },
424 { KE_WIFI, 0x30 },
425 { KE_END, FE_MAIL_LED | FE_UNTESTED }
426};
427
428/* unusual map */
429static struct key_entry keymap_acer_travelmate_220[] __initdata = {
430 { KE_KEY, 0x01, {KEY_HELP} },
431 { KE_KEY, 0x02, {KEY_CONFIG} },
432 { KE_KEY, 0x11, {KEY_MAIL} },
433 { KE_KEY, 0x12, {KEY_WWW} },
434 { KE_KEY, 0x13, {KEY_PROG2} },
435 { KE_KEY, 0x31, {KEY_PROG1} },
436 { KE_END, FE_WIFI_LED | FE_UNTESTED }
437};
438
439static struct key_entry keymap_acer_travelmate_230[] __initdata = {
440 { KE_KEY, 0x01, {KEY_HELP} },
441 { KE_KEY, 0x02, {KEY_CONFIG} },
442 { KE_KEY, 0x11, {KEY_PROG1} },
443 { KE_KEY, 0x12, {KEY_PROG2} },
444 { KE_KEY, 0x31, {KEY_MAIL} },
445 { KE_KEY, 0x36, {KEY_WWW} },
446 { KE_END, FE_WIFI_LED | FE_UNTESTED }
447};
448
449static struct key_entry keymap_acer_travelmate_240[] __initdata = {
450 { KE_KEY, 0x01, {KEY_HELP} },
451 { KE_KEY, 0x02, {KEY_CONFIG} },
452 { KE_KEY, 0x03, {KEY_POWER} },
453 { KE_KEY, 0x08, {KEY_MUTE} },
454 { KE_KEY, 0x31, {KEY_MAIL} },
455 { KE_KEY, 0x36, {KEY_WWW} },
456 { KE_KEY, 0x11, {KEY_PROG1} },
457 { KE_KEY, 0x12, {KEY_PROG2} },
458 { KE_BLUETOOTH, 0x44 },
459 { KE_WIFI, 0x30 },
460 { KE_END, FE_UNTESTED }
461};
462
463static struct key_entry keymap_acer_travelmate_350[] __initdata = {
464 { KE_KEY, 0x01, {KEY_HELP} },
465 { KE_KEY, 0x02, {KEY_CONFIG} },
466 { KE_KEY, 0x11, {KEY_PROG1} },
467 { KE_KEY, 0x12, {KEY_PROG2} },
468 { KE_KEY, 0x13, {KEY_MAIL} },
469 { KE_KEY, 0x14, {KEY_PROG3} },
470 { KE_KEY, 0x15, {KEY_WWW} },
471 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED }
472};
473
474static struct key_entry keymap_acer_travelmate_360[] __initdata = {
475 { KE_KEY, 0x01, {KEY_HELP} },
476 { KE_KEY, 0x02, {KEY_CONFIG} },
477 { KE_KEY, 0x11, {KEY_PROG1} },
478 { KE_KEY, 0x12, {KEY_PROG2} },
479 { KE_KEY, 0x13, {KEY_MAIL} },
480 { KE_KEY, 0x14, {KEY_PROG3} },
481 { KE_KEY, 0x15, {KEY_WWW} },
482 { KE_KEY, 0x40, {KEY_WLAN} },
483 { KE_END, FE_WIFI_LED | FE_UNTESTED } /* no mail led */
484};
485
486/* Wifi subsystem only activates the led. Therefore we need to pass
487 * wifi event as a normal key, then userspace can really change the wifi state.
488 * TODO we need to export led state to userspace (wifi and mail) */
489static struct key_entry keymap_acer_travelmate_610[] __initdata = {
490 { KE_KEY, 0x01, {KEY_HELP} },
491 { KE_KEY, 0x02, {KEY_CONFIG} },
492 { KE_KEY, 0x11, {KEY_PROG1} },
493 { KE_KEY, 0x12, {KEY_PROG2} },
494 { KE_KEY, 0x13, {KEY_PROG3} },
495 { KE_KEY, 0x14, {KEY_MAIL} },
496 { KE_KEY, 0x15, {KEY_WWW} },
497 { KE_KEY, 0x40, {KEY_WLAN} },
498 { KE_END, FE_MAIL_LED | FE_WIFI_LED }
499};
500
501static struct key_entry keymap_acer_travelmate_630[] __initdata = {
502 { KE_KEY, 0x01, {KEY_HELP} },
503 { KE_KEY, 0x02, {KEY_CONFIG} },
504 { KE_KEY, 0x03, {KEY_POWER} },
505 { KE_KEY, 0x08, {KEY_MUTE} }, /* not 620 */
506 { KE_KEY, 0x11, {KEY_PROG1} },
507 { KE_KEY, 0x12, {KEY_PROG2} },
508 { KE_KEY, 0x13, {KEY_PROG3} },
509 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
510 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
511 { KE_KEY, 0x31, {KEY_MAIL} },
512 { KE_KEY, 0x36, {KEY_WWW} },
513 { KE_WIFI, 0x30 },
514 { KE_END, FE_MAIL_LED | FE_UNTESTED }
515};
516
517static struct key_entry keymap_aopen_1559as[] __initdata = {
518 { KE_KEY, 0x01, {KEY_HELP} },
519 { KE_KEY, 0x06, {KEY_PROG3} },
520 { KE_KEY, 0x11, {KEY_PROG1} },
521 { KE_KEY, 0x12, {KEY_PROG2} },
522 { KE_WIFI, 0x30 },
523 { KE_KEY, 0x31, {KEY_MAIL} },
524 { KE_KEY, 0x36, {KEY_WWW} },
335 { KE_END, 0 }, 525 { KE_END, 0 },
336}; 526};
337 527
338static struct key_entry keymap_fs_amilo_d88x0[] = { 528static struct key_entry keymap_fs_amilo_d88x0[] __initdata = {
339 { KE_KEY, 0x01, KEY_HELP }, 529 { KE_KEY, 0x01, {KEY_HELP} },
340 { KE_KEY, 0x08, KEY_MUTE }, 530 { KE_KEY, 0x08, {KEY_MUTE} },
341 { KE_KEY, 0x31, KEY_MAIL }, 531 { KE_KEY, 0x31, {KEY_MAIL} },
342 { KE_KEY, 0x36, KEY_WWW }, 532 { KE_KEY, 0x36, {KEY_WWW} },
343 { KE_KEY, 0x11, KEY_PROG1 }, 533 { KE_KEY, 0x11, {KEY_PROG1} },
344 { KE_KEY, 0x12, KEY_PROG2 }, 534 { KE_KEY, 0x12, {KEY_PROG2} },
345 { KE_KEY, 0x13, KEY_PROG3 }, 535 { KE_KEY, 0x13, {KEY_PROG3} },
536 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED }
537};
538
539static struct key_entry keymap_wistron_md2900[] __initdata = {
540 { KE_KEY, 0x01, {KEY_HELP} },
541 { KE_KEY, 0x02, {KEY_CONFIG} },
542 { KE_KEY, 0x11, {KEY_PROG1} },
543 { KE_KEY, 0x12, {KEY_PROG2} },
544 { KE_KEY, 0x31, {KEY_MAIL} },
545 { KE_KEY, 0x36, {KEY_WWW} },
546 { KE_WIFI, 0x30 },
547 { KE_END, FE_MAIL_LED | FE_UNTESTED }
548};
549
550static struct key_entry keymap_wistron_md96500[] __initdata = {
551 { KE_KEY, 0x01, {KEY_HELP} },
552 { KE_KEY, 0x02, {KEY_CONFIG} },
553 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */
554 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */
555 { KE_KEY, 0x08, {KEY_MUTE} },
556 { KE_KEY, 0x11, {KEY_PROG1} },
557 { KE_KEY, 0x12, {KEY_PROG2} },
558 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
559 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
560 { KE_KEY, 0x22, {KEY_REWIND} },
561 { KE_KEY, 0x23, {KEY_FORWARD} },
562 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
563 { KE_KEY, 0x25, {KEY_STOPCD} },
564 { KE_KEY, 0x31, {KEY_MAIL} },
565 { KE_KEY, 0x36, {KEY_WWW} },
566 { KE_WIFI, 0x30 },
567 { KE_BLUETOOTH, 0x44 },
568 { KE_END, FE_UNTESTED }
569};
570
571static struct key_entry keymap_wistron_generic[] __initdata = {
572 { KE_KEY, 0x01, {KEY_HELP} },
573 { KE_KEY, 0x02, {KEY_CONFIG} },
574 { KE_KEY, 0x03, {KEY_POWER} },
575 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */
576 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */
577 { KE_KEY, 0x08, {KEY_MUTE} },
578 { KE_KEY, 0x11, {KEY_PROG1} },
579 { KE_KEY, 0x12, {KEY_PROG2} },
580 { KE_KEY, 0x13, {KEY_PROG3} },
581 { KE_KEY, 0x14, {KEY_MAIL} },
582 { KE_KEY, 0x15, {KEY_WWW} },
583 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
584 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
585 { KE_KEY, 0x22, {KEY_REWIND} },
586 { KE_KEY, 0x23, {KEY_FORWARD} },
587 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
588 { KE_KEY, 0x25, {KEY_STOPCD} },
589 { KE_KEY, 0x31, {KEY_MAIL} },
590 { KE_KEY, 0x36, {KEY_WWW} },
591 { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */
592 { KE_KEY, 0x40, {KEY_WLAN} },
593 { KE_KEY, 0x49, {KEY_CONFIG} },
594 { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */
595 { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */
596 { KE_KEY, 0x6a, {KEY_CONFIG} },
597 { KE_KEY, 0x6d, {KEY_POWER} },
598 { KE_KEY, 0x71, {KEY_STOPCD} },
599 { KE_KEY, 0x72, {KEY_PLAYPAUSE} },
600 { KE_KEY, 0x74, {KEY_REWIND} },
601 { KE_KEY, 0x78, {KEY_FORWARD} },
602 { KE_WIFI, 0x30 },
603 { KE_BLUETOOTH, 0x44 },
346 { KE_END, 0 } 604 { KE_END, 0 }
347}; 605};
348 606
@@ -390,6 +648,133 @@ static struct dmi_system_id dmi_ids[] __initdata = {
390 }, 648 },
391 { 649 {
392 .callback = dmi_matched, 650 .callback = dmi_matched,
651 .ident = "Acer Aspire 1600",
652 .matches = {
653 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
654 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"),
655 },
656 .driver_data = keymap_acer_aspire_1600
657 },
658 {
659 .callback = dmi_matched,
660 .ident = "Acer Aspire 3020",
661 .matches = {
662 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
663 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"),
664 },
665 .driver_data = keymap_acer_aspire_5020
666 },
667 {
668 .callback = dmi_matched,
669 .ident = "Acer Aspire 5020",
670 .matches = {
671 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
672 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"),
673 },
674 .driver_data = keymap_acer_aspire_5020
675 },
676 {
677 .callback = dmi_matched,
678 .ident = "Acer TravelMate 2100",
679 .matches = {
680 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
681 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"),
682 },
683 .driver_data = keymap_acer_aspire_5020
684 },
685 {
686 .callback = dmi_matched,
687 .ident = "Acer TravelMate 2410",
688 .matches = {
689 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
690 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"),
691 },
692 .driver_data = keymap_acer_travelmate_2410
693 },
694 {
695 .callback = dmi_matched,
696 .ident = "Acer TravelMate C300",
697 .matches = {
698 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
699 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"),
700 },
701 .driver_data = keymap_acer_travelmate_300
702 },
703 {
704 .callback = dmi_matched,
705 .ident = "Acer TravelMate C100",
706 .matches = {
707 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
708 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"),
709 },
710 .driver_data = keymap_acer_travelmate_300
711 },
712 {
713 .callback = dmi_matched,
714 .ident = "Acer TravelMate C110",
715 .matches = {
716 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
717 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"),
718 },
719 .driver_data = keymap_acer_travelmate_110
720 },
721 {
722 .callback = dmi_matched,
723 .ident = "Acer TravelMate 380",
724 .matches = {
725 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
726 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"),
727 },
728 .driver_data = keymap_acer_travelmate_380
729 },
730 {
731 .callback = dmi_matched,
732 .ident = "Acer TravelMate 370",
733 .matches = {
734 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
735 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"),
736 },
737 .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */
738 },
739 {
740 .callback = dmi_matched,
741 .ident = "Acer TravelMate 220",
742 .matches = {
743 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
744 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"),
745 },
746 .driver_data = keymap_acer_travelmate_220
747 },
748 {
749 .callback = dmi_matched,
750 .ident = "Acer TravelMate 260",
751 .matches = {
752 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
753 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"),
754 },
755 .driver_data = keymap_acer_travelmate_220
756 },
757 {
758 .callback = dmi_matched,
759 .ident = "Acer TravelMate 230",
760 .matches = {
761 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
762 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"),
763 /* acerhk looks for "TravelMate F4..." ?! */
764 },
765 .driver_data = keymap_acer_travelmate_230
766 },
767 {
768 .callback = dmi_matched,
769 .ident = "Acer TravelMate 280",
770 .matches = {
771 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
772 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"),
773 },
774 .driver_data = keymap_acer_travelmate_230
775 },
776 {
777 .callback = dmi_matched,
393 .ident = "Acer TravelMate 240", 778 .ident = "Acer TravelMate 240",
394 .matches = { 779 .matches = {
395 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 780 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -399,6 +784,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
399 }, 784 },
400 { 785 {
401 .callback = dmi_matched, 786 .callback = dmi_matched,
787 .ident = "Acer TravelMate 250",
788 .matches = {
789 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
790 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"),
791 },
792 .driver_data = keymap_acer_travelmate_240
793 },
794 {
795 .callback = dmi_matched,
402 .ident = "Acer TravelMate 2424NWXCi", 796 .ident = "Acer TravelMate 2424NWXCi",
403 .matches = { 797 .matches = {
404 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 798 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -408,6 +802,51 @@ static struct dmi_system_id dmi_ids[] __initdata = {
408 }, 802 },
409 { 803 {
410 .callback = dmi_matched, 804 .callback = dmi_matched,
805 .ident = "Acer TravelMate 350",
806 .matches = {
807 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
808 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"),
809 },
810 .driver_data = keymap_acer_travelmate_350
811 },
812 {
813 .callback = dmi_matched,
814 .ident = "Acer TravelMate 360",
815 .matches = {
816 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
817 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
818 },
819 .driver_data = keymap_acer_travelmate_360
820 },
821 {
822 .callback = dmi_matched,
823 .ident = "Acer TravelMate 610",
824 .matches = {
825 DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
826 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"),
827 },
828 .driver_data = keymap_acer_travelmate_610
829 },
830 {
831 .callback = dmi_matched,
832 .ident = "Acer TravelMate 620",
833 .matches = {
834 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
835 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"),
836 },
837 .driver_data = keymap_acer_travelmate_630
838 },
839 {
840 .callback = dmi_matched,
841 .ident = "Acer TravelMate 630",
842 .matches = {
843 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
844 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"),
845 },
846 .driver_data = keymap_acer_travelmate_630
847 },
848 {
849 .callback = dmi_matched,
411 .ident = "AOpen 1559AS", 850 .ident = "AOpen 1559AS",
412 .matches = { 851 .matches = {
413 DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), 852 DMI_MATCH(DMI_PRODUCT_NAME, "E2U"),
@@ -426,6 +865,51 @@ static struct dmi_system_id dmi_ids[] __initdata = {
426 }, 865 },
427 { 866 {
428 .callback = dmi_matched, 867 .callback = dmi_matched,
868 .ident = "Medion MD 40100",
869 .matches = {
870 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
871 DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"),
872 },
873 .driver_data = keymap_wistron_md40100
874 },
875 {
876 .callback = dmi_matched,
877 .ident = "Medion MD 2900",
878 .matches = {
879 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
880 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"),
881 },
882 .driver_data = keymap_wistron_md2900
883 },
884 {
885 .callback = dmi_matched,
886 .ident = "Medion MD 96500",
887 .matches = {
888 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
889 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"),
890 },
891 .driver_data = keymap_wistron_md96500
892 },
893 {
894 .callback = dmi_matched,
895 .ident = "Medion MD 95400",
896 .matches = {
897 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
898 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"),
899 },
900 .driver_data = keymap_wistron_md96500
901 },
902 {
903 .callback = dmi_matched,
904 .ident = "Fujitsu Siemens Amilo D7820",
905 .matches = {
906 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */
907 DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"),
908 },
909 .driver_data = keymap_fs_amilo_d88x0
910 },
911 {
912 .callback = dmi_matched,
429 .ident = "Fujitsu Siemens Amilo D88x0", 913 .ident = "Fujitsu Siemens Amilo D88x0",
430 .matches = { 914 .matches = {
431 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 915 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
@@ -436,17 +920,39 @@ static struct dmi_system_id dmi_ids[] __initdata = {
436 { NULL, } 920 { NULL, }
437}; 921};
438 922
923/* Copy the good keymap, as the original ones are free'd */
924static int __init copy_keymap(void)
925{
926 const struct key_entry *key;
927 struct key_entry *new_keymap;
928 unsigned int length = 1;
929
930 for (key = keymap; key->type != KE_END; key++)
931 length++;
932
933 new_keymap = kmalloc(length * sizeof(struct key_entry), GFP_KERNEL);
934 if (!new_keymap)
935 return -ENOMEM;
936
937 memcpy(new_keymap, keymap, length * sizeof(struct key_entry));
938 keymap = new_keymap;
939
940 return 0;
941}
942
439static int __init select_keymap(void) 943static int __init select_keymap(void)
440{ 944{
945 dmi_check_system(dmi_ids);
441 if (keymap_name != NULL) { 946 if (keymap_name != NULL) {
442 if (strcmp (keymap_name, "1557/MS2141") == 0) 947 if (strcmp (keymap_name, "1557/MS2141") == 0)
443 keymap = keymap_wistron_ms2141; 948 keymap = keymap_wistron_ms2141;
949 else if (strcmp (keymap_name, "generic") == 0)
950 keymap = keymap_wistron_generic;
444 else { 951 else {
445 printk(KERN_ERR "wistron_btns: Keymap unknown\n"); 952 printk(KERN_ERR "wistron_btns: Keymap unknown\n");
446 return -EINVAL; 953 return -EINVAL;
447 } 954 }
448 } 955 }
449 dmi_check_system(dmi_ids);
450 if (keymap == NULL) { 956 if (keymap == NULL) {
451 if (!force) { 957 if (!force) {
452 printk(KERN_ERR "wistron_btns: System unknown\n"); 958 printk(KERN_ERR "wistron_btns: System unknown\n");
@@ -454,7 +960,8 @@ static int __init select_keymap(void)
454 } 960 }
455 keymap = keymap_empty; 961 keymap = keymap_empty;
456 } 962 }
457 return 0; 963
964 return copy_keymap();
458} 965}
459 966
460 /* Input layer interface */ 967 /* Input layer interface */
@@ -476,12 +983,28 @@ static int __devinit setup_input_dev(void)
476 input_dev->cdev.dev = &wistron_device->dev; 983 input_dev->cdev.dev = &wistron_device->dev;
477 984
478 for (key = keymap; key->type != KE_END; key++) { 985 for (key = keymap; key->type != KE_END; key++) {
479 if (key->type == KE_KEY) { 986 switch (key->type) {
480 input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY); 987 case KE_KEY:
481 set_bit(key->keycode, input_dev->keybit); 988 set_bit(EV_KEY, input_dev->evbit);
989 set_bit(key->keycode, input_dev->keybit);
990 break;
991
992 case KE_SW:
993 set_bit(EV_SW, input_dev->evbit);
994 set_bit(key->sw.code, input_dev->swbit);
995 break;
996
997 default:
998 ;
482 } 999 }
483 } 1000 }
484 1001
1002 /* reads information flags on KE_END */
1003 if (key->code & FE_UNTESTED)
1004 printk(KERN_WARNING "Untested laptop multimedia keys, "
1005 "please report success or failure to eric.piel"
1006 "@tremplin-utc.net\n");
1007
485 error = input_register_device(input_dev); 1008 error = input_register_device(input_dev);
486 if (error) { 1009 if (error) {
487 input_free_device(input_dev); 1010 input_free_device(input_dev);
@@ -499,6 +1022,12 @@ static void report_key(unsigned keycode)
499 input_sync(input_dev); 1022 input_sync(input_dev);
500} 1023}
501 1024
1025static void report_switch(unsigned code, int value)
1026{
1027 input_report_switch(input_dev, code, value);
1028 input_sync(input_dev);
1029}
1030
502 /* Driver core */ 1031 /* Driver core */
503 1032
504static int wifi_enabled; 1033static int wifi_enabled;
@@ -519,6 +1048,10 @@ static void handle_key(u8 code)
519 report_key(key->keycode); 1048 report_key(key->keycode);
520 break; 1049 break;
521 1050
1051 case KE_SW:
1052 report_switch(key->sw.code, key->sw.value);
1053 break;
1054
522 case KE_WIFI: 1055 case KE_WIFI:
523 if (have_wifi) { 1056 if (have_wifi) {
524 wifi_enabled = !wifi_enabled; 1057 wifi_enabled = !wifi_enabled;
@@ -534,6 +1067,7 @@ static void handle_key(u8 code)
534 break; 1067 break;
535 1068
536 case KE_END: 1069 case KE_END:
1070 break;
537 default: 1071 default:
538 BUG(); 1072 BUG();
539 } 1073 }
@@ -690,6 +1224,7 @@ static void __exit wb_module_exit(void)
690 platform_device_unregister(wistron_device); 1224 platform_device_unregister(wistron_device);
691 platform_driver_unregister(&wistron_driver); 1225 platform_driver_unregister(&wistron_driver);
692 unmap_bios(); 1226 unmap_bios();
1227 kfree(keymap);
693} 1228}
694 1229
695module_init(wb_module_init); 1230module_init(wb_module_init);