Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hwmon: (dell-smm) Add support for automatic fan mode

Many machines treat fan state 3 as some sort of automatic mode,
which is superior to the separate SMM calls for switching to
automatic fan mode for two reasons:

- the fan control mode can be controlled for each fan separately
- the current fan control mode can be retrieved from the BIOS

On some machines however, this special fan state does not exist.
Fan state 3 acts like a regular fan state on such machines or
does not exist at all. Such machines usually use separate SMM calls
for enabling/disabling automatic fan control.

Add support for it. If the machine supports separate SMM calls
for changing the fan control mode, then the other interface is
ignored.

Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20250917181036.10972-4-W_Armin@gmx.de
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Armin Wolf and committed by
Guenter Roeck
1c165805 205c7302

+95 -31
+32 -18
Documentation/hwmon/dell-smm-hwmon.rst
··· 38 38 fan[1-4]_max RO Maximal Fan speed in RPM 39 39 fan[1-4]_target RO Expected Fan speed in RPM 40 40 pwm[1-4] RW Control the fan PWM duty-cycle. 41 - pwm1_enable WO Enable or disable automatic BIOS fan 41 + pwm[1-4]_enable RW/WO Enable or disable automatic BIOS fan 42 42 control (not supported on all laptops, 43 43 see below for details). 44 44 temp[1-10]_input RO Temperature reading in milli-degrees ··· 49 49 Due to the nature of the SMM interface, each pwmX attribute controls 50 50 fan number X. 51 51 52 - Disabling automatic BIOS fan control 53 - ------------------------------------ 52 + Enabling/Disabling automatic BIOS fan control 53 + --------------------------------------------- 54 54 55 - On some laptops the BIOS automatically sets fan speed every few 56 - seconds. Therefore the fan speed set by mean of this driver is quickly 57 - overwritten. 55 + There exist two methods for enabling/disabling automatic BIOS fan control: 58 56 59 - There is experimental support for disabling automatic BIOS fan 60 - control, at least on laptops where the corresponding SMM command is 61 - known, by writing the value ``1`` in the attribute ``pwm1_enable`` 62 - (writing ``2`` enables automatic BIOS control again). Even if you have 63 - more than one fan, all of them are set to either enabled or disabled 64 - automatic fan control at the same time and, notwithstanding the name, 65 - ``pwm1_enable`` sets automatic control for all fans. 57 + 1. Separate SMM commands to enable/disable automatic BIOS fan control for all fans. 66 58 67 - If ``pwm1_enable`` is not available, then it means that SMM codes for 68 - enabling and disabling automatic BIOS fan control are not whitelisted 69 - for your hardware. It is possible that codes that work for other 70 - laptops actually work for yours as well, or that you have to discover 71 - new codes. 59 + 2. A special fan state that enables automatic BIOS fan control for a individual fan. 60 + 61 + The driver cannot reliably detect what method should be used on a given 62 + device, so instead the following heuristic is used: 63 + 64 + - use fan state 3 for enabling BIOS fan control if the maximum fan state 65 + setable by the user is smaller than 3 (default setting). 66 + 67 + - use separate SMM commands if device is whitelisted to support them. 68 + 69 + When using the first method, each fan will have a standard ``pwmX_enable`` 70 + sysfs attribute. Writing ``1`` into this attribute will disable automatic 71 + BIOS fan control for the associated fan and set it to maximum speed. Enabling 72 + BIOS fan control again can be achieved by writing ``2`` into this attribute. 73 + Reading this sysfs attributes returns the current setting as reported by 74 + the underlying hardware. 75 + 76 + When using the second method however, only the ``pwm1_enable`` sysfs attribute 77 + will be available to enable/disable automatic BIOS fan control globaly for all 78 + fans available on a given device. Additionally, this sysfs attribute is write-only 79 + as there exists no SMM command for reading the current fan control setting. 80 + 81 + If no ``pwmX_enable`` attributes are available, then it means that the driver 82 + cannot use the first method and the SMM codes for enabling and disabling automatic 83 + BIOS fan control are not whitelisted for your device. It is possible that codes 84 + that work for other laptops actually work for yours as well, or that you have to 85 + discover new codes. 72 86 73 87 Check the list ``i8k_whitelist_fan_control`` in file 74 88 ``drivers/hwmon/dell-smm-hwmon.c`` in the kernel tree: as a first
+61 -13
drivers/hwmon/dell-smm-hwmon.c
··· 764 764 if (ret < 0) 765 765 return ret; 766 766 767 + /* 768 + * A fan state bigger than i8k_fan_max might indicate that 769 + * the fan is currently in automatic mode. 770 + */ 771 + if (ret > cdata->data->i8k_fan_max) 772 + return -ENODATA; 773 + 767 774 *state = ret; 768 775 769 776 return 0; ··· 858 851 859 852 break; 860 853 case hwmon_pwm_enable: 861 - if (auto_fan) 854 + if (auto_fan) { 855 + /* 856 + * The setting affects all fans, so only create a 857 + * single attribute. 858 + */ 859 + if (channel != 1) 860 + return 0; 861 + 862 862 /* 863 863 * There is no command for retrieve the current status 864 864 * from BIOS, and userspace/firmware itself can change ··· 873 859 * Thus we can only provide write-only access for now. 874 860 */ 875 861 return 0200; 862 + } 863 + 864 + if (data->fan[channel] && data->i8k_fan_max < I8K_FAN_AUTO) 865 + return 0644; 876 866 877 867 break; 878 868 default: ··· 946 928 } 947 929 break; 948 930 case hwmon_pwm: 931 + ret = i8k_get_fan_status(data, channel); 932 + if (ret < 0) 933 + return ret; 934 + 949 935 switch (attr) { 950 936 case hwmon_pwm_input: 951 - ret = i8k_get_fan_status(data, channel); 952 - if (ret < 0) 953 - return ret; 937 + /* 938 + * A fan state bigger than i8k_fan_max might indicate that 939 + * the fan is currently in automatic mode. 940 + */ 941 + if (ret > data->i8k_fan_max) 942 + return -ENODATA; 954 943 955 944 *val = clamp_val(ret * data->i8k_pwm_mult, 0, 255); 945 + 946 + return 0; 947 + case hwmon_pwm_enable: 948 + if (ret == I8K_FAN_AUTO) 949 + *val = 2; 950 + else 951 + *val = 1; 956 952 957 953 return 0; 958 954 default: ··· 1054 1022 1055 1023 return 0; 1056 1024 case hwmon_pwm_enable: 1057 - if (!val) 1058 - return -EINVAL; 1059 - 1060 - if (val == 1) 1025 + switch (val) { 1026 + case 1: 1061 1027 enable = false; 1062 - else 1028 + break; 1029 + case 2: 1063 1030 enable = true; 1031 + break; 1032 + default: 1033 + return -EINVAL; 1034 + } 1064 1035 1065 1036 mutex_lock(&data->i8k_mutex); 1066 - err = i8k_enable_fan_auto_mode(data, enable); 1037 + if (auto_fan) { 1038 + err = i8k_enable_fan_auto_mode(data, enable); 1039 + } else { 1040 + /* 1041 + * When putting the fan into manual control mode we have to ensure 1042 + * that the device does not overheat until the userspace fan control 1043 + * software takes over. Because of this we set the fan speed to 1044 + * i8k_fan_max when disabling automatic fan control. 1045 + */ 1046 + if (enable) 1047 + err = i8k_set_fan(data, channel, I8K_FAN_AUTO); 1048 + else 1049 + err = i8k_set_fan(data, channel, data->i8k_fan_max); 1050 + } 1067 1051 mutex_unlock(&data->i8k_mutex); 1068 1052 1069 1053 if (err < 0) ··· 1130 1082 ), 1131 1083 HWMON_CHANNEL_INFO(pwm, 1132 1084 HWMON_PWM_INPUT | HWMON_PWM_ENABLE, 1133 - HWMON_PWM_INPUT, 1134 - HWMON_PWM_INPUT, 1135 - HWMON_PWM_INPUT 1085 + HWMON_PWM_INPUT | HWMON_PWM_ENABLE, 1086 + HWMON_PWM_INPUT | HWMON_PWM_ENABLE, 1087 + HWMON_PWM_INPUT | HWMON_PWM_ENABLE 1136 1088 ), 1137 1089 NULL 1138 1090 };
+2
include/uapi/linux/i8k.h
··· 36 36 #define I8K_FAN_LOW 1 37 37 #define I8K_FAN_HIGH 2 38 38 #define I8K_FAN_TURBO 3 39 + /* Many machines treat this mode as some sort of automatic mode */ 40 + #define I8K_FAN_AUTO 3 39 41 #define I8K_FAN_MAX I8K_FAN_TURBO 40 42 41 43 #define I8K_VOL_UP 1