Re: [PATCH v2 2/8] platform/x86: asus-wmi: add support for showing middle fan RPM

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 6/30/23 07:35, Luke D. Jones wrote:
> Some newer ASUS ROG laptops now have a middle/center fan in addition
> to the CPU and GPU fans. This new fan typically blows across the
> heatpipes and VRMs betweent eh CPU and GPU.
> 
> This commit exposes that fan to PWM control plus showing RPM.
> 
> Signed-off-by: Luke D. Jones <luke@xxxxxxxxxx>

Thanks, patch looks good to me:

Reviewed-by: Hans de Goede <hdegoede@xxxxxxxxxx>

Regards,

Hans



> ---
>  drivers/platform/x86/asus-wmi.c            | 91 ++++++++++++++++++++++
>  include/linux/platform_data/x86/asus-wmi.h |  1 +
>  2 files changed, 92 insertions(+)
> 
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index f23375d5fb82..375d25ae0aca 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -72,6 +72,7 @@ module_param(fnlock_default, bool, 0444);
>  
>  #define ASUS_WMI_FNLOCK_BIOS_DISABLED	BIT(0)
>  
> +#define ASUS_MID_FAN_DESC		"mid_fan"
>  #define ASUS_GPU_FAN_DESC		"gpu_fan"
>  #define ASUS_FAN_DESC			"cpu_fan"
>  #define ASUS_FAN_MFUN			0x13
> @@ -229,8 +230,10 @@ struct asus_wmi {
>  
>  	enum fan_type fan_type;
>  	enum fan_type gpu_fan_type;
> +	enum fan_type mid_fan_type;
>  	int fan_pwm_mode;
>  	int gpu_fan_pwm_mode;
> +	int mid_fan_pwm_mode;
>  	int agfn_pwm;
>  
>  	bool fan_boost_mode_available;
> @@ -2129,6 +2132,31 @@ static ssize_t fan2_label_show(struct device *dev,
>  	return sysfs_emit(buf, "%s\n", ASUS_GPU_FAN_DESC);
>  }
>  
> +/* Middle/Center fan on modern ROG laptops */
> +static ssize_t fan3_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_MID_FAN_CTRL, &value);
> +	if (ret < 0)
> +		return ret;
> +
> +	value &= 0xffff;
> +
> +	return sysfs_emit(buf, "%d\n", value * 100);
> +}
> +
> +static ssize_t fan3_label_show(struct device *dev,
> +					  struct device_attribute *attr,
> +					  char *buf)
> +{
> +	return sysfs_emit(buf, "%s\n", ASUS_MID_FAN_DESC);
> +}
> +
>  static ssize_t pwm2_enable_show(struct device *dev,
>  				struct device_attribute *attr,
>  				char *buf)
> @@ -2175,6 +2203,52 @@ static ssize_t pwm2_enable_store(struct device *dev,
>  	return count;
>  }
>  
> +static ssize_t pwm3_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->mid_fan_pwm_mode);
> +}
> +
> +static ssize_t pwm3_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_MID_FAN_CTRL,
> +				    value, &retval);
> +	if (ret)
> +		return ret;
> +
> +	if (retval != 1)
> +		return -EIO;
> +
> +	asus->mid_fan_pwm_mode = state;
> +	return count;
> +}
> +
>  /* Fan1 */
>  static DEVICE_ATTR_RW(pwm1);
>  static DEVICE_ATTR_RW(pwm1_enable);
> @@ -2184,6 +2258,10 @@ static DEVICE_ATTR_RO(fan1_label);
>  static DEVICE_ATTR_RW(pwm2_enable);
>  static DEVICE_ATTR_RO(fan2_input);
>  static DEVICE_ATTR_RO(fan2_label);
> +/* Fan3 - Middle/center fan */
> +static DEVICE_ATTR_RW(pwm3_enable);
> +static DEVICE_ATTR_RO(fan3_input);
> +static DEVICE_ATTR_RO(fan3_label);
>  
>  /* Temperature */
>  static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
> @@ -2192,10 +2270,13 @@ static struct attribute *hwmon_attributes[] = {
>  	&dev_attr_pwm1.attr,
>  	&dev_attr_pwm1_enable.attr,
>  	&dev_attr_pwm2_enable.attr,
> +	&dev_attr_pwm3_enable.attr,
>  	&dev_attr_fan1_input.attr,
>  	&dev_attr_fan1_label.attr,
>  	&dev_attr_fan2_input.attr,
>  	&dev_attr_fan2_label.attr,
> +	&dev_attr_fan3_input.attr,
> +	&dev_attr_fan3_label.attr,
>  
>  	&dev_attr_temp1_input.attr,
>  	NULL
> @@ -2221,6 +2302,11 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
>  	    || attr == &dev_attr_pwm2_enable.attr) {
>  		if (asus->gpu_fan_type == FAN_TYPE_NONE)
>  			return 0;
> +	} else if (attr == &dev_attr_fan3_input.attr
> +	    || attr == &dev_attr_fan3_label.attr
> +	    || attr == &dev_attr_pwm3_enable.attr) {
> +		if (asus->mid_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,
> @@ -2264,6 +2350,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->mid_fan_type = FAN_TYPE_NONE;
>  	asus->fan_type = FAN_TYPE_NONE;
>  	asus->agfn_pwm = -1;
>  
> @@ -2278,6 +2365,10 @@ static int asus_wmi_fan_init(struct asus_wmi *asus)
>  	if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_FAN_CTRL))
>  		asus->gpu_fan_type = FAN_TYPE_SPEC83;
>  
> +	/* Some models also have a center/middle fan */
> +	if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MID_FAN_CTRL))
> +		asus->mid_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 f90cafe26af1..2c03bda7703f 100644
> --- a/include/linux/platform_data/x86/asus-wmi.h
> +++ b/include/linux/platform_data/x86/asus-wmi.h
> @@ -80,6 +80,7 @@
>  #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_MID_FAN_CTRL 0x00110031
>  #define ASUS_WMI_DEVID_CPU_FAN_CURVE	0x00110024
>  #define ASUS_WMI_DEVID_GPU_FAN_CURVE	0x00110025
>  




[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux