Contribute
Register

New Fan Control DSDT - for silent fan at higher temps!

Status
Not open for further replies.

RehabMan

Moderator
Joined
May 2, 2012
Messages
181,112
Motherboard
Intel DH67BL
CPU
i7-2600K
Graphics
HD 3000
Mac
  1. MacBook Air
Mobile Phone
  1. iOS
One thing that has always bugged me about HP laptops is the noisy fan. First of all, it runs when it doesn't need to (IMHO) and it runs faster than it needs to for the given temperatures. Although the ideal solution would be to find a different fan, or use a resistor to reduce the voltage going to the fan (thus reducing it's speed overall), at this point I didn't want to attempt that.

Instead, I've been reading various forums for a solution and a pretty good one has been developed for the Windows side of things. And fortunately, I was able to follow all the information about the ProBook's EC such that I could develop a solution on OS X. My solution should work on both Lion and ML, although I've only tested it on ML (Edit: Now tested on Lion too. Works fine!). I do however expect that it will require more testing, so I hope some of you will want to help with that. In particular, I've only tried this on my i3-2310 HD3000 system. I don't have a system with a faster CPU nor do I have one with dedicated graphics.

Let's start with how the current fan control works in the current DSDT. The current code resides in the TCPU method in the SMCD device (name FAN00000). This device is bound to ACPISensors.kext, which registers the ACPI sensor with FakeSMC. The purpose of this method is to report the CPU temperature so HWMonitor can display it. But our version does a bit more -- it controls the CPU fan as well. What the method does is write to an offset within the EC that has some control over what the fan is doing. This is the byte at offset 0x2F (known as FTGC in the DSDT). Normally this byte is set at 0xFF, which is "automatic mode" for the fan. If you write a value other than 0xFF it indicates the speed. 0x00 is the fastest. 0x80 is the slowest. The fan can only be controlled in steps. We all wish the slowest speed was a little slower, unfortunately there is nothing we can do about that.

You might notice that there is no speed for off. That is because 0xFF represents off when the current CPU temperature is 31C or lower. So unless your laptop idles at less than 31C, you will never see the fan go off in automatic mode. Of course, unless the ambient temperature is very low, seeing the fan off in normal use is fairly rare. But it is possible to control it directly...

The trick depends on the fact that if you write to the EC offset normally reserved for reading CPU temperature, you can trick the EC into thinking that the current CPU temperature is 31C (or lower). The temperature can be written here by writing 1 to offset 0x22 (CRZN), then the fake temperature to offset 0x26 (TEMP). If we simultaneously write 0xFF to the fan control, the fan will turn off. Of course, now the EC is unable to respond to temperature variations automatically, so we need code to run to constantly monitor temperature and modify the fan speed appropriately. To reset the EC, you write zero to TEMP (after selecting zone 1 with CRZN, of course). So even after locking in a temperature it is possible to reset the EC back to normal operation. This is important because the setting of the fake temperature at TEMP survives reboots and power cycles!

In addition, you don't want the fan to be constantly turning on one second, then turning off the next, so whatever logic we have in place must buffer changes to the fan speed, to avoid annoying an unnecessary fan speed changes. My solution uses a couple of techniques to accomplish this. First, it doesn't respond to instant temperature fluctuations. Instead it calculates a moving average (current running over 16 samples, collected a second apart) and responds to changes in the average. Second of all, it delays any change in fan speed by a variable time depending on how "far" the current desired fan speed is from the currently set fan speed. Right now this varies between 20 seconds, and 3 seconds, depending on how far the temperature runs. I would say it is extremely lazy about changing fan speed right now. Maybe too lazy. You can try it and give feedback.

Since my code tricks the EC into believing that the laptop is arbitrarily cool, the current method of letting HWMonitor cause the fan control method to execute is not adequate because there are bunch of scenarios where HWMonitor is not running. Consider the case where you run HWMonitor, causing a "fake" temperature to be set, and the fan to be turned off, then you, logout, restart into BIOS, restart into Chimera, restart and boot another OS like Windows. In all those cases, the fan will be left off, the EC will think the laptop is cool, and the fan would never turn on.

In order to handle some of these scenarios I had to develop a bit more software in addition to the new DSDT patch:

- A Chimera module to be run when Chimera starts up. This module is called Fanreset.dylib and it resets the EC to factory settings when Chimera starts. This handles the case you boot some other OS, or just sit at the Chimera screen for a while.

