All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Kurt Borja" <kuurtb@gmail.com>
To: "Armin Wolf" <W_Armin@gmx.de>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
Cc: <platform-driver-x86@vger.kernel.org>,
	"Hans de Goede" <hdegoede@redhat.com>,
	<Dell.Client.Kernel@dell.com>, <linux-kernel@vger.kernel.org>,
	"Guenter Roeck" <linux@roeck-us.net>
Subject: Re: [PATCH 08/10] platform/x86: alienware-wmi-wmax: Add support for manual fan control
Date: Sun, 16 Feb 2025 16:25:24 -0500	[thread overview]
Message-ID: <D7U6RB4K0P69.241M4E5RQZCTL@gmail.com> (raw)
In-Reply-To: <ee2a8428-0c37-408d-9ad2-a8975c1b3c23@gmx.de>

On Sun Feb 16, 2025 at 1:12 AM -05, Armin Wolf wrote:
> Am 08.02.25 um 06:16 schrieb Kurt Borja:
>
>> All models with the "AWCC" WMAX device support a way of manually
>> controlling fans.
>>
>> The PWM duty cycle of a fan can't be controlled directly. Instead the
>> AWCC interface let's us tune a PWM `boost` value, which has the
>> following empirically discovered behavior over the PWM value:
>>
>> 	pwm = pwm_base + (pwm_boost / 255) * (pwm_max - pwm_base)
>>
>> Where the pwm_base is the locked PWM value controlled by the EC and
>> pwm_boost is a value between 0 and 255.
>>
>> This pwm_boost knob is exposed as a standard `pwm` attribute.
>
> I am not sure if exposing this over the standard "pwm" attribute is correct here,
> since userspace applications expect to have full access to the fan when using the
> "pwm" attribute.
>
> Maybe using a custom attribute like "fanX_boost" would make sense here? Either way

Actually, in the first draft of this patch I actually did this. I
exposed it as pwmX_boost because it behaved like a "percentage" kind of
thing. I'm ok with fanX_boost tho, it's more explicit in it's intention.

> documenting this special behavior would be nice for future users, maybe you can write
> this down under Documentation/admin-guide/laptops?

Sure! I will. I also want to document the legacy driver features, just
like an historical archive, although some people still use these
features.

-- 
 ~ Kurt

