0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/io.h>
0009 #include <linux/dmi.h>
0010 #include <linux/init.h>
0011 #include <linux/input.h>
0012 #include <linux/input/sparse-keymap.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/jiffies.h>
0015 #include <linux/kernel.h>
0016 #include <linux/mc146818rtc.h>
0017 #include <linux/module.h>
0018 #include <linux/preempt.h>
0019 #include <linux/string.h>
0020 #include <linux/slab.h>
0021 #include <linux/types.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/leds.h>
0024
0025
0026 #define POLL_INTERVAL_DEFAULT 500
0027 #define POLL_INTERVAL_BURST 100
0028
0029
0030 #define WIFI 0x35
0031 #define BLUETOOTH 0x34
0032 #define MAIL_LED 0x31
0033
0034 MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
0035 MODULE_DESCRIPTION("Wistron laptop button driver");
0036 MODULE_LICENSE("GPL v2");
0037
0038 static bool force;
0039 module_param(force, bool, 0);
0040 MODULE_PARM_DESC(force, "Load even if computer is not in database");
0041
0042 static char *keymap_name;
0043 module_param_named(keymap, keymap_name, charp, 0);
0044 MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected [generic, 1557/MS2141]");
0045
0046 static struct platform_device *wistron_device;
0047
0048
0049
0050 static void __iomem *bios_entry_point;
0051 static void __iomem *bios_code_map_base;
0052 static void __iomem *bios_data_map_base;
0053
0054 static u8 cmos_address;
0055
0056 struct regs {
0057 u32 eax, ebx, ecx;
0058 };
0059
0060 static void call_bios(struct regs *regs)
0061 {
0062 unsigned long flags;
0063
0064 preempt_disable();
0065 local_irq_save(flags);
0066 asm volatile ("pushl %%ebp;"
0067 "movl %7, %%ebp;"
0068 "call *%6;"
0069 "popl %%ebp"
0070 : "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx)
0071 : "0" (regs->eax), "1" (regs->ebx), "2" (regs->ecx),
0072 "m" (bios_entry_point), "m" (bios_data_map_base)
0073 : "edx", "edi", "esi", "memory");
0074 local_irq_restore(flags);
0075 preempt_enable();
0076 }
0077
0078 static ssize_t __init locate_wistron_bios(void __iomem *base)
0079 {
0080 static unsigned char __initdata signature[] =
0081 { 0x42, 0x21, 0x55, 0x30 };
0082 ssize_t offset;
0083
0084 for (offset = 0; offset < 0x10000; offset += 0x10) {
0085 if (check_signature(base + offset, signature,
0086 sizeof(signature)) != 0)
0087 return offset;
0088 }
0089 return -1;
0090 }
0091
0092 static int __init map_bios(void)
0093 {
0094 void __iomem *base;
0095 ssize_t offset;
0096 u32 entry_point;
0097
0098 base = ioremap(0xF0000, 0x10000);
0099 offset = locate_wistron_bios(base);
0100 if (offset < 0) {
0101 printk(KERN_ERR "wistron_btns: BIOS entry point not found\n");
0102 iounmap(base);
0103 return -ENODEV;
0104 }
0105
0106 entry_point = readl(base + offset + 5);
0107 printk(KERN_DEBUG
0108 "wistron_btns: BIOS signature found at %p, entry point %08X\n",
0109 base + offset, entry_point);
0110
0111 if (entry_point >= 0xF0000) {
0112 bios_code_map_base = base;
0113 bios_entry_point = bios_code_map_base + (entry_point & 0xFFFF);
0114 } else {
0115 iounmap(base);
0116 bios_code_map_base = ioremap(entry_point & ~0x3FFF, 0x4000);
0117 if (bios_code_map_base == NULL) {
0118 printk(KERN_ERR
0119 "wistron_btns: Can't map BIOS code at %08X\n",
0120 entry_point & ~0x3FFF);
0121 goto err;
0122 }
0123 bios_entry_point = bios_code_map_base + (entry_point & 0x3FFF);
0124 }
0125
0126 bios_data_map_base = ioremap(0x400, 0xc00);
0127 if (bios_data_map_base == NULL) {
0128 printk(KERN_ERR "wistron_btns: Can't map BIOS data\n");
0129 goto err_code;
0130 }
0131 return 0;
0132
0133 err_code:
0134 iounmap(bios_code_map_base);
0135 err:
0136 return -ENOMEM;
0137 }
0138
0139 static inline void unmap_bios(void)
0140 {
0141 iounmap(bios_code_map_base);
0142 iounmap(bios_data_map_base);
0143 }
0144
0145
0146
0147 static u16 bios_pop_queue(void)
0148 {
0149 struct regs regs;
0150
0151 memset(®s, 0, sizeof (regs));
0152 regs.eax = 0x9610;
0153 regs.ebx = 0x061C;
0154 regs.ecx = 0x0000;
0155 call_bios(®s);
0156
0157 return regs.eax;
0158 }
0159
0160 static void bios_attach(void)
0161 {
0162 struct regs regs;
0163
0164 memset(®s, 0, sizeof (regs));
0165 regs.eax = 0x9610;
0166 regs.ebx = 0x012E;
0167 call_bios(®s);
0168 }
0169
0170 static void bios_detach(void)
0171 {
0172 struct regs regs;
0173
0174 memset(®s, 0, sizeof (regs));
0175 regs.eax = 0x9610;
0176 regs.ebx = 0x002E;
0177 call_bios(®s);
0178 }
0179
0180 static u8 bios_get_cmos_address(void)
0181 {
0182 struct regs regs;
0183
0184 memset(®s, 0, sizeof (regs));
0185 regs.eax = 0x9610;
0186 regs.ebx = 0x051C;
0187 call_bios(®s);
0188
0189 return regs.ecx;
0190 }
0191
0192 static u16 bios_get_default_setting(u8 subsys)
0193 {
0194 struct regs regs;
0195
0196 memset(®s, 0, sizeof (regs));
0197 regs.eax = 0x9610;
0198 regs.ebx = 0x0200 | subsys;
0199 call_bios(®s);
0200
0201 return regs.eax;
0202 }
0203
0204 static void bios_set_state(u8 subsys, int enable)
0205 {
0206 struct regs regs;
0207
0208 memset(®s, 0, sizeof (regs));
0209 regs.eax = 0x9610;
0210 regs.ebx = (enable ? 0x0100 : 0x0000) | subsys;
0211 call_bios(®s);
0212 }
0213
0214
0215
0216 #define KE_WIFI (KE_LAST + 1)
0217 #define KE_BLUETOOTH (KE_LAST + 2)
0218
0219 #define FE_MAIL_LED 0x01
0220 #define FE_WIFI_LED 0x02
0221 #define FE_UNTESTED 0x80
0222
0223 static struct key_entry *keymap;
0224 static bool have_wifi;
0225 static bool have_bluetooth;
0226 static int leds_present;
0227
0228 static int __init dmi_matched(const struct dmi_system_id *dmi)
0229 {
0230 const struct key_entry *key;
0231
0232 keymap = dmi->driver_data;
0233 for (key = keymap; key->type != KE_END; key++) {
0234 if (key->type == KE_WIFI)
0235 have_wifi = true;
0236 else if (key->type == KE_BLUETOOTH)
0237 have_bluetooth = true;
0238 }
0239 leds_present = key->code & (FE_MAIL_LED | FE_WIFI_LED);
0240
0241 return 1;
0242 }
0243
0244 static struct key_entry keymap_empty[] __initdata = {
0245 { KE_END, 0 }
0246 };
0247
0248 static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
0249 { KE_KEY, 0x01, {KEY_HELP} },
0250 { KE_KEY, 0x11, {KEY_PROG1} },
0251 { KE_KEY, 0x12, {KEY_PROG2} },
0252 { KE_WIFI, 0x30 },
0253 { KE_KEY, 0x31, {KEY_MAIL} },
0254 { KE_KEY, 0x36, {KEY_WWW} },
0255 { KE_END, 0 }
0256 };
0257
0258 static struct key_entry keymap_fs_amilo_pro_v3505[] __initdata = {
0259 { KE_KEY, 0x01, {KEY_HELP} },
0260 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} },
0261 { KE_BLUETOOTH, 0x30 },
0262 { KE_KEY, 0x31, {KEY_MAIL} },
0263 { KE_KEY, 0x36, {KEY_WWW} },
0264 { KE_WIFI, 0x78 },
0265 { KE_END, 0 }
0266 };
0267
0268 static struct key_entry keymap_fs_amilo_pro_v8210[] __initdata = {
0269 { KE_KEY, 0x01, {KEY_HELP} },
0270 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} },
0271 { KE_BLUETOOTH, 0x30 },
0272 { KE_KEY, 0x31, {KEY_MAIL} },
0273 { KE_KEY, 0x36, {KEY_WWW} },
0274 { KE_WIFI, 0x78 },
0275 { KE_END, FE_WIFI_LED }
0276 };
0277
0278 static struct key_entry keymap_fujitsu_n3510[] __initdata = {
0279 { KE_KEY, 0x11, {KEY_PROG1} },
0280 { KE_KEY, 0x12, {KEY_PROG2} },
0281 { KE_KEY, 0x36, {KEY_WWW} },
0282 { KE_KEY, 0x31, {KEY_MAIL} },
0283 { KE_KEY, 0x71, {KEY_STOPCD} },
0284 { KE_KEY, 0x72, {KEY_PLAYPAUSE} },
0285 { KE_KEY, 0x74, {KEY_REWIND} },
0286 { KE_KEY, 0x78, {KEY_FORWARD} },
0287 { KE_END, 0 }
0288 };
0289
0290 static struct key_entry keymap_wistron_ms2111[] __initdata = {
0291 { KE_KEY, 0x11, {KEY_PROG1} },
0292 { KE_KEY, 0x12, {KEY_PROG2} },
0293 { KE_KEY, 0x13, {KEY_PROG3} },
0294 { KE_KEY, 0x31, {KEY_MAIL} },
0295 { KE_KEY, 0x36, {KEY_WWW} },
0296 { KE_END, FE_MAIL_LED }
0297 };
0298
0299 static struct key_entry keymap_wistron_md40100[] __initdata = {
0300 { KE_KEY, 0x01, {KEY_HELP} },
0301 { KE_KEY, 0x02, {KEY_CONFIG} },
0302 { KE_KEY, 0x31, {KEY_MAIL} },
0303 { KE_KEY, 0x36, {KEY_WWW} },
0304 { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} },
0305 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED }
0306 };
0307
0308 static struct key_entry keymap_wistron_ms2141[] __initdata = {
0309 { KE_KEY, 0x11, {KEY_PROG1} },
0310 { KE_KEY, 0x12, {KEY_PROG2} },
0311 { KE_WIFI, 0x30 },
0312 { KE_KEY, 0x22, {KEY_REWIND} },
0313 { KE_KEY, 0x23, {KEY_FORWARD} },
0314 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
0315 { KE_KEY, 0x25, {KEY_STOPCD} },
0316 { KE_KEY, 0x31, {KEY_MAIL} },
0317 { KE_KEY, 0x36, {KEY_WWW} },
0318 { KE_END, 0 }
0319 };
0320
0321 static struct key_entry keymap_acer_aspire_1500[] __initdata = {
0322 { KE_KEY, 0x01, {KEY_HELP} },
0323 { KE_KEY, 0x03, {KEY_POWER} },
0324 { KE_KEY, 0x11, {KEY_PROG1} },
0325 { KE_KEY, 0x12, {KEY_PROG2} },
0326 { KE_WIFI, 0x30 },
0327 { KE_KEY, 0x31, {KEY_MAIL} },
0328 { KE_KEY, 0x36, {KEY_WWW} },
0329 { KE_KEY, 0x49, {KEY_CONFIG} },
0330 { KE_BLUETOOTH, 0x44 },
0331 { KE_END, FE_UNTESTED }
0332 };
0333
0334 static struct key_entry keymap_acer_aspire_1600[] __initdata = {
0335 { KE_KEY, 0x01, {KEY_HELP} },
0336 { KE_KEY, 0x03, {KEY_POWER} },
0337 { KE_KEY, 0x08, {KEY_MUTE} },
0338 { KE_KEY, 0x11, {KEY_PROG1} },
0339 { KE_KEY, 0x12, {KEY_PROG2} },
0340 { KE_KEY, 0x13, {KEY_PROG3} },
0341 { KE_KEY, 0x31, {KEY_MAIL} },
0342 { KE_KEY, 0x36, {KEY_WWW} },
0343 { KE_KEY, 0x49, {KEY_CONFIG} },
0344 { KE_WIFI, 0x30 },
0345 { KE_BLUETOOTH, 0x44 },
0346 { KE_END, FE_MAIL_LED | FE_UNTESTED }
0347 };
0348
0349
0350 static struct key_entry keymap_acer_aspire_5020[] __initdata = {
0351 { KE_KEY, 0x01, {KEY_HELP} },
0352 { KE_KEY, 0x03, {KEY_POWER} },
0353 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} },
0354 { KE_KEY, 0x11, {KEY_PROG1} },
0355 { KE_KEY, 0x12, {KEY_PROG2} },
0356 { KE_KEY, 0x31, {KEY_MAIL} },
0357 { KE_KEY, 0x36, {KEY_WWW} },
0358 { KE_KEY, 0x6a, {KEY_CONFIG} },
0359 { KE_WIFI, 0x30 },
0360 { KE_BLUETOOTH, 0x44 },
0361 { KE_END, FE_MAIL_LED | FE_UNTESTED }
0362 };
0363
0364 static struct key_entry keymap_acer_travelmate_2410[] __initdata = {
0365 { KE_KEY, 0x01, {KEY_HELP} },
0366 { KE_KEY, 0x6d, {KEY_POWER} },
0367 { KE_KEY, 0x11, {KEY_PROG1} },
0368 { KE_KEY, 0x12, {KEY_PROG2} },
0369 { KE_KEY, 0x31, {KEY_MAIL} },
0370 { KE_KEY, 0x36, {KEY_WWW} },
0371 { KE_KEY, 0x6a, {KEY_CONFIG} },
0372 { KE_WIFI, 0x30 },
0373 { KE_BLUETOOTH, 0x44 },
0374 { KE_END, FE_MAIL_LED | FE_UNTESTED }
0375 };
0376
0377 static struct key_entry keymap_acer_travelmate_110[] __initdata = {
0378 { KE_KEY, 0x01, {KEY_HELP} },
0379 { KE_KEY, 0x02, {KEY_CONFIG} },
0380 { KE_KEY, 0x03, {KEY_POWER} },
0381 { KE_KEY, 0x08, {KEY_MUTE} },
0382 { KE_KEY, 0x11, {KEY_PROG1} },
0383 { KE_KEY, 0x12, {KEY_PROG2} },
0384 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
0385 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
0386 { KE_KEY, 0x31, {KEY_MAIL} },
0387 { KE_KEY, 0x36, {KEY_WWW} },
0388 { KE_SW, 0x4a, {.sw = {SW_LID, 1}} },
0389 { KE_SW, 0x4b, {.sw = {SW_LID, 0}} },
0390 { KE_WIFI, 0x30 },
0391 { KE_END, FE_MAIL_LED | FE_UNTESTED }
0392 };
0393
0394 static struct key_entry keymap_acer_travelmate_300[] __initdata = {
0395 { KE_KEY, 0x01, {KEY_HELP} },
0396 { KE_KEY, 0x02, {KEY_CONFIG} },
0397 { KE_KEY, 0x03, {KEY_POWER} },
0398 { KE_KEY, 0x08, {KEY_MUTE} },
0399 { KE_KEY, 0x11, {KEY_PROG1} },
0400 { KE_KEY, 0x12, {KEY_PROG2} },
0401 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
0402 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
0403 { KE_KEY, 0x31, {KEY_MAIL} },
0404 { KE_KEY, 0x36, {KEY_WWW} },
0405 { KE_WIFI, 0x30 },
0406 { KE_BLUETOOTH, 0x44 },
0407 { KE_END, FE_MAIL_LED | FE_UNTESTED }
0408 };
0409
0410 static struct key_entry keymap_acer_travelmate_380[] __initdata = {
0411 { KE_KEY, 0x01, {KEY_HELP} },
0412 { KE_KEY, 0x02, {KEY_CONFIG} },
0413 { KE_KEY, 0x03, {KEY_POWER} },
0414 { KE_KEY, 0x11, {KEY_PROG1} },
0415 { KE_KEY, 0x12, {KEY_PROG2} },
0416 { KE_KEY, 0x13, {KEY_PROG3} },
0417 { KE_KEY, 0x31, {KEY_MAIL} },
0418 { KE_KEY, 0x36, {KEY_WWW} },
0419 { KE_WIFI, 0x30 },
0420 { KE_END, FE_MAIL_LED | FE_UNTESTED }
0421 };
0422
0423
0424 static struct key_entry keymap_acer_travelmate_220[] __initdata = {
0425 { KE_KEY, 0x01, {KEY_HELP} },
0426 { KE_KEY, 0x02, {KEY_CONFIG} },
0427 { KE_KEY, 0x11, {KEY_MAIL} },
0428 { KE_KEY, 0x12, {KEY_WWW} },
0429 { KE_KEY, 0x13, {KEY_PROG2} },
0430 { KE_KEY, 0x31, {KEY_PROG1} },
0431 { KE_END, FE_WIFI_LED | FE_UNTESTED }
0432 };
0433
0434 static struct key_entry keymap_acer_travelmate_230[] __initdata = {
0435 { KE_KEY, 0x01, {KEY_HELP} },
0436 { KE_KEY, 0x02, {KEY_CONFIG} },
0437 { KE_KEY, 0x11, {KEY_PROG1} },
0438 { KE_KEY, 0x12, {KEY_PROG2} },
0439 { KE_KEY, 0x31, {KEY_MAIL} },
0440 { KE_KEY, 0x36, {KEY_WWW} },
0441 { KE_END, FE_WIFI_LED | FE_UNTESTED }
0442 };
0443
0444 static struct key_entry keymap_acer_travelmate_240[] __initdata = {
0445 { KE_KEY, 0x01, {KEY_HELP} },
0446 { KE_KEY, 0x02, {KEY_CONFIG} },
0447 { KE_KEY, 0x03, {KEY_POWER} },
0448 { KE_KEY, 0x08, {KEY_MUTE} },
0449 { KE_KEY, 0x31, {KEY_MAIL} },
0450 { KE_KEY, 0x36, {KEY_WWW} },
0451 { KE_KEY, 0x11, {KEY_PROG1} },
0452 { KE_KEY, 0x12, {KEY_PROG2} },
0453 { KE_BLUETOOTH, 0x44 },
0454 { KE_WIFI, 0x30 },
0455 { KE_END, FE_UNTESTED }
0456 };
0457
0458 static struct key_entry keymap_acer_travelmate_350[] __initdata = {
0459 { KE_KEY, 0x01, {KEY_HELP} },
0460 { KE_KEY, 0x02, {KEY_CONFIG} },
0461 { KE_KEY, 0x11, {KEY_PROG1} },
0462 { KE_KEY, 0x12, {KEY_PROG2} },
0463 { KE_KEY, 0x13, {KEY_MAIL} },
0464 { KE_KEY, 0x14, {KEY_PROG3} },
0465 { KE_KEY, 0x15, {KEY_WWW} },
0466 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED }
0467 };
0468
0469 static struct key_entry keymap_acer_travelmate_360[] __initdata = {
0470 { KE_KEY, 0x01, {KEY_HELP} },
0471 { KE_KEY, 0x02, {KEY_CONFIG} },
0472 { KE_KEY, 0x11, {KEY_PROG1} },
0473 { KE_KEY, 0x12, {KEY_PROG2} },
0474 { KE_KEY, 0x13, {KEY_MAIL} },
0475 { KE_KEY, 0x14, {KEY_PROG3} },
0476 { KE_KEY, 0x15, {KEY_WWW} },
0477 { KE_KEY, 0x40, {KEY_WLAN} },
0478 { KE_END, FE_WIFI_LED | FE_UNTESTED }
0479 };
0480
0481
0482
0483
0484 static struct key_entry keymap_acer_travelmate_610[] __initdata = {
0485 { KE_KEY, 0x01, {KEY_HELP} },
0486 { KE_KEY, 0x02, {KEY_CONFIG} },
0487 { KE_KEY, 0x11, {KEY_PROG1} },
0488 { KE_KEY, 0x12, {KEY_PROG2} },
0489 { KE_KEY, 0x13, {KEY_PROG3} },
0490 { KE_KEY, 0x14, {KEY_MAIL} },
0491 { KE_KEY, 0x15, {KEY_WWW} },
0492 { KE_KEY, 0x40, {KEY_WLAN} },
0493 { KE_END, FE_MAIL_LED | FE_WIFI_LED }
0494 };
0495
0496 static struct key_entry keymap_acer_travelmate_630[] __initdata = {
0497 { KE_KEY, 0x01, {KEY_HELP} },
0498 { KE_KEY, 0x02, {KEY_CONFIG} },
0499 { KE_KEY, 0x03, {KEY_POWER} },
0500 { KE_KEY, 0x08, {KEY_MUTE} },
0501 { KE_KEY, 0x11, {KEY_PROG1} },
0502 { KE_KEY, 0x12, {KEY_PROG2} },
0503 { KE_KEY, 0x13, {KEY_PROG3} },
0504 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
0505 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
0506 { KE_KEY, 0x31, {KEY_MAIL} },
0507 { KE_KEY, 0x36, {KEY_WWW} },
0508 { KE_WIFI, 0x30 },
0509 { KE_END, FE_MAIL_LED | FE_UNTESTED }
0510 };
0511
0512 static struct key_entry keymap_aopen_1559as[] __initdata = {
0513 { KE_KEY, 0x01, {KEY_HELP} },
0514 { KE_KEY, 0x06, {KEY_PROG3} },
0515 { KE_KEY, 0x11, {KEY_PROG1} },
0516 { KE_KEY, 0x12, {KEY_PROG2} },
0517 { KE_WIFI, 0x30 },
0518 { KE_KEY, 0x31, {KEY_MAIL} },
0519 { KE_KEY, 0x36, {KEY_WWW} },
0520 { KE_END, 0 },
0521 };
0522
0523 static struct key_entry keymap_fs_amilo_d88x0[] __initdata = {
0524 { KE_KEY, 0x01, {KEY_HELP} },
0525 { KE_KEY, 0x08, {KEY_MUTE} },
0526 { KE_KEY, 0x31, {KEY_MAIL} },
0527 { KE_KEY, 0x36, {KEY_WWW} },
0528 { KE_KEY, 0x11, {KEY_PROG1} },
0529 { KE_KEY, 0x12, {KEY_PROG2} },
0530 { KE_KEY, 0x13, {KEY_PROG3} },
0531 { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED }
0532 };
0533
0534 static struct key_entry keymap_wistron_md2900[] __initdata = {
0535 { KE_KEY, 0x01, {KEY_HELP} },
0536 { KE_KEY, 0x02, {KEY_CONFIG} },
0537 { KE_KEY, 0x11, {KEY_PROG1} },
0538 { KE_KEY, 0x12, {KEY_PROG2} },
0539 { KE_KEY, 0x31, {KEY_MAIL} },
0540 { KE_KEY, 0x36, {KEY_WWW} },
0541 { KE_WIFI, 0x30 },
0542 { KE_END, FE_MAIL_LED | FE_UNTESTED }
0543 };
0544
0545 static struct key_entry keymap_wistron_md96500[] __initdata = {
0546 { KE_KEY, 0x01, {KEY_HELP} },
0547 { KE_KEY, 0x02, {KEY_CONFIG} },
0548 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} },
0549 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} },
0550 { KE_KEY, 0x08, {KEY_MUTE} },
0551 { KE_KEY, 0x11, {KEY_PROG1} },
0552 { KE_KEY, 0x12, {KEY_PROG2} },
0553 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
0554 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
0555 { KE_KEY, 0x22, {KEY_REWIND} },
0556 { KE_KEY, 0x23, {KEY_FORWARD} },
0557 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
0558 { KE_KEY, 0x25, {KEY_STOPCD} },
0559 { KE_KEY, 0x31, {KEY_MAIL} },
0560 { KE_KEY, 0x36, {KEY_WWW} },
0561 { KE_WIFI, 0x30 },
0562 { KE_BLUETOOTH, 0x44 },
0563 { KE_END, 0 }
0564 };
0565
0566 static struct key_entry keymap_wistron_generic[] __initdata = {
0567 { KE_KEY, 0x01, {KEY_HELP} },
0568 { KE_KEY, 0x02, {KEY_CONFIG} },
0569 { KE_KEY, 0x03, {KEY_POWER} },
0570 { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} },
0571 { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} },
0572 { KE_KEY, 0x08, {KEY_MUTE} },
0573 { KE_KEY, 0x11, {KEY_PROG1} },
0574 { KE_KEY, 0x12, {KEY_PROG2} },
0575 { KE_KEY, 0x13, {KEY_PROG3} },
0576 { KE_KEY, 0x14, {KEY_MAIL} },
0577 { KE_KEY, 0x15, {KEY_WWW} },
0578 { KE_KEY, 0x20, {KEY_VOLUMEUP} },
0579 { KE_KEY, 0x21, {KEY_VOLUMEDOWN} },
0580 { KE_KEY, 0x22, {KEY_REWIND} },
0581 { KE_KEY, 0x23, {KEY_FORWARD} },
0582 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
0583 { KE_KEY, 0x25, {KEY_STOPCD} },
0584 { KE_KEY, 0x31, {KEY_MAIL} },
0585 { KE_KEY, 0x36, {KEY_WWW} },
0586 { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} },
0587 { KE_KEY, 0x40, {KEY_WLAN} },
0588 { KE_KEY, 0x49, {KEY_CONFIG} },
0589 { KE_SW, 0x4a, {.sw = {SW_LID, 1}} },
0590 { KE_SW, 0x4b, {.sw = {SW_LID, 0}} },
0591 { KE_KEY, 0x6a, {KEY_CONFIG} },
0592 { KE_KEY, 0x6d, {KEY_POWER} },
0593 { KE_KEY, 0x71, {KEY_STOPCD} },
0594 { KE_KEY, 0x72, {KEY_PLAYPAUSE} },
0595 { KE_KEY, 0x74, {KEY_REWIND} },
0596 { KE_KEY, 0x78, {KEY_FORWARD} },
0597 { KE_WIFI, 0x30 },
0598 { KE_BLUETOOTH, 0x44 },
0599 { KE_END, 0 }
0600 };
0601
0602 static struct key_entry keymap_aopen_1557[] __initdata = {
0603 { KE_KEY, 0x01, {KEY_HELP} },
0604 { KE_KEY, 0x11, {KEY_PROG1} },
0605 { KE_KEY, 0x12, {KEY_PROG2} },
0606 { KE_WIFI, 0x30 },
0607 { KE_KEY, 0x22, {KEY_REWIND} },
0608 { KE_KEY, 0x23, {KEY_FORWARD} },
0609 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
0610 { KE_KEY, 0x25, {KEY_STOPCD} },
0611 { KE_KEY, 0x31, {KEY_MAIL} },
0612 { KE_KEY, 0x36, {KEY_WWW} },
0613 { KE_END, 0 }
0614 };
0615
0616 static struct key_entry keymap_prestigio[] __initdata = {
0617 { KE_KEY, 0x11, {KEY_PROG1} },
0618 { KE_KEY, 0x12, {KEY_PROG2} },
0619 { KE_WIFI, 0x30 },
0620 { KE_KEY, 0x22, {KEY_REWIND} },
0621 { KE_KEY, 0x23, {KEY_FORWARD} },
0622 { KE_KEY, 0x24, {KEY_PLAYPAUSE} },
0623 { KE_KEY, 0x25, {KEY_STOPCD} },
0624 { KE_KEY, 0x31, {KEY_MAIL} },
0625 { KE_KEY, 0x36, {KEY_WWW} },
0626 { KE_END, 0 }
0627 };
0628
0629
0630
0631
0632
0633
0634
0635 static const struct dmi_system_id dmi_ids[] __initconst = {
0636 {
0637
0638 .callback = dmi_matched,
0639 .matches = {
0640 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
0641 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"),
0642 },
0643 .driver_data = keymap_fs_amilo_pro_v2000
0644 },
0645 {
0646
0647 .callback = dmi_matched,
0648 .matches = {
0649 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
0650 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"),
0651 },
0652 .driver_data = keymap_fs_amilo_pro_v3505
0653 },
0654 {
0655
0656 .callback = dmi_matched,
0657 .matches = {
0658 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
0659 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Series V8210"),
0660 },
0661 .driver_data = keymap_fs_amilo_pro_v8210
0662 },
0663 {
0664
0665 .callback = dmi_matched,
0666 .matches = {
0667 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
0668 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO M "),
0669 },
0670 .driver_data = keymap_fs_amilo_pro_v2000
0671 },
0672 {
0673
0674 .callback = dmi_matched,
0675 .matches = {
0676 DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"),
0677 DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"),
0678 },
0679 .driver_data = keymap_fs_amilo_pro_v2000
0680 },
0681 {
0682
0683 .callback = dmi_matched,
0684 .matches = {
0685 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
0686 DMI_MATCH(DMI_PRODUCT_NAME, "N3510"),
0687 },
0688 .driver_data = keymap_fujitsu_n3510
0689 },
0690 {
0691
0692 .callback = dmi_matched,
0693 .matches = {
0694 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0695 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"),
0696 },
0697 .driver_data = keymap_acer_aspire_1500
0698 },
0699 {
0700
0701 .callback = dmi_matched,
0702 .matches = {
0703 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0704 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"),
0705 },
0706 .driver_data = keymap_acer_aspire_1600
0707 },
0708 {
0709
0710 .callback = dmi_matched,
0711 .matches = {
0712 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0713 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"),
0714 },
0715 .driver_data = keymap_acer_aspire_5020
0716 },
0717 {
0718
0719 .callback = dmi_matched,
0720 .matches = {
0721 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0722 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"),
0723 },
0724 .driver_data = keymap_acer_aspire_5020
0725 },
0726 {
0727
0728 .callback = dmi_matched,
0729 .matches = {
0730 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0731 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"),
0732 },
0733 .driver_data = keymap_acer_aspire_5020
0734 },
0735 {
0736
0737 .callback = dmi_matched,
0738 .matches = {
0739 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0740 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"),
0741 },
0742 .driver_data = keymap_acer_travelmate_2410
0743 },
0744 {
0745
0746 .callback = dmi_matched,
0747 .matches = {
0748 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0749 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"),
0750 },
0751 .driver_data = keymap_acer_travelmate_300
0752 },
0753 {
0754
0755 .callback = dmi_matched,
0756 .matches = {
0757 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0758 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"),
0759 },
0760 .driver_data = keymap_acer_travelmate_300
0761 },
0762 {
0763
0764 .callback = dmi_matched,
0765 .matches = {
0766 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0767 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"),
0768 },
0769 .driver_data = keymap_acer_travelmate_110
0770 },
0771 {
0772
0773 .callback = dmi_matched,
0774 .matches = {
0775 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0776 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"),
0777 },
0778 .driver_data = keymap_acer_travelmate_380
0779 },
0780 {
0781
0782 .callback = dmi_matched,
0783 .matches = {
0784 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0785 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"),
0786 },
0787 .driver_data = keymap_acer_travelmate_380
0788 },
0789 {
0790
0791 .callback = dmi_matched,
0792 .matches = {
0793 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0794 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"),
0795 },
0796 .driver_data = keymap_acer_travelmate_220
0797 },
0798 {
0799
0800 .callback = dmi_matched,
0801 .matches = {
0802 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0803 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"),
0804 },
0805 .driver_data = keymap_acer_travelmate_220
0806 },
0807 {
0808
0809 .callback = dmi_matched,
0810 .matches = {
0811 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0812 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"),
0813
0814 },
0815 .driver_data = keymap_acer_travelmate_230
0816 },
0817 {
0818
0819 .callback = dmi_matched,
0820 .matches = {
0821 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0822 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"),
0823 },
0824 .driver_data = keymap_acer_travelmate_230
0825 },
0826 {
0827
0828 .callback = dmi_matched,
0829 .matches = {
0830 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0831 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"),
0832 },
0833 .driver_data = keymap_acer_travelmate_240
0834 },
0835 {
0836
0837 .callback = dmi_matched,
0838 .matches = {
0839 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0840 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"),
0841 },
0842 .driver_data = keymap_acer_travelmate_240
0843 },
0844 {
0845
0846 .callback = dmi_matched,
0847 .matches = {
0848 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0849 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2420"),
0850 },
0851 .driver_data = keymap_acer_travelmate_240
0852 },
0853 {
0854
0855 .callback = dmi_matched,
0856 .matches = {
0857 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0858 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"),
0859 },
0860 .driver_data = keymap_acer_travelmate_350
0861 },
0862 {
0863
0864 .callback = dmi_matched,
0865 .matches = {
0866 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0867 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
0868 },
0869 .driver_data = keymap_acer_travelmate_360
0870 },
0871 {
0872
0873 .callback = dmi_matched,
0874 .matches = {
0875 DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
0876 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"),
0877 },
0878 .driver_data = keymap_acer_travelmate_610
0879 },
0880 {
0881
0882 .callback = dmi_matched,
0883 .matches = {
0884 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0885 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"),
0886 },
0887 .driver_data = keymap_acer_travelmate_630
0888 },
0889 {
0890
0891 .callback = dmi_matched,
0892 .matches = {
0893 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0894 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"),
0895 },
0896 .driver_data = keymap_acer_travelmate_630
0897 },
0898 {
0899
0900 .callback = dmi_matched,
0901 .matches = {
0902 DMI_MATCH(DMI_PRODUCT_NAME, "E2U"),
0903 DMI_MATCH(DMI_BOARD_NAME, "E2U"),
0904 },
0905 .driver_data = keymap_aopen_1559as
0906 },
0907 {
0908
0909 .callback = dmi_matched,
0910 .matches = {
0911 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
0912 DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"),
0913 },
0914 .driver_data = keymap_wistron_ms2111
0915 },
0916 {
0917
0918 .callback = dmi_matched,
0919 .matches = {
0920 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
0921 DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"),
0922 },
0923 .driver_data = keymap_wistron_md40100
0924 },
0925 {
0926
0927 .callback = dmi_matched,
0928 .matches = {
0929 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
0930 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"),
0931 },
0932 .driver_data = keymap_wistron_md2900
0933 },
0934 {
0935
0936 .callback = dmi_matched,
0937 .matches = {
0938 DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
0939 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"),
0940 },
0941 .driver_data = keymap_fs_amilo_pro_v2000
0942 },
0943 {
0944
0945 .callback = dmi_matched,
0946 .matches = {
0947 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
0948 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"),
0949 },
0950 .driver_data = keymap_wistron_md96500
0951 },
0952 {
0953
0954 .callback = dmi_matched,
0955 .matches = {
0956 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
0957 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"),
0958 },
0959 .driver_data = keymap_wistron_md96500
0960 },
0961 {
0962
0963 .callback = dmi_matched,
0964 .matches = {
0965 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
0966 DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"),
0967 },
0968 .driver_data = keymap_fs_amilo_d88x0
0969 },
0970 {
0971
0972 .callback = dmi_matched,
0973 .matches = {
0974 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
0975 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"),
0976 },
0977 .driver_data = keymap_fs_amilo_d88x0
0978 },
0979 { NULL, }
0980 };
0981 MODULE_DEVICE_TABLE(dmi, dmi_ids);
0982
0983
0984 static int __init copy_keymap(void)
0985 {
0986 const struct key_entry *key;
0987 struct key_entry *new_keymap;
0988 unsigned int length = 1;
0989
0990 for (key = keymap; key->type != KE_END; key++)
0991 length++;
0992
0993 new_keymap = kmemdup(keymap, length * sizeof(struct key_entry),
0994 GFP_KERNEL);
0995 if (!new_keymap)
0996 return -ENOMEM;
0997
0998 keymap = new_keymap;
0999
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
1032
1033 static struct input_dev *wistron_idev;
1034 static unsigned long jiffies_last_press;
1035 static bool wifi_enabled;
1036 static bool bluetooth_enabled;
1037
1038
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
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
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, 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, key, 1, true);
1137 break;
1138 }
1139 jiffies_last_press = jiffies;
1140 } else {
1141 printk(KERN_NOTICE
1142 "wistron_btns: Unknown key code %02X\n", code);
1143 }
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 int wistron_flush(struct input_dev *dev)
1162 {
1163
1164 poll_bios(true);
1165
1166 return 0;
1167 }
1168
1169 static void wistron_poll(struct input_dev *dev)
1170 {
1171 poll_bios(false);
1172
1173
1174 if (time_before(jiffies, jiffies_last_press + 2 * HZ))
1175 input_set_poll_interval(dev, POLL_INTERVAL_BURST);
1176 else
1177 input_set_poll_interval(dev, POLL_INTERVAL_DEFAULT);
1178 }
1179
1180 static int wistron_setup_keymap(struct input_dev *dev,
1181 struct key_entry *entry)
1182 {
1183 switch (entry->type) {
1184
1185
1186 case KE_WIFI:
1187 if (!have_wifi) {
1188 entry->type = KE_KEY;
1189 entry->keycode = KEY_WLAN;
1190 }
1191 break;
1192
1193 case KE_BLUETOOTH:
1194 if (!have_bluetooth) {
1195 entry->type = KE_KEY;
1196 entry->keycode = KEY_BLUETOOTH;
1197 }
1198 break;
1199
1200 case KE_END:
1201 if (entry->code & FE_UNTESTED)
1202 printk(KERN_WARNING "Untested laptop multimedia keys, "
1203 "please report success or failure to "
1204 "eric.piel@tremplin-utc.net\n");
1205 break;
1206 }
1207
1208 return 0;
1209 }
1210
1211 static int setup_input_dev(void)
1212 {
1213 int error;
1214
1215 wistron_idev = input_allocate_device();
1216 if (!wistron_idev)
1217 return -ENOMEM;
1218
1219 wistron_idev->name = "Wistron laptop buttons";
1220 wistron_idev->phys = "wistron/input0";
1221 wistron_idev->id.bustype = BUS_HOST;
1222 wistron_idev->dev.parent = &wistron_device->dev;
1223
1224 wistron_idev->open = wistron_flush;
1225
1226 error = sparse_keymap_setup(wistron_idev, keymap, wistron_setup_keymap);
1227 if (error)
1228 goto err_free_dev;
1229
1230 error = input_setup_polling(wistron_idev, wistron_poll);
1231 if (error)
1232 goto err_free_dev;
1233
1234 input_set_poll_interval(wistron_idev, POLL_INTERVAL_DEFAULT);
1235
1236 error = input_register_device(wistron_idev);
1237 if (error)
1238 goto err_free_dev;
1239
1240 return 0;
1241
1242 err_free_dev:
1243 input_free_device(wistron_idev);
1244 return error;
1245 }
1246
1247
1248
1249 static int wistron_probe(struct platform_device *dev)
1250 {
1251 int err;
1252
1253 bios_attach();
1254 cmos_address = bios_get_cmos_address();
1255
1256 if (have_wifi) {
1257 u16 wifi = bios_get_default_setting(WIFI);
1258 if (wifi & 1)
1259 wifi_enabled = wifi & 2;
1260 else
1261 have_wifi = 0;
1262
1263 if (have_wifi)
1264 bios_set_state(WIFI, wifi_enabled);
1265 }
1266
1267 if (have_bluetooth) {
1268 u16 bt = bios_get_default_setting(BLUETOOTH);
1269 if (bt & 1)
1270 bluetooth_enabled = bt & 2;
1271 else
1272 have_bluetooth = false;
1273
1274 if (have_bluetooth)
1275 bios_set_state(BLUETOOTH, bluetooth_enabled);
1276 }
1277
1278 wistron_led_init(&dev->dev);
1279
1280 err = setup_input_dev();
1281 if (err) {
1282 bios_detach();
1283 return err;
1284 }
1285
1286 return 0;
1287 }
1288
1289 static int wistron_remove(struct platform_device *dev)
1290 {
1291 wistron_led_remove();
1292 input_unregister_device(wistron_idev);
1293 bios_detach();
1294
1295 return 0;
1296 }
1297
1298 #ifdef CONFIG_PM
1299 static int wistron_suspend(struct device *dev)
1300 {
1301 if (have_wifi)
1302 bios_set_state(WIFI, 0);
1303
1304 if (have_bluetooth)
1305 bios_set_state(BLUETOOTH, 0);
1306
1307 wistron_led_suspend();
1308
1309 return 0;
1310 }
1311
1312 static int wistron_resume(struct device *dev)
1313 {
1314 if (have_wifi)
1315 bios_set_state(WIFI, wifi_enabled);
1316
1317 if (have_bluetooth)
1318 bios_set_state(BLUETOOTH, bluetooth_enabled);
1319
1320 wistron_led_resume();
1321
1322 poll_bios(true);
1323
1324 return 0;
1325 }
1326
1327 static const struct dev_pm_ops wistron_pm_ops = {
1328 .suspend = wistron_suspend,
1329 .resume = wistron_resume,
1330 .poweroff = wistron_suspend,
1331 .restore = wistron_resume,
1332 };
1333 #endif
1334
1335 static struct platform_driver wistron_driver = {
1336 .driver = {
1337 .name = "wistron-bios",
1338 #ifdef CONFIG_PM
1339 .pm = &wistron_pm_ops,
1340 #endif
1341 },
1342 .probe = wistron_probe,
1343 .remove = wistron_remove,
1344 };
1345
1346 static int __init wb_module_init(void)
1347 {
1348 int err;
1349
1350 err = select_keymap();
1351 if (err)
1352 return err;
1353
1354 err = map_bios();
1355 if (err)
1356 goto err_free_keymap;
1357
1358 err = platform_driver_register(&wistron_driver);
1359 if (err)
1360 goto err_unmap_bios;
1361
1362 wistron_device = platform_device_alloc("wistron-bios", -1);
1363 if (!wistron_device) {
1364 err = -ENOMEM;
1365 goto err_unregister_driver;
1366 }
1367
1368 err = platform_device_add(wistron_device);
1369 if (err)
1370 goto err_free_device;
1371
1372 return 0;
1373
1374 err_free_device:
1375 platform_device_put(wistron_device);
1376 err_unregister_driver:
1377 platform_driver_unregister(&wistron_driver);
1378 err_unmap_bios:
1379 unmap_bios();
1380 err_free_keymap:
1381 kfree(keymap);
1382
1383 return err;
1384 }
1385
1386 static void __exit wb_module_exit(void)
1387 {
1388 platform_device_unregister(wistron_device);
1389 platform_driver_unregister(&wistron_driver);
1390 unmap_bios();
1391 kfree(keymap);
1392 }
1393
1394 module_init(wb_module_init);
1395 module_exit(wb_module_exit);