diff options
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/misc/wistron_btns.c | 79 |
1 files changed, 59 insertions, 20 deletions
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 76d32e365b5d..6d7e865f9007 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Wistron laptop button driver | 2 | * Wistron laptop button driver |
3 | * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz> | 3 | * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz> |
4 | * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org> | ||
4 | * | 5 | * |
5 | * You can redistribute and/or modify this program under the terms of the | 6 | * You can redistribute and/or modify this program under the terms of the |
6 | * GNU General Public License version 2 as published by the Free Software | 7 | * GNU General Public License version 2 as published by the Free Software |
@@ -40,6 +41,10 @@ | |||
40 | #error "POLL_FREQUENCY too high" | 41 | #error "POLL_FREQUENCY too high" |
41 | #endif | 42 | #endif |
42 | 43 | ||
44 | /* BIOS subsystem IDs */ | ||
45 | #define WIFI 0x35 | ||
46 | #define BLUETOOTH 0x34 | ||
47 | |||
43 | MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); | 48 | MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); |
44 | MODULE_DESCRIPTION("Wistron laptop button driver"); | 49 | MODULE_DESCRIPTION("Wistron laptop button driver"); |
45 | MODULE_LICENSE("GPL v2"); | 50 | MODULE_LICENSE("GPL v2"); |
@@ -197,29 +202,29 @@ static u8 __init bios_get_cmos_address(void) | |||
197 | return regs.ecx; | 202 | return regs.ecx; |
198 | } | 203 | } |
199 | 204 | ||
200 | static u16 __init bios_wifi_get_default_setting(void) | 205 | static u16 __init bios_get_default_setting(u8 subsys) |
201 | { | 206 | { |
202 | struct regs regs; | 207 | struct regs regs; |
203 | 208 | ||
204 | memset(®s, 0, sizeof (regs)); | 209 | memset(®s, 0, sizeof (regs)); |
205 | regs.eax = 0x9610; | 210 | regs.eax = 0x9610; |
206 | regs.ebx = 0x0235; | 211 | regs.ebx = 0x0200 | subsys; |
207 | call_bios(®s); | 212 | call_bios(®s); |
208 | 213 | ||
209 | return regs.eax; | 214 | return regs.eax; |
210 | } | 215 | } |
211 | 216 | ||
212 | static void bios_wifi_set_state(int enable) | 217 | static void bios_set_state(u8 subsys, int enable) |
213 | { | 218 | { |
214 | struct regs regs; | 219 | struct regs regs; |
215 | 220 | ||
216 | memset(®s, 0, sizeof (regs)); | 221 | memset(®s, 0, sizeof (regs)); |
217 | regs.eax = 0x9610; | 222 | regs.eax = 0x9610; |
218 | regs.ebx = enable ? 0x0135 : 0x0035; | 223 | regs.ebx = (enable ? 0x0100 : 0x0000) | subsys; |
219 | call_bios(®s); | 224 | call_bios(®s); |
220 | } | 225 | } |
221 | 226 | ||
222 | /* Hardware database */ | 227 | /* Hardware database */ |
223 | 228 | ||
224 | struct key_entry { | 229 | struct key_entry { |
225 | char type; /* See KE_* below */ | 230 | char type; /* See KE_* below */ |
@@ -227,10 +232,11 @@ struct key_entry { | |||
227 | unsigned keycode; /* For KE_KEY */ | 232 | unsigned keycode; /* For KE_KEY */ |
228 | }; | 233 | }; |
229 | 234 | ||
230 | enum { KE_END, KE_KEY, KE_WIFI }; | 235 | enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH }; |
231 | 236 | ||
232 | static const struct key_entry *keymap; /* = NULL; Current key map */ | 237 | static const struct key_entry *keymap; /* = NULL; Current key map */ |
233 | static int have_wifi; | 238 | static int have_wifi; |
239 | static int have_bluetooth; | ||
234 | 240 | ||
235 | static int __init dmi_matched(struct dmi_system_id *dmi) | 241 | static int __init dmi_matched(struct dmi_system_id *dmi) |
236 | { | 242 | { |
@@ -241,6 +247,9 @@ static int __init dmi_matched(struct dmi_system_id *dmi) | |||
241 | if (key->type == KE_WIFI) { | 247 | if (key->type == KE_WIFI) { |
242 | have_wifi = 1; | 248 | have_wifi = 1; |
243 | break; | 249 | break; |
250 | } else if (key->type == KE_BLUETOOTH) { | ||
251 | have_bluetooth = 1; | ||
252 | break; | ||
244 | } | 253 | } |
245 | } | 254 | } |
246 | return 1; | 255 | return 1; |
@@ -273,6 +282,16 @@ static struct key_entry keymap_wistron_ms2141[] = { | |||
273 | { KE_END, 0 } | 282 | { KE_END, 0 } |
274 | }; | 283 | }; |
275 | 284 | ||
285 | static struct key_entry keymap_acer_aspire_1500[] = { | ||
286 | { KE_KEY, 0x11, KEY_PROG1 }, | ||
287 | { KE_KEY, 0x12, KEY_PROG2 }, | ||
288 | { KE_WIFI, 0x30, 0 }, | ||
289 | { KE_KEY, 0x31, KEY_MAIL }, | ||
290 | { KE_KEY, 0x36, KEY_WWW }, | ||
291 | { KE_BLUETOOTH, 0x44, 0 }, | ||
292 | { KE_END, 0 } | ||
293 | }; | ||
294 | |||
276 | /* | 295 | /* |
277 | * If your machine is not here (which is currently rather likely), please send | 296 | * If your machine is not here (which is currently rather likely), please send |
278 | * a list of buttons and their key codes (reported when loading this module | 297 | * a list of buttons and their key codes (reported when loading this module |
@@ -288,6 +307,15 @@ static struct dmi_system_id dmi_ids[] = { | |||
288 | }, | 307 | }, |
289 | .driver_data = keymap_fs_amilo_pro_v2000 | 308 | .driver_data = keymap_fs_amilo_pro_v2000 |
290 | }, | 309 | }, |
310 | { | ||
311 | .callback = dmi_matched, | ||
312 | .ident = "Acer Aspire 1500", | ||
313 | .matches = { | ||
314 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
315 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"), | ||
316 | }, | ||
317 | .driver_data = keymap_acer_aspire_1500 | ||
318 | }, | ||
291 | { 0, } | 319 | { 0, } |
292 | }; | 320 | }; |
293 | 321 | ||
@@ -344,6 +372,7 @@ static void report_key(unsigned keycode) | |||
344 | /* Driver core */ | 372 | /* Driver core */ |
345 | 373 | ||
346 | static int wifi_enabled; | 374 | static int wifi_enabled; |
375 | static int bluetooth_enabled; | ||
347 | 376 | ||
348 | static void poll_bios(unsigned long); | 377 | static void poll_bios(unsigned long); |
349 | 378 | ||
@@ -363,7 +392,14 @@ static void handle_key(u8 code) | |||
363 | case KE_WIFI: | 392 | case KE_WIFI: |
364 | if (have_wifi) { | 393 | if (have_wifi) { |
365 | wifi_enabled = !wifi_enabled; | 394 | wifi_enabled = !wifi_enabled; |
366 | bios_wifi_set_state(wifi_enabled); | 395 | bios_set_state(WIFI, wifi_enabled); |
396 | } | ||
397 | break; | ||
398 | |||
399 | case KE_BLUETOOTH: | ||
400 | if (have_bluetooth) { | ||
401 | bluetooth_enabled = !bluetooth_enabled; | ||
402 | bios_set_state(BLUETOOTH, bluetooth_enabled); | ||
367 | } | 403 | } |
368 | break; | 404 | break; |
369 | 405 | ||
@@ -407,21 +443,24 @@ static int __init wb_module_init(void) | |||
407 | bios_attach(); | 443 | bios_attach(); |
408 | cmos_address = bios_get_cmos_address(); | 444 | cmos_address = bios_get_cmos_address(); |
409 | if (have_wifi) { | 445 | if (have_wifi) { |
410 | switch (bios_wifi_get_default_setting()) { | 446 | u16 wifi = bios_get_default_setting(WIFI); |
411 | case 0x01: | 447 | if (wifi & 1) |
412 | wifi_enabled = 0; | 448 | wifi_enabled = (wifi & 2) ? 1 : 0; |
413 | break; | 449 | else |
414 | |||
415 | case 0x03: | ||
416 | wifi_enabled = 1; | ||
417 | break; | ||
418 | |||
419 | default: | ||
420 | have_wifi = 0; | 450 | have_wifi = 0; |
421 | break; | 451 | |
422 | } | ||
423 | if (have_wifi) | 452 | if (have_wifi) |
424 | bios_wifi_set_state(wifi_enabled); | 453 | bios_set_state(WIFI, wifi_enabled); |
454 | } | ||
455 | if (have_bluetooth) { | ||
456 | u16 bt = bios_get_default_setting(BLUETOOTH); | ||
457 | if (bt & 1) | ||
458 | bluetooth_enabled = (bt & 2) ? 1 : 0; | ||
459 | else | ||
460 | have_bluetooth = 0; | ||
461 | |||
462 | if (have_bluetooth) | ||
463 | bios_set_state(BLUETOOTH, bluetooth_enabled); | ||
425 | } | 464 | } |
426 | 465 | ||
427 | setup_input_dev(); | 466 | setup_input_dev(); |