- A Kernel Extension (kext) to call the fan control method in the DSDT to get proper fan control when logged out. This also means you do not need to run HWMonitor to get fan control (HWMonitor is back to just displaying information -- not controlling the fan). This new kernel extension is called ACPIPoller.kext and its purpose is to simply call APCI methods every second. It uses a list of methods called out in the Info.plist and simply attaches to our SMCD device and calls the FCPU method (the FCPU method contains the heart of my new fan control logic)

Note: there is no solution to resetting into BIOS. I recommend always booting into Chimera after running OS X with this fan control software active, then restarting into BIOS (Ctrl+Alt+Del). Alternatively, you can use the EC reset procedure detailed later.

How to install:

- First, repatch your DSDT using my patches available here: https://github.com/RehabMan/HP-ProBook-4x30s-DSDT-Patch
(see the wiki for instructions)

The difference between this patch and a normal patch is that instead of using 04_FanPatch.txt, use 04_FanExperimental.txt. If you are using the Makefile, you can use 'make allexp' to make both the normal patch (all_exp.txt, all1080_exp.txt). Then patch your DSDT using Auto Patcher. You can probably also use the 04_FanExperimental.txt to patch an existing DSDT you already have. I have not tried that, but I think it will work. After patching, copy the result to /Extra/dsdt.aml like normal.

- Second, download and install Fanreset.dylib. It is available here: https://github.com/RehabMan/HP-ProBook-4x30s-Fan-Reset
(see downloads section for binary)

Just copy the binary to /Extra/modules/Fanreset.dylib. You will likely have to make the directory /Extra/modules with 'mkdir /Extra/modules'

- Third, download and install ACPIPoller.kext. It is available here: https://github.com/RehabMan/OS-X-ACPI-Poller
(see downloads section for binary)

You can install using Kext Wizard just like you would install any kext.

Note: Make sure you uncheck the BIOS option "Fan always on with AC power"

After all that, reboot, and you should see the fan off at temperatures up to 40C. If you look at the code in the 04_FanExperimental.txt, you will see a table that correlates fan speeds to CPU temperatures. It is here you can tweak things if you want:
Code:
// Fan Control Table (pairs of temp, fan control byte)\n
	Name (FTAB, Buffer ()\n
	{\n
		40, 255, 	// 255 is off (really auto, but at low temp it is off)\n
		45, 128, 	// 128 is slowest speed\n
		50, 82,\n
		55, 74,\n
		60, 59,\n
		70, 49,\n
		0xFF, 0 	// last entry must be 0xFF, 0 is max fan speed\n
	})\n

The first byte of each pair in the buffer is the high temperature threshold for the given fan speed that follows. So, for temps up to 40C, the fan is set to automatic (0xFF or 255) and since we are faking the temperature at 31C, the fan will be off. Certainly you could try running at higher temps before turning the fan on, but it might help to run the way I have it and see how your laptop behaves.

If you think things are not working correctly, it might be wise to turn your laptop off and let it cool. Obviously what we are doing here is pretty sketchy and I'm not going to take any responsibility for you burning your laptop up or otherwise damaging it due to overheating. If you think that your EC is not getting reset (via the Chimera Fanreset module), you can reset the EC to default behavior by turning the laptop off, disconnecting AC power, removing the battery, pressing the power button for 30-secs, then putting everything back together and restarting.

In addition, you might want to monitor temperatures and the operation of this fan control DSDT software. For that I have built a special version of HWMonitor, which I have attached to this post. It displays some debugging information from the FCPU method as well as some additional temperatures.

Credits:

http://forum.notebookreview.com/hp-...ays-help-dsdt-editing-nhc-acpi-module-15.html
(in particular poster tkg2 with super useful information!!!)

http://www.computerbase.de/forum/showthread.php?t=1070494
(german)
http://translate.google.com/transla...ase.de/forum/showthread.php?t=1070494&act=url
(english google translate of german site above)
 

Attachments

  • HWMonitor.zip
    185.6 KB · Views: 1,538
Here's a couple of examples of modification of the FTAB to make the fan turn on/off at different temperatures.

First the original:
Code:
// Fan Control Table (pairs of temp, fan control byte)\n
	Name (FTAB, Buffer ()\n
	{\n
		40, 255, 	// 255 is off (really auto, but at low temp it is off)\n
		45, 128, 	// 128 is slowest speed\n
		50, 82,\n
		55, 74,\n
		60, 59,\n
		70, 49,\n
		0xFF, 0 	// last entry must be 0xFF, 0 is max fan speed\n
	})\n

