From: Luke D. Jones Date: Fri, 26 Aug 2022 00:42:10 +0000 (+1200) Subject: platform/x86: asus-wmi: Support the GPU fan on TUF laptops X-Git-Tag: v6.6.17~6495^2~64 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=12ff4c803d23218f9afea9f82019a5c9619f6744;p=platform%2Fkernel%2Flinux-rpi.git 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: Luke D. Jones Link: https://lore.kernel.org/r/20220826004210.356534-3-luke@ljones.dev Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 94e0be8..eebc20c 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -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; diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h index 6e8a95c..31d810e 100644 --- a/include/linux/platform_data/x86/asus-wmi.h +++ b/include/linux/platform_data/x86/asus-wmi.h @@ -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