aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/asus-wmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/asus-wmi.c')
-rw-r--r--drivers/platform/x86/asus-wmi.c359
1 files changed, 330 insertions, 29 deletions
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 7543a56e0f45..efbc3f0c592b 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -78,6 +78,7 @@ MODULE_LICENSE("GPL");
78#define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */ 78#define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */
79#define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */ 79#define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */
80#define ASUS_WMI_METHODID_SPLV 0x4C425053 /* Set Panel Light Value */ 80#define ASUS_WMI_METHODID_SPLV 0x4C425053 /* Set Panel Light Value */
81#define ASUS_WMI_METHODID_AGFN 0x4E464741 /* FaN? */
81#define ASUS_WMI_METHODID_SFUN 0x4E554653 /* FUNCtionalities */ 82#define ASUS_WMI_METHODID_SFUN 0x4E554653 /* FUNCtionalities */
82#define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */ 83#define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */
83#define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */ 84#define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */
@@ -150,12 +151,38 @@ MODULE_LICENSE("GPL");
150#define ASUS_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF 151#define ASUS_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF
151#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00 152#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00
152 153
154#define ASUS_FAN_DESC "cpu_fan"
155#define ASUS_FAN_MFUN 0x13
156#define ASUS_FAN_SFUN_READ 0x06
157#define ASUS_FAN_SFUN_WRITE 0x07
158#define ASUS_FAN_CTRL_MANUAL 1
159#define ASUS_FAN_CTRL_AUTO 2
160
153struct bios_args { 161struct bios_args {
154 u32 arg0; 162 u32 arg0;
155 u32 arg1; 163 u32 arg1;
156} __packed; 164} __packed;
157 165
158/* 166/*
167 * Struct that's used for all methods called via AGFN. Naming is
168 * identically to the AML code.
169 */
170struct agfn_args {
171 u16 mfun; /* probably "Multi-function" to be called */
172 u16 sfun; /* probably "Sub-function" to be called */
173 u16 len; /* size of the hole struct, including subfunction fields */
174 u8 stas; /* not used by now */
175 u8 err; /* zero on success */
176} __packed;
177
178/* struct used for calling fan read and write methods */
179struct fan_args {
180 struct agfn_args agfn; /* common fields */
181 u8 fan; /* fan number: 0: set auto mode 1: 1st fan */
182 u32 speed; /* read: RPM/100 - write: 0-255 */
183} __packed;
184
185/*
159 * <platform>/ - debugfs root directory 186 * <platform>/ - debugfs root directory
160 * dev_id - current dev_id 187 * dev_id - current dev_id
161 * ctrl_param - current ctrl_param 188 * ctrl_param - current ctrl_param
@@ -204,6 +231,10 @@ struct asus_wmi {
204 struct asus_rfkill gps; 231 struct asus_rfkill gps;
205 struct asus_rfkill uwb; 232 struct asus_rfkill uwb;
206 233
234 bool asus_hwmon_fan_manual_mode;
235 int asus_hwmon_num_fans;
236 int asus_hwmon_pwm;
237
207 struct hotplug_slot *hotplug_slot; 238 struct hotplug_slot *hotplug_slot;
208 struct mutex hotplug_lock; 239 struct mutex hotplug_lock;
209 struct mutex wmi_lock; 240 struct mutex wmi_lock;
@@ -294,6 +325,36 @@ exit:
294 return 0; 325 return 0;
295} 326}
296 327
328static int asus_wmi_evaluate_method_agfn(const struct acpi_buffer args)
329{
330 struct acpi_buffer input;
331 u64 phys_addr;
332 u32 retval;
333 u32 status = -1;
334
335 /*
336 * Copy to dma capable address otherwise memory corruption occurs as
337 * bios has to be able to access it.
338 */
339 input.pointer = kzalloc(args.length, GFP_DMA | GFP_KERNEL);
340 input.length = args.length;
341 if (!input.pointer)
342 return -ENOMEM;
343 phys_addr = virt_to_phys(input.pointer);
344 memcpy(input.pointer, args.pointer, args.length);
345
346 status = asus_wmi_evaluate_method(ASUS_WMI_METHODID_AGFN,
347 phys_addr, 0, &retval);
348 if (!status)
349 memcpy(args.pointer, input.pointer, args.length);
350
351 kfree(input.pointer);
352 if (status)
353 return -ENXIO;
354
355 return retval;
356}
357
297static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval) 358static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
298{ 359{
299 return asus_wmi_evaluate_method(asus->dsts_id, dev_id, 0, retval); 360 return asus_wmi_evaluate_method(asus->dsts_id, dev_id, 0, retval);
@@ -1022,35 +1083,228 @@ exit:
1022/* 1083/*
1023 * Hwmon device 1084 * Hwmon device
1024 */ 1085 */
1025static ssize_t asus_hwmon_pwm1(struct device *dev, 1086static int asus_hwmon_agfn_fan_speed_read(struct asus_wmi *asus, int fan,
1026 struct device_attribute *attr, 1087 int *speed)
1027 char *buf) 1088{
1089 struct fan_args args = {
1090 .agfn.len = sizeof(args),
1091 .agfn.mfun = ASUS_FAN_MFUN,
1092 .agfn.sfun = ASUS_FAN_SFUN_READ,
1093 .fan = fan,
1094 .speed = 0,
1095 };
1096 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
1097 int status;
1098
1099 if (fan != 1)
1100 return -EINVAL;
1101
1102 status = asus_wmi_evaluate_method_agfn(input);
1103
1104 if (status || args.agfn.err)
1105 return -ENXIO;
1106
1107 if (speed)
1108 *speed = args.speed;
1109
1110 return 0;
1111}
1112
1113static int asus_hwmon_agfn_fan_speed_write(struct asus_wmi *asus, int fan,
1114 int *speed)
1115{
1116 struct fan_args args = {
1117 .agfn.len = sizeof(args),
1118 .agfn.mfun = ASUS_FAN_MFUN,
1119 .agfn.sfun = ASUS_FAN_SFUN_WRITE,
1120 .fan = fan,
1121 .speed = speed ? *speed : 0,
1122 };
1123 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
1124 int status;
1125
1126 /* 1: for setting 1st fan's speed 0: setting auto mode */
1127 if (fan != 1 && fan != 0)
1128 return -EINVAL;
1129
1130 status = asus_wmi_evaluate_method_agfn(input);
1131
1132 if (status || args.agfn.err)
1133 return -ENXIO;
1134
1135 if (speed && fan == 1)
1136 asus->asus_hwmon_pwm = *speed;
1137
1138 return 0;
1139}
1140
1141/*
1142 * Check if we can read the speed of one fan. If true we assume we can also
1143 * control it.
1144 */
1145static int asus_hwmon_get_fan_number(struct asus_wmi *asus, int *num_fans)
1146{
1147 int status;
1148 int speed = 0;
1149
1150 *num_fans = 0;
1151
1152 status = asus_hwmon_agfn_fan_speed_read(asus, 1, &speed);
1153 if (!status)
1154 *num_fans = 1;
1155
1156 return 0;
1157}
1158
1159static int asus_hwmon_fan_set_auto(struct asus_wmi *asus)
1160{
1161 int status;
1162
1163 status = asus_hwmon_agfn_fan_speed_write(asus, 0, NULL);
1164 if (status)
1165 return -ENXIO;
1166
1167 asus->asus_hwmon_fan_manual_mode = false;
1168
1169 return 0;
1170}
1171
1172static int asus_hwmon_fan_rpm_show(struct device *dev, int fan)
1028{ 1173{
1029 struct asus_wmi *asus = dev_get_drvdata(dev); 1174 struct asus_wmi *asus = dev_get_drvdata(dev);
1030 u32 value; 1175 int value;
1176 int ret;
1177
1178 /* no speed readable on manual mode */
1179 if (asus->asus_hwmon_fan_manual_mode)
1180 return -ENXIO;
1181
1182 ret = asus_hwmon_agfn_fan_speed_read(asus, fan+1, &value);
1183 if (ret) {
1184 pr_warn("reading fan speed failed: %d\n", ret);
1185 return -ENXIO;
1186 }
1187
1188 return value;
1189}
1190
1191static void asus_hwmon_pwm_show(struct asus_wmi *asus, int fan, int *value)
1192{
1031 int err; 1193 int err;
1032 1194
1033 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value); 1195 if (asus->asus_hwmon_pwm >= 0) {
1196 *value = asus->asus_hwmon_pwm;
1197 return;
1198 }
1034 1199
1200 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, value);
1035 if (err < 0) 1201 if (err < 0)
1036 return err; 1202 return;
1037 1203
1038 value &= 0xFF; 1204 *value &= 0xFF;
1039 1205
1040 if (value == 1) /* Low Speed */ 1206 if (*value == 1) /* Low Speed */
1041 value = 85; 1207 *value = 85;
1042 else if (value == 2) 1208 else if (*value == 2)
1043 value = 170; 1209 *value = 170;
1044 else if (value == 3) 1210 else if (*value == 3)
1045 value = 255; 1211 *value = 255;
1046 else if (value != 0) { 1212 else if (*value) {
1047 pr_err("Unknown fan speed %#x\n", value); 1213 pr_err("Unknown fan speed %#x\n", *value);
1048 value = -1; 1214 *value = -1;
1049 } 1215 }
1216}
1217
1218static ssize_t pwm1_show(struct device *dev,
1219 struct device_attribute *attr,
1220 char *buf)
1221{
1222 struct asus_wmi *asus = dev_get_drvdata(dev);
1223 int value;
1224
1225 asus_hwmon_pwm_show(asus, 0, &value);
1050 1226
1051 return sprintf(buf, "%d\n", value); 1227 return sprintf(buf, "%d\n", value);
1052} 1228}
1053 1229
1230static ssize_t pwm1_store(struct device *dev,
1231 struct device_attribute *attr,
1232 const char *buf, size_t count) {
1233 struct asus_wmi *asus = dev_get_drvdata(dev);
1234 int value;
1235 int state;
1236 int ret;
1237
1238 ret = kstrtouint(buf, 10, &value);
1239
1240 if (ret)
1241 return ret;
1242
1243 value = clamp(value, 0, 255);
1244
1245 state = asus_hwmon_agfn_fan_speed_write(asus, 1, &value);
1246 if (state)
1247 pr_warn("Setting fan speed failed: %d\n", state);
1248 else
1249 asus->asus_hwmon_fan_manual_mode = true;
1250
1251 return count;
1252}
1253
1254static ssize_t fan1_input_show(struct device *dev,
1255 struct device_attribute *attr,
1256 char *buf)
1257{
1258 int value = asus_hwmon_fan_rpm_show(dev, 0);
1259
1260 return sprintf(buf, "%d\n", value < 0 ? -1 : value*100);
1261
1262}
1263
1264static ssize_t pwm1_enable_show(struct device *dev,
1265 struct device_attribute *attr,
1266 char *buf)
1267{
1268 struct asus_wmi *asus = dev_get_drvdata(dev);
1269
1270 if (asus->asus_hwmon_fan_manual_mode)
1271 return sprintf(buf, "%d\n", ASUS_FAN_CTRL_MANUAL);
1272
1273 return sprintf(buf, "%d\n", ASUS_FAN_CTRL_AUTO);
1274}
1275
1276static ssize_t pwm1_enable_store(struct device *dev,
1277 struct device_attribute *attr,
1278 const char *buf, size_t count)
1279{
1280 struct asus_wmi *asus = dev_get_drvdata(dev);
1281 int status = 0;
1282 int state;
1283 int ret;
1284
1285 ret = kstrtouint(buf, 10, &state);
1286
1287 if (ret)
1288 return ret;
1289
1290 if (state == ASUS_FAN_CTRL_MANUAL)
1291 asus->asus_hwmon_fan_manual_mode = true;
1292 else
1293 status = asus_hwmon_fan_set_auto(asus);
1294
1295 if (status)
1296 return status;
1297
1298 return count;
1299}
1300
1301static ssize_t fan1_label_show(struct device *dev,
1302 struct device_attribute *attr,
1303 char *buf)
1304{
1305 return sprintf(buf, "%s\n", ASUS_FAN_DESC);
1306}
1307
1054static ssize_t asus_hwmon_temp1(struct device *dev, 1308static ssize_t asus_hwmon_temp1(struct device *dev,
1055 struct device_attribute *attr, 1309 struct device_attribute *attr,
1056 char *buf) 1310 char *buf)
@@ -1069,11 +1323,21 @@ static ssize_t asus_hwmon_temp1(struct device *dev,
1069 return sprintf(buf, "%d\n", value); 1323 return sprintf(buf, "%d\n", value);
1070} 1324}
1071 1325
1072static DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL); 1326/* Fan1 */
1327static DEVICE_ATTR_RW(pwm1);
1328static DEVICE_ATTR_RW(pwm1_enable);
1329static DEVICE_ATTR_RO(fan1_input);
1330static DEVICE_ATTR_RO(fan1_label);
1331
1332/* Temperature */
1073static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL); 1333static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
1074 1334
1075static struct attribute *hwmon_attributes[] = { 1335static struct attribute *hwmon_attributes[] = {
1076 &dev_attr_pwm1.attr, 1336 &dev_attr_pwm1.attr,
1337 &dev_attr_pwm1_enable.attr,
1338 &dev_attr_fan1_input.attr,
1339 &dev_attr_fan1_label.attr,
1340
1077 &dev_attr_temp1_input.attr, 1341 &dev_attr_temp1_input.attr,
1078 NULL 1342 NULL
1079}; 1343};
@@ -1084,19 +1348,28 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
1084 struct device *dev = container_of(kobj, struct device, kobj); 1348 struct device *dev = container_of(kobj, struct device, kobj);
1085 struct platform_device *pdev = to_platform_device(dev->parent); 1349 struct platform_device *pdev = to_platform_device(dev->parent);
1086 struct asus_wmi *asus = platform_get_drvdata(pdev); 1350 struct asus_wmi *asus = platform_get_drvdata(pdev);
1087 bool ok = true;
1088 int dev_id = -1; 1351 int dev_id = -1;
1352 int fan_attr = -1;
1089 u32 value = ASUS_WMI_UNSUPPORTED_METHOD; 1353 u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
1354 bool ok = true;
1090 1355
1091 if (attr == &dev_attr_pwm1.attr) 1356 if (attr == &dev_attr_pwm1.attr)
1092 dev_id = ASUS_WMI_DEVID_FAN_CTRL; 1357 dev_id = ASUS_WMI_DEVID_FAN_CTRL;
1093 else if (attr == &dev_attr_temp1_input.attr) 1358 else if (attr == &dev_attr_temp1_input.attr)
1094 dev_id = ASUS_WMI_DEVID_THERMAL_CTRL; 1359 dev_id = ASUS_WMI_DEVID_THERMAL_CTRL;
1095 1360
1361
1362 if (attr == &dev_attr_fan1_input.attr
1363 || attr == &dev_attr_fan1_label.attr
1364 || attr == &dev_attr_pwm1.attr
1365 || attr == &dev_attr_pwm1_enable.attr) {
1366 fan_attr = 1;
1367 }
1368
1096 if (dev_id != -1) { 1369 if (dev_id != -1) {
1097 int err = asus_wmi_get_devstate(asus, dev_id, &value); 1370 int err = asus_wmi_get_devstate(asus, dev_id, &value);
1098 1371
1099 if (err < 0) 1372 if (err < 0 && fan_attr == -1)
1100 return 0; /* can't return negative here */ 1373 return 0; /* can't return negative here */
1101 } 1374 }
1102 1375
@@ -1112,10 +1385,16 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
1112 if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 1385 if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
1113 || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) 1386 || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)))
1114 ok = false; 1387 ok = false;
1388 else
1389 ok = fan_attr <= asus->asus_hwmon_num_fans;
1115 } else if (dev_id == ASUS_WMI_DEVID_THERMAL_CTRL) { 1390 } else if (dev_id == ASUS_WMI_DEVID_THERMAL_CTRL) {
1116 /* If value is zero, something is clearly wrong */ 1391 /* If value is zero, something is clearly wrong */
1117 if (value == 0) 1392 if (!value)
1118 ok = false; 1393 ok = false;
1394 } else if (fan_attr <= asus->asus_hwmon_num_fans && fan_attr != -1) {
1395 ok = true;
1396 } else {
1397 ok = false;
1119 } 1398 }
1120 1399
1121 return ok ? attr->mode : 0; 1400 return ok ? attr->mode : 0;
@@ -1364,7 +1643,7 @@ static void asus_wmi_notify(u32 value, void *context)
1364 code = ASUS_WMI_BRN_DOWN; 1643 code = ASUS_WMI_BRN_DOWN;
1365 1644
1366 if (code == ASUS_WMI_BRN_DOWN || code == ASUS_WMI_BRN_UP) { 1645 if (code == ASUS_WMI_BRN_DOWN || code == ASUS_WMI_BRN_UP) {
1367 if (!acpi_video_backlight_support()) { 1646 if (acpi_video_get_backlight_type() == acpi_backlight_vendor) {
1368 asus_wmi_backlight_notify(asus, orig_code); 1647 asus_wmi_backlight_notify(asus, orig_code);
1369 goto exit; 1648 goto exit;
1370 } 1649 }
@@ -1723,6 +2002,25 @@ error_debugfs:
1723 return -ENOMEM; 2002 return -ENOMEM;
1724} 2003}
1725 2004
2005static int asus_wmi_fan_init(struct asus_wmi *asus)
2006{
2007 int status;
2008
2009 asus->asus_hwmon_pwm = -1;
2010 asus->asus_hwmon_num_fans = -1;
2011 asus->asus_hwmon_fan_manual_mode = false;
2012
2013 status = asus_hwmon_get_fan_number(asus, &asus->asus_hwmon_num_fans);
2014 if (status) {
2015 asus->asus_hwmon_num_fans = 0;
2016 pr_warn("Could not determine number of fans: %d\n", status);
2017 return -ENXIO;
2018 }
2019
2020 pr_info("Number of fans: %d\n", asus->asus_hwmon_num_fans);
2021 return 0;
2022}
2023
1726/* 2024/*
1727 * WMI Driver 2025 * WMI Driver
1728 */ 2026 */
@@ -1756,6 +2054,9 @@ static int asus_wmi_add(struct platform_device *pdev)
1756 if (err) 2054 if (err)
1757 goto fail_input; 2055 goto fail_input;
1758 2056
2057 err = asus_wmi_fan_init(asus); /* probably no problems on error */
2058 asus_hwmon_fan_set_auto(asus);
2059
1759 err = asus_wmi_hwmon_init(asus); 2060 err = asus_wmi_hwmon_init(asus);
1760 if (err) 2061 if (err)
1761 goto fail_hwmon; 2062 goto fail_hwmon;
@@ -1772,17 +2073,16 @@ static int asus_wmi_add(struct platform_device *pdev)
1772 stop this from showing up */ 2073 stop this from showing up */
1773 chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE); 2074 chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
1774 if (chassis_type && !strcmp(chassis_type, "3")) 2075 if (chassis_type && !strcmp(chassis_type, "3"))
1775 acpi_video_dmi_promote_vendor(); 2076 acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);
2077
1776 if (asus->driver->quirks->wmi_backlight_power) 2078 if (asus->driver->quirks->wmi_backlight_power)
1777 acpi_video_dmi_promote_vendor(); 2079 acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);
1778 if (!acpi_video_backlight_support()) { 2080
1779 pr_info("Disabling ACPI video driver\n"); 2081 if (acpi_video_get_backlight_type() == acpi_backlight_vendor) {
1780 acpi_video_unregister();
1781 err = asus_wmi_backlight_init(asus); 2082 err = asus_wmi_backlight_init(asus);
1782 if (err && err != -ENODEV) 2083 if (err && err != -ENODEV)
1783 goto fail_backlight; 2084 goto fail_backlight;
1784 } else 2085 }
1785 pr_info("Backlight controlled by ACPI video driver\n");
1786 2086
1787 status = wmi_install_notify_handler(asus->driver->event_guid, 2087 status = wmi_install_notify_handler(asus->driver->event_guid,
1788 asus_wmi_notify, asus); 2088 asus_wmi_notify, asus);
@@ -1832,6 +2132,7 @@ static int asus_wmi_remove(struct platform_device *device)
1832 asus_wmi_rfkill_exit(asus); 2132 asus_wmi_rfkill_exit(asus);
1833 asus_wmi_debugfs_exit(asus); 2133 asus_wmi_debugfs_exit(asus);
1834 asus_wmi_platform_exit(asus); 2134 asus_wmi_platform_exit(asus);
2135 asus_hwmon_fan_set_auto(asus);
1835 2136
1836 kfree(asus); 2137 kfree(asus);
1837 return 0; 2138 return 0;