Say we live in a home with a very high ambient temperature (hot weather) or we just don't like the idea of the fan turning off at all.

We just comment out the first line in the table:

Code:
// Fan Control Table (pairs of temp, fan control byte)\n
	Name (FTAB, Buffer ()\n
	{\n
//		40, 255, 	// 255 is off (really auto, but at low temp it is off)\n
		45, 128, 	// 128 is slowest speed\n
		50, 82,\n
		55, 74,\n
		60, 59,\n
		70, 49,\n
		0xFF, 0 	// last entry must be 0xFF, 0 is max fan speed\n
	})\n

Let's say we want the fan to stay off all the way to 50C:


Code:
// Fan Control Table (pairs of temp, fan control byte)\n
	Name (FTAB, Buffer ()\n
	{\n
		50, 255, 	// 255 is off (really auto, but at low temp it is off)\n
		55, 128, 	// 128 is slowest speed\n
		60, 82,\n
		65, 74,\n
		70, 59,\n
		75, 49,\n
		0xFF, 0 	// last entry must be 0xFF, 0 is max fan speed\n
	})\n

Hope that gives you some options/ideas...
 
Maybe you'd like to see a screen shot:

Screen Shot 2012-09-13 at 5.05.48 PM.png
 
NICE! YES, thank you !!

edit:
I will try later and report. quick question, how can you now turn off fan via hwmonitor app?
 
Wow, that is a thing of beauty

I have to check my laptop to make sure is working because is so silent.
New kext, hwmonitor, big chunk of dsdt code. This is some serious work.

Thank You RehabMan !!!

My i5-2430M stays around 47°-49°
I will try to setup my lowest temperature around 55° and see how it works with light browsing.
More tests will follow tomorrow.
 
NICE! YES, thank you !!

edit:
I will try later and report. quick question, how can you now turn off fan via hwmonitor app?

Well, you can't with the situation before this solution. Unless your laptop runs at 31C or below... That is hard coded into the HP's EC for this laptop.

My solution just tricks it... But it is all the parts working together. The HWMonitor update I have here is just in case we need to troubleshoot things. In the long run it will probably not be necessary...
 
Wow, that is a thing of beauty

I have to check my laptop to make sure is working because is so silent.
New kext, hwmonitor, big chunk of dsdt code. This is some serious work.

Thank You RehabMan !!!

My i5-2430M stays around 47°-49°
I will try to setup my lowest temperature around 55° and see how it works with light browsing.
More tests will follow tomorrow.

Yes, really quiet with fan off and SSD instead of hard disk. I'm now going to start pushing my low temp up and see how it behaves. During development I left it at 40C because I wanted to have some headroom in case the code malfunctioned. Now that it is stable and I trust it, I can start to push the limit a bit...
 
Yes, really quiet with fan off and SSD instead of hard disk. I'm now going to start pushing my low temp up and see how it behaves. During development I left it at 40C because I wanted to have some headroom in case the code malfunctioned. Now that it is stable and I trust it, I can start to push the limit a bit...

Now running w/ lowest temp threshold at 50. This works pretty well, even for (super) light web browsing. If you open 10 tabs at a time in Chrome, the fan might turn on after they get done loading. Normally temp goes slightly above 50C, then the counter starts, and usually the temp drops before counter expires (so fan never turns on). And typing in this editor pushes the temp to 50C+ (I think it is all the smileys on the right using CPU).

Screen Shot 2012-09-14 at 7.30.43 AM.png

Hopefully, with a little feedback we can decide on a good default for the FTAB table. It would be nice for someone with an i7 to report back. And I'd also like to see someone with Radeon graphics to give it a try. For those laptops, I don't really know if they have a second fan with its own controls, or does the single system fan serve to cool both the CPU and GPU. It would be interesting to see how this fix behaves on those systems.
 
Have you guys noticed a difference between Windows and OSX temperature reading ?
When my 4230s is idling, under Windows 7, HWMonitor shows about 50°C, and under Mountain Lion, 40°C.
 
Have you guys noticed a difference between Windows and OSX temperature reading ?
When my 4230s is idling, under Windows 7, HWMonitor shows about 50°C, and under Mountain Lion, 40°C.

Well, for now under Win7, idle is usually in the mid-30s as the fan is always running.
I'm planning to write a version of this fan control for Win7 (probably as a Win7 service) when I get a chance.

I don't really notice any significant difference between idle temps between Win7 and ML using stock fan control software.
 
Status
Not open for further replies.
Back
Top