diff options
| -rw-r--r-- | drivers/platform/x86/acer-wmi.c | 416 |
1 files changed, 213 insertions, 203 deletions
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index fc7c9733bba5..017b1a7eac8e 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
| @@ -190,6 +190,7 @@ enum interface_flags { | |||
| 190 | ACER_AMW0, | 190 | ACER_AMW0, |
| 191 | ACER_AMW0_V2, | 191 | ACER_AMW0_V2, |
| 192 | ACER_WMID, | 192 | ACER_WMID, |
| 193 | ACER_WMID_v2, | ||
| 193 | }; | 194 | }; |
| 194 | 195 | ||
| 195 | #define ACER_DEFAULT_WIRELESS 0 | 196 | #define ACER_DEFAULT_WIRELESS 0 |
| @@ -877,6 +878,177 @@ static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface) | |||
| 877 | return WMI_execute_u32(method_id, (u32)value, NULL); | 878 | return WMI_execute_u32(method_id, (u32)value, NULL); |
| 878 | } | 879 | } |
| 879 | 880 | ||
| 881 | static acpi_status wmid3_get_device_status(u32 *value, u16 device) | ||
| 882 | { | ||
| 883 | struct wmid3_gds_return_value return_value; | ||
| 884 | acpi_status status; | ||
| 885 | union acpi_object *obj; | ||
| 886 | struct wmid3_gds_input_param params = { | ||
| 887 | .function_num = 0x1, | ||
| 888 | .hotkey_number = 0x01, | ||
| 889 | .devices = device, | ||
| 890 | }; | ||
| 891 | struct acpi_buffer input = { | ||
| 892 | sizeof(struct wmid3_gds_input_param), | ||
| 893 | ¶ms | ||
| 894 | }; | ||
| 895 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 896 | |||
| 897 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); | ||
| 898 | if (ACPI_FAILURE(status)) | ||
| 899 | return status; | ||
| 900 | |||
| 901 | obj = output.pointer; | ||
| 902 | |||
| 903 | if (!obj) | ||
| 904 | return AE_ERROR; | ||
| 905 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
| 906 | kfree(obj); | ||
| 907 | return AE_ERROR; | ||
| 908 | } | ||
| 909 | if (obj->buffer.length != 8) { | ||
| 910 | pr_warn("Unknown buffer length %d\n", obj->buffer.length); | ||
| 911 | kfree(obj); | ||
| 912 | return AE_ERROR; | ||
| 913 | } | ||
| 914 | |||
| 915 | return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); | ||
| 916 | kfree(obj); | ||
| 917 | |||
| 918 | if (return_value.error_code || return_value.ec_return_value) | ||
| 919 | pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n", | ||
| 920 | device, | ||
| 921 | return_value.error_code, | ||
| 922 | return_value.ec_return_value); | ||
| 923 | else | ||
| 924 | *value = !!(return_value.devices & device); | ||
| 925 | |||
| 926 | return status; | ||
| 927 | } | ||
| 928 | |||
| 929 | static acpi_status wmid_v2_get_u32(u32 *value, u32 cap) | ||
| 930 | { | ||
| 931 | u16 device; | ||
| 932 | |||
| 933 | switch (cap) { | ||
| 934 | case ACER_CAP_WIRELESS: | ||
| 935 | device = ACER_WMID3_GDS_WIRELESS; | ||
| 936 | break; | ||
| 937 | case ACER_CAP_BLUETOOTH: | ||
| 938 | device = ACER_WMID3_GDS_BLUETOOTH; | ||
| 939 | break; | ||
| 940 | case ACER_CAP_THREEG: | ||
| 941 | device = ACER_WMID3_GDS_THREEG; | ||
| 942 | break; | ||
| 943 | default: | ||
| 944 | return AE_ERROR; | ||
| 945 | } | ||
| 946 | return wmid3_get_device_status(value, device); | ||
| 947 | } | ||
| 948 | |||
| 949 | static acpi_status wmid3_set_device_status(u32 value, u16 device) | ||
| 950 | { | ||
| 951 | struct wmid3_gds_return_value return_value; | ||
| 952 | acpi_status status; | ||
| 953 | union acpi_object *obj; | ||
| 954 | u16 devices; | ||
| 955 | struct wmid3_gds_input_param params = { | ||
| 956 | .function_num = 0x1, | ||
| 957 | .hotkey_number = 0x01, | ||
| 958 | .devices = ACER_WMID3_GDS_WIRELESS | | ||
| 959 | ACER_WMID3_GDS_THREEG | | ||
| 960 | ACER_WMID3_GDS_WIMAX | | ||
| 961 | ACER_WMID3_GDS_BLUETOOTH, | ||
| 962 | }; | ||
| 963 | struct acpi_buffer input = { | ||
| 964 | sizeof(struct wmid3_gds_input_param), | ||
| 965 | ¶ms | ||
| 966 | }; | ||
| 967 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 968 | struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 969 | |||
| 970 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); | ||
| 971 | if (ACPI_FAILURE(status)) | ||
| 972 | return status; | ||
| 973 | |||
| 974 | obj = output.pointer; | ||
| 975 | |||
| 976 | if (!obj) | ||
| 977 | return AE_ERROR; | ||
| 978 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
| 979 | kfree(obj); | ||
| 980 | return AE_ERROR; | ||
| 981 | } | ||
| 982 | if (obj->buffer.length != 8) { | ||
| 983 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | ||
| 984 | kfree(obj); | ||
| 985 | return AE_ERROR; | ||
| 986 | } | ||
| 987 | |||
| 988 | return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); | ||
| 989 | kfree(obj); | ||
| 990 | |||
| 991 | if (return_value.error_code || return_value.ec_return_value) { | ||
| 992 | pr_warning("Get Current Device Status failed: " | ||
| 993 | "0x%x - 0x%x\n", return_value.error_code, | ||
| 994 | return_value.ec_return_value); | ||
| 995 | return status; | ||
| 996 | } | ||
| 997 | |||
| 998 | devices = return_value.devices; | ||
| 999 | params.function_num = 0x2; | ||
| 1000 | params.hotkey_number = 0x01; | ||
| 1001 | params.devices = (value) ? (devices | device) : (devices & ~device); | ||
| 1002 | |||
| 1003 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output2); | ||
| 1004 | if (ACPI_FAILURE(status)) | ||
| 1005 | return status; | ||
| 1006 | |||
| 1007 | obj = output2.pointer; | ||
| 1008 | |||
| 1009 | if (!obj) | ||
| 1010 | return AE_ERROR; | ||
| 1011 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
| 1012 | kfree(obj); | ||
| 1013 | return AE_ERROR; | ||
| 1014 | } | ||
| 1015 | if (obj->buffer.length != 4) { | ||
| 1016 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | ||
| 1017 | kfree(obj); | ||
| 1018 | return AE_ERROR; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); | ||
| 1022 | kfree(obj); | ||
| 1023 | |||
| 1024 | if (return_value.error_code || return_value.ec_return_value) | ||
| 1025 | pr_warning("Set Device Status failed: " | ||
| 1026 | "0x%x - 0x%x\n", return_value.error_code, | ||
| 1027 | return_value.ec_return_value); | ||
| 1028 | |||
| 1029 | return status; | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | static acpi_status wmid_v2_set_u32(u32 value, u32 cap) | ||
| 1033 | { | ||
| 1034 | u16 device; | ||
| 1035 | |||
| 1036 | switch (cap) { | ||
| 1037 | case ACER_CAP_WIRELESS: | ||
| 1038 | device = ACER_WMID3_GDS_WIRELESS; | ||
| 1039 | break; | ||
| 1040 | case ACER_CAP_BLUETOOTH: | ||
| 1041 | device = ACER_WMID3_GDS_BLUETOOTH; | ||
| 1042 | break; | ||
| 1043 | case ACER_CAP_THREEG: | ||
| 1044 | device = ACER_WMID3_GDS_THREEG; | ||
| 1045 | break; | ||
| 1046 | default: | ||
| 1047 | return AE_ERROR; | ||
| 1048 | } | ||
| 1049 | return wmid3_set_device_status(value, device); | ||
| 1050 | } | ||
| 1051 | |||
| 880 | static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy) | 1052 | static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy) |
| 881 | { | 1053 | { |
| 882 | struct hotkey_function_type_aa *type_aa; | 1054 | struct hotkey_function_type_aa *type_aa; |
| @@ -922,17 +1094,11 @@ static acpi_status WMID_set_capabilities(void) | |||
| 922 | return AE_ERROR; | 1094 | return AE_ERROR; |
| 923 | } | 1095 | } |
| 924 | 1096 | ||
| 925 | dmi_walk(type_aa_dmi_decode, NULL); | 1097 | interface->capability |= ACER_CAP_WIRELESS; |
| 926 | if (!has_type_aa) { | 1098 | if (devices & 0x40) |
| 927 | interface->capability |= ACER_CAP_WIRELESS; | 1099 | interface->capability |= ACER_CAP_THREEG; |
| 928 | if (devices & 0x40) | 1100 | if (devices & 0x10) |
| 929 | interface->capability |= ACER_CAP_THREEG; | 1101 | interface->capability |= ACER_CAP_BLUETOOTH; |
| 930 | if (devices & 0x10) | ||
| 931 | interface->capability |= ACER_CAP_BLUETOOTH; | ||
| 932 | } | ||
| 933 | |||
| 934 | /* WMID always provides brightness methods */ | ||
| 935 | interface->capability |= ACER_CAP_BRIGHTNESS; | ||
| 936 | 1102 | ||
| 937 | if (!(devices & 0x20)) | 1103 | if (!(devices & 0x20)) |
| 938 | max_brightness = 0x9; | 1104 | max_brightness = 0x9; |
| @@ -945,6 +1111,10 @@ static struct wmi_interface wmid_interface = { | |||
| 945 | .type = ACER_WMID, | 1111 | .type = ACER_WMID, |
| 946 | }; | 1112 | }; |
| 947 | 1113 | ||
| 1114 | static struct wmi_interface wmid_v2_interface = { | ||
| 1115 | .type = ACER_WMID_v2, | ||
| 1116 | }; | ||
| 1117 | |||
| 948 | /* | 1118 | /* |
| 949 | * Generic Device (interface-independent) | 1119 | * Generic Device (interface-independent) |
| 950 | */ | 1120 | */ |
| @@ -965,6 +1135,14 @@ static acpi_status get_u32(u32 *value, u32 cap) | |||
| 965 | case ACER_WMID: | 1135 | case ACER_WMID: |
| 966 | status = WMID_get_u32(value, cap, interface); | 1136 | status = WMID_get_u32(value, cap, interface); |
| 967 | break; | 1137 | break; |
| 1138 | case ACER_WMID_v2: | ||
| 1139 | if (cap & (ACER_CAP_WIRELESS | | ||
| 1140 | ACER_CAP_BLUETOOTH | | ||
| 1141 | ACER_CAP_THREEG)) | ||
| 1142 | status = wmid_v2_get_u32(value, cap); | ||
| 1143 | else if (wmi_has_guid(WMID_GUID2)) | ||
| 1144 | status = WMID_get_u32(value, cap, interface); | ||
| 1145 | break; | ||
| 968 | } | 1146 | } |
| 969 | 1147 | ||
| 970 | return status; | 1148 | return status; |
| @@ -998,6 +1176,13 @@ static acpi_status set_u32(u32 value, u32 cap) | |||
| 998 | } | 1176 | } |
| 999 | case ACER_WMID: | 1177 | case ACER_WMID: |
| 1000 | return WMID_set_u32(value, cap, interface); | 1178 | return WMID_set_u32(value, cap, interface); |
| 1179 | case ACER_WMID_v2: | ||
| 1180 | if (cap & (ACER_CAP_WIRELESS | | ||
| 1181 | ACER_CAP_BLUETOOTH | | ||
| 1182 | ACER_CAP_THREEG)) | ||
| 1183 | return wmid_v2_set_u32(value, cap); | ||
| 1184 | else if (wmi_has_guid(WMID_GUID2)) | ||
| 1185 | return WMID_set_u32(value, cap, interface); | ||
| 1001 | default: | 1186 | default: |
| 1002 | return AE_BAD_PARAMETER; | 1187 | return AE_BAD_PARAMETER; |
| 1003 | } | 1188 | } |
| @@ -1104,186 +1289,6 @@ static void acer_backlight_exit(void) | |||
| 1104 | backlight_device_unregister(acer_backlight_device); | 1289 | backlight_device_unregister(acer_backlight_device); |
| 1105 | } | 1290 | } |
| 1106 | 1291 | ||
| 1107 | static acpi_status wmid3_get_device_status(u32 *value, u16 device) | ||
| 1108 | { | ||
| 1109 | struct wmid3_gds_return_value return_value; | ||
| 1110 | acpi_status status; | ||
| 1111 | union acpi_object *obj; | ||
| 1112 | struct wmid3_gds_input_param params = { | ||
| 1113 | .function_num = 0x1, | ||
| 1114 | .hotkey_number = 0x01, | ||
| 1115 | .devices = device, | ||
| 1116 | }; | ||
| 1117 | struct acpi_buffer input = { | ||
| 1118 | sizeof(struct wmid3_gds_input_param), | ||
| 1119 | ¶ms | ||
| 1120 | }; | ||
| 1121 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 1122 | |||
| 1123 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); | ||
| 1124 | if (ACPI_FAILURE(status)) | ||
| 1125 | return status; | ||
| 1126 | |||
| 1127 | obj = output.pointer; | ||
| 1128 | |||
| 1129 | if (!obj) | ||
| 1130 | return AE_ERROR; | ||
| 1131 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
| 1132 | kfree(obj); | ||
| 1133 | return AE_ERROR; | ||
| 1134 | } | ||
| 1135 | if (obj->buffer.length != 8) { | ||
| 1136 | pr_warn("Unknown buffer length %d\n", obj->buffer.length); | ||
| 1137 | kfree(obj); | ||
| 1138 | return AE_ERROR; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); | ||
| 1142 | kfree(obj); | ||
| 1143 | |||
| 1144 | if (return_value.error_code || return_value.ec_return_value) | ||
| 1145 | pr_warn("Get Device Status failed: 0x%x - 0x%x\n", | ||
| 1146 | return_value.error_code, | ||
| 1147 | return_value.ec_return_value); | ||
| 1148 | else | ||
| 1149 | *value = !!(return_value.devices & device); | ||
| 1150 | |||
| 1151 | return status; | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | static acpi_status get_device_status(u32 *value, u32 cap) | ||
| 1155 | { | ||
| 1156 | if (wmi_has_guid(WMID_GUID3)) { | ||
| 1157 | u16 device; | ||
| 1158 | |||
| 1159 | switch (cap) { | ||
| 1160 | case ACER_CAP_WIRELESS: | ||
| 1161 | device = ACER_WMID3_GDS_WIRELESS; | ||
| 1162 | break; | ||
| 1163 | case ACER_CAP_BLUETOOTH: | ||
| 1164 | device = ACER_WMID3_GDS_BLUETOOTH; | ||
| 1165 | break; | ||
| 1166 | case ACER_CAP_THREEG: | ||
| 1167 | device = ACER_WMID3_GDS_THREEG; | ||
| 1168 | break; | ||
| 1169 | default: | ||
| 1170 | return AE_ERROR; | ||
| 1171 | } | ||
| 1172 | return wmid3_get_device_status(value, device); | ||
| 1173 | |||
| 1174 | } else { | ||
| 1175 | return get_u32(value, cap); | ||
| 1176 | } | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | static acpi_status wmid3_set_device_status(u32 value, u16 device) | ||
| 1180 | { | ||
| 1181 | struct wmid3_gds_return_value return_value; | ||
| 1182 | acpi_status status; | ||
| 1183 | union acpi_object *obj; | ||
| 1184 | u16 devices; | ||
| 1185 | struct wmid3_gds_input_param params = { | ||
| 1186 | .function_num = 0x1, | ||
| 1187 | .hotkey_number = 0x01, | ||
| 1188 | .devices = ACER_WMID3_GDS_WIRELESS | | ||
| 1189 | ACER_WMID3_GDS_THREEG | | ||
| 1190 | ACER_WMID3_GDS_WIMAX | | ||
| 1191 | ACER_WMID3_GDS_BLUETOOTH, | ||
| 1192 | }; | ||
| 1193 | struct acpi_buffer input = { | ||
| 1194 | sizeof(struct wmid3_gds_input_param), | ||
| 1195 | ¶ms | ||
| 1196 | }; | ||
| 1197 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 1198 | struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 1199 | |||
| 1200 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); | ||
| 1201 | if (ACPI_FAILURE(status)) | ||
| 1202 | return status; | ||
| 1203 | |||
| 1204 | obj = output.pointer; | ||
| 1205 | |||
| 1206 | if (!obj) | ||
| 1207 | return AE_ERROR; | ||
| 1208 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
| 1209 | kfree(obj); | ||
| 1210 | return AE_ERROR; | ||
| 1211 | } | ||
| 1212 | if (obj->buffer.length != 8) { | ||
| 1213 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | ||
| 1214 | kfree(obj); | ||
| 1215 | return AE_ERROR; | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); | ||
| 1219 | kfree(obj); | ||
| 1220 | |||
| 1221 | if (return_value.error_code || return_value.ec_return_value) { | ||
| 1222 | pr_warning("Get Current Device Status failed: " | ||
| 1223 | "0x%x - 0x%x\n", return_value.error_code, | ||
| 1224 | return_value.ec_return_value); | ||
| 1225 | return status; | ||
| 1226 | } | ||
| 1227 | |||
| 1228 | devices = return_value.devices; | ||
| 1229 | params.function_num = 0x2; | ||
| 1230 | params.hotkey_number = 0x01; | ||
| 1231 | params.devices = (value) ? (devices | device) : (devices & ~device); | ||
| 1232 | |||
| 1233 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output2); | ||
| 1234 | if (ACPI_FAILURE(status)) | ||
| 1235 | return status; | ||
| 1236 | |||
| 1237 | obj = output2.pointer; | ||
| 1238 | |||
| 1239 | if (!obj) | ||
| 1240 | return AE_ERROR; | ||
| 1241 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
| 1242 | kfree(obj); | ||
| 1243 | return AE_ERROR; | ||
| 1244 | } | ||
| 1245 | if (obj->buffer.length != 4) { | ||
| 1246 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | ||
| 1247 | kfree(obj); | ||
| 1248 | return AE_ERROR; | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); | ||
| 1252 | kfree(obj); | ||
| 1253 | |||
| 1254 | if (return_value.error_code || return_value.ec_return_value) | ||
| 1255 | pr_warning("Set Device Status failed: " | ||
| 1256 | "0x%x - 0x%x\n", return_value.error_code, | ||
| 1257 | return_value.ec_return_value); | ||
| 1258 | |||
| 1259 | return status; | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | static acpi_status set_device_status(u32 value, u32 cap) | ||
| 1263 | { | ||
| 1264 | if (wmi_has_guid(WMID_GUID3)) { | ||
| 1265 | u16 device; | ||
| 1266 | |||
| 1267 | switch (cap) { | ||
| 1268 | case ACER_CAP_WIRELESS: | ||
| 1269 | device = ACER_WMID3_GDS_WIRELESS; | ||
| 1270 | break; | ||
| 1271 | case ACER_CAP_BLUETOOTH: | ||
| 1272 | device = ACER_WMID3_GDS_BLUETOOTH; | ||
| 1273 | break; | ||
| 1274 | case ACER_CAP_THREEG: | ||
| 1275 | device = ACER_WMID3_GDS_THREEG; | ||
| 1276 | break; | ||
| 1277 | default: | ||
| 1278 | return AE_ERROR; | ||
| 1279 | } | ||
| 1280 | return wmid3_set_device_status(value, device); | ||
| 1281 | |||
| 1282 | } else { | ||
| 1283 | return set_u32(value, cap); | ||
| 1284 | } | ||
| 1285 | } | ||
| 1286 | |||
| 1287 | /* | 1292 | /* |
| 1288 | * Rfkill devices | 1293 | * Rfkill devices |
| 1289 | */ | 1294 | */ |
| @@ -1311,8 +1316,7 @@ static void acer_rfkill_update(struct work_struct *ignored) | |||
| 1311 | } | 1316 | } |
| 1312 | 1317 | ||
| 1313 | if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) { | 1318 | if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) { |
| 1314 | status = wmid3_get_device_status(&state, | 1319 | status = get_u32(&state, ACER_WMID3_GDS_THREEG); |
| 1315 | ACER_WMID3_GDS_THREEG); | ||
| 1316 | if (ACPI_SUCCESS(status)) | 1320 | if (ACPI_SUCCESS(status)) |
| 1317 | rfkill_set_sw_state(threeg_rfkill, !state); | 1321 | rfkill_set_sw_state(threeg_rfkill, !state); |
| 1318 | } | 1322 | } |
| @@ -1326,7 +1330,7 @@ static int acer_rfkill_set(void *data, bool blocked) | |||
| 1326 | u32 cap = (unsigned long)data; | 1330 | u32 cap = (unsigned long)data; |
| 1327 | 1331 | ||
| 1328 | if (rfkill_inited) { | 1332 | if (rfkill_inited) { |
| 1329 | status = set_device_status(!blocked, cap); | 1333 | status = set_u32(!blocked, cap); |
| 1330 | if (ACPI_FAILURE(status)) | 1334 | if (ACPI_FAILURE(status)) |
| 1331 | return -ENODEV; | 1335 | return -ENODEV; |
| 1332 | } | 1336 | } |
| @@ -1353,7 +1357,7 @@ static struct rfkill *acer_rfkill_register(struct device *dev, | |||
| 1353 | if (!rfkill_dev) | 1357 | if (!rfkill_dev) |
| 1354 | return ERR_PTR(-ENOMEM); | 1358 | return ERR_PTR(-ENOMEM); |
| 1355 | 1359 | ||
| 1356 | status = get_device_status(&state, cap); | 1360 | status = get_u32(&state, cap); |
| 1357 | 1361 | ||
| 1358 | err = rfkill_register(rfkill_dev); | 1362 | err = rfkill_register(rfkill_dev); |
| 1359 | if (err) { | 1363 | if (err) { |
| @@ -1457,11 +1461,7 @@ static ssize_t show_bool_threeg(struct device *dev, | |||
| 1457 | 1461 | ||
| 1458 | pr_info("This threeg sysfs will be removed in 2012" | 1462 | pr_info("This threeg sysfs will be removed in 2012" |
| 1459 | " - used by: %s\n", current->comm); | 1463 | " - used by: %s\n", current->comm); |
| 1460 | if (wmi_has_guid(WMID_GUID3)) | 1464 | status = get_u32(&result, ACER_CAP_THREEG); |
| 1461 | status = wmid3_get_device_status(&result, | ||
| 1462 | ACER_WMID3_GDS_THREEG); | ||
| 1463 | else | ||
| 1464 | status = get_u32(&result, ACER_CAP_THREEG); | ||
| 1465 | if (ACPI_SUCCESS(status)) | 1465 | if (ACPI_SUCCESS(status)) |
| 1466 | return sprintf(buf, "%u\n", result); | 1466 | return sprintf(buf, "%u\n", result); |
| 1467 | return sprintf(buf, "Read error\n"); | 1467 | return sprintf(buf, "Read error\n"); |
| @@ -1493,6 +1493,8 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr, | |||
| 1493 | return sprintf(buf, "AMW0 v2\n"); | 1493 | return sprintf(buf, "AMW0 v2\n"); |
| 1494 | case ACER_WMID: | 1494 | case ACER_WMID: |
| 1495 | return sprintf(buf, "WMID\n"); | 1495 | return sprintf(buf, "WMID\n"); |
| 1496 | case ACER_WMID_v2: | ||
| 1497 | return sprintf(buf, "WMID v2\n"); | ||
| 1496 | default: | 1498 | default: |
| 1497 | return sprintf(buf, "Error!\n"); | 1499 | return sprintf(buf, "Error!\n"); |
| 1498 | } | 1500 | } |
| @@ -1912,12 +1914,20 @@ static int __init acer_wmi_init(void) | |||
| 1912 | if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) | 1914 | if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) |
| 1913 | interface = &wmid_interface; | 1915 | interface = &wmid_interface; |
| 1914 | 1916 | ||
| 1917 | if (wmi_has_guid(WMID_GUID3)) | ||
| 1918 | interface = &wmid_v2_interface; | ||
| 1919 | |||
| 1920 | if (interface) | ||
| 1921 | dmi_walk(type_aa_dmi_decode, NULL); | ||
| 1922 | |||
| 1915 | if (wmi_has_guid(WMID_GUID2) && interface) { | 1923 | if (wmi_has_guid(WMID_GUID2) && interface) { |
| 1916 | if (ACPI_FAILURE(WMID_set_capabilities())) { | 1924 | if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) { |
| 1917 | pr_err("Unable to detect available WMID devices\n"); | 1925 | pr_err("Unable to detect available WMID devices\n"); |
| 1918 | return -ENODEV; | 1926 | return -ENODEV; |
| 1919 | } | 1927 | } |
| 1920 | } else if (!wmi_has_guid(WMID_GUID2) && interface) { | 1928 | /* WMID always provides brightness methods */ |
| 1929 | interface->capability |= ACER_CAP_BRIGHTNESS; | ||
| 1930 | } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) { | ||
| 1921 | pr_err("No WMID device detection method found\n"); | 1931 | pr_err("No WMID device detection method found\n"); |
| 1922 | return -ENODEV; | 1932 | return -ENODEV; |
| 1923 | } | 1933 | } |
| @@ -1941,7 +1951,7 @@ static int __init acer_wmi_init(void) | |||
| 1941 | 1951 | ||
| 1942 | set_quirks(); | 1952 | set_quirks(); |
| 1943 | 1953 | ||
| 1944 | if (acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) { | 1954 | if (acpi_video_backlight_support()) { |
| 1945 | interface->capability &= ~ACER_CAP_BRIGHTNESS; | 1955 | interface->capability &= ~ACER_CAP_BRIGHTNESS; |
| 1946 | pr_info("Brightness must be controlled by " | 1956 | pr_info("Brightness must be controlled by " |
| 1947 | "generic video driver\n"); | 1957 | "generic video driver\n"); |
