@@ -71,6 +71,8 @@ MODULE_LICENSE("GPL");
#define ASUS_FAN_SFUN_READ 0x06
#define ASUS_FAN_SFUN_WRITE 0x07
+#define ASUS_GPU_FAN_DESC "gpu_fan"
+
/* Based on standard hwmon pwmX_enable values */
#define ASUS_FAN_CTRL_FULLSPEED 0
#define ASUS_FAN_CTRL_MANUAL 1
@@ -201,6 +203,7 @@ struct asus_wmi {
enum fan_type fan_type;
int fan_pwm_mode;
int agfn_pwm;
+ bool gpu_fan_available;
bool fan_boost_mode_available;
u8 fan_boost_mode_mask;
@@ -1546,6 +1549,29 @@ static ssize_t fan1_label_show(struct device *dev,
return sprintf(buf, "%s\n", ASUS_FAN_DESC);
}
+static ssize_t fan2_input_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+ int value;
+ int ret;
+
+ ret = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_GPU_FAN_CTRL, &value);
+ if (ret < 0)
+ return ret;
+
+ value &= 0xFFFF;
+ return sprintf(buf, "%d\n", value < 0 ? -1 : value * 100);
+}
+
+static ssize_t fan2_label_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%s\n", ASUS_GPU_FAN_DESC);
+}
+
static ssize_t asus_hwmon_temp1(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -1568,6 +1594,10 @@ static DEVICE_ATTR_RW(pwm1_enable);
static DEVICE_ATTR_RO(fan1_input);
static DEVICE_ATTR_RO(fan1_label);
+/* GPU fan */
+static DEVICE_ATTR_RO(fan2_input);
+static DEVICE_ATTR_RO(fan2_label);
+
/* Temperature */
static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
@@ -1577,6 +1607,9 @@ static struct attribute *hwmon_attributes[] = {
&dev_attr_fan1_input.attr,
&dev_attr_fan1_label.attr,
+ &dev_attr_fan2_input.attr,
+ &dev_attr_fan2_label.attr,
+
&dev_attr_temp1_input.attr,
NULL
};
@@ -1596,6 +1629,10 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
|| attr == &dev_attr_pwm1_enable.attr) {
if (asus->fan_type == FAN_TYPE_NONE)
return 0;
+ } else if (attr == &dev_attr_fan2_input.attr
+ || attr == &dev_attr_fan2_label.attr) {
+ if (!asus->gpu_fan_available)
+ return 0;
} else if (attr == &dev_attr_temp1_input.attr) {
int err = asus_wmi_get_devstate(asus,
ASUS_WMI_DEVID_THERMAL_CTRL,
@@ -1640,6 +1677,7 @@ static int asus_wmi_fan_init(struct asus_wmi *asus)
{
asus->fan_type = FAN_TYPE_NONE;
asus->agfn_pwm = -1;
+ asus->gpu_fan_available = false;
if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CPU_FAN_CTRL))
asus->fan_type = FAN_TYPE_SPEC83;
@@ -1653,6 +1691,11 @@ static int asus_wmi_fan_init(struct asus_wmi *asus)
asus_fan_set_auto(asus);
asus->fan_pwm_mode = ASUS_FAN_CTRL_AUTO;
+
+ if (asus->fan_type == FAN_TYPE_SPEC83 &&
+ asus_wmi_has_fan(asus, ASUS_WMI_DEVID_GPU_FAN_CTRL))
+ asus->gpu_fan_available = true;
+
return 0;
}
@@ -75,6 +75,7 @@
#define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011
#define ASUS_WMI_DEVID_FAN_CTRL 0x00110012 /* deprecated */
#define ASUS_WMI_DEVID_CPU_FAN_CTRL 0x00110013
+#define ASUS_WMI_DEVID_GPU_FAN_CTRL 0x00110014
/* Power */
#define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012
The GPU fan interface is same as the CPU fan, so it is straightforward. Signed-off-by: Vasiliy Kupriakov <rublag-ns@yandex.ru> --- drivers/platform/x86/asus-wmi.c | 43 ++++++++++++++++++++++ include/linux/platform_data/x86/asus-wmi.h | 1 + 2 files changed, 44 insertions(+)