aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorBernhard Rosenkraenzer <bero@arklinux.org>2005-11-20 00:50:37 -0500
committerDmitry Torokhov <dtor_core@ameritech.net>2005-11-20 00:50:37 -0500
commit84b256a66360cedc25eb6e2ac6f167ca9778307b (patch)
tree55fe8c50722332fb59e0a7a499146c1f4a49e12a /drivers/input/misc
parente9fb028ea2a0a70dad0f467410418e5ee2af811b (diff)
Input: wistron - add support for Acer Aspire 1500 notebooks
Also fix a potential issue with some notebooks: The current code assumes the response to bios_wifi_get_default_setting is either 1 (disabled) or 3 (enabled), or wifi isn't supported. The BIOS response appears to be a bit field w/ 0x1 indicating hardware presence, 0x2 indicating actiation status, and the other 6 bits being unknown/reserved -- with the patch, these 6 bits are ignored. Signed-off-by: Bernhard Rosenkraenzer <bero@arklinux.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/misc')
-rw-r--r--drivers/input/misc/wistron_btns.c79
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
43MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); 48MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
44MODULE_DESCRIPTION("Wistron laptop button driver"); 49MODULE_DESCRIPTION("Wistron laptop button driver");
45MODULE_LICENSE("GPL v2"); 50MODULE_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
200static u16 __init bios_wifi_get_default_setting(void) 205static u16 __init bios_get_default_setting(u8 subsys)
201{ 206{
202 struct regs regs; 207 struct regs regs;
203 208
204 memset(&regs, 0, sizeof (regs)); 209 memset(&regs, 0, sizeof (regs));
205 regs.eax = 0x9610; 210 regs.eax = 0x9610;
206 regs.ebx = 0x0235; 211 regs.ebx = 0x0200 | subsys;
207 call_bios(&regs); 212 call_bios(&regs);
208 213
209 return regs.eax; 214 return regs.eax;
210} 215}
211 216
212static void bios_wifi_set_state(int enable) 217static void bios_set_state(u8 subsys, int enable)
213{ 218{
214 struct regs regs; 219 struct regs regs;
215 220
216 memset(&regs, 0, sizeof (regs)); 221 memset(&regs, 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(&regs); 224 call_bios(&regs);
220} 225}
221 226
222 /* Hardware database */ 227/* Hardware database */
223 228
224struct key_entry { 229struct 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
230enum { KE_END, KE_KEY, KE_WIFI }; 235enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH };
231 236
232static const struct key_entry *keymap; /* = NULL; Current key map */ 237static const struct key_entry *keymap; /* = NULL; Current key map */
233static int have_wifi; 238static int have_wifi;
239static int have_bluetooth;
234 240
235static int __init dmi_matched(struct dmi_system_id *dmi) 241static 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
285static 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
346static int wifi_enabled; 374static int wifi_enabled;
375static int bluetooth_enabled;
347 376
348static void poll_bios(unsigned long); 377static 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();