2022-08-08 05:14:40

by Luke D. Jones

[permalink] [raw]
Subject: [PATCH 1/2] asus-wmi: Modify behaviour of Fn+F5 fan key

Some more recent TUF laptops have both fan_boost and thermal_throttle.
The key code for Fn+F5 is also different and unmapped.

This patch adjusts the asus_wmi_handle_event_code() match to match
for both 0x99 and 0xAE, and run both mode switch functions for
fan_boost and/or thermal_throttle if either are available.

It is required that both are tried, as in some instances the ACPI
set-method for one may not have any code body within it even though
it was returned as supported by the get method.

Signed-off-by: Luke D. Jones <[email protected]>
---
drivers/platform/x86/asus-nb-wmi.c | 1 +
drivers/platform/x86/asus-wmi.c | 11 +++++------
2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index a81dc4b191b7..18eec80b7154 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -573,6 +573,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
{ KE_KEY, 0xA5, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + HDMI */
{ KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */
{ KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */
+ { KE_KEY, 0xAE, { KEY_FN_F5 } }, /* Fn+F5 fan mode on 2020+ */
{ KE_KEY, 0xB5, { KEY_CALC } },
{ KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
{ KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 0e7fbed8a50d..ac06fec0565c 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -3099,14 +3099,13 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
return;
}

- if (asus->fan_boost_mode_available && code == NOTIFY_KBD_FBM) {
- fan_boost_mode_switch_next(asus);
+ if (code == NOTIFY_KBD_FBM || code == NOTIFY_KBD_TTP) {
+ if (asus->fan_boost_mode_available)
+ fan_boost_mode_switch_next(asus);
+ if (asus->throttle_thermal_policy_available)
+ throttle_thermal_policy_switch_next(asus);
return;
- }

- if (asus->throttle_thermal_policy_available && code == NOTIFY_KBD_TTP) {
- throttle_thermal_policy_switch_next(asus);
- return;
}

if (is_display_toggle(code) && asus->driver->quirks->no_display_toggle)
--
2.37.1


2022-08-08 05:20:08

by Luke D. Jones

[permalink] [raw]
Subject: [PATCH 2/2] 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 run as boost (fullspeed), or auto.

Signed-off-by: Luke D. Jones <[email protected]>
---
drivers/platform/x86/asus-wmi.c | 71 ++++++++++++++++++++++
include/linux/platform_data/x86/asus-wmi.h | 1 +
2 files changed, 72 insertions(+)

diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index ac06fec0565c..2a74e468591a 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -221,7 +221,9 @@ struct asus_wmi {
struct asus_rfkill uwb;

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;
@@ -1757,6 +1759,18 @@ static int asus_fan_set_auto(struct asus_wmi *asus)
return -ENXIO;
}

+ /*
+ * Modern models like 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;
}
@@ -1959,9 +1973,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 sprintf(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);

@@ -1971,6 +2033,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,

@@ -1993,6 +2056,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,
@@ -2035,6 +2101,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;

@@ -2043,6 +2110,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 a571b47ff362..bcffb77371be 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -77,6 +77,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

--
2.37.1

2022-08-08 16:39:51

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 2/2] asus-wmi: Support the GPU fan on TUF laptops

On Mon, Aug 8, 2022 at 6:38 AM Luke D. Jones <[email protected]> wrote:
>
> 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 run as boost (fullspeed), or auto.

Single 'run' is enough, I believe.

...

> + /*
> + * Modern models like G713 also have GPU fan control. This is not AGFN.

like the G713
(Also possibly to surround this subphrase by commas)

...

> +static ssize_t pwm2_enable_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct asus_wmi *asus = dev_get_drvdata(dev);
> +
> + return sprintf(buf, "%d\n", asus->gpu_fan_pwm_mode);

SHould be sysfs_emit(). If there are other uses of sprintf() or
similar in the cases when it goes to sysfs, you may add another patch
to fix them all.

> +}

--
With Best Regards,
Andy Shevchenko