>
> Thanks,
> Armin Wolf
>
>> Cc: Guenter Roeck <linux@roeck-us.net>
>> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
>> ---
>>   .../platform/x86/dell/alienware-wmi-wmax.c    | 55 +++++++++++++++++--
>>   1 file changed, 49 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platform/x86/dell/alienware-wmi-wmax.c
>> index 5f02da7ff25f..06d6f88ea54b 100644
>> --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c
>> +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c
>> @@ -13,6 +13,7 @@
>>   #include <linux/dmi.h>
>>   #include <linux/hwmon.h>
>>   #include <linux/jiffies.h>
>> +#include <linux/minmax.h>
>>   #include <linux/moduleparam.h>
>>   #include <linux/mutex.h>
>>   #include <linux/overflow.h>
>> @@ -176,10 +177,12 @@ enum AWCC_THERMAL_INFORMATION_OPERATIONS {
>>   	AWCC_OP_GET_MIN_RPM			= 0x08,
>>   	AWCC_OP_GET_MAX_RPM			= 0x09,
>>   	AWCC_OP_GET_CURRENT_PROFILE		= 0x0B,
>> +	AWCC_OP_GET_FAN_BOOST			= 0x0C,
>>   };
>>
>>   enum AWCC_THERMAL_CONTROL_OPERATIONS {
>>   	AWCC_OP_ACTIVATE_PROFILE		= 0x01,
>> +	AWCC_OP_SET_FAN_BOOST			= 0x02,
>>   };
>>
>>   enum AWCC_GAME_SHIFT_STATUS_OPERATIONS {
>> @@ -563,12 +566,13 @@ static inline int awcc_thermal_information(struct wmi_device *wdev, u8 operation
>>   	return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, out);
>>   }
>>
>> -static inline int awcc_thermal_control(struct wmi_device *wdev, u8 profile)
>> +static inline int awcc_thermal_control(struct wmi_device *wdev, u8 operation,
>> +				       u8 arg1, u8 arg2)
>>   {
>>   	struct wmax_u32_args args = {
>> -		.operation = AWCC_OP_ACTIVATE_PROFILE,
>> -		.arg1 = profile,
>> -		.arg2 = 0,
>> +		.operation = operation,
>> +		.arg1 = arg1,
>> +		.arg2 = arg2,
>>   		.arg3 = 0,
>>   	};
>>   	u32 out;
>> @@ -684,6 +688,11 @@ static umode_t awcc_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_type
>>   		if (channel < priv->fan_count)
>>   			return 0444;
>>
>> +		break;
>> +	case hwmon_pwm:
>> +		if (channel < priv->fan_count)
>> +			return 0644;
>> +
>>   		break;
>>   	default:
>>   		break;
>> @@ -698,6 +707,7 @@ static int awcc_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
>>   	struct awcc_priv *priv = dev_get_drvdata(dev);
>>   	struct awcc_temp_channel_data *temp;
>>   	struct awcc_fan_channel_data *fan;
>> +	u32 fan_boost;
>>   	int ret;
>>
>>   	switch (type) {
>> @@ -742,6 +752,16 @@ static int awcc_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
>>   			return -EOPNOTSUPP;
>>   		}
>>
>> +		break;
>> +	case hwmon_pwm:
>> +		fan = &priv->fan_data[channel];
>> +
>> +		ret = awcc_thermal_information(priv->wdev, AWCC_OP_GET_FAN_BOOST,
>> +					       fan->id, &fan_boost);
>> +		if (ret)
>> +			return ret;
>> +
>> +		*val = fan_boost;
>>   		break;
>>   	default:
>>   		return -EOPNOTSUPP;
>> @@ -796,10 +816,27 @@ static int awcc_hwmon_read_string(struct device *dev, enum hwmon_sensor_types ty
>>   	return 0;
>>   }
>>
>> +
>> +static int awcc_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
>> +			    u32 attr, int channel, long val)
>> +{
>> +	struct awcc_priv *priv = dev_get_drvdata(dev);
>> +	u8 fan_id = priv->fan_data[channel].id;
>> +
>> +	switch (type) {
>> +	case hwmon_pwm:
>> +		return awcc_thermal_control(priv->wdev, AWCC_OP_SET_FAN_BOOST,
>> +					    fan_id, (u8)clamp_val(val, 0, 255));
>> +	default:
>> +		return -EOPNOTSUPP;
>> +	}
>> +}
>> +
>>   static const struct hwmon_ops awcc_hwmon_ops = {
>>   	.is_visible = awcc_hwmon_is_visible,
>>   	.read = awcc_hwmon_read,
>>   	.read_string = awcc_hwmon_read_string,
>> +	.write = awcc_hwmon_write,
>>   };
>>
>>   static const struct hwmon_channel_info * const awcc_hwmon_info[] = {
>> @@ -814,6 +851,12 @@ static const struct hwmon_channel_info * const awcc_hwmon_info[] = {
>>   			   HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX,
>>   			   HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX
>>   			   ),
>> +	HWMON_CHANNEL_INFO(pwm,
>> +			   HWMON_PWM_INPUT,
>> +			   HWMON_PWM_INPUT,
>> +			   HWMON_PWM_INPUT,
>> +			   HWMON_PWM_INPUT
>> +			   ),
>>   	NULL
>>   };
>>
>> @@ -954,8 +997,8 @@ static int awcc_platform_profile_set(struct device *dev,
>>   		}
>>   	}
>>
>> -	return awcc_thermal_control(priv->wdev,
>> -				    priv->supported_profiles[profile]);
>> +	return awcc_thermal_control(priv->wdev, AWCC_OP_ACTIVATE_PROFILE,
>> +				    priv->supported_profiles[profile], 0);
>>   }
>>
>>   static int awcc_platform_profile_probe(void *drvdata, unsigned long *choices)


  parent reply	other threads:[~2025-02-16 21:25 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-08  5:16 [PATCH 00/10] HWMON support + DebugFS + Improvements Kurt Borja
2025-02-08  5:16 ` [PATCH 01/10] platform/x86: alienware-wmi-wmax: Rename thermal related symbols Kurt Borja
2025-02-16  5:40   ` Armin Wolf
2025-02-08  5:16 ` [PATCH 02/10] platform/x86: alienware-wmi-wmax: Refactor is_awcc_thermal_mode() Kurt Borja
2025-02-16  5:44   ` Armin Wolf
2025-02-08  5:16 ` [PATCH 03/10] platform/x86: alienware-wmi-wmax: Improve internal AWCC API Kurt Borja
2025-02-16  5:48   ` Armin Wolf
2025-02-08  5:16 ` [PATCH 04/10] platform/x86: alienware-wmi-wmax: Modify supported_thermal_profiles[] Kurt Borja
2025-02-16  5:49   ` Armin Wolf
2025-02-08  5:16 ` [PATCH 05/10] platform/x86: alienware-wmi-wmax: Improve platform profile probe Kurt Borja
2025-02-16  5:57   ` Armin Wolf
2025-02-08  5:16 ` [PATCH 06/10] platform/x86: alienware-wmi-wmax: Add support for the "custom" thermal profile Kurt Borja
2025-02-16  5:59   ` Armin Wolf
2025-02-08  5:16 ` [PATCH 07/10] platform/x86: alienware-wmi-wmax: Add HWMON support Kurt Borja
2025-02-16  6:06   ` Armin Wolf
2025-02-16 21:27     ` Kurt Borja
2025-02-08  5:16 ` [PATCH 08/10] platform/x86: alienware-wmi-wmax: Add support for manual fan control Kurt Borja
2025-02-16  6:12   ` Armin Wolf
2025-02-16  6:14     ` Armin Wolf
2025-02-16 21:25     ` Kurt Borja [this message]
2025-02-08  5:16 ` [PATCH 09/10] platform/x86: alienware-wmi-wmax: Add a DebugFS interface Kurt Borja
2025-02-08  5:16 ` [PATCH 10/10] platform/x86: alienware-wmi: Improve and update documentation Kurt Borja
2025-02-16  6:22   ` Armin Wolf
2025-02-16 20:51     ` Kurt Borja
2025-02-16 21:29       ` Armin Wolf
2025-02-16 21:38         ` Kurt Borja

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=D7U6RB4K0P69.241M4E5RQZCTL@gmail.com \
    --to=kuurtb@gmail.com \
    --cc=Dell.Client.Kernel@dell.com \
    --cc=W_Armin@gmx.de \
    --cc=hdegoede@redhat.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=platform-driver-x86@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.