diff options
| -rw-r--r-- | Documentation/ABI/testing/sysfs-driver-samsung-laptop | 8 | ||||
| -rw-r--r-- | Documentation/ABI/testing/sysfs-driver-toshiba_acpi | 114 | ||||
| -rw-r--r-- | drivers/platform/x86/asus-laptop.c | 97 | ||||
| -rw-r--r-- | drivers/platform/x86/classmate-laptop.c | 2 | ||||
| -rw-r--r-- | drivers/platform/x86/fujitsu-laptop.c | 7 | ||||
| -rw-r--r-- | drivers/platform/x86/intel_scu_ipc.c | 77 | ||||
| -rw-r--r-- | drivers/platform/x86/samsung-laptop.c | 146 | ||||
| -rw-r--r-- | drivers/platform/x86/sony-laptop.c | 2 | ||||
| -rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 24 | ||||
| -rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 1025 |
10 files changed, 1259 insertions, 243 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-samsung-laptop b/Documentation/ABI/testing/sysfs-driver-samsung-laptop index 678819a3f8bf..63c1ad0212fc 100644 --- a/Documentation/ABI/testing/sysfs-driver-samsung-laptop +++ b/Documentation/ABI/testing/sysfs-driver-samsung-laptop | |||
| @@ -35,3 +35,11 @@ Contact: Corentin Chary <corentin.chary@gmail.com> | |||
| 35 | Description: Use your USB ports to charge devices, even | 35 | Description: Use your USB ports to charge devices, even |
| 36 | when your laptop is powered off. | 36 | when your laptop is powered off. |
| 37 | 1 means enabled, 0 means disabled. | 37 | 1 means enabled, 0 means disabled. |
| 38 | |||
| 39 | What: /sys/devices/platform/samsung/lid_handling | ||
| 40 | Date: December 11, 2014 | ||
| 41 | KernelVersion: 3.19 | ||
| 42 | Contact: Julijonas Kikutis <julijonas.kikutis@gmail.com> | ||
| 43 | Description: Some Samsung laptops handle lid closing quicker and | ||
| 44 | only handle lid opening with this mode enabled. | ||
| 45 | 1 means enabled, 0 means disabled. | ||
diff --git a/Documentation/ABI/testing/sysfs-driver-toshiba_acpi b/Documentation/ABI/testing/sysfs-driver-toshiba_acpi new file mode 100644 index 000000000000..ca9c71a531c5 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-toshiba_acpi | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/kbd_backlight_mode | ||
| 2 | Date: June 8, 2014 | ||
| 3 | KernelVersion: 3.15 | ||
| 4 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 5 | Description: This file controls the keyboard backlight operation mode, valid | ||
| 6 | values are: | ||
| 7 | * 0x1 -> FN-Z | ||
| 8 | * 0x2 -> AUTO (also called TIMER) | ||
| 9 | * 0x8 -> ON | ||
| 10 | * 0x10 -> OFF | ||
| 11 | Note that the kernel 3.16 onwards this file accepts all listed | ||
| 12 | parameters, kernel 3.15 only accepts the first two (FN-Z and | ||
| 13 | AUTO). | ||
| 14 | Users: KToshiba | ||
| 15 | |||
| 16 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/kbd_backlight_timeout | ||
| 17 | Date: June 8, 2014 | ||
| 18 | KernelVersion: 3.15 | ||
| 19 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 20 | Description: This file controls the timeout of the keyboard backlight | ||
| 21 | whenever the operation mode is set to AUTO (or TIMER), | ||
| 22 | valid values range from 0-60. | ||
| 23 | Note that the kernel 3.15 only had support for the first | ||
| 24 | keyboard type, the kernel 3.16 added support for the second | ||
| 25 | type and the range accepted for type 2 is 1-60. | ||
| 26 | See the entry named "kbd_type" | ||
| 27 | Users: KToshiba | ||
| 28 | |||
| 29 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/position | ||
| 30 | Date: June 8, 2014 | ||
| 31 | KernelVersion: 3.15 | ||
| 32 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 33 | Description: This file shows the absolute position of the built-in | ||
| 34 | accelereometer. | ||
| 35 | |||
| 36 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/touchpad | ||
| 37 | Date: June 8, 2014 | ||
| 38 | KernelVersion: 3.15 | ||
| 39 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 40 | Description: This files controls the status of the touchpad and pointing | ||
| 41 | stick (if available), valid values are: | ||
| 42 | * 0 -> OFF | ||
| 43 | * 1 -> ON | ||
| 44 | Users: KToshiba | ||
| 45 | |||
| 46 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/available_kbd_modes | ||
| 47 | Date: August 3, 2014 | ||
| 48 | KernelVersion: 3.16 | ||
| 49 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 50 | Description: This file shows the supported keyboard backlight modes | ||
| 51 | the system supports, which can be: | ||
| 52 | * 0x1 -> FN-Z | ||
| 53 | * 0x2 -> AUTO (also called TIMER) | ||
| 54 | * 0x8 -> ON | ||
| 55 | * 0x10 -> OFF | ||
| 56 | Note that not all keyboard types support the listed modes. | ||
| 57 | See the entry named "available_kbd_modes" | ||
| 58 | Users: KToshiba | ||
| 59 | |||
| 60 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/kbd_type | ||
| 61 | Date: August 3, 2014 | ||
| 62 | KernelVersion: 3.16 | ||
| 63 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 64 | Description: This file shows the current keyboard backlight type, | ||
| 65 | which can be: | ||
| 66 | * 1 -> Type 1, supporting modes FN-Z and AUTO | ||
| 67 | * 2 -> Type 2, supporting modes TIMER, ON and OFF | ||
| 68 | Users: KToshiba | ||
| 69 | |||
| 70 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/version | ||
| 71 | Date: February, 2015 | ||
| 72 | KernelVersion: 3.20 | ||
| 73 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 74 | Description: This file shows the current version of the driver | ||
| 75 | |||
| 76 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/fan | ||
| 77 | Date: February, 2015 | ||
| 78 | KernelVersion: 3.20 | ||
| 79 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 80 | Description: This file controls the state of the internal fan, valid | ||
| 81 | values are: | ||
| 82 | * 0 -> OFF | ||
| 83 | * 1 -> ON | ||
| 84 | |||
| 85 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/kbd_function_keys | ||
| 86 | Date: February, 2015 | ||
| 87 | KernelVersion: 3.20 | ||
| 88 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 89 | Description: This file controls the Special Functions (hotkeys) operation | ||
| 90 | mode, valid values are: | ||
| 91 | * 0 -> Normal Operation | ||
| 92 | * 1 -> Special Functions | ||
| 93 | In the "Normal Operation" mode, the F{1-12} keys are as usual | ||
| 94 | and the hotkeys are accessed via FN-F{1-12}. | ||
| 95 | In the "Special Functions" mode, the F{1-12} keys trigger the | ||
| 96 | hotkey and the F{1-12} keys are accessed via FN-F{1-12}. | ||
| 97 | |||
| 98 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/panel_power_on | ||
| 99 | Date: February, 2015 | ||
| 100 | KernelVersion: 3.20 | ||
| 101 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 102 | Description: This file controls whether the laptop should turn ON whenever | ||
| 103 | the LID is opened, valid values are: | ||
| 104 | * 0 -> Disabled | ||
| 105 | * 1 -> Enabled | ||
| 106 | |||
| 107 | What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/usb_three | ||
| 108 | Date: February, 2015 | ||
| 109 | KernelVersion: 3.20 | ||
| 110 | Contact: Azael Avalos <coproscefalo@gmail.com> | ||
| 111 | Description: This file controls whether the USB 3 functionality, valid | ||
| 112 | values are: | ||
| 113 | * 0 -> Disabled (Acts as a regular USB 2) | ||
| 114 | * 1 -> Enabled (Full USB 3 functionality) | ||
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index f71700e0d132..46b274693872 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
| @@ -856,8 +856,8 @@ static void asus_backlight_exit(struct asus_laptop *asus) | |||
| 856 | * than count bytes. We set eof to 1 if we handle those 2 values. We return the | 856 | * than count bytes. We set eof to 1 if we handle those 2 values. We return the |
| 857 | * number of bytes written in page | 857 | * number of bytes written in page |
| 858 | */ | 858 | */ |
| 859 | static ssize_t show_infos(struct device *dev, | 859 | static ssize_t infos_show(struct device *dev, struct device_attribute *attr, |
| 860 | struct device_attribute *attr, char *page) | 860 | char *page) |
| 861 | { | 861 | { |
| 862 | struct asus_laptop *asus = dev_get_drvdata(dev); | 862 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 863 | int len = 0; | 863 | int len = 0; |
| @@ -926,6 +926,7 @@ static ssize_t show_infos(struct device *dev, | |||
| 926 | 926 | ||
| 927 | return len; | 927 | return len; |
| 928 | } | 928 | } |
| 929 | static DEVICE_ATTR_RO(infos); | ||
| 929 | 930 | ||
| 930 | static int parse_arg(const char *buf, unsigned long count, int *val) | 931 | static int parse_arg(const char *buf, unsigned long count, int *val) |
| 931 | { | 932 | { |
| @@ -957,15 +958,15 @@ static ssize_t sysfs_acpi_set(struct asus_laptop *asus, | |||
| 957 | /* | 958 | /* |
| 958 | * LEDD display | 959 | * LEDD display |
| 959 | */ | 960 | */ |
| 960 | static ssize_t show_ledd(struct device *dev, | 961 | static ssize_t ledd_show(struct device *dev, struct device_attribute *attr, |
| 961 | struct device_attribute *attr, char *buf) | 962 | char *buf) |
| 962 | { | 963 | { |
| 963 | struct asus_laptop *asus = dev_get_drvdata(dev); | 964 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 964 | 965 | ||
| 965 | return sprintf(buf, "0x%08x\n", asus->ledd_status); | 966 | return sprintf(buf, "0x%08x\n", asus->ledd_status); |
| 966 | } | 967 | } |
| 967 | 968 | ||
| 968 | static ssize_t store_ledd(struct device *dev, struct device_attribute *attr, | 969 | static ssize_t ledd_store(struct device *dev, struct device_attribute *attr, |
| 969 | const char *buf, size_t count) | 970 | const char *buf, size_t count) |
| 970 | { | 971 | { |
| 971 | struct asus_laptop *asus = dev_get_drvdata(dev); | 972 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| @@ -981,6 +982,7 @@ static ssize_t store_ledd(struct device *dev, struct device_attribute *attr, | |||
| 981 | } | 982 | } |
| 982 | return rv; | 983 | return rv; |
| 983 | } | 984 | } |
| 985 | static DEVICE_ATTR_RW(ledd); | ||
| 984 | 986 | ||
| 985 | /* | 987 | /* |
| 986 | * Wireless | 988 | * Wireless |
| @@ -1014,21 +1016,22 @@ static int asus_wlan_set(struct asus_laptop *asus, int status) | |||
| 1014 | return 0; | 1016 | return 0; |
| 1015 | } | 1017 | } |
| 1016 | 1018 | ||
| 1017 | static ssize_t show_wlan(struct device *dev, | 1019 | static ssize_t wlan_show(struct device *dev, struct device_attribute *attr, |
| 1018 | struct device_attribute *attr, char *buf) | 1020 | char *buf) |
| 1019 | { | 1021 | { |
| 1020 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1022 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1021 | 1023 | ||
| 1022 | return sprintf(buf, "%d\n", asus_wireless_status(asus, WL_RSTS)); | 1024 | return sprintf(buf, "%d\n", asus_wireless_status(asus, WL_RSTS)); |
| 1023 | } | 1025 | } |
| 1024 | 1026 | ||
| 1025 | static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, | 1027 | static ssize_t wlan_store(struct device *dev, struct device_attribute *attr, |
| 1026 | const char *buf, size_t count) | 1028 | const char *buf, size_t count) |
| 1027 | { | 1029 | { |
| 1028 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1030 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1029 | 1031 | ||
| 1030 | return sysfs_acpi_set(asus, buf, count, METHOD_WLAN); | 1032 | return sysfs_acpi_set(asus, buf, count, METHOD_WLAN); |
| 1031 | } | 1033 | } |
| 1034 | static DEVICE_ATTR_RW(wlan); | ||
| 1032 | 1035 | ||
| 1033 | /*e | 1036 | /*e |
| 1034 | * Bluetooth | 1037 | * Bluetooth |
| @@ -1042,15 +1045,15 @@ static int asus_bluetooth_set(struct asus_laptop *asus, int status) | |||
| 1042 | return 0; | 1045 | return 0; |
| 1043 | } | 1046 | } |
| 1044 | 1047 | ||
| 1045 | static ssize_t show_bluetooth(struct device *dev, | 1048 | static ssize_t bluetooth_show(struct device *dev, struct device_attribute *attr, |
| 1046 | struct device_attribute *attr, char *buf) | 1049 | char *buf) |
| 1047 | { | 1050 | { |
| 1048 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1051 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1049 | 1052 | ||
| 1050 | return sprintf(buf, "%d\n", asus_wireless_status(asus, BT_RSTS)); | 1053 | return sprintf(buf, "%d\n", asus_wireless_status(asus, BT_RSTS)); |
| 1051 | } | 1054 | } |
| 1052 | 1055 | ||
| 1053 | static ssize_t store_bluetooth(struct device *dev, | 1056 | static ssize_t bluetooth_store(struct device *dev, |
| 1054 | struct device_attribute *attr, const char *buf, | 1057 | struct device_attribute *attr, const char *buf, |
| 1055 | size_t count) | 1058 | size_t count) |
| 1056 | { | 1059 | { |
| @@ -1058,6 +1061,7 @@ static ssize_t store_bluetooth(struct device *dev, | |||
| 1058 | 1061 | ||
| 1059 | return sysfs_acpi_set(asus, buf, count, METHOD_BLUETOOTH); | 1062 | return sysfs_acpi_set(asus, buf, count, METHOD_BLUETOOTH); |
| 1060 | } | 1063 | } |
| 1064 | static DEVICE_ATTR_RW(bluetooth); | ||
| 1061 | 1065 | ||
| 1062 | /* | 1066 | /* |
| 1063 | * Wimax | 1067 | * Wimax |
| @@ -1071,22 +1075,22 @@ static int asus_wimax_set(struct asus_laptop *asus, int status) | |||
| 1071 | return 0; | 1075 | return 0; |
| 1072 | } | 1076 | } |
| 1073 | 1077 | ||
| 1074 | static ssize_t show_wimax(struct device *dev, | 1078 | static ssize_t wimax_show(struct device *dev, struct device_attribute *attr, |
| 1075 | struct device_attribute *attr, char *buf) | 1079 | char *buf) |
| 1076 | { | 1080 | { |
| 1077 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1081 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1078 | 1082 | ||
| 1079 | return sprintf(buf, "%d\n", asus_wireless_status(asus, WM_RSTS)); | 1083 | return sprintf(buf, "%d\n", asus_wireless_status(asus, WM_RSTS)); |
| 1080 | } | 1084 | } |
| 1081 | 1085 | ||
| 1082 | static ssize_t store_wimax(struct device *dev, | 1086 | static ssize_t wimax_store(struct device *dev, struct device_attribute *attr, |
| 1083 | struct device_attribute *attr, const char *buf, | 1087 | const char *buf, size_t count) |
| 1084 | size_t count) | ||
| 1085 | { | 1088 | { |
| 1086 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1089 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1087 | 1090 | ||
| 1088 | return sysfs_acpi_set(asus, buf, count, METHOD_WIMAX); | 1091 | return sysfs_acpi_set(asus, buf, count, METHOD_WIMAX); |
| 1089 | } | 1092 | } |
| 1093 | static DEVICE_ATTR_RW(wimax); | ||
| 1090 | 1094 | ||
| 1091 | /* | 1095 | /* |
| 1092 | * Wwan | 1096 | * Wwan |
| @@ -1100,22 +1104,22 @@ static int asus_wwan_set(struct asus_laptop *asus, int status) | |||
| 1100 | return 0; | 1104 | return 0; |
| 1101 | } | 1105 | } |
| 1102 | 1106 | ||
| 1103 | static ssize_t show_wwan(struct device *dev, | 1107 | static ssize_t wwan_show(struct device *dev, struct device_attribute *attr, |
| 1104 | struct device_attribute *attr, char *buf) | 1108 | char *buf) |
| 1105 | { | 1109 | { |
| 1106 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1110 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1107 | 1111 | ||
| 1108 | return sprintf(buf, "%d\n", asus_wireless_status(asus, WW_RSTS)); | 1112 | return sprintf(buf, "%d\n", asus_wireless_status(asus, WW_RSTS)); |
| 1109 | } | 1113 | } |
| 1110 | 1114 | ||
| 1111 | static ssize_t store_wwan(struct device *dev, | 1115 | static ssize_t wwan_store(struct device *dev, struct device_attribute *attr, |
| 1112 | struct device_attribute *attr, const char *buf, | 1116 | const char *buf, size_t count) |
| 1113 | size_t count) | ||
| 1114 | { | 1117 | { |
| 1115 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1118 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1116 | 1119 | ||
| 1117 | return sysfs_acpi_set(asus, buf, count, METHOD_WWAN); | 1120 | return sysfs_acpi_set(asus, buf, count, METHOD_WWAN); |
| 1118 | } | 1121 | } |
| 1122 | static DEVICE_ATTR_RW(wwan); | ||
| 1119 | 1123 | ||
| 1120 | /* | 1124 | /* |
| 1121 | * Display | 1125 | * Display |
| @@ -1135,8 +1139,8 @@ static void asus_set_display(struct asus_laptop *asus, int value) | |||
| 1135 | * displays hooked up simultaneously, so be warned. See the acpi4asus README | 1139 | * displays hooked up simultaneously, so be warned. See the acpi4asus README |
| 1136 | * for more info. | 1140 | * for more info. |
| 1137 | */ | 1141 | */ |
| 1138 | static ssize_t store_disp(struct device *dev, struct device_attribute *attr, | 1142 | static ssize_t display_store(struct device *dev, struct device_attribute *attr, |
| 1139 | const char *buf, size_t count) | 1143 | const char *buf, size_t count) |
| 1140 | { | 1144 | { |
| 1141 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1145 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1142 | int rv, value; | 1146 | int rv, value; |
| @@ -1146,6 +1150,7 @@ static ssize_t store_disp(struct device *dev, struct device_attribute *attr, | |||
| 1146 | asus_set_display(asus, value); | 1150 | asus_set_display(asus, value); |
| 1147 | return rv; | 1151 | return rv; |
| 1148 | } | 1152 | } |
| 1153 | static DEVICE_ATTR_WO(display); | ||
| 1149 | 1154 | ||
| 1150 | /* | 1155 | /* |
| 1151 | * Light Sens | 1156 | * Light Sens |
| @@ -1167,16 +1172,17 @@ static void asus_als_switch(struct asus_laptop *asus, int value) | |||
| 1167 | asus->light_switch = value; | 1172 | asus->light_switch = value; |
| 1168 | } | 1173 | } |
| 1169 | 1174 | ||
| 1170 | static ssize_t show_lssw(struct device *dev, | 1175 | static ssize_t ls_switch_show(struct device *dev, struct device_attribute *attr, |
| 1171 | struct device_attribute *attr, char *buf) | 1176 | char *buf) |
| 1172 | { | 1177 | { |
| 1173 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1178 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1174 | 1179 | ||
| 1175 | return sprintf(buf, "%d\n", asus->light_switch); | 1180 | return sprintf(buf, "%d\n", asus->light_switch); |
| 1176 | } | 1181 | } |
| 1177 | 1182 | ||
| 1178 | static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, | 1183 | static ssize_t ls_switch_store(struct device *dev, |
| 1179 | const char *buf, size_t count) | 1184 | struct device_attribute *attr, const char *buf, |
| 1185 | size_t count) | ||
| 1180 | { | 1186 | { |
| 1181 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1187 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1182 | int rv, value; | 1188 | int rv, value; |
| @@ -1187,6 +1193,7 @@ static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, | |||
| 1187 | 1193 | ||
| 1188 | return rv; | 1194 | return rv; |
| 1189 | } | 1195 | } |
| 1196 | static DEVICE_ATTR_RW(ls_switch); | ||
| 1190 | 1197 | ||
| 1191 | static void asus_als_level(struct asus_laptop *asus, int value) | 1198 | static void asus_als_level(struct asus_laptop *asus, int value) |
| 1192 | { | 1199 | { |
| @@ -1195,16 +1202,16 @@ static void asus_als_level(struct asus_laptop *asus, int value) | |||
| 1195 | asus->light_level = value; | 1202 | asus->light_level = value; |
| 1196 | } | 1203 | } |
| 1197 | 1204 | ||
| 1198 | static ssize_t show_lslvl(struct device *dev, | 1205 | static ssize_t ls_level_show(struct device *dev, struct device_attribute *attr, |
| 1199 | struct device_attribute *attr, char *buf) | 1206 | char *buf) |
| 1200 | { | 1207 | { |
| 1201 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1208 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1202 | 1209 | ||
| 1203 | return sprintf(buf, "%d\n", asus->light_level); | 1210 | return sprintf(buf, "%d\n", asus->light_level); |
| 1204 | } | 1211 | } |
| 1205 | 1212 | ||
| 1206 | static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr, | 1213 | static ssize_t ls_level_store(struct device *dev, struct device_attribute *attr, |
| 1207 | const char *buf, size_t count) | 1214 | const char *buf, size_t count) |
| 1208 | { | 1215 | { |
| 1209 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1216 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1210 | int rv, value; | 1217 | int rv, value; |
| @@ -1218,6 +1225,7 @@ static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr, | |||
| 1218 | 1225 | ||
| 1219 | return rv; | 1226 | return rv; |
| 1220 | } | 1227 | } |
| 1228 | static DEVICE_ATTR_RW(ls_level); | ||
| 1221 | 1229 | ||
| 1222 | static int pega_int_read(struct asus_laptop *asus, int arg, int *result) | 1230 | static int pega_int_read(struct asus_laptop *asus, int arg, int *result) |
| 1223 | { | 1231 | { |
| @@ -1234,8 +1242,8 @@ static int pega_int_read(struct asus_laptop *asus, int arg, int *result) | |||
| 1234 | return err; | 1242 | return err; |
| 1235 | } | 1243 | } |
| 1236 | 1244 | ||
| 1237 | static ssize_t show_lsvalue(struct device *dev, | 1245 | static ssize_t ls_value_show(struct device *dev, struct device_attribute *attr, |
| 1238 | struct device_attribute *attr, char *buf) | 1246 | char *buf) |
| 1239 | { | 1247 | { |
| 1240 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1248 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1241 | int err, hi, lo; | 1249 | int err, hi, lo; |
| @@ -1247,6 +1255,7 @@ static ssize_t show_lsvalue(struct device *dev, | |||
| 1247 | return sprintf(buf, "%d\n", 10 * hi + lo); | 1255 | return sprintf(buf, "%d\n", 10 * hi + lo); |
| 1248 | return err; | 1256 | return err; |
| 1249 | } | 1257 | } |
| 1258 | static DEVICE_ATTR_RO(ls_value); | ||
| 1250 | 1259 | ||
| 1251 | /* | 1260 | /* |
| 1252 | * GPS | 1261 | * GPS |
| @@ -1274,15 +1283,15 @@ static int asus_gps_switch(struct asus_laptop *asus, int status) | |||
| 1274 | return 0; | 1283 | return 0; |
| 1275 | } | 1284 | } |
| 1276 | 1285 | ||
| 1277 | static ssize_t show_gps(struct device *dev, | 1286 | static ssize_t gps_show(struct device *dev, struct device_attribute *attr, |
| 1278 | struct device_attribute *attr, char *buf) | 1287 | char *buf) |
| 1279 | { | 1288 | { |
| 1280 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1289 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 1281 | 1290 | ||
| 1282 | return sprintf(buf, "%d\n", asus_gps_status(asus)); | 1291 | return sprintf(buf, "%d\n", asus_gps_status(asus)); |
| 1283 | } | 1292 | } |
| 1284 | 1293 | ||
| 1285 | static ssize_t store_gps(struct device *dev, struct device_attribute *attr, | 1294 | static ssize_t gps_store(struct device *dev, struct device_attribute *attr, |
| 1286 | const char *buf, size_t count) | 1295 | const char *buf, size_t count) |
| 1287 | { | 1296 | { |
| 1288 | struct asus_laptop *asus = dev_get_drvdata(dev); | 1297 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| @@ -1298,6 +1307,7 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr, | |||
| 1298 | rfkill_set_sw_state(asus->gps.rfkill, !value); | 1307 | rfkill_set_sw_state(asus->gps.rfkill, !value); |
| 1299 | return rv; | 1308 | return rv; |
| 1300 | } | 1309 | } |
| 1310 | static DEVICE_ATTR_RW(gps); | ||
| 1301 | 1311 | ||
| 1302 | /* | 1312 | /* |
| 1303 | * rfkill | 1313 | * rfkill |
| @@ -1569,19 +1579,6 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event) | |||
| 1569 | asus_input_notify(asus, event); | 1579 | asus_input_notify(asus, event); |
| 1570 | } | 1580 | } |
| 1571 | 1581 | ||
| 1572 | static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL); | ||
| 1573 | static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan); | ||
| 1574 | static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, | ||
| 1575 | show_bluetooth, store_bluetooth); | ||
| 1576 | static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax); | ||
| 1577 | static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan); | ||
| 1578 | static DEVICE_ATTR(display, S_IWUSR, NULL, store_disp); | ||
| 1579 | static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd); | ||
| 1580 | static DEVICE_ATTR(ls_value, S_IRUGO, show_lsvalue, NULL); | ||
| 1581 | static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl); | ||
| 1582 | static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw); | ||
| 1583 | static DEVICE_ATTR(gps, S_IRUGO | S_IWUSR, show_gps, store_gps); | ||
| 1584 | |||
| 1585 | static struct attribute *asus_attributes[] = { | 1582 | static struct attribute *asus_attributes[] = { |
| 1586 | &dev_attr_infos.attr, | 1583 | &dev_attr_infos.attr, |
| 1587 | &dev_attr_wlan.attr, | 1584 | &dev_attr_wlan.attr, |
| @@ -1616,7 +1613,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, | |||
| 1616 | else | 1613 | else |
| 1617 | goto normal; | 1614 | goto normal; |
| 1618 | 1615 | ||
| 1619 | return supported; | 1616 | return supported ? attr->mode : 0; |
| 1620 | } | 1617 | } |
| 1621 | 1618 | ||
| 1622 | normal: | 1619 | normal: |
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 70d355a9ae2c..55cf10bc7817 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c | |||
| @@ -520,7 +520,7 @@ static acpi_status cmpc_get_accel(acpi_handle handle, | |||
| 520 | { | 520 | { |
| 521 | union acpi_object param[2]; | 521 | union acpi_object param[2]; |
| 522 | struct acpi_object_list input; | 522 | struct acpi_object_list input; |
| 523 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, 0 }; | 523 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 524 | unsigned char *locs; | 524 | unsigned char *locs; |
| 525 | acpi_status status; | 525 | acpi_status status; |
| 526 | 526 | ||
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 7c21c1c44dfa..2a9afa261c61 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
| @@ -64,6 +64,7 @@ | |||
| 64 | #include <linux/acpi.h> | 64 | #include <linux/acpi.h> |
| 65 | #include <linux/dmi.h> | 65 | #include <linux/dmi.h> |
| 66 | #include <linux/backlight.h> | 66 | #include <linux/backlight.h> |
| 67 | #include <linux/fb.h> | ||
| 67 | #include <linux/input.h> | 68 | #include <linux/input.h> |
| 68 | #include <linux/kfifo.h> | 69 | #include <linux/kfifo.h> |
| 69 | #include <linux/platform_device.h> | 70 | #include <linux/platform_device.h> |
| @@ -398,7 +399,7 @@ static int bl_get_brightness(struct backlight_device *b) | |||
| 398 | static int bl_update_status(struct backlight_device *b) | 399 | static int bl_update_status(struct backlight_device *b) |
| 399 | { | 400 | { |
| 400 | int ret; | 401 | int ret; |
| 401 | if (b->props.power == 4) | 402 | if (b->props.power == FB_BLANK_POWERDOWN) |
| 402 | ret = call_fext_func(FUNC_BACKLIGHT, 0x1, 0x4, 0x3); | 403 | ret = call_fext_func(FUNC_BACKLIGHT, 0x1, 0x4, 0x3); |
| 403 | else | 404 | else |
| 404 | ret = call_fext_func(FUNC_BACKLIGHT, 0x1, 0x4, 0x0); | 405 | ret = call_fext_func(FUNC_BACKLIGHT, 0x1, 0x4, 0x0); |
| @@ -1139,9 +1140,9 @@ static int __init fujitsu_init(void) | |||
| 1139 | 1140 | ||
| 1140 | if (!acpi_video_backlight_support()) { | 1141 | if (!acpi_video_backlight_support()) { |
| 1141 | if (call_fext_func(FUNC_BACKLIGHT, 0x2, 0x4, 0x0) == 3) | 1142 | if (call_fext_func(FUNC_BACKLIGHT, 0x2, 0x4, 0x0) == 3) |
| 1142 | fujitsu->bl_device->props.power = 4; | 1143 | fujitsu->bl_device->props.power = FB_BLANK_POWERDOWN; |
| 1143 | else | 1144 | else |
| 1144 | fujitsu->bl_device->props.power = 0; | 1145 | fujitsu->bl_device->props.power = FB_BLANK_UNBLANK; |
| 1145 | } | 1146 | } |
| 1146 | 1147 | ||
| 1147 | pr_info("driver " FUJITSU_DRIVER_VERSION " successfully loaded\n"); | 1148 | pr_info("driver " FUJITSU_DRIVER_VERSION " successfully loaded\n"); |
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 66a4d3284aab..001b199a8c33 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism | 2 | * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism |
| 3 | * | 3 | * |
| 4 | * (C) Copyright 2008-2010 Intel Corporation | 4 | * (C) Copyright 2008-2010,2015 Intel Corporation |
| 5 | * Author: Sreedhara DS (sreedhara.ds@intel.com) | 5 | * Author: Sreedhara DS (sreedhara.ds@intel.com) |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
| @@ -43,10 +43,9 @@ | |||
| 43 | /* | 43 | /* |
| 44 | * IPC register summary | 44 | * IPC register summary |
| 45 | * | 45 | * |
| 46 | * IPC register blocks are memory mapped at fixed address of 0xFF11C000 | 46 | * IPC register blocks are memory mapped at fixed address of PCI BAR 0. |
| 47 | * To read or write information to the SCU, driver writes to IPC-1 memory | 47 | * To read or write information to the SCU, driver writes to IPC-1 memory |
| 48 | * mapped registers (base address 0xFF11C000). The following is the IPC | 48 | * mapped registers. The following is the IPC mechanism |
| 49 | * mechanism | ||
| 50 | * | 49 | * |
| 51 | * 1. IA core cDMI interface claims this transaction and converts it to a | 50 | * 1. IA core cDMI interface claims this transaction and converts it to a |
| 52 | * Transaction Layer Packet (TLP) message which is sent across the cDMI. | 51 | * Transaction Layer Packet (TLP) message which is sent across the cDMI. |
| @@ -67,36 +66,28 @@ | |||
| 67 | #define PCI_DEVICE_ID_CLOVERVIEW 0x08ea | 66 | #define PCI_DEVICE_ID_CLOVERVIEW 0x08ea |
| 68 | #define PCI_DEVICE_ID_TANGIER 0x11a0 | 67 | #define PCI_DEVICE_ID_TANGIER 0x11a0 |
| 69 | 68 | ||
| 70 | /* intel scu ipc driver data*/ | 69 | /* intel scu ipc driver data */ |
| 71 | struct intel_scu_ipc_pdata_t { | 70 | struct intel_scu_ipc_pdata_t { |
| 72 | u32 ipc_base; | ||
| 73 | u32 i2c_base; | 71 | u32 i2c_base; |
| 74 | u32 ipc_len; | ||
| 75 | u32 i2c_len; | 72 | u32 i2c_len; |
| 76 | u8 irq_mode; | 73 | u8 irq_mode; |
| 77 | }; | 74 | }; |
| 78 | 75 | ||
| 79 | static struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = { | 76 | static struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = { |
| 80 | .ipc_base = 0xff11c000, | ||
| 81 | .i2c_base = 0xff12b000, | 77 | .i2c_base = 0xff12b000, |
| 82 | .ipc_len = 0x100, | ||
| 83 | .i2c_len = 0x10, | 78 | .i2c_len = 0x10, |
| 84 | .irq_mode = 0, | 79 | .irq_mode = 0, |
| 85 | }; | 80 | }; |
| 86 | 81 | ||
| 87 | /* Penwell and Cloverview */ | 82 | /* Penwell and Cloverview */ |
| 88 | static struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = { | 83 | static struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = { |
| 89 | .ipc_base = 0xff11c000, | ||
| 90 | .i2c_base = 0xff12b000, | 84 | .i2c_base = 0xff12b000, |
| 91 | .ipc_len = 0x100, | ||
| 92 | .i2c_len = 0x10, | 85 | .i2c_len = 0x10, |
| 93 | .irq_mode = 1, | 86 | .irq_mode = 1, |
| 94 | }; | 87 | }; |
| 95 | 88 | ||
| 96 | static struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = { | 89 | static struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = { |
| 97 | .ipc_base = 0xff009000, | ||
| 98 | .i2c_base = 0xff00d000, | 90 | .i2c_base = 0xff00d000, |
| 99 | .ipc_len = 0x100, | ||
| 100 | .i2c_len = 0x10, | 91 | .i2c_len = 0x10, |
| 101 | .irq_mode = 0, | 92 | .irq_mode = 0, |
| 102 | }; | 93 | }; |
| @@ -114,8 +105,6 @@ struct intel_scu_ipc_dev { | |||
| 114 | 105 | ||
| 115 | static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ | 106 | static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ |
| 116 | 107 | ||
| 117 | static int platform; /* Platform type */ | ||
| 118 | |||
| 119 | /* | 108 | /* |
| 120 | * IPC Read Buffer (Read Only): | 109 | * IPC Read Buffer (Read Only): |
| 121 | * 16 byte buffer for receiving data from SCU, if IPC command | 110 | * 16 byte buffer for receiving data from SCU, if IPC command |
| @@ -160,7 +149,6 @@ static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */ | |||
| 160 | * Format: | 149 | * Format: |
| 161 | * |rfu3(8)|error code(8)|initiator id(8)|cmd id(4)|rfu1(2)|error(1)|busy(1)| | 150 | * |rfu3(8)|error code(8)|initiator id(8)|cmd id(4)|rfu1(2)|error(1)|busy(1)| |
| 162 | */ | 151 | */ |
| 163 | |||
| 164 | static inline u8 ipc_read_status(void) | 152 | static inline u8 ipc_read_status(void) |
| 165 | { | 153 | { |
| 166 | return __raw_readl(ipcdev.ipc_base + 0x04); | 154 | return __raw_readl(ipcdev.ipc_base + 0x04); |
| @@ -176,23 +164,24 @@ static inline u32 ipc_data_readl(u32 offset) /* Read ipc u32 data */ | |||
| 176 | return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); | 164 | return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); |
| 177 | } | 165 | } |
| 178 | 166 | ||
| 179 | static inline int busy_loop(void) /* Wait till scu status is busy */ | 167 | /* Wait till scu status is busy */ |
| 168 | static inline int busy_loop(void) | ||
| 180 | { | 169 | { |
| 181 | u32 status = 0; | 170 | u32 status = ipc_read_status(); |
| 182 | u32 loop_count = 0; | 171 | u32 loop_count = 100000; |
| 183 | 172 | ||
| 184 | status = ipc_read_status(); | 173 | /* break if scu doesn't reset busy bit after huge retry */ |
| 185 | while (status & 1) { | 174 | while ((status & BIT(0)) && --loop_count) { |
| 186 | udelay(1); /* scu processing time is in few u secods */ | 175 | udelay(1); /* scu processing time is in few u secods */ |
| 187 | status = ipc_read_status(); | 176 | status = ipc_read_status(); |
| 188 | loop_count++; | ||
| 189 | /* break if scu doesn't reset busy bit after huge retry */ | ||
| 190 | if (loop_count > 100000) { | ||
| 191 | dev_err(&ipcdev.pdev->dev, "IPC timed out"); | ||
| 192 | return -ETIMEDOUT; | ||
| 193 | } | ||
| 194 | } | 177 | } |
| 195 | if ((status >> 1) & 1) | 178 | |
| 179 | if (status & BIT(0)) { | ||
| 180 | dev_err(&ipcdev.pdev->dev, "IPC timed out"); | ||
| 181 | return -ETIMEDOUT; | ||
| 182 | } | ||
| 183 | |||
| 184 | if (status & BIT(1)) | ||
| 196 | return -EIO; | 185 | return -EIO; |
| 197 | 186 | ||
| 198 | return 0; | 187 | return 0; |
| @@ -210,14 +199,13 @@ static inline int ipc_wait_for_interrupt(void) | |||
| 210 | } | 199 | } |
| 211 | 200 | ||
| 212 | status = ipc_read_status(); | 201 | status = ipc_read_status(); |
| 213 | 202 | if (status & BIT(1)) | |
| 214 | if ((status >> 1) & 1) | ||
| 215 | return -EIO; | 203 | return -EIO; |
| 216 | 204 | ||
| 217 | return 0; | 205 | return 0; |
| 218 | } | 206 | } |
| 219 | 207 | ||
| 220 | int intel_scu_ipc_check_status(void) | 208 | static int intel_scu_ipc_check_status(void) |
| 221 | { | 209 | { |
| 222 | return ipcdev.irq_mode ? ipc_wait_for_interrupt() : busy_loop(); | 210 | return ipcdev.irq_mode ? ipc_wait_for_interrupt() : busy_loop(); |
| 223 | } | 211 | } |
| @@ -248,18 +236,18 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) | |||
| 248 | if (id == IPC_CMD_PCNTRL_R) { | 236 | if (id == IPC_CMD_PCNTRL_R) { |
| 249 | for (nc = 0, offset = 0; nc < count; nc++, offset += 4) | 237 | for (nc = 0, offset = 0; nc < count; nc++, offset += 4) |
| 250 | ipc_data_writel(wbuf[nc], offset); | 238 | ipc_data_writel(wbuf[nc], offset); |
| 251 | ipc_command((count*2) << 16 | id << 12 | 0 << 8 | op); | 239 | ipc_command((count * 2) << 16 | id << 12 | 0 << 8 | op); |
| 252 | } else if (id == IPC_CMD_PCNTRL_W) { | 240 | } else if (id == IPC_CMD_PCNTRL_W) { |
| 253 | for (nc = 0; nc < count; nc++, offset += 1) | 241 | for (nc = 0; nc < count; nc++, offset += 1) |
| 254 | cbuf[offset] = data[nc]; | 242 | cbuf[offset] = data[nc]; |
| 255 | for (nc = 0, offset = 0; nc < count; nc++, offset += 4) | 243 | for (nc = 0, offset = 0; nc < count; nc++, offset += 4) |
| 256 | ipc_data_writel(wbuf[nc], offset); | 244 | ipc_data_writel(wbuf[nc], offset); |
| 257 | ipc_command((count*3) << 16 | id << 12 | 0 << 8 | op); | 245 | ipc_command((count * 3) << 16 | id << 12 | 0 << 8 | op); |
| 258 | } else if (id == IPC_CMD_PCNTRL_M) { | 246 | } else if (id == IPC_CMD_PCNTRL_M) { |
| 259 | cbuf[offset] = data[0]; | 247 | cbuf[offset] = data[0]; |
| 260 | cbuf[offset + 1] = data[1]; | 248 | cbuf[offset + 1] = data[1]; |
| 261 | ipc_data_writel(wbuf[0], 0); /* Write wbuff */ | 249 | ipc_data_writel(wbuf[0], 0); /* Write wbuff */ |
| 262 | ipc_command(4 << 16 | id << 12 | 0 << 8 | op); | 250 | ipc_command(4 << 16 | id << 12 | 0 << 8 | op); |
| 263 | } | 251 | } |
| 264 | 252 | ||
| 265 | err = intel_scu_ipc_check_status(); | 253 | err = intel_scu_ipc_check_status(); |
| @@ -301,7 +289,7 @@ EXPORT_SYMBOL(intel_scu_ipc_ioread8); | |||
| 301 | */ | 289 | */ |
| 302 | int intel_scu_ipc_ioread16(u16 addr, u16 *data) | 290 | int intel_scu_ipc_ioread16(u16 addr, u16 *data) |
| 303 | { | 291 | { |
| 304 | u16 x[2] = {addr, addr + 1 }; | 292 | u16 x[2] = {addr, addr + 1}; |
| 305 | return pwr_reg_rdwr(x, (u8 *)data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); | 293 | return pwr_reg_rdwr(x, (u8 *)data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); |
| 306 | } | 294 | } |
| 307 | EXPORT_SYMBOL(intel_scu_ipc_ioread16); | 295 | EXPORT_SYMBOL(intel_scu_ipc_ioread16); |
| @@ -351,7 +339,7 @@ EXPORT_SYMBOL(intel_scu_ipc_iowrite8); | |||
| 351 | */ | 339 | */ |
| 352 | int intel_scu_ipc_iowrite16(u16 addr, u16 data) | 340 | int intel_scu_ipc_iowrite16(u16 addr, u16 data) |
| 353 | { | 341 | { |
| 354 | u16 x[2] = {addr, addr + 1 }; | 342 | u16 x[2] = {addr, addr + 1}; |
| 355 | return pwr_reg_rdwr(x, (u8 *)&data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); | 343 | return pwr_reg_rdwr(x, (u8 *)&data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); |
| 356 | } | 344 | } |
| 357 | EXPORT_SYMBOL(intel_scu_ipc_iowrite16); | 345 | EXPORT_SYMBOL(intel_scu_ipc_iowrite16); |
| @@ -412,7 +400,6 @@ int intel_scu_ipc_writev(u16 *addr, u8 *data, int len) | |||
| 412 | } | 400 | } |
| 413 | EXPORT_SYMBOL(intel_scu_ipc_writev); | 401 | EXPORT_SYMBOL(intel_scu_ipc_writev); |
| 414 | 402 | ||
| 415 | |||
| 416 | /** | 403 | /** |
| 417 | * intel_scu_ipc_update_register - r/m/w a register | 404 | * intel_scu_ipc_update_register - r/m/w a register |
| 418 | * @addr: register address | 405 | * @addr: register address |
| @@ -475,9 +462,8 @@ EXPORT_SYMBOL(intel_scu_ipc_simple_command); | |||
| 475 | * Issue a command to the SCU which involves data transfers. Do the | 462 | * Issue a command to the SCU which involves data transfers. Do the |
| 476 | * data copies under the lock but leave it for the caller to interpret | 463 | * data copies under the lock but leave it for the caller to interpret |
| 477 | */ | 464 | */ |
| 478 | |||
| 479 | int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, | 465 | int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, |
| 480 | u32 *out, int outlen) | 466 | u32 *out, int outlen) |
| 481 | { | 467 | { |
| 482 | int i, err; | 468 | int i, err; |
| 483 | 469 | ||
| @@ -503,7 +489,7 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, | |||
| 503 | } | 489 | } |
| 504 | EXPORT_SYMBOL(intel_scu_ipc_command); | 490 | EXPORT_SYMBOL(intel_scu_ipc_command); |
| 505 | 491 | ||
| 506 | /*I2C commands */ | 492 | /* I2C commands */ |
| 507 | #define IPC_I2C_WRITE 1 /* I2C Write command */ | 493 | #define IPC_I2C_WRITE 1 /* I2C Write command */ |
| 508 | #define IPC_I2C_READ 2 /* I2C Read command */ | 494 | #define IPC_I2C_READ 2 /* I2C Read command */ |
| 509 | 495 | ||
| @@ -577,7 +563,7 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 577 | { | 563 | { |
| 578 | int err; | 564 | int err; |
| 579 | struct intel_scu_ipc_pdata_t *pdata; | 565 | struct intel_scu_ipc_pdata_t *pdata; |
| 580 | resource_size_t pci_resource; | 566 | resource_size_t base; |
| 581 | 567 | ||
| 582 | if (ipcdev.pdev) /* We support only one SCU */ | 568 | if (ipcdev.pdev) /* We support only one SCU */ |
| 583 | return -EBUSY; | 569 | return -EBUSY; |
| @@ -595,8 +581,8 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 595 | if (err) | 581 | if (err) |
| 596 | return err; | 582 | return err; |
| 597 | 583 | ||
| 598 | pci_resource = pci_resource_start(dev, 0); | 584 | base = pci_resource_start(dev, 0); |
| 599 | if (!pci_resource) | 585 | if (!base) |
| 600 | return -ENOMEM; | 586 | return -ENOMEM; |
| 601 | 587 | ||
| 602 | init_completion(&ipcdev.cmd_complete); | 588 | init_completion(&ipcdev.cmd_complete); |
| @@ -604,7 +590,7 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 604 | if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev)) | 590 | if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev)) |
| 605 | return -EBUSY; | 591 | return -EBUSY; |
| 606 | 592 | ||
| 607 | ipcdev.ipc_base = ioremap_nocache(pdata->ipc_base, pdata->ipc_len); | 593 | ipcdev.ipc_base = ioremap_nocache(base, pci_resource_len(dev, 0)); |
| 608 | if (!ipcdev.ipc_base) | 594 | if (!ipcdev.ipc_base) |
| 609 | return -ENOMEM; | 595 | return -ENOMEM; |
| 610 | 596 | ||
| @@ -666,9 +652,10 @@ static struct pci_driver ipc_driver = { | |||
| 666 | .remove = ipc_remove, | 652 | .remove = ipc_remove, |
| 667 | }; | 653 | }; |
| 668 | 654 | ||
| 669 | |||
| 670 | static int __init intel_scu_ipc_init(void) | 655 | static int __init intel_scu_ipc_init(void) |
| 671 | { | 656 | { |
| 657 | int platform; /* Platform type */ | ||
| 658 | |||
| 672 | platform = intel_mid_identify_cpu(); | 659 | platform = intel_mid_identify_cpu(); |
| 673 | if (platform == 0) | 660 | if (platform == 0) |
| 674 | return -ENODEV; | 661 | return -ENODEV; |
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index ff765d8e1a09..9e701b2256f9 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c | |||
| @@ -124,6 +124,10 @@ struct sabi_commands { | |||
| 124 | u16 get_wireless_status; | 124 | u16 get_wireless_status; |
| 125 | u16 set_wireless_status; | 125 | u16 set_wireless_status; |
| 126 | 126 | ||
| 127 | /* 0x80 is off, 0x81 is on */ | ||
| 128 | u16 get_lid_handling; | ||
| 129 | u16 set_lid_handling; | ||
| 130 | |||
| 127 | /* 0x81 to read, (0x82 | level << 8) to set, 0xaabb to enable */ | 131 | /* 0x81 to read, (0x82 | level << 8) to set, 0xaabb to enable */ |
| 128 | u16 kbd_backlight; | 132 | u16 kbd_backlight; |
| 129 | 133 | ||
| @@ -194,6 +198,9 @@ static const struct sabi_config sabi_configs[] = { | |||
| 194 | .get_wireless_status = 0xFFFF, | 198 | .get_wireless_status = 0xFFFF, |
| 195 | .set_wireless_status = 0xFFFF, | 199 | .set_wireless_status = 0xFFFF, |
| 196 | 200 | ||
| 201 | .get_lid_handling = 0xFFFF, | ||
| 202 | .set_lid_handling = 0xFFFF, | ||
| 203 | |||
| 197 | .kbd_backlight = 0xFFFF, | 204 | .kbd_backlight = 0xFFFF, |
| 198 | 205 | ||
| 199 | .set_linux = 0x0a, | 206 | .set_linux = 0x0a, |
| @@ -254,6 +261,9 @@ static const struct sabi_config sabi_configs[] = { | |||
| 254 | .get_wireless_status = 0x69, | 261 | .get_wireless_status = 0x69, |
| 255 | .set_wireless_status = 0x6a, | 262 | .set_wireless_status = 0x6a, |
| 256 | 263 | ||
| 264 | .get_lid_handling = 0x6d, | ||
| 265 | .set_lid_handling = 0x6e, | ||
| 266 | |||
| 257 | .kbd_backlight = 0x78, | 267 | .kbd_backlight = 0x78, |
| 258 | 268 | ||
| 259 | .set_linux = 0xff, | 269 | .set_linux = 0xff, |
| @@ -353,6 +363,8 @@ struct samsung_quirks { | |||
| 353 | bool broken_acpi_video; | 363 | bool broken_acpi_video; |
| 354 | bool four_kbd_backlight_levels; | 364 | bool four_kbd_backlight_levels; |
| 355 | bool enable_kbd_backlight; | 365 | bool enable_kbd_backlight; |
| 366 | bool use_native_backlight; | ||
| 367 | bool lid_handling; | ||
| 356 | }; | 368 | }; |
| 357 | 369 | ||
| 358 | static struct samsung_quirks samsung_unknown = {}; | 370 | static struct samsung_quirks samsung_unknown = {}; |
| @@ -361,11 +373,19 @@ static struct samsung_quirks samsung_broken_acpi_video = { | |||
| 361 | .broken_acpi_video = true, | 373 | .broken_acpi_video = true, |
| 362 | }; | 374 | }; |
| 363 | 375 | ||
| 376 | static struct samsung_quirks samsung_use_native_backlight = { | ||
| 377 | .use_native_backlight = true, | ||
| 378 | }; | ||
| 379 | |||
| 364 | static struct samsung_quirks samsung_np740u3e = { | 380 | static struct samsung_quirks samsung_np740u3e = { |
| 365 | .four_kbd_backlight_levels = true, | 381 | .four_kbd_backlight_levels = true, |
| 366 | .enable_kbd_backlight = true, | 382 | .enable_kbd_backlight = true, |
| 367 | }; | 383 | }; |
| 368 | 384 | ||
| 385 | static struct samsung_quirks samsung_lid_handling = { | ||
| 386 | .lid_handling = true, | ||
| 387 | }; | ||
| 388 | |||
| 369 | static bool force; | 389 | static bool force; |
| 370 | module_param(force, bool, 0); | 390 | module_param(force, bool, 0); |
| 371 | MODULE_PARM_DESC(force, | 391 | MODULE_PARM_DESC(force, |
| @@ -748,7 +768,7 @@ static ssize_t set_battery_life_extender(struct device *dev, | |||
| 748 | struct samsung_laptop *samsung = dev_get_drvdata(dev); | 768 | struct samsung_laptop *samsung = dev_get_drvdata(dev); |
| 749 | int ret, value; | 769 | int ret, value; |
| 750 | 770 | ||
| 751 | if (!count || sscanf(buf, "%i", &value) != 1) | 771 | if (!count || kstrtoint(buf, 0, &value) != 0) |
| 752 | return -EINVAL; | 772 | return -EINVAL; |
| 753 | 773 | ||
| 754 | ret = write_battery_life_extender(samsung, !!value); | 774 | ret = write_battery_life_extender(samsung, !!value); |
| @@ -817,7 +837,7 @@ static ssize_t set_usb_charge(struct device *dev, | |||
| 817 | struct samsung_laptop *samsung = dev_get_drvdata(dev); | 837 | struct samsung_laptop *samsung = dev_get_drvdata(dev); |
| 818 | int ret, value; | 838 | int ret, value; |
| 819 | 839 | ||
| 820 | if (!count || sscanf(buf, "%i", &value) != 1) | 840 | if (!count || kstrtoint(buf, 0, &value) != 0) |
| 821 | return -EINVAL; | 841 | return -EINVAL; |
| 822 | 842 | ||
| 823 | ret = write_usb_charge(samsung, !!value); | 843 | ret = write_usb_charge(samsung, !!value); |
| @@ -830,10 +850,76 @@ static ssize_t set_usb_charge(struct device *dev, | |||
| 830 | static DEVICE_ATTR(usb_charge, S_IWUSR | S_IRUGO, | 850 | static DEVICE_ATTR(usb_charge, S_IWUSR | S_IRUGO, |
| 831 | get_usb_charge, set_usb_charge); | 851 | get_usb_charge, set_usb_charge); |
| 832 | 852 | ||
| 853 | static int read_lid_handling(struct samsung_laptop *samsung) | ||
| 854 | { | ||
| 855 | const struct sabi_commands *commands = &samsung->config->commands; | ||
| 856 | struct sabi_data data; | ||
| 857 | int retval; | ||
| 858 | |||
| 859 | if (commands->get_lid_handling == 0xFFFF) | ||
| 860 | return -ENODEV; | ||
| 861 | |||
| 862 | memset(&data, 0, sizeof(data)); | ||
| 863 | retval = sabi_command(samsung, commands->get_lid_handling, | ||
| 864 | &data, &data); | ||
| 865 | |||
| 866 | if (retval) | ||
| 867 | return retval; | ||
| 868 | |||
| 869 | return data.data[0] & 0x1; | ||
| 870 | } | ||
| 871 | |||
| 872 | static int write_lid_handling(struct samsung_laptop *samsung, | ||
| 873 | int enabled) | ||
| 874 | { | ||
| 875 | const struct sabi_commands *commands = &samsung->config->commands; | ||
| 876 | struct sabi_data data; | ||
| 877 | |||
| 878 | memset(&data, 0, sizeof(data)); | ||
| 879 | data.data[0] = 0x80 | enabled; | ||
| 880 | return sabi_command(samsung, commands->set_lid_handling, | ||
| 881 | &data, NULL); | ||
| 882 | } | ||
| 883 | |||
| 884 | static ssize_t get_lid_handling(struct device *dev, | ||
| 885 | struct device_attribute *attr, | ||
| 886 | char *buf) | ||
| 887 | { | ||
| 888 | struct samsung_laptop *samsung = dev_get_drvdata(dev); | ||
| 889 | int ret; | ||
| 890 | |||
| 891 | ret = read_lid_handling(samsung); | ||
| 892 | if (ret < 0) | ||
| 893 | return ret; | ||
| 894 | |||
| 895 | return sprintf(buf, "%d\n", ret); | ||
| 896 | } | ||
| 897 | |||
| 898 | static ssize_t set_lid_handling(struct device *dev, | ||
| 899 | struct device_attribute *attr, | ||
| 900 | const char *buf, size_t count) | ||
| 901 | { | ||
| 902 | struct samsung_laptop *samsung = dev_get_drvdata(dev); | ||
| 903 | int ret, value; | ||
| 904 | |||
| 905 | if (!count || kstrtoint(buf, 0, &value) != 0) | ||
| 906 | return -EINVAL; | ||
| 907 | |||
| 908 | ret = write_lid_handling(samsung, !!value); | ||
| 909 | if (ret < 0) | ||
| 910 | return ret; | ||
| 911 | |||
| 912 | return count; | ||
| 913 | } | ||
| 914 | |||
| 915 | static DEVICE_ATTR(lid_handling, S_IWUSR | S_IRUGO, | ||
| 916 | get_lid_handling, set_lid_handling); | ||
| 917 | |||
| 833 | static struct attribute *platform_attributes[] = { | 918 | static struct attribute *platform_attributes[] = { |
| 834 | &dev_attr_performance_level.attr, | 919 | &dev_attr_performance_level.attr, |
| 835 | &dev_attr_battery_life_extender.attr, | 920 | &dev_attr_battery_life_extender.attr, |
| 836 | &dev_attr_usb_charge.attr, | 921 | &dev_attr_usb_charge.attr, |
| 922 | &dev_attr_lid_handling.attr, | ||
| 837 | NULL | 923 | NULL |
| 838 | }; | 924 | }; |
| 839 | 925 | ||
| @@ -956,6 +1042,22 @@ static int __init samsung_rfkill_init(struct samsung_laptop *samsung) | |||
| 956 | return 0; | 1042 | return 0; |
| 957 | } | 1043 | } |
| 958 | 1044 | ||
| 1045 | static void samsung_lid_handling_exit(struct samsung_laptop *samsung) | ||
| 1046 | { | ||
| 1047 | if (samsung->quirks->lid_handling) | ||
| 1048 | write_lid_handling(samsung, 0); | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | static int __init samsung_lid_handling_init(struct samsung_laptop *samsung) | ||
| 1052 | { | ||
| 1053 | int retval = 0; | ||
| 1054 | |||
| 1055 | if (samsung->quirks->lid_handling) | ||
| 1056 | retval = write_lid_handling(samsung, 1); | ||
| 1057 | |||
| 1058 | return retval; | ||
| 1059 | } | ||
| 1060 | |||
| 959 | static int kbd_backlight_enable(struct samsung_laptop *samsung) | 1061 | static int kbd_backlight_enable(struct samsung_laptop *samsung) |
| 960 | { | 1062 | { |
| 961 | const struct sabi_commands *commands = &samsung->config->commands; | 1063 | const struct sabi_commands *commands = &samsung->config->commands; |
| @@ -1111,7 +1213,7 @@ static int __init samsung_backlight_init(struct samsung_laptop *samsung) | |||
| 1111 | } | 1213 | } |
| 1112 | 1214 | ||
| 1113 | static umode_t samsung_sysfs_is_visible(struct kobject *kobj, | 1215 | static umode_t samsung_sysfs_is_visible(struct kobject *kobj, |
| 1114 | struct attribute *attr, int idx) | 1216 | struct attribute *attr, int idx) |
| 1115 | { | 1217 | { |
| 1116 | struct device *dev = container_of(kobj, struct device, kobj); | 1218 | struct device *dev = container_of(kobj, struct device, kobj); |
| 1117 | struct platform_device *pdev = to_platform_device(dev); | 1219 | struct platform_device *pdev = to_platform_device(dev); |
| @@ -1124,6 +1226,8 @@ static umode_t samsung_sysfs_is_visible(struct kobject *kobj, | |||
| 1124 | ok = !!(read_battery_life_extender(samsung) >= 0); | 1226 | ok = !!(read_battery_life_extender(samsung) >= 0); |
| 1125 | if (attr == &dev_attr_usb_charge.attr) | 1227 | if (attr == &dev_attr_usb_charge.attr) |
| 1126 | ok = !!(read_usb_charge(samsung) >= 0); | 1228 | ok = !!(read_usb_charge(samsung) >= 0); |
| 1229 | if (attr == &dev_attr_lid_handling.attr) | ||
| 1230 | ok = !!(read_lid_handling(samsung) >= 0); | ||
| 1127 | 1231 | ||
| 1128 | return ok ? attr->mode : 0; | 1232 | return ok ? attr->mode : 0; |
| 1129 | } | 1233 | } |
| @@ -1357,7 +1461,7 @@ static int __init samsung_sabi_init(struct samsung_laptop *samsung) | |||
| 1357 | samsung_sabi_diag(samsung); | 1461 | samsung_sabi_diag(samsung); |
| 1358 | 1462 | ||
| 1359 | /* Try to find one of the signatures in memory to find the header */ | 1463 | /* Try to find one of the signatures in memory to find the header */ |
| 1360 | for (i = 0; sabi_configs[i].test_string != 0; ++i) { | 1464 | for (i = 0; sabi_configs[i].test_string != NULL; ++i) { |
| 1361 | samsung->config = &sabi_configs[i]; | 1465 | samsung->config = &sabi_configs[i]; |
| 1362 | loca = find_signature(samsung->f0000_segment, | 1466 | loca = find_signature(samsung->f0000_segment, |
| 1363 | samsung->config->test_string); | 1467 | samsung->config->test_string); |
| @@ -1436,6 +1540,9 @@ static int samsung_pm_notification(struct notifier_block *nb, | |||
| 1436 | samsung->quirks->enable_kbd_backlight) | 1540 | samsung->quirks->enable_kbd_backlight) |
| 1437 | kbd_backlight_enable(samsung); | 1541 | kbd_backlight_enable(samsung); |
| 1438 | 1542 | ||
| 1543 | if (val == PM_POST_HIBERNATION && samsung->quirks->lid_handling) | ||
| 1544 | write_lid_handling(samsung, 1); | ||
| 1545 | |||
| 1439 | return 0; | 1546 | return 0; |
| 1440 | } | 1547 | } |
| 1441 | 1548 | ||
| @@ -1507,7 +1614,7 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { | |||
| 1507 | DMI_MATCH(DMI_PRODUCT_NAME, "N150P"), | 1614 | DMI_MATCH(DMI_PRODUCT_NAME, "N150P"), |
| 1508 | DMI_MATCH(DMI_BOARD_NAME, "N150P"), | 1615 | DMI_MATCH(DMI_BOARD_NAME, "N150P"), |
| 1509 | }, | 1616 | }, |
| 1510 | .driver_data = &samsung_broken_acpi_video, | 1617 | .driver_data = &samsung_use_native_backlight, |
| 1511 | }, | 1618 | }, |
| 1512 | { | 1619 | { |
| 1513 | .callback = samsung_dmi_matched, | 1620 | .callback = samsung_dmi_matched, |
| @@ -1517,7 +1624,7 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { | |||
| 1517 | DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"), | 1624 | DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"), |
| 1518 | DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"), | 1625 | DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"), |
| 1519 | }, | 1626 | }, |
| 1520 | .driver_data = &samsung_broken_acpi_video, | 1627 | .driver_data = &samsung_use_native_backlight, |
| 1521 | }, | 1628 | }, |
| 1522 | { | 1629 | { |
| 1523 | .callback = samsung_dmi_matched, | 1630 | .callback = samsung_dmi_matched, |
| @@ -1557,7 +1664,7 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { | |||
| 1557 | DMI_MATCH(DMI_PRODUCT_NAME, "N250P"), | 1664 | DMI_MATCH(DMI_PRODUCT_NAME, "N250P"), |
| 1558 | DMI_MATCH(DMI_BOARD_NAME, "N250P"), | 1665 | DMI_MATCH(DMI_BOARD_NAME, "N250P"), |
| 1559 | }, | 1666 | }, |
| 1560 | .driver_data = &samsung_broken_acpi_video, | 1667 | .driver_data = &samsung_use_native_backlight, |
| 1561 | }, | 1668 | }, |
| 1562 | { | 1669 | { |
| 1563 | .callback = samsung_dmi_matched, | 1670 | .callback = samsung_dmi_matched, |
| @@ -1578,6 +1685,15 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { | |||
| 1578 | }, | 1685 | }, |
| 1579 | .driver_data = &samsung_np740u3e, | 1686 | .driver_data = &samsung_np740u3e, |
| 1580 | }, | 1687 | }, |
| 1688 | { | ||
| 1689 | .callback = samsung_dmi_matched, | ||
| 1690 | .ident = "300V3Z/300V4Z/300V5Z", | ||
| 1691 | .matches = { | ||
| 1692 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
| 1693 | DMI_MATCH(DMI_PRODUCT_NAME, "300V3Z/300V4Z/300V5Z"), | ||
| 1694 | }, | ||
| 1695 | .driver_data = &samsung_lid_handling, | ||
| 1696 | }, | ||
| 1581 | { }, | 1697 | { }, |
| 1582 | }; | 1698 | }; |
| 1583 | MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); | 1699 | MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); |
| @@ -1616,6 +1732,15 @@ static int __init samsung_init(void) | |||
| 1616 | pr_info("Disabling ACPI video driver\n"); | 1732 | pr_info("Disabling ACPI video driver\n"); |
| 1617 | acpi_video_unregister(); | 1733 | acpi_video_unregister(); |
| 1618 | } | 1734 | } |
| 1735 | |||
| 1736 | if (samsung->quirks->use_native_backlight) { | ||
| 1737 | pr_info("Using native backlight driver\n"); | ||
| 1738 | /* Tell acpi-video to not handle the backlight */ | ||
| 1739 | acpi_video_dmi_promote_vendor(); | ||
| 1740 | acpi_video_unregister(); | ||
| 1741 | /* And also do not handle it ourselves */ | ||
| 1742 | samsung->handle_backlight = false; | ||
| 1743 | } | ||
| 1619 | #endif | 1744 | #endif |
| 1620 | 1745 | ||
| 1621 | ret = samsung_platform_init(samsung); | 1746 | ret = samsung_platform_init(samsung); |
| @@ -1648,6 +1773,10 @@ static int __init samsung_init(void) | |||
| 1648 | if (ret) | 1773 | if (ret) |
| 1649 | goto error_leds; | 1774 | goto error_leds; |
| 1650 | 1775 | ||
| 1776 | ret = samsung_lid_handling_init(samsung); | ||
| 1777 | if (ret) | ||
| 1778 | goto error_lid_handling; | ||
| 1779 | |||
| 1651 | ret = samsung_debugfs_init(samsung); | 1780 | ret = samsung_debugfs_init(samsung); |
| 1652 | if (ret) | 1781 | if (ret) |
| 1653 | goto error_debugfs; | 1782 | goto error_debugfs; |
| @@ -1659,6 +1788,8 @@ static int __init samsung_init(void) | |||
| 1659 | return ret; | 1788 | return ret; |
| 1660 | 1789 | ||
| 1661 | error_debugfs: | 1790 | error_debugfs: |
| 1791 | samsung_lid_handling_exit(samsung); | ||
| 1792 | error_lid_handling: | ||
| 1662 | samsung_leds_exit(samsung); | 1793 | samsung_leds_exit(samsung); |
| 1663 | error_leds: | 1794 | error_leds: |
| 1664 | samsung_rfkill_exit(samsung); | 1795 | samsung_rfkill_exit(samsung); |
| @@ -1683,6 +1814,7 @@ static void __exit samsung_exit(void) | |||
| 1683 | unregister_pm_notifier(&samsung->pm_nb); | 1814 | unregister_pm_notifier(&samsung->pm_nb); |
| 1684 | 1815 | ||
| 1685 | samsung_debugfs_exit(samsung); | 1816 | samsung_debugfs_exit(samsung); |
| 1817 | samsung_lid_handling_exit(samsung); | ||
| 1686 | samsung_leds_exit(samsung); | 1818 | samsung_leds_exit(samsung); |
| 1687 | samsung_rfkill_exit(samsung); | 1819 | samsung_rfkill_exit(samsung); |
| 1688 | samsung_backlight_exit(samsung); | 1820 | samsung_backlight_exit(samsung); |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 6dd1c0e7dcd9..e51c1e753607 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
| @@ -1032,7 +1032,7 @@ struct sony_backlight_props { | |||
| 1032 | u8 offset; | 1032 | u8 offset; |
| 1033 | u8 maxlvl; | 1033 | u8 maxlvl; |
| 1034 | }; | 1034 | }; |
| 1035 | struct sony_backlight_props sony_bl_props; | 1035 | static struct sony_backlight_props sony_bl_props; |
| 1036 | 1036 | ||
| 1037 | static int sony_backlight_update_status(struct backlight_device *bd) | 1037 | static int sony_backlight_update_status(struct backlight_device *bd) |
| 1038 | { | 1038 | { |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index c3d11fabc46f..3b8ceee7c5cb 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
| @@ -196,6 +196,7 @@ enum tpacpi_hkey_event_t { | |||
| 196 | /* Key-related user-interface events */ | 196 | /* Key-related user-interface events */ |
| 197 | TP_HKEY_EV_KEY_NUMLOCK = 0x6000, /* NumLock key pressed */ | 197 | TP_HKEY_EV_KEY_NUMLOCK = 0x6000, /* NumLock key pressed */ |
| 198 | TP_HKEY_EV_KEY_FN = 0x6005, /* Fn key pressed? E420 */ | 198 | TP_HKEY_EV_KEY_FN = 0x6005, /* Fn key pressed? E420 */ |
| 199 | TP_HKEY_EV_KEY_FN_ESC = 0x6060, /* Fn+Esc key pressed X240 */ | ||
| 199 | 200 | ||
| 200 | /* Thermal events */ | 201 | /* Thermal events */ |
| 201 | TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ | 202 | TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ |
| @@ -3456,7 +3457,7 @@ enum ADAPTIVE_KEY_MODE { | |||
| 3456 | LAYFLAT_MODE | 3457 | LAYFLAT_MODE |
| 3457 | }; | 3458 | }; |
| 3458 | 3459 | ||
| 3459 | const int adaptive_keyboard_modes[] = { | 3460 | static const int adaptive_keyboard_modes[] = { |
| 3460 | HOME_MODE, | 3461 | HOME_MODE, |
| 3461 | /* WEB_BROWSER_MODE = 2, | 3462 | /* WEB_BROWSER_MODE = 2, |
| 3462 | WEB_CONFERENCE_MODE = 3, */ | 3463 | WEB_CONFERENCE_MODE = 3, */ |
| @@ -3712,6 +3713,7 @@ static bool hotkey_notify_6xxx(const u32 hkey, | |||
| 3712 | 3713 | ||
| 3713 | case TP_HKEY_EV_KEY_NUMLOCK: | 3714 | case TP_HKEY_EV_KEY_NUMLOCK: |
| 3714 | case TP_HKEY_EV_KEY_FN: | 3715 | case TP_HKEY_EV_KEY_FN: |
| 3716 | case TP_HKEY_EV_KEY_FN_ESC: | ||
| 3715 | /* key press events, we just ignore them as long as the EC | 3717 | /* key press events, we just ignore them as long as the EC |
| 3716 | * is still reporting them in the normal keyboard stream */ | 3718 | * is still reporting them in the normal keyboard stream */ |
| 3717 | *send_acpi_ev = false; | 3719 | *send_acpi_ev = false; |
| @@ -8883,17 +8885,31 @@ static bool __pure __init tpacpi_is_fw_digit(const char c) | |||
| 8883 | return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'); | 8885 | return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'); |
| 8884 | } | 8886 | } |
| 8885 | 8887 | ||
| 8886 | /* Most models: xxyTkkWW (#.##c); Ancient 570/600 and -SL lacks (#.##c) */ | ||
| 8887 | static bool __pure __init tpacpi_is_valid_fw_id(const char * const s, | 8888 | static bool __pure __init tpacpi_is_valid_fw_id(const char * const s, |
| 8888 | const char t) | 8889 | const char t) |
| 8889 | { | 8890 | { |
| 8890 | return s && strlen(s) >= 8 && | 8891 | /* |
| 8892 | * Most models: xxyTkkWW (#.##c) | ||
| 8893 | * Ancient 570/600 and -SL lacks (#.##c) | ||
| 8894 | */ | ||
| 8895 | if (s && strlen(s) >= 8 && | ||
| 8891 | tpacpi_is_fw_digit(s[0]) && | 8896 | tpacpi_is_fw_digit(s[0]) && |
| 8892 | tpacpi_is_fw_digit(s[1]) && | 8897 | tpacpi_is_fw_digit(s[1]) && |
| 8893 | s[2] == t && | 8898 | s[2] == t && |
| 8894 | (s[3] == 'T' || s[3] == 'N') && | 8899 | (s[3] == 'T' || s[3] == 'N') && |
| 8895 | tpacpi_is_fw_digit(s[4]) && | 8900 | tpacpi_is_fw_digit(s[4]) && |
| 8896 | tpacpi_is_fw_digit(s[5]); | 8901 | tpacpi_is_fw_digit(s[5])) |
| 8902 | return true; | ||
| 8903 | |||
| 8904 | /* New models: xxxyTkkW (#.##c); T550 and some others */ | ||
| 8905 | return s && strlen(s) >= 8 && | ||
| 8906 | tpacpi_is_fw_digit(s[0]) && | ||
| 8907 | tpacpi_is_fw_digit(s[1]) && | ||
| 8908 | tpacpi_is_fw_digit(s[2]) && | ||
| 8909 | s[3] == t && | ||
| 8910 | (s[4] == 'T' || s[4] == 'N') && | ||
| 8911 | tpacpi_is_fw_digit(s[5]) && | ||
| 8912 | tpacpi_is_fw_digit(s[6]); | ||
| 8897 | } | 8913 | } |
| 8898 | 8914 | ||
| 8899 | /* returns 0 - probe ok, or < 0 - probe error. | 8915 | /* returns 0 - probe ok, or < 0 - probe error. |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index fc34a71866ed..dbcb7a8915b8 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
| @@ -1,11 +1,10 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * toshiba_acpi.c - Toshiba Laptop ACPI Extras | 2 | * toshiba_acpi.c - Toshiba Laptop ACPI Extras |
| 3 | * | 3 | * |
| 4 | * | ||
| 5 | * Copyright (C) 2002-2004 John Belmonte | 4 | * Copyright (C) 2002-2004 John Belmonte |
| 6 | * Copyright (C) 2008 Philip Langdale | 5 | * Copyright (C) 2008 Philip Langdale |
| 7 | * Copyright (C) 2010 Pierre Ducroquet | 6 | * Copyright (C) 2010 Pierre Ducroquet |
| 8 | * Copyright (C) 2014 Azael Avalos | 7 | * Copyright (C) 2014-2015 Azael Avalos |
| 9 | * | 8 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -17,10 +16,8 @@ | |||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
| 19 | * | 18 | * |
| 20 | * You should have received a copy of the GNU General Public License | 19 | * The full GNU General Public License is included in this distribution in |
| 21 | * along with this program; if not, write to the Free Software | 20 | * the file called "COPYING". |
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 23 | * | ||
| 24 | * | 21 | * |
| 25 | * The devolpment page for this driver is located at | 22 | * The devolpment page for this driver is located at |
| 26 | * http://memebeam.org/toys/ToshibaAcpiDriver. | 23 | * http://memebeam.org/toys/ToshibaAcpiDriver. |
| @@ -30,15 +27,11 @@ | |||
| 30 | * engineering the Windows drivers | 27 | * engineering the Windows drivers |
| 31 | * Yasushi Nagato - changes for linux kernel 2.4 -> 2.5 | 28 | * Yasushi Nagato - changes for linux kernel 2.4 -> 2.5 |
| 32 | * Rob Miller - TV out and hotkeys help | 29 | * Rob Miller - TV out and hotkeys help |
| 33 | * | ||
| 34 | * | ||
| 35 | * TODO | ||
| 36 | * | ||
| 37 | */ | 30 | */ |
| 38 | 31 | ||
| 39 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 32 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 40 | 33 | ||
| 41 | #define TOSHIBA_ACPI_VERSION "0.20" | 34 | #define TOSHIBA_ACPI_VERSION "0.21" |
| 42 | #define PROC_INTERFACE_VERSION 1 | 35 | #define PROC_INTERFACE_VERSION 1 |
| 43 | 36 | ||
| 44 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
| @@ -57,7 +50,7 @@ | |||
| 57 | #include <linux/i8042.h> | 50 | #include <linux/i8042.h> |
| 58 | #include <linux/acpi.h> | 51 | #include <linux/acpi.h> |
| 59 | #include <linux/dmi.h> | 52 | #include <linux/dmi.h> |
| 60 | #include <asm/uaccess.h> | 53 | #include <linux/uaccess.h> |
| 61 | 54 | ||
| 62 | MODULE_AUTHOR("John Belmonte"); | 55 | MODULE_AUTHOR("John Belmonte"); |
| 63 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); | 56 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); |
| @@ -71,7 +64,8 @@ MODULE_LICENSE("GPL"); | |||
| 71 | /* Toshiba ACPI method paths */ | 64 | /* Toshiba ACPI method paths */ |
| 72 | #define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" | 65 | #define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" |
| 73 | 66 | ||
| 74 | /* The Toshiba configuration interface is composed of the HCI and the SCI, | 67 | /* |
| 68 | * The Toshiba configuration interface is composed of the HCI and the SCI, | ||
| 75 | * which are defined as follows: | 69 | * which are defined as follows: |
| 76 | * | 70 | * |
| 77 | * HCI is Toshiba's "Hardware Control Interface" which is supposed to | 71 | * HCI is Toshiba's "Hardware Control Interface" which is supposed to |
| @@ -108,6 +102,7 @@ MODULE_LICENSE("GPL"); | |||
| 108 | #define TOS_FIFO_EMPTY 0x8c00 | 102 | #define TOS_FIFO_EMPTY 0x8c00 |
| 109 | #define TOS_DATA_NOT_AVAILABLE 0x8d20 | 103 | #define TOS_DATA_NOT_AVAILABLE 0x8d20 |
| 110 | #define TOS_NOT_INITIALIZED 0x8d50 | 104 | #define TOS_NOT_INITIALIZED 0x8d50 |
| 105 | #define TOS_NOT_INSTALLED 0x8e00 | ||
| 111 | 106 | ||
| 112 | /* registers */ | 107 | /* registers */ |
| 113 | #define HCI_FAN 0x0004 | 108 | #define HCI_FAN 0x0004 |
| @@ -121,9 +116,14 @@ MODULE_LICENSE("GPL"); | |||
| 121 | #define HCI_KBD_ILLUMINATION 0x0095 | 116 | #define HCI_KBD_ILLUMINATION 0x0095 |
| 122 | #define HCI_ECO_MODE 0x0097 | 117 | #define HCI_ECO_MODE 0x0097 |
| 123 | #define HCI_ACCELEROMETER2 0x00a6 | 118 | #define HCI_ACCELEROMETER2 0x00a6 |
| 119 | #define SCI_PANEL_POWER_ON 0x010d | ||
| 124 | #define SCI_ILLUMINATION 0x014e | 120 | #define SCI_ILLUMINATION 0x014e |
| 121 | #define SCI_USB_SLEEP_CHARGE 0x0150 | ||
| 125 | #define SCI_KBD_ILLUM_STATUS 0x015c | 122 | #define SCI_KBD_ILLUM_STATUS 0x015c |
| 123 | #define SCI_USB_SLEEP_MUSIC 0x015e | ||
| 124 | #define SCI_USB_THREE 0x0169 | ||
| 126 | #define SCI_TOUCHPAD 0x050e | 125 | #define SCI_TOUCHPAD 0x050e |
| 126 | #define SCI_KBD_FUNCTION_KEYS 0x0522 | ||
| 127 | 127 | ||
| 128 | /* field definitions */ | 128 | /* field definitions */ |
| 129 | #define HCI_ACCEL_MASK 0x7fff | 129 | #define HCI_ACCEL_MASK 0x7fff |
| @@ -146,6 +146,15 @@ MODULE_LICENSE("GPL"); | |||
| 146 | #define SCI_KBD_MODE_ON 0x8 | 146 | #define SCI_KBD_MODE_ON 0x8 |
| 147 | #define SCI_KBD_MODE_OFF 0x10 | 147 | #define SCI_KBD_MODE_OFF 0x10 |
| 148 | #define SCI_KBD_TIME_MAX 0x3c001a | 148 | #define SCI_KBD_TIME_MAX 0x3c001a |
| 149 | #define SCI_USB_CHARGE_MODE_MASK 0xff | ||
| 150 | #define SCI_USB_CHARGE_DISABLED 0x30000 | ||
| 151 | #define SCI_USB_CHARGE_ALTERNATE 0x30009 | ||
| 152 | #define SCI_USB_CHARGE_AUTO 0x30021 | ||
| 153 | #define SCI_USB_CHARGE_BAT_MASK 0x7 | ||
| 154 | #define SCI_USB_CHARGE_BAT_LVL_OFF 0x1 | ||
| 155 | #define SCI_USB_CHARGE_BAT_LVL_ON 0x4 | ||
| 156 | #define SCI_USB_CHARGE_BAT_LVL 0x0200 | ||
| 157 | #define SCI_USB_CHARGE_RAPID_DSP 0x0300 | ||
| 149 | 158 | ||
| 150 | struct toshiba_acpi_dev { | 159 | struct toshiba_acpi_dev { |
| 151 | struct acpi_device *acpi_dev; | 160 | struct acpi_device *acpi_dev; |
| @@ -164,6 +173,7 @@ struct toshiba_acpi_dev { | |||
| 164 | int kbd_type; | 173 | int kbd_type; |
| 165 | int kbd_mode; | 174 | int kbd_mode; |
| 166 | int kbd_time; | 175 | int kbd_time; |
| 176 | int usbsc_bat_level; | ||
| 167 | 177 | ||
| 168 | unsigned int illumination_supported:1; | 178 | unsigned int illumination_supported:1; |
| 169 | unsigned int video_supported:1; | 179 | unsigned int video_supported:1; |
| @@ -177,6 +187,12 @@ struct toshiba_acpi_dev { | |||
| 177 | unsigned int touchpad_supported:1; | 187 | unsigned int touchpad_supported:1; |
| 178 | unsigned int eco_supported:1; | 188 | unsigned int eco_supported:1; |
| 179 | unsigned int accelerometer_supported:1; | 189 | unsigned int accelerometer_supported:1; |
| 190 | unsigned int usb_sleep_charge_supported:1; | ||
| 191 | unsigned int usb_rapid_charge_supported:1; | ||
| 192 | unsigned int usb_sleep_music_supported:1; | ||
| 193 | unsigned int kbd_function_keys_supported:1; | ||
| 194 | unsigned int panel_power_on_supported:1; | ||
| 195 | unsigned int usb_three_supported:1; | ||
| 180 | unsigned int sysfs_created:1; | 196 | unsigned int sysfs_created:1; |
| 181 | 197 | ||
| 182 | struct mutex mutex; | 198 | struct mutex mutex; |
| @@ -264,15 +280,17 @@ static const struct key_entry toshiba_acpi_alt_keymap[] = { | |||
| 264 | { KE_END, 0 }, | 280 | { KE_END, 0 }, |
| 265 | }; | 281 | }; |
| 266 | 282 | ||
| 267 | /* utility | 283 | /* |
| 284 | * Utility | ||
| 268 | */ | 285 | */ |
| 269 | 286 | ||
| 270 | static __inline__ void _set_bit(u32 * word, u32 mask, int value) | 287 | static inline void _set_bit(u32 *word, u32 mask, int value) |
| 271 | { | 288 | { |
| 272 | *word = (*word & ~mask) | (mask * value); | 289 | *word = (*word & ~mask) | (mask * value); |
| 273 | } | 290 | } |
| 274 | 291 | ||
| 275 | /* acpi interface wrappers | 292 | /* |
| 293 | * ACPI interface wrappers | ||
| 276 | */ | 294 | */ |
| 277 | 295 | ||
| 278 | static int write_acpi_int(const char *methodName, int val) | 296 | static int write_acpi_int(const char *methodName, int val) |
| @@ -283,7 +301,8 @@ static int write_acpi_int(const char *methodName, int val) | |||
| 283 | return (status == AE_OK) ? 0 : -EIO; | 301 | return (status == AE_OK) ? 0 : -EIO; |
| 284 | } | 302 | } |
| 285 | 303 | ||
| 286 | /* Perform a raw configuration call. Here we don't care about input or output | 304 | /* |
| 305 | * Perform a raw configuration call. Here we don't care about input or output | ||
| 287 | * buffer format. | 306 | * buffer format. |
| 288 | */ | 307 | */ |
| 289 | static acpi_status tci_raw(struct toshiba_acpi_dev *dev, | 308 | static acpi_status tci_raw(struct toshiba_acpi_dev *dev, |
| @@ -310,15 +329,15 @@ static acpi_status tci_raw(struct toshiba_acpi_dev *dev, | |||
| 310 | (char *)dev->method_hci, ¶ms, | 329 | (char *)dev->method_hci, ¶ms, |
| 311 | &results); | 330 | &results); |
| 312 | if ((status == AE_OK) && (out_objs->package.count <= TCI_WORDS)) { | 331 | if ((status == AE_OK) && (out_objs->package.count <= TCI_WORDS)) { |
| 313 | for (i = 0; i < out_objs->package.count; ++i) { | 332 | for (i = 0; i < out_objs->package.count; ++i) |
| 314 | out[i] = out_objs->package.elements[i].integer.value; | 333 | out[i] = out_objs->package.elements[i].integer.value; |
| 315 | } | ||
| 316 | } | 334 | } |
| 317 | 335 | ||
| 318 | return status; | 336 | return status; |
| 319 | } | 337 | } |
| 320 | 338 | ||
| 321 | /* common hci tasks (get or set one or two value) | 339 | /* |
| 340 | * Common hci tasks (get or set one or two value) | ||
| 322 | * | 341 | * |
| 323 | * In addition to the ACPI status, the HCI system returns a result which | 342 | * In addition to the ACPI status, the HCI system returns a result which |
| 324 | * may be useful (such as "not supported"). | 343 | * may be useful (such as "not supported"). |
| @@ -338,6 +357,7 @@ static u32 hci_read1(struct toshiba_acpi_dev *dev, u32 reg, u32 *out1) | |||
| 338 | u32 in[TCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 }; | 357 | u32 in[TCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 }; |
| 339 | u32 out[TCI_WORDS]; | 358 | u32 out[TCI_WORDS]; |
| 340 | acpi_status status = tci_raw(dev, in, out); | 359 | acpi_status status = tci_raw(dev, in, out); |
| 360 | |||
| 341 | if (ACPI_FAILURE(status)) | 361 | if (ACPI_FAILURE(status)) |
| 342 | return TOS_FAILURE; | 362 | return TOS_FAILURE; |
| 343 | 363 | ||
| @@ -355,11 +375,13 @@ static u32 hci_write2(struct toshiba_acpi_dev *dev, u32 reg, u32 in1, u32 in2) | |||
| 355 | return ACPI_SUCCESS(status) ? out[0] : TOS_FAILURE; | 375 | return ACPI_SUCCESS(status) ? out[0] : TOS_FAILURE; |
| 356 | } | 376 | } |
| 357 | 377 | ||
| 358 | static u32 hci_read2(struct toshiba_acpi_dev *dev, u32 reg, u32 *out1, u32 *out2) | 378 | static u32 hci_read2(struct toshiba_acpi_dev *dev, |
| 379 | u32 reg, u32 *out1, u32 *out2) | ||
| 359 | { | 380 | { |
| 360 | u32 in[TCI_WORDS] = { HCI_GET, reg, *out1, *out2, 0, 0 }; | 381 | u32 in[TCI_WORDS] = { HCI_GET, reg, *out1, *out2, 0, 0 }; |
| 361 | u32 out[TCI_WORDS]; | 382 | u32 out[TCI_WORDS]; |
| 362 | acpi_status status = tci_raw(dev, in, out); | 383 | acpi_status status = tci_raw(dev, in, out); |
| 384 | |||
| 363 | if (ACPI_FAILURE(status)) | 385 | if (ACPI_FAILURE(status)) |
| 364 | return TOS_FAILURE; | 386 | return TOS_FAILURE; |
| 365 | 387 | ||
| @@ -369,7 +391,8 @@ static u32 hci_read2(struct toshiba_acpi_dev *dev, u32 reg, u32 *out1, u32 *out2 | |||
| 369 | return out[0]; | 391 | return out[0]; |
| 370 | } | 392 | } |
| 371 | 393 | ||
| 372 | /* common sci tasks | 394 | /* |
| 395 | * Common sci tasks | ||
| 373 | */ | 396 | */ |
| 374 | 397 | ||
| 375 | static int sci_open(struct toshiba_acpi_dev *dev) | 398 | static int sci_open(struct toshiba_acpi_dev *dev) |
| @@ -389,6 +412,20 @@ static int sci_open(struct toshiba_acpi_dev *dev) | |||
| 389 | } else if (out[0] == TOS_ALREADY_OPEN) { | 412 | } else if (out[0] == TOS_ALREADY_OPEN) { |
| 390 | pr_info("Toshiba SCI already opened\n"); | 413 | pr_info("Toshiba SCI already opened\n"); |
| 391 | return 1; | 414 | return 1; |
| 415 | } else if (out[0] == TOS_NOT_SUPPORTED) { | ||
| 416 | /* | ||
| 417 | * Some BIOSes do not have the SCI open/close functions | ||
| 418 | * implemented and return 0x8000 (Not Supported), failing to | ||
| 419 | * register some supported features. | ||
| 420 | * | ||
| 421 | * Simply return 1 if we hit those affected laptops to make the | ||
| 422 | * supported features work. | ||
| 423 | * | ||
| 424 | * In the case that some laptops really do not support the SCI, | ||
| 425 | * all the SCI dependent functions check for TOS_NOT_SUPPORTED, | ||
| 426 | * and thus, not registering support for the queried feature. | ||
| 427 | */ | ||
| 428 | return 1; | ||
| 392 | } else if (out[0] == TOS_NOT_PRESENT) { | 429 | } else if (out[0] == TOS_NOT_PRESENT) { |
| 393 | pr_info("Toshiba SCI is not present\n"); | 430 | pr_info("Toshiba SCI is not present\n"); |
| 394 | } | 431 | } |
| @@ -421,6 +458,7 @@ static u32 sci_read(struct toshiba_acpi_dev *dev, u32 reg, u32 *out1) | |||
| 421 | u32 in[TCI_WORDS] = { SCI_GET, reg, 0, 0, 0, 0 }; | 458 | u32 in[TCI_WORDS] = { SCI_GET, reg, 0, 0, 0, 0 }; |
| 422 | u32 out[TCI_WORDS]; | 459 | u32 out[TCI_WORDS]; |
| 423 | acpi_status status = tci_raw(dev, in, out); | 460 | acpi_status status = tci_raw(dev, in, out); |
| 461 | |||
| 424 | if (ACPI_FAILURE(status)) | 462 | if (ACPI_FAILURE(status)) |
| 425 | return TOS_FAILURE; | 463 | return TOS_FAILURE; |
| 426 | 464 | ||
| @@ -529,10 +567,11 @@ static int toshiba_kbd_illum_available(struct toshiba_acpi_dev *dev) | |||
| 529 | return 0; | 567 | return 0; |
| 530 | } | 568 | } |
| 531 | 569 | ||
| 532 | /* Check for keyboard backlight timeout max value, | 570 | /* |
| 571 | * Check for keyboard backlight timeout max value, | ||
| 533 | * previous kbd backlight implementation set this to | 572 | * previous kbd backlight implementation set this to |
| 534 | * 0x3c0003, and now the new implementation set this | 573 | * 0x3c0003, and now the new implementation set this |
| 535 | * to 0x3c001a, use this to distinguish between them | 574 | * to 0x3c001a, use this to distinguish between them. |
| 536 | */ | 575 | */ |
| 537 | if (out[3] == SCI_KBD_TIME_MAX) | 576 | if (out[3] == SCI_KBD_TIME_MAX) |
| 538 | dev->kbd_type = 2; | 577 | dev->kbd_type = 2; |
| @@ -667,19 +706,37 @@ static int toshiba_touchpad_get(struct toshiba_acpi_dev *dev, u32 *state) | |||
| 667 | static int toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) | 706 | static int toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) |
| 668 | { | 707 | { |
| 669 | acpi_status status; | 708 | acpi_status status; |
| 670 | u32 in[TCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 1, 0, 0 }; | 709 | u32 in[TCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 0, 0, 0 }; |
| 671 | u32 out[TCI_WORDS]; | 710 | u32 out[TCI_WORDS]; |
| 672 | 711 | ||
| 673 | status = tci_raw(dev, in, out); | 712 | status = tci_raw(dev, in, out); |
| 674 | if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) { | 713 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { |
| 675 | pr_info("ACPI call to get ECO led failed\n"); | 714 | pr_err("ACPI call to get ECO led failed\n"); |
| 676 | return 0; | 715 | } else if (out[0] == TOS_NOT_INSTALLED) { |
| 716 | pr_info("ECO led not installed"); | ||
| 717 | } else if (out[0] == TOS_INPUT_DATA_ERROR) { | ||
| 718 | /* | ||
| 719 | * If we receive 0x8300 (Input Data Error), it means that the | ||
| 720 | * LED device is present, but that we just screwed the input | ||
| 721 | * parameters. | ||
| 722 | * | ||
| 723 | * Let's query the status of the LED to see if we really have a | ||
| 724 | * success response, indicating the actual presense of the LED, | ||
| 725 | * bail out otherwise. | ||
| 726 | */ | ||
| 727 | in[3] = 1; | ||
| 728 | status = tci_raw(dev, in, out); | ||
| 729 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) | ||
| 730 | pr_err("ACPI call to get ECO led failed\n"); | ||
| 731 | else if (out[0] == TOS_SUCCESS) | ||
| 732 | return 1; | ||
| 677 | } | 733 | } |
| 678 | 734 | ||
| 679 | return 1; | 735 | return 0; |
| 680 | } | 736 | } |
| 681 | 737 | ||
| 682 | static enum led_brightness toshiba_eco_mode_get_status(struct led_classdev *cdev) | 738 | static enum led_brightness |
| 739 | toshiba_eco_mode_get_status(struct led_classdev *cdev) | ||
| 683 | { | 740 | { |
| 684 | struct toshiba_acpi_dev *dev = container_of(cdev, | 741 | struct toshiba_acpi_dev *dev = container_of(cdev, |
| 685 | struct toshiba_acpi_dev, eco_led); | 742 | struct toshiba_acpi_dev, eco_led); |
| @@ -721,7 +778,8 @@ static int toshiba_accelerometer_supported(struct toshiba_acpi_dev *dev) | |||
| 721 | u32 out[TCI_WORDS]; | 778 | u32 out[TCI_WORDS]; |
| 722 | acpi_status status; | 779 | acpi_status status; |
| 723 | 780 | ||
| 724 | /* Check if the accelerometer call exists, | 781 | /* |
| 782 | * Check if the accelerometer call exists, | ||
| 725 | * this call also serves as initialization | 783 | * this call also serves as initialization |
| 726 | */ | 784 | */ |
| 727 | status = tci_raw(dev, in, out); | 785 | status = tci_raw(dev, in, out); |
| @@ -760,6 +818,337 @@ static int toshiba_accelerometer_get(struct toshiba_acpi_dev *dev, | |||
| 760 | return 0; | 818 | return 0; |
| 761 | } | 819 | } |
| 762 | 820 | ||
| 821 | /* Sleep (Charge and Music) utilities support */ | ||
| 822 | static int toshiba_usb_sleep_charge_get(struct toshiba_acpi_dev *dev, | ||
| 823 | u32 *mode) | ||
| 824 | { | ||
| 825 | u32 result; | ||
| 826 | |||
| 827 | if (!sci_open(dev)) | ||
| 828 | return -EIO; | ||
| 829 | |||
| 830 | result = sci_read(dev, SCI_USB_SLEEP_CHARGE, mode); | ||
| 831 | sci_close(dev); | ||
| 832 | if (result == TOS_FAILURE) { | ||
| 833 | pr_err("ACPI call to set USB S&C mode failed\n"); | ||
| 834 | return -EIO; | ||
| 835 | } else if (result == TOS_NOT_SUPPORTED) { | ||
| 836 | pr_info("USB Sleep and Charge not supported\n"); | ||
| 837 | return -ENODEV; | ||
| 838 | } else if (result == TOS_INPUT_DATA_ERROR) { | ||
| 839 | return -EIO; | ||
| 840 | } | ||
| 841 | |||
| 842 | return 0; | ||
| 843 | } | ||
| 844 | |||
| 845 | static int toshiba_usb_sleep_charge_set(struct toshiba_acpi_dev *dev, | ||
| 846 | u32 mode) | ||
| 847 | { | ||
| 848 | u32 result; | ||
| 849 | |||
| 850 | if (!sci_open(dev)) | ||
| 851 | return -EIO; | ||
| 852 | |||
| 853 | result = sci_write(dev, SCI_USB_SLEEP_CHARGE, mode); | ||
| 854 | sci_close(dev); | ||
| 855 | if (result == TOS_FAILURE) { | ||
| 856 | pr_err("ACPI call to set USB S&C mode failed\n"); | ||
| 857 | return -EIO; | ||
| 858 | } else if (result == TOS_NOT_SUPPORTED) { | ||
| 859 | pr_info("USB Sleep and Charge not supported\n"); | ||
| 860 | return -ENODEV; | ||
| 861 | } else if (result == TOS_INPUT_DATA_ERROR) { | ||
| 862 | return -EIO; | ||
| 863 | } | ||
| 864 | |||
| 865 | return 0; | ||
| 866 | } | ||
| 867 | |||
| 868 | static int toshiba_sleep_functions_status_get(struct toshiba_acpi_dev *dev, | ||
| 869 | u32 *mode) | ||
| 870 | { | ||
| 871 | u32 in[TCI_WORDS] = { SCI_GET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 }; | ||
| 872 | u32 out[TCI_WORDS]; | ||
| 873 | acpi_status status; | ||
| 874 | |||
| 875 | if (!sci_open(dev)) | ||
| 876 | return -EIO; | ||
| 877 | |||
| 878 | in[5] = SCI_USB_CHARGE_BAT_LVL; | ||
| 879 | status = tci_raw(dev, in, out); | ||
| 880 | sci_close(dev); | ||
| 881 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { | ||
| 882 | pr_err("ACPI call to get USB S&C battery level failed\n"); | ||
| 883 | return -EIO; | ||
| 884 | } else if (out[0] == TOS_NOT_SUPPORTED) { | ||
| 885 | pr_info("USB Sleep and Charge not supported\n"); | ||
| 886 | return -ENODEV; | ||
| 887 | } else if (out[0] == TOS_INPUT_DATA_ERROR) { | ||
| 888 | return -EIO; | ||
| 889 | } | ||
| 890 | |||
| 891 | *mode = out[2]; | ||
| 892 | |||
| 893 | return 0; | ||
| 894 | } | ||
| 895 | |||
| 896 | static int toshiba_sleep_functions_status_set(struct toshiba_acpi_dev *dev, | ||
| 897 | u32 mode) | ||
| 898 | { | ||
| 899 | u32 in[TCI_WORDS] = { SCI_SET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 }; | ||
| 900 | u32 out[TCI_WORDS]; | ||
| 901 | acpi_status status; | ||
| 902 | |||
| 903 | if (!sci_open(dev)) | ||
| 904 | return -EIO; | ||
| 905 | |||
| 906 | in[2] = mode; | ||
| 907 | in[5] = SCI_USB_CHARGE_BAT_LVL; | ||
| 908 | status = tci_raw(dev, in, out); | ||
| 909 | sci_close(dev); | ||
| 910 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { | ||
| 911 | pr_err("ACPI call to set USB S&C battery level failed\n"); | ||
| 912 | return -EIO; | ||
| 913 | } else if (out[0] == TOS_NOT_SUPPORTED) { | ||
| 914 | pr_info("USB Sleep and Charge not supported\n"); | ||
| 915 | return -ENODEV; | ||
| 916 | } else if (out[0] == TOS_INPUT_DATA_ERROR) { | ||
| 917 | return -EIO; | ||
| 918 | } | ||
| 919 | |||
| 920 | return 0; | ||
| 921 | } | ||
| 922 | |||
| 923 | static int toshiba_usb_rapid_charge_get(struct toshiba_acpi_dev *dev, | ||
| 924 | u32 *state) | ||
| 925 | { | ||
| 926 | u32 in[TCI_WORDS] = { SCI_GET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 }; | ||
| 927 | u32 out[TCI_WORDS]; | ||
| 928 | acpi_status status; | ||
| 929 | |||
| 930 | if (!sci_open(dev)) | ||
| 931 | return -EIO; | ||
| 932 | |||
| 933 | in[5] = SCI_USB_CHARGE_RAPID_DSP; | ||
| 934 | status = tci_raw(dev, in, out); | ||
| 935 | sci_close(dev); | ||
| 936 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { | ||
| 937 | pr_err("ACPI call to get USB S&C battery level failed\n"); | ||
| 938 | return -EIO; | ||
| 939 | } else if (out[0] == TOS_NOT_SUPPORTED || | ||
| 940 | out[0] == TOS_INPUT_DATA_ERROR) { | ||
| 941 | pr_info("USB Sleep and Charge not supported\n"); | ||
| 942 | return -ENODEV; | ||
| 943 | } | ||
| 944 | |||
| 945 | *state = out[2]; | ||
| 946 | |||
| 947 | return 0; | ||
| 948 | } | ||
| 949 | |||
| 950 | static int toshiba_usb_rapid_charge_set(struct toshiba_acpi_dev *dev, | ||
| 951 | u32 state) | ||
| 952 | { | ||
| 953 | u32 in[TCI_WORDS] = { SCI_SET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 }; | ||
| 954 | u32 out[TCI_WORDS]; | ||
| 955 | acpi_status status; | ||
| 956 | |||
| 957 | if (!sci_open(dev)) | ||
| 958 | return -EIO; | ||
| 959 | |||
| 960 | in[2] = state; | ||
| 961 | in[5] = SCI_USB_CHARGE_RAPID_DSP; | ||
| 962 | status = tci_raw(dev, in, out); | ||
| 963 | sci_close(dev); | ||
| 964 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { | ||
| 965 | pr_err("ACPI call to set USB S&C battery level failed\n"); | ||
| 966 | return -EIO; | ||
| 967 | } else if (out[0] == TOS_NOT_SUPPORTED) { | ||
| 968 | pr_info("USB Sleep and Charge not supported\n"); | ||
| 969 | return -ENODEV; | ||
| 970 | } else if (out[0] == TOS_INPUT_DATA_ERROR) { | ||
| 971 | return -EIO; | ||
| 972 | } | ||
| 973 | |||
| 974 | return 0; | ||
| 975 | } | ||
| 976 | |||
| 977 | static int toshiba_usb_sleep_music_get(struct toshiba_acpi_dev *dev, u32 *state) | ||
| 978 | { | ||
| 979 | u32 result; | ||
| 980 | |||
| 981 | if (!sci_open(dev)) | ||
| 982 | return -EIO; | ||
| 983 | |||
| 984 | result = sci_read(dev, SCI_USB_SLEEP_MUSIC, state); | ||
| 985 | sci_close(dev); | ||
| 986 | if (result == TOS_FAILURE) { | ||
| 987 | pr_err("ACPI call to set USB S&C mode failed\n"); | ||
| 988 | return -EIO; | ||
| 989 | } else if (result == TOS_NOT_SUPPORTED) { | ||
| 990 | pr_info("USB Sleep and Charge not supported\n"); | ||
| 991 | return -ENODEV; | ||
| 992 | } else if (result == TOS_INPUT_DATA_ERROR) { | ||
| 993 | return -EIO; | ||
| 994 | } | ||
| 995 | |||
| 996 | return 0; | ||
| 997 | } | ||
| 998 | |||
| 999 | static int toshiba_usb_sleep_music_set(struct toshiba_acpi_dev *dev, u32 state) | ||
| 1000 | { | ||
| 1001 | u32 result; | ||
| 1002 | |||
| 1003 | if (!sci_open(dev)) | ||
| 1004 | return -EIO; | ||
| 1005 | |||
| 1006 | result = sci_write(dev, SCI_USB_SLEEP_MUSIC, state); | ||
| 1007 | sci_close(dev); | ||
| 1008 | if (result == TOS_FAILURE) { | ||
| 1009 | pr_err("ACPI call to set USB S&C mode failed\n"); | ||
| 1010 | return -EIO; | ||
| 1011 | } else if (result == TOS_NOT_SUPPORTED) { | ||
| 1012 | pr_info("USB Sleep and Charge not supported\n"); | ||
| 1013 | return -ENODEV; | ||
| 1014 | } else if (result == TOS_INPUT_DATA_ERROR) { | ||
| 1015 | return -EIO; | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | return 0; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | /* Keyboard function keys */ | ||
| 1022 | static int toshiba_function_keys_get(struct toshiba_acpi_dev *dev, u32 *mode) | ||
| 1023 | { | ||
| 1024 | u32 result; | ||
| 1025 | |||
| 1026 | if (!sci_open(dev)) | ||
| 1027 | return -EIO; | ||
| 1028 | |||
| 1029 | result = sci_read(dev, SCI_KBD_FUNCTION_KEYS, mode); | ||
| 1030 | sci_close(dev); | ||
| 1031 | if (result == TOS_FAILURE || result == TOS_INPUT_DATA_ERROR) { | ||
| 1032 | pr_err("ACPI call to get KBD function keys failed\n"); | ||
| 1033 | return -EIO; | ||
| 1034 | } else if (result == TOS_NOT_SUPPORTED) { | ||
| 1035 | pr_info("KBD function keys not supported\n"); | ||
| 1036 | return -ENODEV; | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | return 0; | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | static int toshiba_function_keys_set(struct toshiba_acpi_dev *dev, u32 mode) | ||
| 1043 | { | ||
| 1044 | u32 result; | ||
| 1045 | |||
| 1046 | if (!sci_open(dev)) | ||
| 1047 | return -EIO; | ||
| 1048 | |||
| 1049 | result = sci_write(dev, SCI_KBD_FUNCTION_KEYS, mode); | ||
| 1050 | sci_close(dev); | ||
| 1051 | if (result == TOS_FAILURE || result == TOS_INPUT_DATA_ERROR) { | ||
| 1052 | pr_err("ACPI call to set KBD function keys failed\n"); | ||
| 1053 | return -EIO; | ||
| 1054 | } else if (result == TOS_NOT_SUPPORTED) { | ||
| 1055 | pr_info("KBD function keys not supported\n"); | ||
| 1056 | return -ENODEV; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | return 0; | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | /* Panel Power ON */ | ||
| 1063 | static int toshiba_panel_power_on_get(struct toshiba_acpi_dev *dev, u32 *state) | ||
| 1064 | { | ||
| 1065 | u32 result; | ||
| 1066 | |||
| 1067 | if (!sci_open(dev)) | ||
| 1068 | return -EIO; | ||
| 1069 | |||
| 1070 | result = sci_read(dev, SCI_PANEL_POWER_ON, state); | ||
| 1071 | sci_close(dev); | ||
| 1072 | if (result == TOS_FAILURE) { | ||
| 1073 | pr_err("ACPI call to get Panel Power ON failed\n"); | ||
| 1074 | return -EIO; | ||
| 1075 | } else if (result == TOS_NOT_SUPPORTED) { | ||
| 1076 | pr_info("Panel Power on not supported\n"); | ||
| 1077 | return -ENODEV; | ||
| 1078 | } else if (result == TOS_INPUT_DATA_ERROR) { | ||
| 1079 | return -EIO; | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | return 0; | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | static int toshiba_panel_power_on_set(struct toshiba_acpi_dev *dev, u32 state) | ||
| 1086 | { | ||
| 1087 | u32 result; | ||
| 1088 | |||
| 1089 | if (!sci_open(dev)) | ||
| 1090 | return -EIO; | ||
| 1091 | |||
| 1092 | result = sci_write(dev, SCI_PANEL_POWER_ON, state); | ||
| 1093 | sci_close(dev); | ||
| 1094 | if (result == TOS_FAILURE) { | ||
| 1095 | pr_err("ACPI call to set Panel Power ON failed\n"); | ||
| 1096 | return -EIO; | ||
| 1097 | } else if (result == TOS_NOT_SUPPORTED) { | ||
| 1098 | pr_info("Panel Power ON not supported\n"); | ||
| 1099 | return -ENODEV; | ||
| 1100 | } else if (result == TOS_INPUT_DATA_ERROR) { | ||
| 1101 | return -EIO; | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | return 0; | ||
| 1105 | } | ||
| 1106 | |||
| 1107 | /* USB Three */ | ||
| 1108 | static int toshiba_usb_three_get(struct toshiba_acpi_dev *dev, u32 *state) | ||
| 1109 | { | ||
| 1110 | u32 result; | ||
| 1111 | |||
| 1112 | if (!sci_open(dev)) | ||
| 1113 | return -EIO; | ||
| 1114 | |||
| 1115 | result = sci_read(dev, SCI_USB_THREE, state); | ||
| 1116 | sci_close(dev); | ||
| 1117 | if (result == TOS_FAILURE) { | ||
| 1118 | pr_err("ACPI call to get USB 3 failed\n"); | ||
| 1119 | return -EIO; | ||
| 1120 | } else if (result == TOS_NOT_SUPPORTED) { | ||
| 1121 | pr_info("USB 3 not supported\n"); | ||
| 1122 | return -ENODEV; | ||
| 1123 | } else if (result == TOS_INPUT_DATA_ERROR) { | ||
| 1124 | return -EIO; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | return 0; | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | static int toshiba_usb_three_set(struct toshiba_acpi_dev *dev, u32 state) | ||
| 1131 | { | ||
| 1132 | u32 result; | ||
| 1133 | |||
| 1134 | if (!sci_open(dev)) | ||
| 1135 | return -EIO; | ||
| 1136 | |||
| 1137 | result = sci_write(dev, SCI_USB_THREE, state); | ||
| 1138 | sci_close(dev); | ||
| 1139 | if (result == TOS_FAILURE) { | ||
| 1140 | pr_err("ACPI call to set USB 3 failed\n"); | ||
| 1141 | return -EIO; | ||
| 1142 | } else if (result == TOS_NOT_SUPPORTED) { | ||
| 1143 | pr_info("USB 3 not supported\n"); | ||
| 1144 | return -ENODEV; | ||
| 1145 | } else if (result == TOS_INPUT_DATA_ERROR) { | ||
| 1146 | return -EIO; | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | return 0; | ||
| 1150 | } | ||
| 1151 | |||
| 763 | /* Bluetooth rfkill handlers */ | 1152 | /* Bluetooth rfkill handlers */ |
| 764 | 1153 | ||
| 765 | static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) | 1154 | static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) |
| @@ -870,7 +1259,7 @@ static int set_tr_backlight_status(struct toshiba_acpi_dev *dev, bool enable) | |||
| 870 | return hci_result == TOS_SUCCESS ? 0 : -EIO; | 1259 | return hci_result == TOS_SUCCESS ? 0 : -EIO; |
| 871 | } | 1260 | } |
| 872 | 1261 | ||
| 873 | static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; | 1262 | static struct proc_dir_entry *toshiba_proc_dir /*= 0*/; |
| 874 | 1263 | ||
| 875 | static int __get_lcd_brightness(struct toshiba_acpi_dev *dev) | 1264 | static int __get_lcd_brightness(struct toshiba_acpi_dev *dev) |
| 876 | { | 1265 | { |
| @@ -881,6 +1270,7 @@ static int __get_lcd_brightness(struct toshiba_acpi_dev *dev) | |||
| 881 | if (dev->tr_backlight_supported) { | 1270 | if (dev->tr_backlight_supported) { |
| 882 | bool enabled; | 1271 | bool enabled; |
| 883 | int ret = get_tr_backlight_status(dev, &enabled); | 1272 | int ret = get_tr_backlight_status(dev, &enabled); |
| 1273 | |||
| 884 | if (ret) | 1274 | if (ret) |
| 885 | return ret; | 1275 | return ret; |
| 886 | if (enabled) | 1276 | if (enabled) |
| @@ -898,6 +1288,7 @@ static int __get_lcd_brightness(struct toshiba_acpi_dev *dev) | |||
| 898 | static int get_lcd_brightness(struct backlight_device *bd) | 1288 | static int get_lcd_brightness(struct backlight_device *bd) |
| 899 | { | 1289 | { |
| 900 | struct toshiba_acpi_dev *dev = bl_get_data(bd); | 1290 | struct toshiba_acpi_dev *dev = bl_get_data(bd); |
| 1291 | |||
| 901 | return __get_lcd_brightness(dev); | 1292 | return __get_lcd_brightness(dev); |
| 902 | } | 1293 | } |
| 903 | 1294 | ||
| @@ -934,6 +1325,7 @@ static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) | |||
| 934 | if (dev->tr_backlight_supported) { | 1325 | if (dev->tr_backlight_supported) { |
| 935 | bool enable = !value; | 1326 | bool enable = !value; |
| 936 | int ret = set_tr_backlight_status(dev, enable); | 1327 | int ret = set_tr_backlight_status(dev, enable); |
| 1328 | |||
| 937 | if (ret) | 1329 | if (ret) |
| 938 | return ret; | 1330 | return ret; |
| 939 | if (value) | 1331 | if (value) |
| @@ -948,6 +1340,7 @@ static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) | |||
| 948 | static int set_lcd_status(struct backlight_device *bd) | 1340 | static int set_lcd_status(struct backlight_device *bd) |
| 949 | { | 1341 | { |
| 950 | struct toshiba_acpi_dev *dev = bl_get_data(bd); | 1342 | struct toshiba_acpi_dev *dev = bl_get_data(bd); |
| 1343 | |||
| 951 | return set_lcd_brightness(dev, bd->props.brightness); | 1344 | return set_lcd_brightness(dev, bd->props.brightness); |
| 952 | } | 1345 | } |
| 953 | 1346 | ||
| @@ -1005,6 +1398,7 @@ static int video_proc_show(struct seq_file *m, void *v) | |||
| 1005 | int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; | 1398 | int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; |
| 1006 | int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; | 1399 | int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; |
| 1007 | int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0; | 1400 | int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0; |
| 1401 | |||
| 1008 | seq_printf(m, "lcd_out: %d\n", is_lcd); | 1402 | seq_printf(m, "lcd_out: %d\n", is_lcd); |
| 1009 | seq_printf(m, "crt_out: %d\n", is_crt); | 1403 | seq_printf(m, "crt_out: %d\n", is_crt); |
| 1010 | seq_printf(m, "tv_out: %d\n", is_tv); | 1404 | seq_printf(m, "tv_out: %d\n", is_tv); |
| @@ -1042,9 +1436,9 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, | |||
| 1042 | 1436 | ||
| 1043 | buffer = cmd; | 1437 | buffer = cmd; |
| 1044 | 1438 | ||
| 1045 | /* scan expression. Multiple expressions may be delimited with ; | 1439 | /* |
| 1046 | * | 1440 | * Scan expression. Multiple expressions may be delimited with ; |
| 1047 | * NOTE: to keep scanning simple, invalid fields are ignored | 1441 | * NOTE: To keep scanning simple, invalid fields are ignored. |
| 1048 | */ | 1442 | */ |
| 1049 | while (remain) { | 1443 | while (remain) { |
| 1050 | if (sscanf(buffer, " lcd_out : %i", &value) == 1) | 1444 | if (sscanf(buffer, " lcd_out : %i", &value) == 1) |
| @@ -1053,12 +1447,11 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, | |||
| 1053 | crt_out = value & 1; | 1447 | crt_out = value & 1; |
| 1054 | else if (sscanf(buffer, " tv_out : %i", &value) == 1) | 1448 | else if (sscanf(buffer, " tv_out : %i", &value) == 1) |
| 1055 | tv_out = value & 1; | 1449 | tv_out = value & 1; |
| 1056 | /* advance to one character past the next ; */ | 1450 | /* Advance to one character past the next ; */ |
| 1057 | do { | 1451 | do { |
| 1058 | ++buffer; | 1452 | ++buffer; |
| 1059 | --remain; | 1453 | --remain; |
| 1060 | } | 1454 | } while (remain && *(buffer - 1) != ';'); |
| 1061 | while (remain && *(buffer - 1) != ';'); | ||
| 1062 | } | 1455 | } |
| 1063 | 1456 | ||
| 1064 | kfree(cmd); | 1457 | kfree(cmd); |
| @@ -1066,13 +1459,15 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, | |||
| 1066 | ret = get_video_status(dev, &video_out); | 1459 | ret = get_video_status(dev, &video_out); |
| 1067 | if (!ret) { | 1460 | if (!ret) { |
| 1068 | unsigned int new_video_out = video_out; | 1461 | unsigned int new_video_out = video_out; |
| 1462 | |||
| 1069 | if (lcd_out != -1) | 1463 | if (lcd_out != -1) |
| 1070 | _set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out); | 1464 | _set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out); |
| 1071 | if (crt_out != -1) | 1465 | if (crt_out != -1) |
| 1072 | _set_bit(&new_video_out, HCI_VIDEO_OUT_CRT, crt_out); | 1466 | _set_bit(&new_video_out, HCI_VIDEO_OUT_CRT, crt_out); |
| 1073 | if (tv_out != -1) | 1467 | if (tv_out != -1) |
| 1074 | _set_bit(&new_video_out, HCI_VIDEO_OUT_TV, tv_out); | 1468 | _set_bit(&new_video_out, HCI_VIDEO_OUT_TV, tv_out); |
| 1075 | /* To avoid unnecessary video disruption, only write the new | 1469 | /* |
| 1470 | * To avoid unnecessary video disruption, only write the new | ||
| 1076 | * video setting if something changed. */ | 1471 | * video setting if something changed. */ |
| 1077 | if (new_video_out != video_out) | 1472 | if (new_video_out != video_out) |
| 1078 | ret = write_acpi_int(METHOD_VIDEO_OUT, new_video_out); | 1473 | ret = write_acpi_int(METHOD_VIDEO_OUT, new_video_out); |
| @@ -1135,10 +1530,10 @@ static ssize_t fan_proc_write(struct file *file, const char __user *buf, | |||
| 1135 | if (sscanf(cmd, " force_on : %i", &value) == 1 && | 1530 | if (sscanf(cmd, " force_on : %i", &value) == 1 && |
| 1136 | value >= 0 && value <= 1) { | 1531 | value >= 0 && value <= 1) { |
| 1137 | hci_result = hci_write1(dev, HCI_FAN, value); | 1532 | hci_result = hci_write1(dev, HCI_FAN, value); |
| 1138 | if (hci_result != TOS_SUCCESS) | 1533 | if (hci_result == TOS_SUCCESS) |
| 1139 | return -EIO; | ||
| 1140 | else | ||
| 1141 | dev->force_fan = value; | 1534 | dev->force_fan = value; |
| 1535 | else | ||
| 1536 | return -EIO; | ||
| 1142 | } else { | 1537 | } else { |
| 1143 | return -EINVAL; | 1538 | return -EINVAL; |
| 1144 | } | 1539 | } |
| @@ -1167,11 +1562,13 @@ static int keys_proc_show(struct seq_file *m, void *v) | |||
| 1167 | dev->key_event_valid = 1; | 1562 | dev->key_event_valid = 1; |
| 1168 | dev->last_key_event = value; | 1563 | dev->last_key_event = value; |
| 1169 | } else if (hci_result == TOS_FIFO_EMPTY) { | 1564 | } else if (hci_result == TOS_FIFO_EMPTY) { |
| 1170 | /* better luck next time */ | 1565 | /* Better luck next time */ |
| 1171 | } else if (hci_result == TOS_NOT_SUPPORTED) { | 1566 | } else if (hci_result == TOS_NOT_SUPPORTED) { |
| 1172 | /* This is a workaround for an unresolved issue on | 1567 | /* |
| 1568 | * This is a workaround for an unresolved issue on | ||
| 1173 | * some machines where system events sporadically | 1569 | * some machines where system events sporadically |
| 1174 | * become disabled. */ | 1570 | * become disabled. |
| 1571 | */ | ||
| 1175 | hci_result = hci_write1(dev, HCI_SYSTEM_EVENT, 1); | 1572 | hci_result = hci_write1(dev, HCI_SYSTEM_EVENT, 1); |
| 1176 | pr_notice("Re-enabled hotkeys\n"); | 1573 | pr_notice("Re-enabled hotkeys\n"); |
| 1177 | } else { | 1574 | } else { |
| @@ -1203,11 +1600,10 @@ static ssize_t keys_proc_write(struct file *file, const char __user *buf, | |||
| 1203 | return -EFAULT; | 1600 | return -EFAULT; |
| 1204 | cmd[len] = '\0'; | 1601 | cmd[len] = '\0'; |
| 1205 | 1602 | ||
| 1206 | if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) { | 1603 | if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) |
| 1207 | dev->key_event_valid = 0; | 1604 | dev->key_event_valid = 0; |
| 1208 | } else { | 1605 | else |
| 1209 | return -EINVAL; | 1606 | return -EINVAL; |
| 1210 | } | ||
| 1211 | 1607 | ||
| 1212 | return count; | 1608 | return count; |
| 1213 | } | 1609 | } |
| @@ -1241,7 +1637,8 @@ static const struct file_operations version_proc_fops = { | |||
| 1241 | .release = single_release, | 1637 | .release = single_release, |
| 1242 | }; | 1638 | }; |
| 1243 | 1639 | ||
| 1244 | /* proc and module init | 1640 | /* |
| 1641 | * Proc and module init | ||
| 1245 | */ | 1642 | */ |
| 1246 | 1643 | ||
| 1247 | #define PROC_TOSHIBA "toshiba" | 1644 | #define PROC_TOSHIBA "toshiba" |
| @@ -1286,66 +1683,56 @@ static const struct backlight_ops toshiba_backlight_data = { | |||
| 1286 | /* | 1683 | /* |
| 1287 | * Sysfs files | 1684 | * Sysfs files |
| 1288 | */ | 1685 | */ |
| 1289 | static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, | 1686 | static ssize_t version_show(struct device *dev, |
| 1290 | struct device_attribute *attr, | 1687 | struct device_attribute *attr, char *buf) |
| 1291 | const char *buf, size_t count); | 1688 | { |
| 1292 | static ssize_t toshiba_kbd_bl_mode_show(struct device *dev, | 1689 | return sprintf(buf, "%s\n", TOSHIBA_ACPI_VERSION); |
| 1293 | struct device_attribute *attr, | 1690 | } |
| 1294 | char *buf); | 1691 | static DEVICE_ATTR_RO(version); |
| 1295 | static ssize_t toshiba_kbd_type_show(struct device *dev, | ||
| 1296 | struct device_attribute *attr, | ||
| 1297 | char *buf); | ||
| 1298 | static ssize_t toshiba_available_kbd_modes_show(struct device *dev, | ||
| 1299 | struct device_attribute *attr, | ||
| 1300 | char *buf); | ||
| 1301 | static ssize_t toshiba_kbd_bl_timeout_store(struct device *dev, | ||
| 1302 | struct device_attribute *attr, | ||
| 1303 | const char *buf, size_t count); | ||
| 1304 | static ssize_t toshiba_kbd_bl_timeout_show(struct device *dev, | ||
| 1305 | struct device_attribute *attr, | ||
| 1306 | char *buf); | ||
| 1307 | static ssize_t toshiba_touchpad_store(struct device *dev, | ||
| 1308 | struct device_attribute *attr, | ||
| 1309 | const char *buf, size_t count); | ||
| 1310 | static ssize_t toshiba_touchpad_show(struct device *dev, | ||
| 1311 | struct device_attribute *attr, | ||
| 1312 | char *buf); | ||
| 1313 | static ssize_t toshiba_position_show(struct device *dev, | ||
| 1314 | struct device_attribute *attr, | ||
| 1315 | char *buf); | ||
| 1316 | |||
| 1317 | static DEVICE_ATTR(kbd_backlight_mode, S_IRUGO | S_IWUSR, | ||
| 1318 | toshiba_kbd_bl_mode_show, toshiba_kbd_bl_mode_store); | ||
| 1319 | static DEVICE_ATTR(kbd_type, S_IRUGO, toshiba_kbd_type_show, NULL); | ||
| 1320 | static DEVICE_ATTR(available_kbd_modes, S_IRUGO, | ||
| 1321 | toshiba_available_kbd_modes_show, NULL); | ||
| 1322 | static DEVICE_ATTR(kbd_backlight_timeout, S_IRUGO | S_IWUSR, | ||
| 1323 | toshiba_kbd_bl_timeout_show, toshiba_kbd_bl_timeout_store); | ||
| 1324 | static DEVICE_ATTR(touchpad, S_IRUGO | S_IWUSR, | ||
| 1325 | toshiba_touchpad_show, toshiba_touchpad_store); | ||
| 1326 | static DEVICE_ATTR(position, S_IRUGO, toshiba_position_show, NULL); | ||
| 1327 | 1692 | ||
| 1328 | static struct attribute *toshiba_attributes[] = { | 1693 | static ssize_t fan_store(struct device *dev, |
| 1329 | &dev_attr_kbd_backlight_mode.attr, | 1694 | struct device_attribute *attr, |
| 1330 | &dev_attr_kbd_type.attr, | 1695 | const char *buf, size_t count) |
| 1331 | &dev_attr_available_kbd_modes.attr, | 1696 | { |
| 1332 | &dev_attr_kbd_backlight_timeout.attr, | 1697 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1333 | &dev_attr_touchpad.attr, | 1698 | u32 result; |
| 1334 | &dev_attr_position.attr, | 1699 | int state; |
| 1335 | NULL, | 1700 | int ret; |
| 1336 | }; | ||
| 1337 | 1701 | ||
| 1338 | static umode_t toshiba_sysfs_is_visible(struct kobject *, | 1702 | ret = kstrtoint(buf, 0, &state); |
| 1339 | struct attribute *, int); | 1703 | if (ret) |
| 1704 | return ret; | ||
| 1340 | 1705 | ||
| 1341 | static struct attribute_group toshiba_attr_group = { | 1706 | if (state != 0 && state != 1) |
| 1342 | .is_visible = toshiba_sysfs_is_visible, | 1707 | return -EINVAL; |
| 1343 | .attrs = toshiba_attributes, | ||
| 1344 | }; | ||
| 1345 | 1708 | ||
| 1346 | static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, | 1709 | result = hci_write1(toshiba, HCI_FAN, state); |
| 1347 | struct device_attribute *attr, | 1710 | if (result == TOS_FAILURE) |
| 1348 | const char *buf, size_t count) | 1711 | return -EIO; |
| 1712 | else if (result == TOS_NOT_SUPPORTED) | ||
| 1713 | return -ENODEV; | ||
| 1714 | |||
| 1715 | return count; | ||
| 1716 | } | ||
| 1717 | |||
| 1718 | static ssize_t fan_show(struct device *dev, | ||
| 1719 | struct device_attribute *attr, char *buf) | ||
| 1720 | { | ||
| 1721 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 1722 | u32 value; | ||
| 1723 | int ret; | ||
| 1724 | |||
| 1725 | ret = get_fan_status(toshiba, &value); | ||
| 1726 | if (ret) | ||
| 1727 | return ret; | ||
| 1728 | |||
| 1729 | return sprintf(buf, "%d\n", value); | ||
| 1730 | } | ||
| 1731 | static DEVICE_ATTR_RW(fan); | ||
| 1732 | |||
| 1733 | static ssize_t kbd_backlight_mode_store(struct device *dev, | ||
| 1734 | struct device_attribute *attr, | ||
| 1735 | const char *buf, size_t count) | ||
| 1349 | { | 1736 | { |
| 1350 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | 1737 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1351 | int mode; | 1738 | int mode; |
| @@ -1369,7 +1756,8 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, | |||
| 1369 | return -EINVAL; | 1756 | return -EINVAL; |
| 1370 | } | 1757 | } |
| 1371 | 1758 | ||
| 1372 | /* Set the Keyboard Backlight Mode where: | 1759 | /* |
| 1760 | * Set the Keyboard Backlight Mode where: | ||
| 1373 | * Auto - KBD backlight turns off automatically in given time | 1761 | * Auto - KBD backlight turns off automatically in given time |
| 1374 | * FN-Z - KBD backlight "toggles" when hotkey pressed | 1762 | * FN-Z - KBD backlight "toggles" when hotkey pressed |
| 1375 | * ON - KBD backlight is always on | 1763 | * ON - KBD backlight is always on |
| @@ -1400,9 +1788,9 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, | |||
| 1400 | return count; | 1788 | return count; |
| 1401 | } | 1789 | } |
| 1402 | 1790 | ||
| 1403 | static ssize_t toshiba_kbd_bl_mode_show(struct device *dev, | 1791 | static ssize_t kbd_backlight_mode_show(struct device *dev, |
| 1404 | struct device_attribute *attr, | 1792 | struct device_attribute *attr, |
| 1405 | char *buf) | 1793 | char *buf) |
| 1406 | { | 1794 | { |
| 1407 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | 1795 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1408 | u32 time; | 1796 | u32 time; |
| @@ -1412,19 +1800,20 @@ static ssize_t toshiba_kbd_bl_mode_show(struct device *dev, | |||
| 1412 | 1800 | ||
| 1413 | return sprintf(buf, "%i\n", time & SCI_KBD_MODE_MASK); | 1801 | return sprintf(buf, "%i\n", time & SCI_KBD_MODE_MASK); |
| 1414 | } | 1802 | } |
| 1803 | static DEVICE_ATTR_RW(kbd_backlight_mode); | ||
| 1415 | 1804 | ||
| 1416 | static ssize_t toshiba_kbd_type_show(struct device *dev, | 1805 | static ssize_t kbd_type_show(struct device *dev, |
| 1417 | struct device_attribute *attr, | 1806 | struct device_attribute *attr, char *buf) |
| 1418 | char *buf) | ||
| 1419 | { | 1807 | { |
| 1420 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | 1808 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1421 | 1809 | ||
| 1422 | return sprintf(buf, "%d\n", toshiba->kbd_type); | 1810 | return sprintf(buf, "%d\n", toshiba->kbd_type); |
| 1423 | } | 1811 | } |
| 1812 | static DEVICE_ATTR_RO(kbd_type); | ||
| 1424 | 1813 | ||
| 1425 | static ssize_t toshiba_available_kbd_modes_show(struct device *dev, | 1814 | static ssize_t available_kbd_modes_show(struct device *dev, |
| 1426 | struct device_attribute *attr, | 1815 | struct device_attribute *attr, |
| 1427 | char *buf) | 1816 | char *buf) |
| 1428 | { | 1817 | { |
| 1429 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | 1818 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1430 | 1819 | ||
| @@ -1435,10 +1824,11 @@ static ssize_t toshiba_available_kbd_modes_show(struct device *dev, | |||
| 1435 | return sprintf(buf, "%x %x %x\n", | 1824 | return sprintf(buf, "%x %x %x\n", |
| 1436 | SCI_KBD_MODE_AUTO, SCI_KBD_MODE_ON, SCI_KBD_MODE_OFF); | 1825 | SCI_KBD_MODE_AUTO, SCI_KBD_MODE_ON, SCI_KBD_MODE_OFF); |
| 1437 | } | 1826 | } |
| 1827 | static DEVICE_ATTR_RO(available_kbd_modes); | ||
| 1438 | 1828 | ||
| 1439 | static ssize_t toshiba_kbd_bl_timeout_store(struct device *dev, | 1829 | static ssize_t kbd_backlight_timeout_store(struct device *dev, |
| 1440 | struct device_attribute *attr, | 1830 | struct device_attribute *attr, |
| 1441 | const char *buf, size_t count) | 1831 | const char *buf, size_t count) |
| 1442 | { | 1832 | { |
| 1443 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | 1833 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1444 | int time; | 1834 | int time; |
| @@ -1479,9 +1869,9 @@ static ssize_t toshiba_kbd_bl_timeout_store(struct device *dev, | |||
| 1479 | return count; | 1869 | return count; |
| 1480 | } | 1870 | } |
| 1481 | 1871 | ||
| 1482 | static ssize_t toshiba_kbd_bl_timeout_show(struct device *dev, | 1872 | static ssize_t kbd_backlight_timeout_show(struct device *dev, |
| 1483 | struct device_attribute *attr, | 1873 | struct device_attribute *attr, |
| 1484 | char *buf) | 1874 | char *buf) |
| 1485 | { | 1875 | { |
| 1486 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | 1876 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1487 | u32 time; | 1877 | u32 time; |
| @@ -1491,10 +1881,11 @@ static ssize_t toshiba_kbd_bl_timeout_show(struct device *dev, | |||
| 1491 | 1881 | ||
| 1492 | return sprintf(buf, "%i\n", time >> HCI_MISC_SHIFT); | 1882 | return sprintf(buf, "%i\n", time >> HCI_MISC_SHIFT); |
| 1493 | } | 1883 | } |
| 1884 | static DEVICE_ATTR_RW(kbd_backlight_timeout); | ||
| 1494 | 1885 | ||
| 1495 | static ssize_t toshiba_touchpad_store(struct device *dev, | 1886 | static ssize_t touchpad_store(struct device *dev, |
| 1496 | struct device_attribute *attr, | 1887 | struct device_attribute *attr, |
| 1497 | const char *buf, size_t count) | 1888 | const char *buf, size_t count) |
| 1498 | { | 1889 | { |
| 1499 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | 1890 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1500 | int state; | 1891 | int state; |
| @@ -1514,8 +1905,8 @@ static ssize_t toshiba_touchpad_store(struct device *dev, | |||
| 1514 | return count; | 1905 | return count; |
| 1515 | } | 1906 | } |
| 1516 | 1907 | ||
| 1517 | static ssize_t toshiba_touchpad_show(struct device *dev, | 1908 | static ssize_t touchpad_show(struct device *dev, |
| 1518 | struct device_attribute *attr, char *buf) | 1909 | struct device_attribute *attr, char *buf) |
| 1519 | { | 1910 | { |
| 1520 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | 1911 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1521 | u32 state; | 1912 | u32 state; |
| @@ -1527,9 +1918,10 @@ static ssize_t toshiba_touchpad_show(struct device *dev, | |||
| 1527 | 1918 | ||
| 1528 | return sprintf(buf, "%i\n", state); | 1919 | return sprintf(buf, "%i\n", state); |
| 1529 | } | 1920 | } |
| 1921 | static DEVICE_ATTR_RW(touchpad); | ||
| 1530 | 1922 | ||
| 1531 | static ssize_t toshiba_position_show(struct device *dev, | 1923 | static ssize_t position_show(struct device *dev, |
| 1532 | struct device_attribute *attr, char *buf) | 1924 | struct device_attribute *attr, char *buf) |
| 1533 | { | 1925 | { |
| 1534 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | 1926 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); |
| 1535 | u32 xyval, zval, tmp; | 1927 | u32 xyval, zval, tmp; |
| @@ -1548,6 +1940,336 @@ static ssize_t toshiba_position_show(struct device *dev, | |||
| 1548 | 1940 | ||
| 1549 | return sprintf(buf, "%d %d %d\n", x, y, z); | 1941 | return sprintf(buf, "%d %d %d\n", x, y, z); |
| 1550 | } | 1942 | } |
| 1943 | static DEVICE_ATTR_RO(position); | ||
| 1944 | |||
| 1945 | static ssize_t usb_sleep_charge_show(struct device *dev, | ||
| 1946 | struct device_attribute *attr, char *buf) | ||
| 1947 | { | ||
| 1948 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 1949 | u32 mode; | ||
| 1950 | int ret; | ||
| 1951 | |||
| 1952 | ret = toshiba_usb_sleep_charge_get(toshiba, &mode); | ||
| 1953 | if (ret < 0) | ||
| 1954 | return ret; | ||
| 1955 | |||
| 1956 | return sprintf(buf, "%x\n", mode & SCI_USB_CHARGE_MODE_MASK); | ||
| 1957 | } | ||
| 1958 | |||
| 1959 | static ssize_t usb_sleep_charge_store(struct device *dev, | ||
| 1960 | struct device_attribute *attr, | ||
| 1961 | const char *buf, size_t count) | ||
| 1962 | { | ||
| 1963 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 1964 | u32 mode; | ||
| 1965 | int state; | ||
| 1966 | int ret; | ||
| 1967 | |||
| 1968 | ret = kstrtoint(buf, 0, &state); | ||
| 1969 | if (ret) | ||
| 1970 | return ret; | ||
| 1971 | /* | ||
| 1972 | * Check for supported values, where: | ||
| 1973 | * 0 - Disabled | ||
| 1974 | * 1 - Alternate (Non USB conformant devices that require more power) | ||
| 1975 | * 2 - Auto (USB conformant devices) | ||
| 1976 | */ | ||
| 1977 | if (state != 0 && state != 1 && state != 2) | ||
| 1978 | return -EINVAL; | ||
| 1979 | |||
| 1980 | /* Set the USB charging mode to internal value */ | ||
| 1981 | if (state == 0) | ||
| 1982 | mode = SCI_USB_CHARGE_DISABLED; | ||
| 1983 | else if (state == 1) | ||
| 1984 | mode = SCI_USB_CHARGE_ALTERNATE; | ||
| 1985 | else if (state == 2) | ||
| 1986 | mode = SCI_USB_CHARGE_AUTO; | ||
| 1987 | |||
| 1988 | ret = toshiba_usb_sleep_charge_set(toshiba, mode); | ||
| 1989 | if (ret) | ||
| 1990 | return ret; | ||
| 1991 | |||
| 1992 | return count; | ||
| 1993 | } | ||
| 1994 | static DEVICE_ATTR_RW(usb_sleep_charge); | ||
| 1995 | |||
| 1996 | static ssize_t sleep_functions_on_battery_show(struct device *dev, | ||
| 1997 | struct device_attribute *attr, | ||
| 1998 | char *buf) | ||
| 1999 | { | ||
| 2000 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2001 | u32 state; | ||
| 2002 | int bat_lvl; | ||
| 2003 | int status; | ||
| 2004 | int ret; | ||
| 2005 | int tmp; | ||
| 2006 | |||
| 2007 | ret = toshiba_sleep_functions_status_get(toshiba, &state); | ||
| 2008 | if (ret < 0) | ||
| 2009 | return ret; | ||
| 2010 | |||
| 2011 | /* Determine the status: 0x4 - Enabled | 0x1 - Disabled */ | ||
| 2012 | tmp = state & SCI_USB_CHARGE_BAT_MASK; | ||
| 2013 | status = (tmp == 0x4) ? 1 : 0; | ||
| 2014 | /* Determine the battery level set */ | ||
| 2015 | bat_lvl = state >> HCI_MISC_SHIFT; | ||
| 2016 | |||
| 2017 | return sprintf(buf, "%d %d\n", status, bat_lvl); | ||
| 2018 | } | ||
| 2019 | |||
| 2020 | static ssize_t sleep_functions_on_battery_store(struct device *dev, | ||
| 2021 | struct device_attribute *attr, | ||
| 2022 | const char *buf, size_t count) | ||
| 2023 | { | ||
| 2024 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2025 | u32 status; | ||
| 2026 | int value; | ||
| 2027 | int ret; | ||
| 2028 | int tmp; | ||
| 2029 | |||
| 2030 | ret = kstrtoint(buf, 0, &value); | ||
| 2031 | if (ret) | ||
| 2032 | return ret; | ||
| 2033 | |||
| 2034 | /* | ||
| 2035 | * Set the status of the function: | ||
| 2036 | * 0 - Disabled | ||
| 2037 | * 1-100 - Enabled | ||
| 2038 | */ | ||
| 2039 | if (value < 0 || value > 100) | ||
| 2040 | return -EINVAL; | ||
| 2041 | |||
| 2042 | if (value == 0) { | ||
| 2043 | tmp = toshiba->usbsc_bat_level << HCI_MISC_SHIFT; | ||
| 2044 | status = tmp | SCI_USB_CHARGE_BAT_LVL_OFF; | ||
| 2045 | } else { | ||
| 2046 | tmp = value << HCI_MISC_SHIFT; | ||
| 2047 | status = tmp | SCI_USB_CHARGE_BAT_LVL_ON; | ||
| 2048 | } | ||
| 2049 | ret = toshiba_sleep_functions_status_set(toshiba, status); | ||
| 2050 | if (ret < 0) | ||
| 2051 | return ret; | ||
| 2052 | |||
| 2053 | toshiba->usbsc_bat_level = status >> HCI_MISC_SHIFT; | ||
| 2054 | |||
| 2055 | return count; | ||
| 2056 | } | ||
| 2057 | static DEVICE_ATTR_RW(sleep_functions_on_battery); | ||
| 2058 | |||
| 2059 | static ssize_t usb_rapid_charge_show(struct device *dev, | ||
| 2060 | struct device_attribute *attr, char *buf) | ||
| 2061 | { | ||
| 2062 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2063 | u32 state; | ||
| 2064 | int ret; | ||
| 2065 | |||
| 2066 | ret = toshiba_usb_rapid_charge_get(toshiba, &state); | ||
| 2067 | if (ret < 0) | ||
| 2068 | return ret; | ||
| 2069 | |||
| 2070 | return sprintf(buf, "%d\n", state); | ||
| 2071 | } | ||
| 2072 | |||
| 2073 | static ssize_t usb_rapid_charge_store(struct device *dev, | ||
| 2074 | struct device_attribute *attr, | ||
| 2075 | const char *buf, size_t count) | ||
| 2076 | { | ||
| 2077 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2078 | int state; | ||
| 2079 | int ret; | ||
| 2080 | |||
| 2081 | ret = kstrtoint(buf, 0, &state); | ||
| 2082 | if (ret) | ||
| 2083 | return ret; | ||
| 2084 | if (state != 0 && state != 1) | ||
| 2085 | return -EINVAL; | ||
| 2086 | |||
| 2087 | ret = toshiba_usb_rapid_charge_set(toshiba, state); | ||
| 2088 | if (ret) | ||
| 2089 | return ret; | ||
| 2090 | |||
| 2091 | return count; | ||
| 2092 | } | ||
| 2093 | static DEVICE_ATTR_RW(usb_rapid_charge); | ||
| 2094 | |||
| 2095 | static ssize_t usb_sleep_music_show(struct device *dev, | ||
| 2096 | struct device_attribute *attr, char *buf) | ||
| 2097 | { | ||
| 2098 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2099 | u32 state; | ||
| 2100 | int ret; | ||
| 2101 | |||
| 2102 | ret = toshiba_usb_sleep_music_get(toshiba, &state); | ||
| 2103 | if (ret < 0) | ||
| 2104 | return ret; | ||
| 2105 | |||
| 2106 | return sprintf(buf, "%d\n", state); | ||
| 2107 | } | ||
| 2108 | |||
| 2109 | static ssize_t usb_sleep_music_store(struct device *dev, | ||
| 2110 | struct device_attribute *attr, | ||
| 2111 | const char *buf, size_t count) | ||
| 2112 | { | ||
| 2113 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2114 | int state; | ||
| 2115 | int ret; | ||
| 2116 | |||
| 2117 | ret = kstrtoint(buf, 0, &state); | ||
| 2118 | if (ret) | ||
| 2119 | return ret; | ||
| 2120 | if (state != 0 && state != 1) | ||
| 2121 | return -EINVAL; | ||
| 2122 | |||
| 2123 | ret = toshiba_usb_sleep_music_set(toshiba, state); | ||
| 2124 | if (ret) | ||
| 2125 | return ret; | ||
| 2126 | |||
| 2127 | return count; | ||
| 2128 | } | ||
| 2129 | static DEVICE_ATTR_RW(usb_sleep_music); | ||
| 2130 | |||
| 2131 | static ssize_t kbd_function_keys_show(struct device *dev, | ||
| 2132 | struct device_attribute *attr, char *buf) | ||
| 2133 | { | ||
| 2134 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2135 | int mode; | ||
| 2136 | int ret; | ||
| 2137 | |||
| 2138 | ret = toshiba_function_keys_get(toshiba, &mode); | ||
| 2139 | if (ret < 0) | ||
| 2140 | return ret; | ||
| 2141 | |||
| 2142 | return sprintf(buf, "%d\n", mode); | ||
| 2143 | } | ||
| 2144 | |||
| 2145 | static ssize_t kbd_function_keys_store(struct device *dev, | ||
| 2146 | struct device_attribute *attr, | ||
| 2147 | const char *buf, size_t count) | ||
| 2148 | { | ||
| 2149 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2150 | int mode; | ||
| 2151 | int ret; | ||
| 2152 | |||
| 2153 | ret = kstrtoint(buf, 0, &mode); | ||
| 2154 | if (ret) | ||
| 2155 | return ret; | ||
| 2156 | /* | ||
| 2157 | * Check for the function keys mode where: | ||
| 2158 | * 0 - Normal operation (F{1-12} as usual and hotkeys via FN-F{1-12}) | ||
| 2159 | * 1 - Special functions (Opposite of the above setting) | ||
| 2160 | */ | ||
| 2161 | if (mode != 0 && mode != 1) | ||
| 2162 | return -EINVAL; | ||
| 2163 | |||
| 2164 | ret = toshiba_function_keys_set(toshiba, mode); | ||
| 2165 | if (ret) | ||
| 2166 | return ret; | ||
| 2167 | |||
| 2168 | pr_info("Reboot for changes to KBD Function Keys to take effect"); | ||
| 2169 | |||
| 2170 | return count; | ||
| 2171 | } | ||
| 2172 | static DEVICE_ATTR_RW(kbd_function_keys); | ||
| 2173 | |||
| 2174 | static ssize_t panel_power_on_show(struct device *dev, | ||
| 2175 | struct device_attribute *attr, char *buf) | ||
| 2176 | { | ||
| 2177 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2178 | u32 state; | ||
| 2179 | int ret; | ||
| 2180 | |||
| 2181 | ret = toshiba_panel_power_on_get(toshiba, &state); | ||
| 2182 | if (ret < 0) | ||
| 2183 | return ret; | ||
| 2184 | |||
| 2185 | return sprintf(buf, "%d\n", state); | ||
| 2186 | } | ||
| 2187 | |||
| 2188 | static ssize_t panel_power_on_store(struct device *dev, | ||
| 2189 | struct device_attribute *attr, | ||
| 2190 | const char *buf, size_t count) | ||
| 2191 | { | ||
| 2192 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2193 | int state; | ||
| 2194 | int ret; | ||
| 2195 | |||
| 2196 | ret = kstrtoint(buf, 0, &state); | ||
| 2197 | if (ret) | ||
| 2198 | return ret; | ||
| 2199 | if (state != 0 && state != 1) | ||
| 2200 | return -EINVAL; | ||
| 2201 | |||
| 2202 | ret = toshiba_panel_power_on_set(toshiba, state); | ||
| 2203 | if (ret) | ||
| 2204 | return ret; | ||
| 2205 | |||
| 2206 | pr_info("Reboot for changes to Panel Power ON to take effect"); | ||
| 2207 | |||
| 2208 | return count; | ||
| 2209 | } | ||
| 2210 | static DEVICE_ATTR_RW(panel_power_on); | ||
| 2211 | |||
| 2212 | static ssize_t usb_three_show(struct device *dev, | ||
| 2213 | struct device_attribute *attr, char *buf) | ||
| 2214 | { | ||
| 2215 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2216 | u32 state; | ||
| 2217 | int ret; | ||
| 2218 | |||
| 2219 | ret = toshiba_usb_three_get(toshiba, &state); | ||
| 2220 | if (ret < 0) | ||
| 2221 | return ret; | ||
| 2222 | |||
| 2223 | return sprintf(buf, "%d\n", state); | ||
| 2224 | } | ||
| 2225 | |||
| 2226 | static ssize_t usb_three_store(struct device *dev, | ||
| 2227 | struct device_attribute *attr, | ||
| 2228 | const char *buf, size_t count) | ||
| 2229 | { | ||
| 2230 | struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); | ||
| 2231 | int state; | ||
| 2232 | int ret; | ||
| 2233 | |||
| 2234 | ret = kstrtoint(buf, 0, &state); | ||
| 2235 | if (ret) | ||
| 2236 | return ret; | ||
| 2237 | /* | ||
| 2238 | * Check for USB 3 mode where: | ||
| 2239 | * 0 - Disabled (Acts like a USB 2 port, saving power) | ||
| 2240 | * 1 - Enabled | ||
| 2241 | */ | ||
| 2242 | if (state != 0 && state != 1) | ||
| 2243 | return -EINVAL; | ||
| 2244 | |||
| 2245 | ret = toshiba_usb_three_set(toshiba, state); | ||
| 2246 | if (ret) | ||
| 2247 | return ret; | ||
| 2248 | |||
| 2249 | pr_info("Reboot for changes to USB 3 to take effect"); | ||
| 2250 | |||
| 2251 | return count; | ||
| 2252 | } | ||
| 2253 | static DEVICE_ATTR_RW(usb_three); | ||
| 2254 | |||
| 2255 | static struct attribute *toshiba_attributes[] = { | ||
| 2256 | &dev_attr_version.attr, | ||
| 2257 | &dev_attr_fan.attr, | ||
| 2258 | &dev_attr_kbd_backlight_mode.attr, | ||
| 2259 | &dev_attr_kbd_type.attr, | ||
| 2260 | &dev_attr_available_kbd_modes.attr, | ||
| 2261 | &dev_attr_kbd_backlight_timeout.attr, | ||
| 2262 | &dev_attr_touchpad.attr, | ||
| 2263 | &dev_attr_position.attr, | ||
| 2264 | &dev_attr_usb_sleep_charge.attr, | ||
| 2265 | &dev_attr_sleep_functions_on_battery.attr, | ||
| 2266 | &dev_attr_usb_rapid_charge.attr, | ||
| 2267 | &dev_attr_usb_sleep_music.attr, | ||
| 2268 | &dev_attr_kbd_function_keys.attr, | ||
| 2269 | &dev_attr_panel_power_on.attr, | ||
| 2270 | &dev_attr_usb_three.attr, | ||
| 2271 | NULL, | ||
| 2272 | }; | ||
| 1551 | 2273 | ||
| 1552 | static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, | 2274 | static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, |
| 1553 | struct attribute *attr, int idx) | 2275 | struct attribute *attr, int idx) |
| @@ -1556,7 +2278,9 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, | |||
| 1556 | struct toshiba_acpi_dev *drv = dev_get_drvdata(dev); | 2278 | struct toshiba_acpi_dev *drv = dev_get_drvdata(dev); |
| 1557 | bool exists = true; | 2279 | bool exists = true; |
| 1558 | 2280 | ||
| 1559 | if (attr == &dev_attr_kbd_backlight_mode.attr) | 2281 | if (attr == &dev_attr_fan.attr) |
| 2282 | exists = (drv->fan_supported) ? true : false; | ||
| 2283 | else if (attr == &dev_attr_kbd_backlight_mode.attr) | ||
| 1560 | exists = (drv->kbd_illum_supported) ? true : false; | 2284 | exists = (drv->kbd_illum_supported) ? true : false; |
| 1561 | else if (attr == &dev_attr_kbd_backlight_timeout.attr) | 2285 | else if (attr == &dev_attr_kbd_backlight_timeout.attr) |
| 1562 | exists = (drv->kbd_mode == SCI_KBD_MODE_AUTO) ? true : false; | 2286 | exists = (drv->kbd_mode == SCI_KBD_MODE_AUTO) ? true : false; |
| @@ -1564,10 +2288,29 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, | |||
| 1564 | exists = (drv->touchpad_supported) ? true : false; | 2288 | exists = (drv->touchpad_supported) ? true : false; |
| 1565 | else if (attr == &dev_attr_position.attr) | 2289 | else if (attr == &dev_attr_position.attr) |
| 1566 | exists = (drv->accelerometer_supported) ? true : false; | 2290 | exists = (drv->accelerometer_supported) ? true : false; |
| 2291 | else if (attr == &dev_attr_usb_sleep_charge.attr) | ||
| 2292 | exists = (drv->usb_sleep_charge_supported) ? true : false; | ||
| 2293 | else if (attr == &dev_attr_sleep_functions_on_battery.attr) | ||
| 2294 | exists = (drv->usb_sleep_charge_supported) ? true : false; | ||
| 2295 | else if (attr == &dev_attr_usb_rapid_charge.attr) | ||
| 2296 | exists = (drv->usb_rapid_charge_supported) ? true : false; | ||
| 2297 | else if (attr == &dev_attr_usb_sleep_music.attr) | ||
| 2298 | exists = (drv->usb_sleep_music_supported) ? true : false; | ||
| 2299 | else if (attr == &dev_attr_kbd_function_keys.attr) | ||
| 2300 | exists = (drv->kbd_function_keys_supported) ? true : false; | ||
| 2301 | else if (attr == &dev_attr_panel_power_on.attr) | ||
| 2302 | exists = (drv->panel_power_on_supported) ? true : false; | ||
| 2303 | else if (attr == &dev_attr_usb_three.attr) | ||
| 2304 | exists = (drv->usb_three_supported) ? true : false; | ||
| 1567 | 2305 | ||
| 1568 | return exists ? attr->mode : 0; | 2306 | return exists ? attr->mode : 0; |
| 1569 | } | 2307 | } |
| 1570 | 2308 | ||
| 2309 | static struct attribute_group toshiba_attr_group = { | ||
| 2310 | .is_visible = toshiba_sysfs_is_visible, | ||
| 2311 | .attrs = toshiba_attributes, | ||
| 2312 | }; | ||
| 2313 | |||
| 1571 | /* | 2314 | /* |
| 1572 | * Hotkeys | 2315 | * Hotkeys |
| 1573 | */ | 2316 | */ |
| @@ -1644,7 +2387,7 @@ static void toshiba_acpi_report_hotkey(struct toshiba_acpi_dev *dev, | |||
| 1644 | if (scancode == 0x100) | 2387 | if (scancode == 0x100) |
| 1645 | return; | 2388 | return; |
| 1646 | 2389 | ||
| 1647 | /* act on key press; ignore key release */ | 2390 | /* Act on key press; ignore key release */ |
| 1648 | if (scancode & 0x80) | 2391 | if (scancode & 0x80) |
| 1649 | return; | 2392 | return; |
| 1650 | 2393 | ||
| @@ -1680,7 +2423,7 @@ static void toshiba_acpi_process_hotkeys(struct toshiba_acpi_dev *dev) | |||
| 1680 | hci_result = | 2423 | hci_result = |
| 1681 | hci_write1(dev, HCI_SYSTEM_EVENT, 1); | 2424 | hci_write1(dev, HCI_SYSTEM_EVENT, 1); |
| 1682 | pr_notice("Re-enabled hotkeys\n"); | 2425 | pr_notice("Re-enabled hotkeys\n"); |
| 1683 | /* fall through */ | 2426 | /* Fall through */ |
| 1684 | default: | 2427 | default: |
| 1685 | retries--; | 2428 | retries--; |
| 1686 | break; | 2429 | break; |
| @@ -1802,7 +2545,7 @@ static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev) | |||
| 1802 | props.type = BACKLIGHT_PLATFORM; | 2545 | props.type = BACKLIGHT_PLATFORM; |
| 1803 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; | 2546 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; |
| 1804 | 2547 | ||
| 1805 | /* adding an extra level and having 0 change to transflective mode */ | 2548 | /* Adding an extra level and having 0 change to transflective mode */ |
| 1806 | if (dev->tr_backlight_supported) | 2549 | if (dev->tr_backlight_supported) |
| 1807 | props.max_brightness++; | 2550 | props.max_brightness++; |
| 1808 | 2551 | ||
| @@ -1973,6 +2716,24 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
| 1973 | ret = toshiba_accelerometer_supported(dev); | 2716 | ret = toshiba_accelerometer_supported(dev); |
| 1974 | dev->accelerometer_supported = !ret; | 2717 | dev->accelerometer_supported = !ret; |
| 1975 | 2718 | ||
| 2719 | ret = toshiba_usb_sleep_charge_get(dev, &dummy); | ||
| 2720 | dev->usb_sleep_charge_supported = !ret; | ||
| 2721 | |||
| 2722 | ret = toshiba_usb_rapid_charge_get(dev, &dummy); | ||
| 2723 | dev->usb_rapid_charge_supported = !ret; | ||
| 2724 | |||
| 2725 | ret = toshiba_usb_sleep_music_get(dev, &dummy); | ||
| 2726 | dev->usb_sleep_music_supported = !ret; | ||
| 2727 | |||
| 2728 | ret = toshiba_function_keys_get(dev, &dummy); | ||
| 2729 | dev->kbd_function_keys_supported = !ret; | ||
| 2730 | |||
| 2731 | ret = toshiba_panel_power_on_get(dev, &dummy); | ||
| 2732 | dev->panel_power_on_supported = !ret; | ||
| 2733 | |||
| 2734 | ret = toshiba_usb_three_get(dev, &dummy); | ||
| 2735 | dev->usb_three_supported = !ret; | ||
| 2736 | |||
| 1976 | /* Determine whether or not BIOS supports fan and video interfaces */ | 2737 | /* Determine whether or not BIOS supports fan and video interfaces */ |
| 1977 | 2738 | ||
| 1978 | ret = get_video_status(dev, &dummy); | 2739 | ret = get_video_status(dev, &dummy); |
