Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

toshiba_acpi: Update and fix USB Sleep and Charge modes

This patch fixes the USB Sleep and Charge mode on certain models
where the value returned by the BIOS is different, and thus, making
this feature not to work for those models.

Also, the "Typical" charging mode was added as a supported mode.

Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>

authored by

Azael Avalos and committed by
Darren Hart
c8c91842 097c27fc

+62 -9
+62 -9
drivers/platform/x86/toshiba_acpi.c
··· 150 150 #define SCI_KBD_MODE_OFF 0x10 151 151 #define SCI_KBD_TIME_MAX 0x3c001a 152 152 #define SCI_USB_CHARGE_MODE_MASK 0xff 153 - #define SCI_USB_CHARGE_DISABLED 0x30000 154 - #define SCI_USB_CHARGE_ALTERNATE 0x30009 155 - #define SCI_USB_CHARGE_AUTO 0x30021 153 + #define SCI_USB_CHARGE_DISABLED 0x00 154 + #define SCI_USB_CHARGE_ALTERNATE 0x09 155 + #define SCI_USB_CHARGE_TYPICAL 0x11 156 + #define SCI_USB_CHARGE_AUTO 0x21 156 157 #define SCI_USB_CHARGE_BAT_MASK 0x7 157 158 #define SCI_USB_CHARGE_BAT_LVL_OFF 0x1 158 159 #define SCI_USB_CHARGE_BAT_LVL_ON 0x4 ··· 178 177 int kbd_mode; 179 178 int kbd_time; 180 179 int usbsc_bat_level; 180 + int usbsc_mode_base; 181 181 int hotkey_event_type; 182 182 183 183 unsigned int illumination_supported:1; ··· 802 800 } 803 801 804 802 /* Sleep (Charge and Music) utilities support */ 803 + static void toshiba_usb_sleep_charge_available(struct toshiba_acpi_dev *dev) 804 + { 805 + u32 in[TCI_WORDS] = { SCI_GET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 }; 806 + u32 out[TCI_WORDS]; 807 + acpi_status status; 808 + 809 + /* Set the feature to "not supported" in case of error */ 810 + dev->usb_sleep_charge_supported = 0; 811 + 812 + if (!sci_open(dev)) 813 + return; 814 + 815 + status = tci_raw(dev, in, out); 816 + if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { 817 + pr_err("ACPI call to get USB Sleep and Charge mode failed\n"); 818 + sci_close(dev); 819 + return; 820 + } else if (out[0] == TOS_NOT_SUPPORTED) { 821 + pr_info("USB Sleep and Charge not supported\n"); 822 + sci_close(dev); 823 + return; 824 + } else if (out[0] == TOS_SUCCESS) { 825 + dev->usbsc_mode_base = out[4]; 826 + } 827 + 828 + in[5] = SCI_USB_CHARGE_BAT_LVL; 829 + status = tci_raw(dev, in, out); 830 + if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { 831 + pr_err("ACPI call to get USB Sleep and Charge mode failed\n"); 832 + sci_close(dev); 833 + return; 834 + } else if (out[0] == TOS_NOT_SUPPORTED) { 835 + pr_info("USB Sleep and Charge not supported\n"); 836 + sci_close(dev); 837 + return; 838 + } else if (out[0] == TOS_SUCCESS) { 839 + dev->usbsc_bat_level = out[2]; 840 + /* 841 + * If we reach this point, it means that the laptop has support 842 + * for this feature and all values are initialized. 843 + * Set it as supported. 844 + */ 845 + dev->usb_sleep_charge_supported = 1; 846 + } 847 + 848 + sci_close(dev); 849 + } 850 + 805 851 static int toshiba_usb_sleep_charge_get(struct toshiba_acpi_dev *dev, 806 852 u32 *mode) 807 853 { ··· 2026 1976 * 0 - Disabled 2027 1977 * 1 - Alternate (Non USB conformant devices that require more power) 2028 1978 * 2 - Auto (USB conformant devices) 1979 + * 3 - Typical 2029 1980 */ 2030 - if (state != 0 && state != 1 && state != 2) 1981 + if (state != 0 && state != 1 && state != 2 && state != 3) 2031 1982 return -EINVAL; 2032 1983 2033 1984 /* Set the USB charging mode to internal value */ 1985 + mode = toshiba->usbsc_mode_base; 2034 1986 if (state == 0) 2035 - mode = SCI_USB_CHARGE_DISABLED; 1987 + mode |= SCI_USB_CHARGE_DISABLED; 2036 1988 else if (state == 1) 2037 - mode = SCI_USB_CHARGE_ALTERNATE; 1989 + mode |= SCI_USB_CHARGE_ALTERNATE; 2038 1990 else if (state == 2) 2039 - mode = SCI_USB_CHARGE_AUTO; 1991 + mode |= SCI_USB_CHARGE_AUTO; 1992 + else if (state == 3) 1993 + mode |= SCI_USB_CHARGE_TYPICAL; 2040 1994 2041 1995 ret = toshiba_usb_sleep_charge_set(toshiba, mode); 2042 1996 if (ret) ··· 2810 2756 ret = toshiba_accelerometer_supported(dev); 2811 2757 dev->accelerometer_supported = !ret; 2812 2758 2813 - ret = toshiba_usb_sleep_charge_get(dev, &dummy); 2814 - dev->usb_sleep_charge_supported = !ret; 2759 + toshiba_usb_sleep_charge_available(dev); 2815 2760 2816 2761 ret = toshiba_usb_rapid_charge_get(dev, &dummy); 2817 2762 dev->usb_rapid_charge_supported = !ret;