- 
                Notifications
    
You must be signed in to change notification settings  - Fork 76
 
Fixes LOQ model fancurves, new WMI functions #347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Correct offset for read/writes CPU,GPU,IC groups - WMI functions to read/write Fan Table Indices
- Read correctly the common ec memory area of CPU min temp, max temp, rpm, there is no GPU or IC data in that area, has no effect writing on this area to the current fan curve. - Adds function wmi_write_fancurve_defaults to call WMI method SFAN to trigger the selection of fan curve from bios data for the custom powermode. - Expose function wmi_write_fancurve_defaults as an entry in hwmon path as auto_points_defaults, use : 'echo 0 > auto_points_defaults'.
| 
           Hi, with the data from the comments in #352 , I added a commit to simplify the use for the models LZCN and NZCN : 
 Example: 
 
 $ sensors legion_hwmon-isa-0000
legion_hwmon-isa-0000
Adapter: ISA adapter
Fan 1:           1400 RPM  (max = 10000 RPM)
Fan 2:           1400 RPM  (max = 10000 RPM)
CPU Temperature:  +42.0°C
GPU Temperature:  +35.0°C
IC Temperature:    +0.0°C
pwm1:                 N/A  (mode = pwm)Edit : There is a WMI Method that can return the selected fan curve from the internal fan tables, but I cant make it work, maybe someone knows how, keep getting ACPI Error 4100:fwts dsl struct WMIFanTableReadLoq { // FACT table
	u16 FNIM;
	u16 FNID;
	u32 FNLE;
	u16 FNS0;
	u16 FNS1;
	u16 FNS2;
	u16 FNS3;
	u16 FNS4;
	u16 FNS5;
	u16 FNS6;
	u16 FNS7;
	u16 FNS8;
	u16 FNS9;
	u32 SEID;
	u32 STLE;
	u16 SST0;
	u16 SST1;
	u16 SST2;
	u16 SST3;
	u16 SST4;
	u16 SST5;
	u16 SST6;
	u16 SST7;
	u16 SST8;
	u16 SST9;
	u8  SOU1;
	u8  SOU2;
	u16 CFMS;
	u8  SOU3;
	u8  SOU4;
	u16 CFIS;
	u16 FSSP;
	u16 MST1;
	u16 MST2;
	u16 MSTP;
} __packed;
static ssize_t wmi_read_fancurve_idx(const struct model_config *model,
					struct fancurve *fancurve)
{
	u8 buffer[10];
	int err;
	u8 input[2] = { 0x09, 0x0 };
	struct acpi_buffer in_buf = {
		.length = sizeof(input),
		.pointer = input,
	};
	err = wmi_exec_ints("87FB2A6D-D802-48E7-9208-4576C5F5C8D8", 0,
					0xa7, &in_buf, buffer, sizeof(buffer));
	if (!err) {
		struct WMIFanTableReadLoq *fantable =
			(struct WMIFanTableReadLoq *)&buffer[0];
		fancurve->current_point_i = 0;
		fancurve->size = fantable->FNLE;
		fancurve->fan_speed_unit = FAN_SPEED_UNIT_RPM_HUNDRED;
		fancurve->points[0].speed1 = fantable->FNS0;
		fancurve->points[1].speed1 = fantable->FNS1;
		fancurve->points[2].speed1 = fantable->FNS2;
		fancurve->points[3].speed1 = fantable->FNS3;
		fancurve->points[4].speed1 = fantable->FNS4;
		fancurve->points[5].speed1 = fantable->FNS5;
		fancurve->points[6].speed1 = fantable->FNS6;
		fancurve->points[7].speed1 = fantable->FNS7;
		fancurve->points[8].speed1 = fantable->FNS8;
		fancurve->points[9].speed1 = fantable->FNS9;
		print_hex_dump(KERN_DEBUG, "legion_laptop fan table idx wmi buffer",
		       DUMP_PREFIX_ADDRESS, 16, 1, buffer, sizeof(buffer),
		       true);
	}
	return err;
}``
</details> | 
    
powermodes when in custom mode.
| 
           In Vantage App when the Custom Mode is selected, there is a drop down control to the right that says "Resets" and gives the options of powermodes : "Quiet, Balanced, Performance". It means that when in Custom Mode/balanced-performance 255 it can use any of the default fancurves from "Quiet, Balanced, Performance" modes. This last commit does that. 
 
 
 
 
  | 
    
Hi me again :), tldr of this PR :
Now the details :
When using the Lenovo Vantage Application when setting the custom mode and modifying its levels (points) :
It can be queried with the following powershell script :
FanTable : {2, 2, 3, 4, 5, 6, 7, 8 ,9 ,9} FanTableSize : 10 SensorTable : {2, 2, 3, 4, 5, 6 ,7, 8, 9 ,9} SensorTableSize : 10 ReturnValue : TrueIn this output the value 2 is repeated because I changed the first point of the fancurve to the same level as the second point (1400, 1400). This method is implemented now in function
wmi_read_fancurve_idx. FanId and SensorId parameters doesnt make any difference.There are many Fan Curves defined and can be queried with the following powershell :
This output is just one example, In Windows it shows 15 I assume it gets only the Fan Table specific for the laptop model, In the ACPI DSDT there are 4 Tables of 15 each one. Also the temps here are not used there are other tables with temps selected also by the thermal mode, dgpu and PRID logic.
We dont care too much about the Fan Curves predefined, maybe as a reference, however Vantage app doesnt use the 10th one that has the highest temp 120 for the IC sensor (the index doesnt start at 0 as C arrays it starts at 1), you can see in the output of
Get_Fan_Tableuses index 9 for the 10th position. This can be a warning when changing those values.The WMI call that the Vantage App uses
LENOVO_FAN_METHOD.Fan_Set_Tablerelated to the ACPI/DSDT SFAN Method only works with the indices mapping, doesnt set directly RPM's it obtains them from its internal tables. This method is implemented inwmi_write_fancurve_idx.The function
wmi_read/write_fancurve_idxcan be used as new feature on the variables exposed by the driver in hwmon or acpi/firmware (maybe) and also on the python client, if someone wants to develop it.Besides the modes Quiet (1), Balanced (2), Performance (3) and Custom (255) there is a Extreme Mode (224).
So following the DSDT code as a guide of how to obtain the rpm's, I replaced the old
ec_read/write_fancurve_loqto reset the index mapping to an ordered list (1-10) that represent the speed RPM's that are being passed as arguments (via cmd line, legion.py, legion_gui.py), sets the correct values on the offsets on the 3 groups (cpu, gpu, ic), and activates a flag to tell the device/ec to use the new values.Note:
echo "balanced" > /sys/firmware/acpi/platform_profile, the values are reset to the bios/dsdt defaults and the 3 sets of custom values are not changed, so when queryingcat /sys/kernel/debug/legion/fancurveit will appear the custom values but not the current ones, I think that when changing powermodes also we have to callwmi_write_fancurve_idxso we reset the indices, and the acpi/dsdt set the default speeds and temps of the current powermode.Test Output of Fancurve (Custom Mode, modes set in Vantage App):
Changing the CPU and GPU fans
output of fancurve