diff options
Diffstat (limited to 'drivers')
-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"); |