Closed Ex3mS1ze closed 4 years ago
310-15isk has the same bios as 510-15isk. I'm also trying to find the writeregister, but still no success.
There is progress?
I was wondering if any of you know the config for the 310-14isk. --Editted It´s the same bios as the 510-XXisk and the 310-XXisk
I have spent hours trying to find the correct write register for the Ideapad 310-15isk. I have given up at this point, but please reach out if anyone comes up with a config that works for either the Ideapad 510 or 310
I have found a power management app version that has an anti-dust function. It actually speed the fan up, stop it, reverse it and then stop it. But I can´t manage to look at the EC registers in real time. this is the link: https://support.lenovo.com/br/pt/downloads/ds040484
Seems like all new lenovo laptops have an EC that controls low-level PM stuff. I found this linux program, that is aimed at yoga 13: https://github.com/blan4/lenovo-yoga-fan-control Lenovo calls their EC as "MCU" (microcontroller?), and its fw can be updated along bios. Our cn43 bios had an mcu update included. https://download.lenovo.com/consumer/mobiles/0xcn43ww.txt
So, afaik, there are three approaches we can take:
Have you tried any of these? For the time being I am using tornado ThrottleStop and I only disable Turbo function.
I finally got some time to check this topic again. I monitored the EC while doing the fan cleaning procedure from the lenovo app @doiiido has linked. The results were:
The first red line is the exact moment I started the cleaning procedure, the second one is when I stopped it. I also increased the ec-probe pool rate to 1 second (default is 5). As you can see, first the 0x01 register (VDAT) is set to 0x01, then 0xAB (MODE) is set to 0x08, followed by 0x01 being set to 0x03 and then the fan speed (0x06, known as FANS) got high.
BUT, I tried many ways to write to 0x06, even trying to write to it while the cleaning procedure was being done, but none worked. My guess is that the register for writing the fan speed is in another memory address that isn't the EC one.
I don't have the time nor the skills to reverse engineer the energy manager app, but if someone is willing to do it, I'd be more than happy to send a donation. Also, @hirschmann do you have any idea of what is going on?
I've also been looking into this recently. My laptop is an Y700-ISK but it's all similar enough. (For the record, there are two fans and their speed can be read from 0x06
for fan #1, and 0xFE
for fan #2, while the range seems to be from 0x00
to 0x30
, i.e. 48).
It appears on many models fans can be controlled by writing to 0xB0
. Although technically this is not setting fan speed but faking CPU temperature, it seems to have worked as a solution for many people (I looked into all the profiles for Lenovo laptops posted in the GitHub repo).
The proper way, however, is to reverse engineer the Energy Management utility as stated above. I suggest starting with this version of it, which is newer, yet the file is half the size: https://support.lenovo.com/us/en/downloads/ds030145
I posted an extracted, minimal version of this utility here (unpacked, twice, with InnoExtract/InnoUnp and WinRAR, then just kept the necessary files and deleted the rest; hopefully this saves some time for anyone else who wants to investigate it too): https://forums.lenovo.com/t5/Gaming-Laptops/Reducing-fans-noise-on-Lenovo-Legion-laptops/m-p/4125653/#M17900
As @danielstuart14 observed, running the app has the effect of changing the state of many EC registers, although in fact it's often just setting particular flags (bits) within these registers, so the resulting value the EC register is set to will depend on what its "usual" value is. For example, on my laptop 0xAB
changes from 0xA4
to 0xAC
when the "dust extraction" is running but:
0xA4
= 0b101001000xAC
= 0b10101100So this is equivalent to just setting bit 3 (counting from the right-hand side, starting from 0).
Fortunately, on my laptop at least, the meaning behind many of those seems to be somewhat documented in DSDT. I created an RwEverything information file, also readable in plain text, that lists all the information obtained from DSDT on my laptop. The file is linked to the post here: https://forums.lenovo.com/t5/Gaming-Laptops/Reducing-fans-noise-on-Lenovo-Legion-laptops/m-p/4125651#M17899
For example, for 0xAB
it says: (\r
replaced with newlines for clarity)
AB =
Bit 0: MODE
Bits 1-2: (Omitted in DSDT)
Bit 3: INIT
Bit 4: FAN1
Bit 5: FAN2
Bit 6: FAOK
Bit 7: SKIN
So we can observe that this particular change is equivalent to setting the INIT
flag.
However, the "dust extraction" routine seems to be doing more than just modifying EC registers. I haven't had the chance to fully look investigate it yet but here's what I've found out so far: alongside the .NET utility, there is a DLL LenovoEmExpandedAPI.dll
, which includes many low-level hardware functions. In particular, in relation to the fans, there are SetCleanDust
, GetCleanDustStatus
and SupportCleanDust
, all called in the following manner:
internal unsafe static int CMainFrame.OnCreate(CMainFrame* P_0, tagCREATESTRUCTW* lpCreateStruct)
int num;
SupportCleanDust(&num, 0u);
if (num == 0) ...
internal unsafe static int CPageDust.OnInitDialog(CPageDust* P_0)
SetCleanDust(1, 0u);
internal unsafe static void CPageDust.OnBnClickedDustclose(CPageDust* P_0)
internal unsafe static void CPageDust.OnBnClickedDustshut(CPageDust* P_0)
SetCleanDust(0, 0u);
internal unsafe static void CPageDust.OnTimer(CPageDust* P_0, ulong nIDEvent)
int num = 1;
GetCleanDustStatus(&num, 0u);
if (num == 0 && ...
Then, there are some lower-level CAtmThermalControl
and CAtmDriverLibrary
methods, which appear very promising as it seems the fan speed can be controlled completely:
internal unsafe static int CAtmThermalControl.ChangeFanSpeed(CAtmThermalControl* P_0, uint dwFanCtrlCmd, uint* dwActionStatus)
{
return CAtmDriverLibrary.ChangeFanxSpeed((CAtmDriverLibrary*)((long)(IntPtr)P_0 + 8), dwFanCtrlCmd, dwActionStatus);
}
internal unsafe static int CAtmDriverLibrary.ChangeFanxSpeed(CAtmDriverLibrary* P_0, uint dwFanCtrlCmd, uint* pActionStatus)
{
ulong num = (ulong)(*(long*)((long)(IntPtr)P_0 + 8));
uint num2;
if (-1L != (long)num && DeviceIoControl((void*)num, 2198873468u, &dwFanCtrlCmd, 4u, pActionStatus, 4u, &num2, null) != 0)
{
return 0;
}
return -2147467259;
}
internal unsafe static int CAtmThermalControl.GetFanSpeed(CAtmThermalControl* P_0, uint* pFanSpeed)
{
ushort num = *(ushort*)((long)(IntPtr)P_0 + 60);
int result = default(int);
if (1 == num)
{
uint num2;
result = CAtmDriverLibrary.QueryFanSpeed((CAtmDriverLibrary*)((long)(IntPtr)P_0 + 8), 0u, &num2);
*pFanSpeed = (num2 & 0xFFFF);
}
else if (3 == num)
{
CAtmThermalControl* ptr = (CAtmThermalControl*)((long)(IntPtr)P_0 + 8);
uint num3;
CAtmDriverLibrary.QueryFanSpeed((CAtmDriverLibrary*)ptr, 0u, &num3);
uint num4;
result = CAtmDriverLibrary.QueryFanSpeed((CAtmDriverLibrary*)ptr, 1u, &num4);
*pFanSpeed = ((num4 << 16) | (num3 & 0xFFFF));
}
return result;
}
internal unsafe static int CAtmDriverLibrary.QueryFanSpeed(CAtmDriverLibrary* P_0, uint dwIndexFan, uint* pFANxSpeed)
{
uint num = 0u;
ulong num2 = (ulong)(*(long*)((long)(IntPtr)P_0 + 8));
uint num3;
int result;
if (-1L != (long)num2 && DeviceIoControl((void*)num2, 2198873456u, &dwIndexFan, 4u, &num, 4u, &num3, null) != 0)
{
result = 0;
*pFANxSpeed = num;
}
else
{
result = -2147467259;
}
return result;
}
Finally, at the lowest level there is DeviceIoControl
itself:
public unsafe static extern int DeviceIoControl(void* P_0, uint P_1, void* P_2, uint P_3, void* P_4, uint P_5, uint* P_6, _OVERLAPPED* P_7);
And it appears to be writing to \\.\EnergyDrv
to make actual changes. The only other mention of this I was able to find is a page here: http://itachi.pl/lenovo-bluetooth-i-windows-8-1/
It's not in English but the gist of it appears to be that somebody found a way to switch Bluetooth on/off in a laptop that lacks a hardware switch for that. The code for this was also posted on GitHub: https://github.com/ITachiLab/bluedentist/
The website link gives an example how the DLL exports can be called from Python. Separately, it appears somebody else was doing it from VB, in the following manner:
<DllImport("LenovoEmExpandedAPI.dll", callingconvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)> _
Public Shared Function SetCleanDust(ByVal arg_0 As IntPtr, ByVal arg_18 As IntPtr) As IntPtr
End Function
As I've mentioned, I haven't had the time to look at all of this in detail myself but it seems all the information necessary to control the fans on these laptops is contained within that Energy Management utility, so it's just a matter of getting it out one way or another, and repurposing it.
Unfortunately this version of Lenovo's utility doesn't work with my ideapad 310. Also, I tried bluedentist and it doesn't seem to work either. I think LenovoEmExpandedAPI is incompatible with my laptop's EC.
And even worse, seems like the older power manager utility (which is target to windows 8.1, so, yeah, idk why it's older) doesn't have a DLL that it externaly calls to when doing any interaction with the hardware. Seems like all the functions we want to expose are built in the app, which makes it quite hard to reverse engineer, as the functions aren't public.
For anyone thirsty for a better cooling: select the Yoga 510 config, then change the Write Register to 189. At least you can set the fan to 100% now.
It isn't the best way to do it, as it only fakes the cpu temp. But for now it's good enough.
Lenovo Energy Management version 7.0.3.9 (15.01.2016) works on Win 10. The dust cleaning function (maximum fan speed) is working. Maybe this will somehow help.
This issue is stale because it has been open more than 180 days with no activity. If nobody comments within 7 days, this issue will be closed
Here is a config I made, it can trigger cleaning mode speed on Lenovo V310-15IKB 80T3. Lenovo V310-15IKB 80T3.zip
For anyone thirsty for a better cooling: select the Yoga 510 config, then change the Write Register to 189. At least you can set the fan to 100% now.
It isn't the best way to do it, as it only fakes the cpu temp. But for now it's good enough.
I was curious about setting up my lenovo 310 laptop with 100% fan speed, following your advice - it worked well!
I have to say, I don't think I've ever heard my laptop work at 100% fan speed prior to this - holy hell 😂
Thank you for the trick, this will be useful 👍
I tried the recommended models. The configuration from the LENOVO Ideapad 510s shows a true speed, but I can't adjust the speed. I looked through the DSDT and tried to change write register. After observing the change in the values of the registers, 176 is very similar to the one searched. But the speed doesn't change. There is also an AUTO parameter, but can't change it. ReadRegister=6 WriteRegister=?