Commit 12ff4c80 authored by Luke D. Jones's avatar Luke D. Jones Committed by Hans de Goede
Browse files

platform/x86: asus-wmi: Support the GPU fan on TUF laptops



Add support for TUF laptops which have the ability to control
the GPU fan. This will show as a second fan in hwmon, and has
the ability to run as boost (fullspeed), or auto.

Signed-off-by: default avatarLuke D. Jones <luke@ljones.dev>
Link: https://lore.kernel.org/r/20220826004210.356534-3-luke@ljones.dev


Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
parent 601eb4c8
Loading
Loading
Loading
Loading
+71 −0
Original line number Diff line number Diff line
@@ -226,7 +226,9 @@ struct asus_wmi {
	u32 tablet_switch_dev_id;

	enum fan_type fan_type;
	enum fan_type gpu_fan_type;
	int fan_pwm_mode;
	int gpu_fan_pwm_mode;
	int agfn_pwm;

	bool fan_boost_mode_available;
@@ -1734,6 +1736,18 @@ static int asus_fan_set_auto(struct asus_wmi *asus)
		return -ENXIO;
	}

	/*
	 * Modern models like the G713 also have GPU fan control (this is not AGFN)
	 */
	if (asus->gpu_fan_type == FAN_TYPE_SPEC83) {
		status = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_FAN_CTRL,
					       0, &retval);
		if (status)
			return status;

		if (retval != 1)
			return -EIO;
	}

	return 0;
}
@@ -1936,9 +1950,57 @@ static ssize_t asus_hwmon_temp1(struct device *dev,
		       deci_kelvin_to_millicelsius(value & 0xFFFF));
}

/* GPU fan on modern ROG laptops */
static ssize_t pwm2_enable_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct asus_wmi *asus = dev_get_drvdata(dev);

	return sysfs_emit(buf, "%d\n", asus->gpu_fan_pwm_mode);
}

static ssize_t pwm2_enable_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct asus_wmi *asus = dev_get_drvdata(dev);
	int state;
	int value;
	int ret;
	u32 retval;

	ret = kstrtouint(buf, 10, &state);
	if (ret)
		return ret;

	switch (state) { /* standard documented hwmon values */
	case ASUS_FAN_CTRL_FULLSPEED:
		value = 1;
		break;
	case ASUS_FAN_CTRL_AUTO:
		value = 0;
		break;
	default:
		return -EINVAL;
	}

	ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_FAN_CTRL,
				    value, &retval);
	if (ret)
		return ret;

	if (retval != 1)
		return -EIO;

	asus->gpu_fan_pwm_mode = state;
	return count;
}

/* Fan1 */
static DEVICE_ATTR_RW(pwm1);
static DEVICE_ATTR_RW(pwm1_enable);
static DEVICE_ATTR_RW(pwm2_enable);
static DEVICE_ATTR_RO(fan1_input);
static DEVICE_ATTR_RO(fan1_label);

@@ -1948,6 +2010,7 @@ static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
static struct attribute *hwmon_attributes[] = {
	&dev_attr_pwm1.attr,
	&dev_attr_pwm1_enable.attr,
	&dev_attr_pwm2_enable.attr,
	&dev_attr_fan1_input.attr,
	&dev_attr_fan1_label.attr,

@@ -1970,6 +2033,9 @@ 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_pwm2_enable.attr) {
		if (asus->gpu_fan_type == FAN_TYPE_NONE)
			return 0;
	} else if (attr == &dev_attr_temp1_input.attr) {
		int err = asus_wmi_get_devstate(asus,
						ASUS_WMI_DEVID_THERMAL_CTRL,
@@ -2012,6 +2078,7 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus)

static int asus_wmi_fan_init(struct asus_wmi *asus)
{
	asus->gpu_fan_type = FAN_TYPE_NONE;
	asus->fan_type = FAN_TYPE_NONE;
	asus->agfn_pwm = -1;

@@ -2020,6 +2087,10 @@ static int asus_wmi_fan_init(struct asus_wmi *asus)
	else if (asus_wmi_has_agfn_fan(asus))
		asus->fan_type = FAN_TYPE_AGFN;

	/*  Modern models like G713 also have GPU fan control */
	if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_FAN_CTRL))
		asus->gpu_fan_type = FAN_TYPE_SPEC83;

	if (asus->fan_type == FAN_TYPE_NONE)
		return -ENODEV;

+1 −0
Original line number Diff line number Diff line
@@ -79,6 +79,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
#define ASUS_WMI_DEVID_CPU_FAN_CURVE	0x00110024
#define ASUS_WMI_DEVID_GPU_FAN_CURVE	0x00110025