diff options
Diffstat (limited to 'drivers/platform/x86/eeepc-laptop.c')
-rw-r--r-- | drivers/platform/x86/eeepc-laptop.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 6f54fd1757cd..353a898c3693 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -158,6 +158,7 @@ enum { KE_KEY, KE_END }; | |||
158 | static struct key_entry eeepc_keymap[] = { | 158 | static struct key_entry eeepc_keymap[] = { |
159 | /* Sleep already handled via generic ACPI code */ | 159 | /* Sleep already handled via generic ACPI code */ |
160 | {KE_KEY, 0x10, KEY_WLAN }, | 160 | {KE_KEY, 0x10, KEY_WLAN }, |
161 | {KE_KEY, 0x11, KEY_WLAN }, | ||
161 | {KE_KEY, 0x12, KEY_PROG1 }, | 162 | {KE_KEY, 0x12, KEY_PROG1 }, |
162 | {KE_KEY, 0x13, KEY_MUTE }, | 163 | {KE_KEY, 0x13, KEY_MUTE }, |
163 | {KE_KEY, 0x14, KEY_VOLUMEDOWN }, | 164 | {KE_KEY, 0x14, KEY_VOLUMEDOWN }, |
@@ -166,6 +167,8 @@ static struct key_entry eeepc_keymap[] = { | |||
166 | {KE_KEY, 0x1b, KEY_ZOOM }, | 167 | {KE_KEY, 0x1b, KEY_ZOOM }, |
167 | {KE_KEY, 0x1c, KEY_PROG2 }, | 168 | {KE_KEY, 0x1c, KEY_PROG2 }, |
168 | {KE_KEY, 0x1d, KEY_PROG3 }, | 169 | {KE_KEY, 0x1d, KEY_PROG3 }, |
170 | {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN }, | ||
171 | {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP }, | ||
169 | {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, | 172 | {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, |
170 | {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, | 173 | {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, |
171 | {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, | 174 | {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, |
@@ -381,11 +384,13 @@ static ssize_t show_sys_acpi(int cm, char *buf) | |||
381 | EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); | 384 | EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); |
382 | EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); | 385 | EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); |
383 | EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); | 386 | EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); |
387 | EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV); | ||
384 | 388 | ||
385 | static struct attribute *platform_attributes[] = { | 389 | static struct attribute *platform_attributes[] = { |
386 | &dev_attr_camera.attr, | 390 | &dev_attr_camera.attr, |
387 | &dev_attr_cardr.attr, | 391 | &dev_attr_cardr.attr, |
388 | &dev_attr_disp.attr, | 392 | &dev_attr_disp.attr, |
393 | &dev_attr_cpufv.attr, | ||
389 | NULL | 394 | NULL |
390 | }; | 395 | }; |
391 | 396 | ||
@@ -512,15 +517,21 @@ static int eeepc_hotk_check(void) | |||
512 | return 0; | 517 | return 0; |
513 | } | 518 | } |
514 | 519 | ||
515 | static void notify_brn(void) | 520 | static int notify_brn(void) |
516 | { | 521 | { |
522 | /* returns the *previous* brightness, or -1 */ | ||
517 | struct backlight_device *bd = eeepc_backlight_device; | 523 | struct backlight_device *bd = eeepc_backlight_device; |
518 | if (bd) | 524 | if (bd) { |
525 | int old = bd->props.brightness; | ||
519 | bd->props.brightness = read_brightness(bd); | 526 | bd->props.brightness = read_brightness(bd); |
527 | return old; | ||
528 | } | ||
529 | return -1; | ||
520 | } | 530 | } |
521 | 531 | ||
522 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | 532 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) |
523 | { | 533 | { |
534 | enum rfkill_state state; | ||
524 | struct pci_dev *dev; | 535 | struct pci_dev *dev; |
525 | struct pci_bus *bus = pci_find_bus(0, 1); | 536 | struct pci_bus *bus = pci_find_bus(0, 1); |
526 | 537 | ||
@@ -532,7 +543,9 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | |||
532 | return; | 543 | return; |
533 | } | 544 | } |
534 | 545 | ||
535 | if (get_acpi(CM_ASL_WLAN) == 1) { | 546 | eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state); |
547 | |||
548 | if (state == RFKILL_STATE_UNBLOCKED) { | ||
536 | dev = pci_get_slot(bus, 0); | 549 | dev = pci_get_slot(bus, 0); |
537 | if (dev) { | 550 | if (dev) { |
538 | /* Device already present */ | 551 | /* Device already present */ |
@@ -552,23 +565,41 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | |||
552 | pci_dev_put(dev); | 565 | pci_dev_put(dev); |
553 | } | 566 | } |
554 | } | 567 | } |
568 | |||
569 | rfkill_force_state(ehotk->eeepc_wlan_rfkill, state); | ||
555 | } | 570 | } |
556 | 571 | ||
557 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) | 572 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) |
558 | { | 573 | { |
559 | static struct key_entry *key; | 574 | static struct key_entry *key; |
560 | u16 count; | 575 | u16 count; |
576 | int brn = -ENODEV; | ||
561 | 577 | ||
562 | if (!ehotk) | 578 | if (!ehotk) |
563 | return; | 579 | return; |
564 | if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) | 580 | if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) |
565 | notify_brn(); | 581 | brn = notify_brn(); |
566 | count = ehotk->event_count[event % 128]++; | 582 | count = ehotk->event_count[event % 128]++; |
567 | acpi_bus_generate_proc_event(ehotk->device, event, count); | 583 | acpi_bus_generate_proc_event(ehotk->device, event, count); |
568 | acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, | 584 | acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, |
569 | dev_name(&ehotk->device->dev), event, | 585 | dev_name(&ehotk->device->dev), event, |
570 | count); | 586 | count); |
571 | if (ehotk->inputdev) { | 587 | if (ehotk->inputdev) { |
588 | if (brn != -ENODEV) { | ||
589 | /* brightness-change events need special | ||
590 | * handling for conversion to key events | ||
591 | */ | ||
592 | if (brn < 0) | ||
593 | brn = event; | ||
594 | else | ||
595 | brn += NOTIFY_BRN_MIN; | ||
596 | if (event < brn) | ||
597 | event = NOTIFY_BRN_MIN; /* brightness down */ | ||
598 | else if (event > brn) | ||
599 | event = NOTIFY_BRN_MIN + 2; /* ... up */ | ||
600 | else | ||
601 | event = NOTIFY_BRN_MIN + 1; /* ... unchanged */ | ||
602 | } | ||
572 | key = eepc_get_entry_by_scancode(event); | 603 | key = eepc_get_entry_by_scancode(event); |
573 | if (key) { | 604 | if (key) { |
574 | switch (key->type) { | 605 | switch (key->type) { |
@@ -649,6 +680,9 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
649 | if (ACPI_FAILURE(status)) | 680 | if (ACPI_FAILURE(status)) |
650 | printk(EEEPC_ERR "Error installing notify handler\n"); | 681 | printk(EEEPC_ERR "Error installing notify handler\n"); |
651 | 682 | ||
683 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
684 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
685 | |||
652 | if (get_acpi(CM_ASL_WLAN) != -1) { | 686 | if (get_acpi(CM_ASL_WLAN) != -1) { |
653 | ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, | 687 | ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, |
654 | RFKILL_TYPE_WLAN); | 688 | RFKILL_TYPE_WLAN); |
@@ -704,9 +738,6 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
704 | goto bluetooth_fail; | 738 | goto bluetooth_fail; |
705 | } | 739 | } |
706 | 740 | ||
707 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
708 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
709 | |||
710 | return 0; | 741 | return 0; |
711 | 742 | ||
712 | bluetooth_fail: | 743 | bluetooth_fail: |
@@ -717,6 +748,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
717 | wlan_fail: | 748 | wlan_fail: |
718 | if (ehotk->eeepc_wlan_rfkill) | 749 | if (ehotk->eeepc_wlan_rfkill) |
719 | rfkill_free(ehotk->eeepc_wlan_rfkill); | 750 | rfkill_free(ehotk->eeepc_wlan_rfkill); |
751 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
752 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
720 | ehotk_fail: | 753 | ehotk_fail: |
721 | kfree(ehotk); | 754 | kfree(ehotk); |
722 | ehotk = NULL; | 755 | ehotk = NULL; |