aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/asus_acpi.c183
1 files changed, 93 insertions, 90 deletions
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 099f92a2c6f2..07b4c8b872cb 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -1044,6 +1044,65 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
1044} 1044}
1045 1045
1046/* 1046/*
1047 * Match the model string to the list of supported models. Return END_MODEL if
1048 * no match or model is NULL.
1049 */
1050static int asus_model_match(char *model)
1051{
1052 if (model == NULL)
1053 return END_MODEL;
1054
1055 if (strncmp(model, "L3D", 3) == 0)
1056 return L3D;
1057 else if (strncmp(model, "L2E", 3) == 0 ||
1058 strncmp(model, "L3H", 3) == 0 || strncmp(model, "L5D", 3) == 0)
1059 return L3H;
1060 else if (strncmp(model, "L3", 2) == 0 || strncmp(model, "L2B", 3) == 0)
1061 return L3C;
1062 else if (strncmp(model, "L8L", 3) == 0)
1063 return L8L;
1064 else if (strncmp(model, "L4R", 3) == 0)
1065 return L4R;
1066 else if (strncmp(model, "M6N", 3) == 0 || strncmp(model, "W3N", 3) == 0)
1067 return M6N;
1068 else if (strncmp(model, "M6R", 3) == 0 || strncmp(model, "A3G", 3) == 0)
1069 return M6R;
1070 else if (strncmp(model, "M2N", 3) == 0 ||
1071 strncmp(model, "M3N", 3) == 0 ||
1072 strncmp(model, "M5N", 3) == 0 ||
1073 strncmp(model, "M6N", 3) == 0 ||
1074 strncmp(model, "S1N", 3) == 0 ||
1075 strncmp(model, "S5N", 3) == 0 || strncmp(model, "W1N", 3) == 0)
1076 return xxN;
1077 else if (strncmp(model, "M1", 2) == 0)
1078 return M1A;
1079 else if (strncmp(model, "M2", 2) == 0 || strncmp(model, "L4E", 3) == 0)
1080 return M2E;
1081 else if (strncmp(model, "L2", 2) == 0)
1082 return L2D;
1083 else if (strncmp(model, "L8", 2) == 0)
1084 return S1x;
1085 else if (strncmp(model, "D1", 2) == 0)
1086 return D1x;
1087 else if (strncmp(model, "A1", 2) == 0)
1088 return A1x;
1089 else if (strncmp(model, "A2", 2) == 0)
1090 return A2x;
1091 else if (strncmp(model, "J1", 2) == 0)
1092 return S2x;
1093 else if (strncmp(model, "L5", 2) == 0)
1094 return L5x;
1095 else if (strncmp(model, "A4G", 3) == 0)
1096 return A4G;
1097 else if (strncmp(model, "W1N", 3) == 0)
1098 return W1N;
1099 else if (strncmp(model, "W5A", 3) == 0)
1100 return W5A;
1101 else
1102 return END_MODEL;
1103}
1104
1105/*
1047 * This function is used to initialize the hotk with right values. In this 1106 * This function is used to initialize the hotk with right values. In this
1048 * method, we can make all the detection we want, and modify the hotk struct 1107 * method, we can make all the detection we want, and modify the hotk struct
1049 */ 1108 */
@@ -1053,6 +1112,7 @@ static int asus_hotk_get_info(void)
1053 struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; 1112 struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL };
1054 union acpi_object *model = NULL; 1113 union acpi_object *model = NULL;
1055 int bsts_result; 1114 int bsts_result;
1115 char *string = NULL;
1056 acpi_status status; 1116 acpi_status status;
1057 1117
1058 /* 1118 /*
@@ -1082,120 +1142,63 @@ static int asus_hotk_get_info(void)
1082 printk(KERN_NOTICE " BSTS called, 0x%02x returned\n", 1142 printk(KERN_NOTICE " BSTS called, 0x%02x returned\n",
1083 bsts_result); 1143 bsts_result);
1084 1144
1085 /* This is unlikely with implicit return */
1086 if (buffer.pointer == NULL)
1087 return -EINVAL;
1088
1089 model = (union acpi_object *)buffer.pointer;
1090 /* 1145 /*
1091 * Samsung P30 has a device with a valid _HID whose INIT does not 1146 * Try to match the object returned by INIT to the specific model.
1092 * return anything. It used to be possible to catch this exception, 1147 * Handle every possible object (or the lack of thereof) the DSDT
1093 * but the implicit return code will now happily confuse the 1148 * writers might throw at us. When in trouble, we pass NULL to
1094 * driver. We assume that every ACPI_TYPE_STRING is a valid model 1149 * asus_model_match() and try something completely different.
1095 * identifier but it's still possible to get completely bogus data.
1096 */ 1150 */
1097 if (model->type == ACPI_TYPE_STRING) { 1151 if (buffer.pointer) {
1098 printk(KERN_NOTICE " %s model detected, ", 1152 model = (union acpi_object *)buffer.pointer;
1099 model->string.pointer); 1153 switch (model->type) {
1100 } else { 1154 case ACPI_TYPE_STRING:
1101 if (asus_info && /* Samsung P30 */ 1155 string = model->string.pointer;
1156 break;
1157 case ACPI_TYPE_BUFFER:
1158 string = model->buffer.pointer;
1159 break;
1160 default:
1161 kfree(model);
1162 break;
1163 }
1164 }
1165 hotk->model = asus_model_match(string);
1166 if (hotk->model == END_MODEL) { /* match failed */
1167 if (asus_info &&
1102 strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) { 1168 strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) {
1103 hotk->model = P30; 1169 hotk->model = P30;
1104 printk(KERN_NOTICE 1170 printk(KERN_NOTICE
1105 " Samsung P30 detected, supported\n"); 1171 " Samsung P30 detected, supported\n");
1106 } else { 1172 } else {
1107 hotk->model = M2E; 1173 hotk->model = M2E;
1108 printk(KERN_WARNING " no string returned by INIT\n"); 1174 printk(KERN_NOTICE " unsupported model %s, trying "
1109 printk(KERN_WARNING " trying default values, supply " 1175 "default values\n", string);
1110 "the developers with your DSDT\n"); 1176 printk(KERN_NOTICE
1177 " send /proc/acpi/dsdt to the developers\n");
1111 } 1178 }
1112 hotk->methods = &model_conf[hotk->model]; 1179 hotk->methods = &model_conf[hotk->model];
1113
1114 kfree(model);
1115
1116 return AE_OK; 1180 return AE_OK;
1117 } 1181 }
1118
1119 hotk->model = END_MODEL;
1120 if (strncmp(model->string.pointer, "L3D", 3) == 0)
1121 hotk->model = L3D;
1122 else if (strncmp(model->string.pointer, "L2E", 3) == 0 ||
1123 strncmp(model->string.pointer, "L3H", 3) == 0 ||
1124 strncmp(model->string.pointer, "L5D", 3) == 0)
1125 hotk->model = L3H;
1126 else if (strncmp(model->string.pointer, "L3", 2) == 0 ||
1127 strncmp(model->string.pointer, "L2B", 3) == 0)
1128 hotk->model = L3C;
1129 else if (strncmp(model->string.pointer, "L8L", 3) == 0)
1130 hotk->model = L8L;
1131 else if (strncmp(model->string.pointer, "L4R", 3) == 0)
1132 hotk->model = L4R;
1133 else if (strncmp(model->string.pointer, "M6N", 3) == 0 ||
1134 strncmp(model->string.pointer, "W3N", 3) == 0)
1135 hotk->model = M6N;
1136 else if (strncmp(model->string.pointer, "M6R", 3) == 0 ||
1137 strncmp(model->string.pointer, "A3G", 3) == 0)
1138 hotk->model = M6R;
1139 else if (strncmp(model->string.pointer, "M2N", 3) == 0 ||
1140 strncmp(model->string.pointer, "M3N", 3) == 0 ||
1141 strncmp(model->string.pointer, "M5N", 3) == 0 ||
1142 strncmp(model->string.pointer, "M6N", 3) == 0 ||
1143 strncmp(model->string.pointer, "S1N", 3) == 0 ||
1144 strncmp(model->string.pointer, "S5N", 3) == 0)
1145 hotk->model = xxN;
1146 else if (strncmp(model->string.pointer, "M1", 2) == 0)
1147 hotk->model = M1A;
1148 else if (strncmp(model->string.pointer, "M2", 2) == 0 ||
1149 strncmp(model->string.pointer, "L4E", 3) == 0)
1150 hotk->model = M2E;
1151 else if (strncmp(model->string.pointer, "L2", 2) == 0)
1152 hotk->model = L2D;
1153 else if (strncmp(model->string.pointer, "L8", 2) == 0)
1154 hotk->model = S1x;
1155 else if (strncmp(model->string.pointer, "D1", 2) == 0)
1156 hotk->model = D1x;
1157 else if (strncmp(model->string.pointer, "A1", 2) == 0)
1158 hotk->model = A1x;
1159 else if (strncmp(model->string.pointer, "A2", 2) == 0)
1160 hotk->model = A2x;
1161 else if (strncmp(model->string.pointer, "J1", 2) == 0)
1162 hotk->model = S2x;
1163 else if (strncmp(model->string.pointer, "L5", 2) == 0)
1164 hotk->model = L5x;
1165 else if (strncmp(model->string.pointer, "A4G", 3) == 0)
1166 hotk->model = A4G;
1167 else if (strncmp(model->string.pointer, "W1N", 3) == 0)
1168 hotk->model = W1N;
1169 else if (strncmp(model->string.pointer, "W5A", 3) == 0)
1170 hotk->model = W5A;
1171
1172 if (hotk->model == END_MODEL) {
1173 printk("unsupported, trying default values, supply the "
1174 "developers with your DSDT\n");
1175 hotk->model = M2E;
1176 } else {
1177 printk("supported\n");
1178 }
1179
1180 hotk->methods = &model_conf[hotk->model]; 1182 hotk->methods = &model_conf[hotk->model];
1183 printk(KERN_NOTICE " %s model detected, supported\n", string);
1181 1184
1182 /* Sort of per-model blacklist */ 1185 /* Sort of per-model blacklist */
1183 if (strncmp(model->string.pointer, "L2B", 3) == 0) 1186 if (strncmp(string, "L2B", 3) == 0)
1184 hotk->methods->lcd_status = NULL; 1187 hotk->methods->lcd_status = NULL;
1185 /* L2B is similar enough to L3C to use its settings, with this only 1188 /* L2B is similar enough to L3C to use its settings, with this only
1186 exception */ 1189 exception */
1187 else if (strncmp(model->string.pointer, "A3G", 3) == 0) 1190 else if (strncmp(string, "A3G", 3) == 0)
1188 hotk->methods->lcd_status = "\\BLFG"; 1191 hotk->methods->lcd_status = "\\BLFG";
1189 /* A3G is like M6R */ 1192 /* A3G is like M6R */
1190 else if (strncmp(model->string.pointer, "S5N", 3) == 0 || 1193 else if (strncmp(string, "S5N", 3) == 0 ||
1191 strncmp(model->string.pointer, "M5N", 3) == 0 || 1194 strncmp(string, "M5N", 3) == 0 ||
1192 strncmp(model->string.pointer, "W3N", 3) == 0) 1195 strncmp(string, "W3N", 3) == 0)
1193 hotk->methods->mt_mled = NULL; 1196 hotk->methods->mt_mled = NULL;
1194 /* S5N, M5N and W3N have no MLED */ 1197 /* S5N, M5N and W3N have no MLED */
1195 else if (strncmp(model->string.pointer, "L5D", 3) == 0) 1198 else if (strncmp(string, "L5D", 3) == 0)
1196 hotk->methods->mt_wled = NULL; 1199 hotk->methods->mt_wled = NULL;
1197 /* L5D's WLED is not controlled by ACPI */ 1200 /* L5D's WLED is not controlled by ACPI */
1198 else if (strncmp(model->string.pointer, "M2N", 3) == 0) 1201 else if (strncmp(string, "M2N", 3) == 0)
1199 hotk->methods->mt_wled = "WLED"; 1202 hotk->methods->mt_wled = "WLED";
1200 /* M2N has a usable WLED */ 1203 /* M2N has a usable WLED */
1201 else if (asus_info) { 1204 else if (asus_info) {