diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-19 13:56:51 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-19 13:56:51 -0500 |
commit | 6ed3e57fd2ffe63385e0073fe3cde8bf91b4c9fa (patch) | |
tree | 0eb9265c6c04ee0fa3d7bd773ca8d98bf2fb69b2 /drivers/platform/x86 | |
parent | b11a2783974791d37e44abbb48d41e8c120b5126 (diff) | |
parent | c57c0fa4bc9c2ad023674ef478c25719abaace7d (diff) |
Merge tag 'platform-drivers-x86-v3.20-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86
Pull platform driver update from Darren Hart:
"This includes a significant update to the toshiba_acpi driver,
bringing it to feature parity with the Windows driver, followed by
some needed cleanups.
The other changes are mostly minor updates, quirks, sparse fixes, or
cleanups.
Details:
- toshiba_acpi:
Add support for missing features from the Windows driver, bump the
sysfs version, and clean up the driver.
- thinkpad_acpi:
BIOS string versions, unhandled hkey events.
- msamsung-laptop:
Add native backlight quirk, enable better lid handling.
- intel_scu_ipc:
Read resources from PCI configuration
- other:
Fix sparse warnings, general cleanups"
* tag 'platform-drivers-x86-v3.20-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86: (34 commits)
toshiba_acpi: Cleanup GPL header
toshiba_acpi: Cleanup comment blocks and capitalization
toshiba_acpi: Make use of DEVICE_ATTR_{RO, RW} macros
toshiba_acpi: Drop the toshiba_ prefix from sysfs function names
toshiba_acpi: Move sysfs function and struct declarations further down
Documentation/ABI: Add file describing the sysfs entries for toshiba_acpi
toshiba_acpi: Clean file according to coding style
toshiba_acpi: Bump version number to 0.21
toshiba_acpi: Add support to enable/disable USB 3
toshiba_acpi: Add support for Panel Power ON
toshiba_acpi: Add support for Keyboard functions mode
toshiba_acpi: Add fan entry to sysfs
toshiba_acpi: Add version entry to sysfs
thinkpad_acpi: support new BIOS version string pattern
thinkpad_acpi: unhandled hkey event
toshiba_acpi: Make toshiba_eco_mode_available more robust
classmate-laptop: Fix sparse warning (0 as NULL)
Sony-laptop: Fix sparse warning (make undeclared var static)
thinkpad_acpi.c: Fix sparse warning (make undeclared var static)
samsung-laptop.c: Prefer kstrtoint over single variable sscanf
...
Diffstat (limited to 'drivers/platform/x86')
-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 |
8 files changed, 1137 insertions, 243 deletions
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); |