aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-12-15 22:35:40 -0500
committerLen Brown <len.brown@intel.com>2009-12-15 22:35:40 -0500
commitabdef01daceb120ef8cc03fbc96d5e029e2810b0 (patch)
tree066c600b161b87cc2453153b87f892ad484a61a2 /drivers/platform
parent6cbef9fd7c7fa105ad758dc342cc0a14f413fa07 (diff)
parente5fbba85a7acc2626d4fe14501816811d702f3e9 (diff)
Merge branch 'hp-wmi' into release
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/hp-wmi.c139
1 files changed, 84 insertions, 55 deletions
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index f00a71c58e69..63c3e658a884 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -51,6 +51,12 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
51#define HPWMI_WIRELESS_QUERY 0x5 51#define HPWMI_WIRELESS_QUERY 0x5
52#define HPWMI_HOTKEY_QUERY 0xc 52#define HPWMI_HOTKEY_QUERY 0xc
53 53
54enum hp_wmi_radio {
55 HPWMI_WIFI = 0,
56 HPWMI_BLUETOOTH = 1,
57 HPWMI_WWAN = 2,
58};
59
54static int __init hp_wmi_bios_setup(struct platform_device *device); 60static int __init hp_wmi_bios_setup(struct platform_device *device);
55static int __exit hp_wmi_bios_remove(struct platform_device *device); 61static int __exit hp_wmi_bios_remove(struct platform_device *device);
56static int hp_wmi_resume_handler(struct device *device); 62static int hp_wmi_resume_handler(struct device *device);
@@ -175,8 +181,8 @@ static int hp_wmi_tablet_state(void)
175 181
176static int hp_wmi_set_block(void *data, bool blocked) 182static int hp_wmi_set_block(void *data, bool blocked)
177{ 183{
178 unsigned long b = (unsigned long) data; 184 enum hp_wmi_radio r = (enum hp_wmi_radio) data;
179 int query = BIT(b + 8) | ((!blocked) << b); 185 int query = BIT(r + 8) | ((!blocked) << r);
180 186
181 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query); 187 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query);
182} 188}
@@ -185,31 +191,23 @@ static const struct rfkill_ops hp_wmi_rfkill_ops = {
185 .set_block = hp_wmi_set_block, 191 .set_block = hp_wmi_set_block,
186}; 192};
187 193
188static bool hp_wmi_wifi_state(void) 194static bool hp_wmi_get_sw_state(enum hp_wmi_radio r)
189{
190 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
191
192 if (wireless & 0x100)
193 return false;
194 else
195 return true;
196}
197
198static bool hp_wmi_bluetooth_state(void)
199{ 195{
200 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 196 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
197 int mask = 0x200 << (r * 8);
201 198
202 if (wireless & 0x10000) 199 if (wireless & mask)
203 return false; 200 return false;
204 else 201 else
205 return true; 202 return true;
206} 203}
207 204
208static bool hp_wmi_wwan_state(void) 205static bool hp_wmi_get_hw_state(enum hp_wmi_radio r)
209{ 206{
210 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 207 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
208 int mask = 0x800 << (r * 8);
211 209
212 if (wireless & 0x1000000) 210 if (wireless & mask)
213 return false; 211 return false;
214 else 212 else
215 return true; 213 return true;
@@ -334,49 +332,55 @@ static void hp_wmi_notify(u32 value, void *context)
334 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; 332 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
335 static struct key_entry *key; 333 static struct key_entry *key;
336 union acpi_object *obj; 334 union acpi_object *obj;
335 int eventcode;
337 336
338 wmi_get_event_data(value, &response); 337 wmi_get_event_data(value, &response);
339 338
340 obj = (union acpi_object *)response.pointer; 339 obj = (union acpi_object *)response.pointer;
341 340
342 if (obj && obj->type == ACPI_TYPE_BUFFER && obj->buffer.length == 8) { 341 if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) {
343 int eventcode = *((u8 *) obj->buffer.pointer); 342 printk(KERN_INFO "HP WMI: Unknown response received\n");
344 if (eventcode == 0x4) 343 return;
345 eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, 344 }
346 0); 345
347 key = hp_wmi_get_entry_by_scancode(eventcode); 346 eventcode = *((u8 *) obj->buffer.pointer);
348 if (key) { 347 if (eventcode == 0x4)
349 switch (key->type) { 348 eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0,
350 case KE_KEY: 349 0);
351 input_report_key(hp_wmi_input_dev, 350 key = hp_wmi_get_entry_by_scancode(eventcode);
352 key->keycode, 1); 351 if (key) {
353 input_sync(hp_wmi_input_dev); 352 switch (key->type) {
354 input_report_key(hp_wmi_input_dev, 353 case KE_KEY:
355 key->keycode, 0); 354 input_report_key(hp_wmi_input_dev,
356 input_sync(hp_wmi_input_dev); 355 key->keycode, 1);
357 break; 356 input_sync(hp_wmi_input_dev);
358 } 357 input_report_key(hp_wmi_input_dev,
359 } else if (eventcode == 0x1) { 358 key->keycode, 0);
360 input_report_switch(hp_wmi_input_dev, SW_DOCK,
361 hp_wmi_dock_state());
362 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
363 hp_wmi_tablet_state());
364 input_sync(hp_wmi_input_dev); 359 input_sync(hp_wmi_input_dev);
365 } else if (eventcode == 0x5) { 360 break;
366 if (wifi_rfkill) 361 }
367 rfkill_set_sw_state(wifi_rfkill, 362 } else if (eventcode == 0x1) {
368 hp_wmi_wifi_state()); 363 input_report_switch(hp_wmi_input_dev, SW_DOCK,
369 if (bluetooth_rfkill) 364 hp_wmi_dock_state());
370 rfkill_set_sw_state(bluetooth_rfkill, 365 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
371 hp_wmi_bluetooth_state()); 366 hp_wmi_tablet_state());
372 if (wwan_rfkill) 367 input_sync(hp_wmi_input_dev);
373 rfkill_set_sw_state(wwan_rfkill, 368 } else if (eventcode == 0x5) {
374 hp_wmi_wwan_state()); 369 if (wifi_rfkill)
375 } else 370 rfkill_set_states(wifi_rfkill,
376 printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", 371 hp_wmi_get_sw_state(HPWMI_WIFI),
377 eventcode); 372 hp_wmi_get_hw_state(HPWMI_WIFI));
373 if (bluetooth_rfkill)
374 rfkill_set_states(bluetooth_rfkill,
375 hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
376 hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
377 if (wwan_rfkill)
378 rfkill_set_states(wwan_rfkill,
379 hp_wmi_get_sw_state(HPWMI_WWAN),
380 hp_wmi_get_hw_state(HPWMI_WWAN));
378 } else 381 } else
379 printk(KERN_INFO "HP WMI: Unknown response received\n"); 382 printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n",
383 eventcode);
380} 384}
381 385
382static int __init hp_wmi_input_setup(void) 386static int __init hp_wmi_input_setup(void)
@@ -455,7 +459,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
455 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev, 459 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
456 RFKILL_TYPE_WLAN, 460 RFKILL_TYPE_WLAN,
457 &hp_wmi_rfkill_ops, 461 &hp_wmi_rfkill_ops,
458 (void *) 0); 462 (void *) HPWMI_WIFI);
463 rfkill_init_sw_state(wifi_rfkill,
464 hp_wmi_get_sw_state(HPWMI_WIFI));
465 rfkill_set_hw_state(wifi_rfkill,
466 hp_wmi_get_hw_state(HPWMI_WIFI));
459 err = rfkill_register(wifi_rfkill); 467 err = rfkill_register(wifi_rfkill);
460 if (err) 468 if (err)
461 goto register_wifi_error; 469 goto register_wifi_error;
@@ -465,7 +473,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
465 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev, 473 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
466 RFKILL_TYPE_BLUETOOTH, 474 RFKILL_TYPE_BLUETOOTH,
467 &hp_wmi_rfkill_ops, 475 &hp_wmi_rfkill_ops,
468 (void *) 1); 476 (void *) HPWMI_BLUETOOTH);
477 rfkill_init_sw_state(bluetooth_rfkill,
478 hp_wmi_get_sw_state(HPWMI_BLUETOOTH));
479 rfkill_set_hw_state(bluetooth_rfkill,
480 hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
469 err = rfkill_register(bluetooth_rfkill); 481 err = rfkill_register(bluetooth_rfkill);
470 if (err) 482 if (err)
471 goto register_bluetooth_error; 483 goto register_bluetooth_error;
@@ -475,7 +487,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
475 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev, 487 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
476 RFKILL_TYPE_WWAN, 488 RFKILL_TYPE_WWAN,
477 &hp_wmi_rfkill_ops, 489 &hp_wmi_rfkill_ops,
478 (void *) 2); 490 (void *) HPWMI_WWAN);
491 rfkill_init_sw_state(wwan_rfkill,
492 hp_wmi_get_sw_state(HPWMI_WWAN));
493 rfkill_set_hw_state(wwan_rfkill,
494 hp_wmi_get_hw_state(HPWMI_WWAN));
479 err = rfkill_register(wwan_rfkill); 495 err = rfkill_register(wwan_rfkill);
480 if (err) 496 if (err)
481 goto register_wwan_err; 497 goto register_wwan_err;
@@ -533,6 +549,19 @@ static int hp_wmi_resume_handler(struct device *device)
533 input_sync(hp_wmi_input_dev); 549 input_sync(hp_wmi_input_dev);
534 } 550 }
535 551
552 if (wifi_rfkill)
553 rfkill_set_states(wifi_rfkill,
554 hp_wmi_get_sw_state(HPWMI_WIFI),
555 hp_wmi_get_hw_state(HPWMI_WIFI));
556 if (bluetooth_rfkill)
557 rfkill_set_states(bluetooth_rfkill,
558 hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
559 hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
560 if (wwan_rfkill)
561 rfkill_set_states(wwan_rfkill,
562 hp_wmi_get_sw_state(HPWMI_WWAN),
563 hp_wmi_get_hw_state(HPWMI_WWAN));
564
536 return 0; 565 return 0;
537} 566}
538 567