diff options
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 129 |
1 files changed, 62 insertions, 67 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index f7228987bd50..d983dc45f30d 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -187,7 +187,6 @@ struct toshiba_acpi_dev { | |||
187 | unsigned int info_supported:1; | 187 | unsigned int info_supported:1; |
188 | unsigned int tr_backlight_supported:1; | 188 | unsigned int tr_backlight_supported:1; |
189 | unsigned int kbd_illum_supported:1; | 189 | unsigned int kbd_illum_supported:1; |
190 | unsigned int kbd_led_registered:1; | ||
191 | unsigned int touchpad_supported:1; | 190 | unsigned int touchpad_supported:1; |
192 | unsigned int eco_supported:1; | 191 | unsigned int eco_supported:1; |
193 | unsigned int accelerometer_supported:1; | 192 | unsigned int accelerometer_supported:1; |
@@ -198,6 +197,10 @@ struct toshiba_acpi_dev { | |||
198 | unsigned int panel_power_on_supported:1; | 197 | unsigned int panel_power_on_supported:1; |
199 | unsigned int usb_three_supported:1; | 198 | unsigned int usb_three_supported:1; |
200 | unsigned int sysfs_created:1; | 199 | unsigned int sysfs_created:1; |
200 | |||
201 | bool kbd_led_registered; | ||
202 | bool illumination_led_registered; | ||
203 | bool eco_led_registered; | ||
201 | }; | 204 | }; |
202 | 205 | ||
203 | static struct toshiba_acpi_dev *toshiba_acpi; | 206 | static struct toshiba_acpi_dev *toshiba_acpi; |
@@ -439,26 +442,26 @@ static u32 sci_write(struct toshiba_acpi_dev *dev, u32 reg, u32 in1) | |||
439 | } | 442 | } |
440 | 443 | ||
441 | /* Illumination support */ | 444 | /* Illumination support */ |
442 | static int toshiba_illumination_available(struct toshiba_acpi_dev *dev) | 445 | static void toshiba_illumination_available(struct toshiba_acpi_dev *dev) |
443 | { | 446 | { |
444 | u32 in[TCI_WORDS] = { SCI_GET, SCI_ILLUMINATION, 0, 0, 0, 0 }; | 447 | u32 in[TCI_WORDS] = { SCI_GET, SCI_ILLUMINATION, 0, 0, 0, 0 }; |
445 | u32 out[TCI_WORDS]; | 448 | u32 out[TCI_WORDS]; |
446 | acpi_status status; | 449 | acpi_status status; |
447 | 450 | ||
451 | dev->illumination_supported = 0; | ||
452 | dev->illumination_led_registered = false; | ||
453 | |||
448 | if (!sci_open(dev)) | 454 | if (!sci_open(dev)) |
449 | return 0; | 455 | return; |
450 | 456 | ||
451 | status = tci_raw(dev, in, out); | 457 | status = tci_raw(dev, in, out); |
452 | sci_close(dev); | 458 | sci_close(dev); |
453 | if (ACPI_FAILURE(status)) { | 459 | if (ACPI_FAILURE(status)) |
454 | pr_err("ACPI call to query Illumination support failed\n"); | 460 | pr_err("ACPI call to query Illumination support failed\n"); |
455 | return 0; | 461 | else if (out[0] == TOS_NOT_SUPPORTED) |
456 | } else if (out[0] == TOS_NOT_SUPPORTED) { | ||
457 | pr_info("Illumination device not available\n"); | 462 | pr_info("Illumination device not available\n"); |
458 | return 0; | 463 | else if (out[0] == TOS_SUCCESS) |
459 | } | 464 | dev->illumination_supported = 1; |
460 | |||
461 | return 1; | ||
462 | } | 465 | } |
463 | 466 | ||
464 | static void toshiba_illumination_set(struct led_classdev *cdev, | 467 | static void toshiba_illumination_set(struct led_classdev *cdev, |
@@ -510,41 +513,42 @@ static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev) | |||
510 | } | 513 | } |
511 | 514 | ||
512 | /* KBD Illumination */ | 515 | /* KBD Illumination */ |
513 | static int toshiba_kbd_illum_available(struct toshiba_acpi_dev *dev) | 516 | static void toshiba_kbd_illum_available(struct toshiba_acpi_dev *dev) |
514 | { | 517 | { |
515 | u32 in[TCI_WORDS] = { SCI_GET, SCI_KBD_ILLUM_STATUS, 0, 0, 0, 0 }; | 518 | u32 in[TCI_WORDS] = { SCI_GET, SCI_KBD_ILLUM_STATUS, 0, 0, 0, 0 }; |
516 | u32 out[TCI_WORDS]; | 519 | u32 out[TCI_WORDS]; |
517 | acpi_status status; | 520 | acpi_status status; |
518 | 521 | ||
522 | dev->kbd_illum_supported = 0; | ||
523 | dev->kbd_led_registered = false; | ||
524 | |||
519 | if (!sci_open(dev)) | 525 | if (!sci_open(dev)) |
520 | return 0; | 526 | return; |
521 | 527 | ||
522 | status = tci_raw(dev, in, out); | 528 | status = tci_raw(dev, in, out); |
523 | sci_close(dev); | 529 | sci_close(dev); |
524 | if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) { | 530 | if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) { |
525 | pr_err("ACPI call to query kbd illumination support failed\n"); | 531 | pr_err("ACPI call to query kbd illumination support failed\n"); |
526 | return 0; | ||
527 | } else if (out[0] == TOS_NOT_SUPPORTED) { | 532 | } else if (out[0] == TOS_NOT_SUPPORTED) { |
528 | pr_info("Keyboard illumination not available\n"); | 533 | pr_info("Keyboard illumination not available\n"); |
529 | return 0; | 534 | } else if (out[0] == TOS_SUCCESS) { |
535 | /* | ||
536 | * Check for keyboard backlight timeout max value, | ||
537 | * previous kbd backlight implementation set this to | ||
538 | * 0x3c0003, and now the new implementation set this | ||
539 | * to 0x3c001a, use this to distinguish between them. | ||
540 | */ | ||
541 | if (out[3] == SCI_KBD_TIME_MAX) | ||
542 | dev->kbd_type = 2; | ||
543 | else | ||
544 | dev->kbd_type = 1; | ||
545 | /* Get the current keyboard backlight mode */ | ||
546 | dev->kbd_mode = out[2] & SCI_KBD_MODE_MASK; | ||
547 | /* Get the current time (1-60 seconds) */ | ||
548 | dev->kbd_time = out[2] >> HCI_MISC_SHIFT; | ||
549 | /* Flag as supported */ | ||
550 | dev->kbd_illum_supported = 1; | ||
530 | } | 551 | } |
531 | |||
532 | /* | ||
533 | * Check for keyboard backlight timeout max value, | ||
534 | * previous kbd backlight implementation set this to | ||
535 | * 0x3c0003, and now the new implementation set this | ||
536 | * to 0x3c001a, use this to distinguish between them. | ||
537 | */ | ||
538 | if (out[3] == SCI_KBD_TIME_MAX) | ||
539 | dev->kbd_type = 2; | ||
540 | else | ||
541 | dev->kbd_type = 1; | ||
542 | /* Get the current keyboard backlight mode */ | ||
543 | dev->kbd_mode = out[2] & SCI_KBD_MODE_MASK; | ||
544 | /* Get the current time (1-60 seconds) */ | ||
545 | dev->kbd_time = out[2] >> HCI_MISC_SHIFT; | ||
546 | |||
547 | return 1; | ||
548 | } | 552 | } |
549 | 553 | ||
550 | static int toshiba_kbd_illum_status_set(struct toshiba_acpi_dev *dev, u32 time) | 554 | static int toshiba_kbd_illum_status_set(struct toshiba_acpi_dev *dev, u32 time) |
@@ -665,12 +669,15 @@ static int toshiba_touchpad_get(struct toshiba_acpi_dev *dev, u32 *state) | |||
665 | } | 669 | } |
666 | 670 | ||
667 | /* Eco Mode support */ | 671 | /* Eco Mode support */ |
668 | static int toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) | 672 | static void toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) |
669 | { | 673 | { |
670 | acpi_status status; | 674 | acpi_status status; |
671 | u32 in[TCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 0, 0, 0 }; | 675 | u32 in[TCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 0, 0, 0 }; |
672 | u32 out[TCI_WORDS]; | 676 | u32 out[TCI_WORDS]; |
673 | 677 | ||
678 | dev->eco_supported = 0; | ||
679 | dev->eco_led_registered = false; | ||
680 | |||
674 | status = tci_raw(dev, in, out); | 681 | status = tci_raw(dev, in, out); |
675 | if (ACPI_FAILURE(status)) { | 682 | if (ACPI_FAILURE(status)) { |
676 | pr_err("ACPI call to get ECO led failed\n"); | 683 | pr_err("ACPI call to get ECO led failed\n"); |
@@ -691,10 +698,8 @@ static int toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) | |||
691 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) | 698 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) |
692 | pr_err("ACPI call to get ECO led failed\n"); | 699 | pr_err("ACPI call to get ECO led failed\n"); |
693 | else if (out[0] == TOS_SUCCESS) | 700 | else if (out[0] == TOS_SUCCESS) |
694 | return 1; | 701 | dev->eco_supported = 1; |
695 | } | 702 | } |
696 | |||
697 | return 0; | ||
698 | } | 703 | } |
699 | 704 | ||
700 | static enum led_brightness | 705 | static enum led_brightness |
@@ -734,30 +739,28 @@ static void toshiba_eco_mode_set_status(struct led_classdev *cdev, | |||
734 | } | 739 | } |
735 | 740 | ||
736 | /* Accelerometer support */ | 741 | /* Accelerometer support */ |
737 | static int toshiba_accelerometer_supported(struct toshiba_acpi_dev *dev) | 742 | static void toshiba_accelerometer_available(struct toshiba_acpi_dev *dev) |
738 | { | 743 | { |
739 | u32 in[TCI_WORDS] = { HCI_GET, HCI_ACCELEROMETER2, 0, 0, 0, 0 }; | 744 | u32 in[TCI_WORDS] = { HCI_GET, HCI_ACCELEROMETER2, 0, 0, 0, 0 }; |
740 | u32 out[TCI_WORDS]; | 745 | u32 out[TCI_WORDS]; |
741 | acpi_status status; | 746 | acpi_status status; |
742 | 747 | ||
748 | dev->accelerometer_supported = 0; | ||
749 | |||
743 | /* | 750 | /* |
744 | * Check if the accelerometer call exists, | 751 | * Check if the accelerometer call exists, |
745 | * this call also serves as initialization | 752 | * this call also serves as initialization |
746 | */ | 753 | */ |
747 | status = tci_raw(dev, in, out); | 754 | status = tci_raw(dev, in, out); |
748 | if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) { | 755 | if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) |
749 | pr_err("ACPI call to query the accelerometer failed\n"); | 756 | pr_err("ACPI call to query the accelerometer failed\n"); |
750 | return -EIO; | 757 | else if (out[0] == TOS_DATA_NOT_AVAILABLE || |
751 | } else if (out[0] == TOS_DATA_NOT_AVAILABLE || | 758 | out[0] == TOS_NOT_INITIALIZED) |
752 | out[0] == TOS_NOT_INITIALIZED) { | ||
753 | pr_err("Accelerometer not initialized\n"); | 759 | pr_err("Accelerometer not initialized\n"); |
754 | return -EIO; | 760 | else if (out[0] == TOS_NOT_SUPPORTED) |
755 | } else if (out[0] == TOS_NOT_SUPPORTED) { | ||
756 | pr_info("Accelerometer not supported\n"); | 761 | pr_info("Accelerometer not supported\n"); |
757 | return -ENODEV; | 762 | else if (out[0] == TOS_SUCCESS) |
758 | } | 763 | dev->accelerometer_supported = 1; |
759 | |||
760 | return 0; | ||
761 | } | 764 | } |
762 | 765 | ||
763 | static int toshiba_accelerometer_get(struct toshiba_acpi_dev *dev, | 766 | static int toshiba_accelerometer_get(struct toshiba_acpi_dev *dev, |
@@ -787,7 +790,6 @@ static void toshiba_usb_sleep_charge_available(struct toshiba_acpi_dev *dev) | |||
787 | u32 out[TCI_WORDS]; | 790 | u32 out[TCI_WORDS]; |
788 | acpi_status status; | 791 | acpi_status status; |
789 | 792 | ||
790 | /* Set the feature to "not supported" in case of error */ | ||
791 | dev->usb_sleep_charge_supported = 0; | 793 | dev->usb_sleep_charge_supported = 0; |
792 | 794 | ||
793 | if (!sci_open(dev)) | 795 | if (!sci_open(dev)) |
@@ -808,25 +810,17 @@ static void toshiba_usb_sleep_charge_available(struct toshiba_acpi_dev *dev) | |||
808 | 810 | ||
809 | in[5] = SCI_USB_CHARGE_BAT_LVL; | 811 | in[5] = SCI_USB_CHARGE_BAT_LVL; |
810 | status = tci_raw(dev, in, out); | 812 | status = tci_raw(dev, in, out); |
813 | sci_close(dev); | ||
811 | if (ACPI_FAILURE(status)) { | 814 | if (ACPI_FAILURE(status)) { |
812 | pr_err("ACPI call to get USB Sleep and Charge mode failed\n"); | 815 | pr_err("ACPI call to get USB Sleep and Charge mode failed\n"); |
813 | sci_close(dev); | ||
814 | return; | ||
815 | } else if (out[0] == TOS_NOT_SUPPORTED) { | 816 | } else if (out[0] == TOS_NOT_SUPPORTED) { |
816 | pr_info("USB Sleep and Charge not supported\n"); | 817 | pr_info("USB Sleep and Charge not supported\n"); |
817 | sci_close(dev); | ||
818 | return; | ||
819 | } else if (out[0] == TOS_SUCCESS) { | 818 | } else if (out[0] == TOS_SUCCESS) { |
820 | dev->usbsc_bat_level = out[2]; | 819 | dev->usbsc_bat_level = out[2]; |
821 | /* | 820 | /* Flag as supported */ |
822 | * If we reach this point, it means that the laptop has support | ||
823 | * for this feature and all values are initialized. | ||
824 | * Set it as supported. | ||
825 | */ | ||
826 | dev->usb_sleep_charge_supported = 1; | 821 | dev->usb_sleep_charge_supported = 1; |
827 | } | 822 | } |
828 | 823 | ||
829 | sci_close(dev); | ||
830 | } | 824 | } |
831 | 825 | ||
832 | static int toshiba_usb_sleep_charge_get(struct toshiba_acpi_dev *dev, | 826 | static int toshiba_usb_sleep_charge_get(struct toshiba_acpi_dev *dev, |
@@ -2639,13 +2633,13 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev) | |||
2639 | 2633 | ||
2640 | backlight_device_unregister(dev->backlight_dev); | 2634 | backlight_device_unregister(dev->backlight_dev); |
2641 | 2635 | ||
2642 | if (dev->illumination_supported) | 2636 | if (dev->illumination_led_registered) |
2643 | led_classdev_unregister(&dev->led_dev); | 2637 | led_classdev_unregister(&dev->led_dev); |
2644 | 2638 | ||
2645 | if (dev->kbd_led_registered) | 2639 | if (dev->kbd_led_registered) |
2646 | led_classdev_unregister(&dev->kbd_led); | 2640 | led_classdev_unregister(&dev->kbd_led); |
2647 | 2641 | ||
2648 | if (dev->eco_supported) | 2642 | if (dev->eco_led_registered) |
2649 | led_classdev_unregister(&dev->eco_led); | 2643 | led_classdev_unregister(&dev->eco_led); |
2650 | 2644 | ||
2651 | if (toshiba_acpi) | 2645 | if (toshiba_acpi) |
@@ -2727,25 +2721,27 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
2727 | if (ret) | 2721 | if (ret) |
2728 | goto error; | 2722 | goto error; |
2729 | 2723 | ||
2730 | if (toshiba_illumination_available(dev)) { | 2724 | toshiba_illumination_available(dev); |
2725 | if (dev->illumination_supported) { | ||
2731 | dev->led_dev.name = "toshiba::illumination"; | 2726 | dev->led_dev.name = "toshiba::illumination"; |
2732 | dev->led_dev.max_brightness = 1; | 2727 | dev->led_dev.max_brightness = 1; |
2733 | dev->led_dev.brightness_set = toshiba_illumination_set; | 2728 | dev->led_dev.brightness_set = toshiba_illumination_set; |
2734 | dev->led_dev.brightness_get = toshiba_illumination_get; | 2729 | dev->led_dev.brightness_get = toshiba_illumination_get; |
2735 | if (!led_classdev_register(&acpi_dev->dev, &dev->led_dev)) | 2730 | if (!led_classdev_register(&acpi_dev->dev, &dev->led_dev)) |
2736 | dev->illumination_supported = 1; | 2731 | dev->illumination_led_registered = true; |
2737 | } | 2732 | } |
2738 | 2733 | ||
2739 | if (toshiba_eco_mode_available(dev)) { | 2734 | toshiba_eco_mode_available(dev); |
2735 | if (dev->eco_supported) { | ||
2740 | dev->eco_led.name = "toshiba::eco_mode"; | 2736 | dev->eco_led.name = "toshiba::eco_mode"; |
2741 | dev->eco_led.max_brightness = 1; | 2737 | dev->eco_led.max_brightness = 1; |
2742 | dev->eco_led.brightness_set = toshiba_eco_mode_set_status; | 2738 | dev->eco_led.brightness_set = toshiba_eco_mode_set_status; |
2743 | dev->eco_led.brightness_get = toshiba_eco_mode_get_status; | 2739 | dev->eco_led.brightness_get = toshiba_eco_mode_get_status; |
2744 | if (!led_classdev_register(&dev->acpi_dev->dev, &dev->eco_led)) | 2740 | if (!led_classdev_register(&dev->acpi_dev->dev, &dev->eco_led)) |
2745 | dev->eco_supported = 1; | 2741 | dev->eco_led_registered = true; |
2746 | } | 2742 | } |
2747 | 2743 | ||
2748 | dev->kbd_illum_supported = toshiba_kbd_illum_available(dev); | 2744 | toshiba_kbd_illum_available(dev); |
2749 | /* | 2745 | /* |
2750 | * Only register the LED if KBD illumination is supported | 2746 | * Only register the LED if KBD illumination is supported |
2751 | * and the keyboard backlight operation mode is set to FN-Z | 2747 | * and the keyboard backlight operation mode is set to FN-Z |
@@ -2756,14 +2752,13 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
2756 | dev->kbd_led.brightness_set = toshiba_kbd_backlight_set; | 2752 | dev->kbd_led.brightness_set = toshiba_kbd_backlight_set; |
2757 | dev->kbd_led.brightness_get = toshiba_kbd_backlight_get; | 2753 | dev->kbd_led.brightness_get = toshiba_kbd_backlight_get; |
2758 | if (!led_classdev_register(&dev->acpi_dev->dev, &dev->kbd_led)) | 2754 | if (!led_classdev_register(&dev->acpi_dev->dev, &dev->kbd_led)) |
2759 | dev->kbd_led_registered = 1; | 2755 | dev->kbd_led_registered = true; |
2760 | } | 2756 | } |
2761 | 2757 | ||
2762 | ret = toshiba_touchpad_get(dev, &dummy); | 2758 | ret = toshiba_touchpad_get(dev, &dummy); |
2763 | dev->touchpad_supported = !ret; | 2759 | dev->touchpad_supported = !ret; |
2764 | 2760 | ||
2765 | ret = toshiba_accelerometer_supported(dev); | 2761 | toshiba_accelerometer_available(dev); |
2766 | dev->accelerometer_supported = !ret; | ||
2767 | 2762 | ||
2768 | toshiba_usb_sleep_charge_available(dev); | 2763 | toshiba_usb_sleep_charge_available(dev); |
2769 | 2764 | ||