Simple MacBook Pro Fan Daemon

The fan control on the MacBook Pro under Linux is not the best… I would say it does not work at all but I once saw the fan speed increase slightly on its own so it appears to do something, sometimes, according to some logic I can not figure out.

It turns out that taking “manual” control of the fan is quite easy. A simple

echo 1 > /sys/devices/platform/applesmc.768/fan1_manual
sets the fan to manual mode. Then you can adjust fan1_output in the same directory to set the current fan speed. Do not get confused with fan1_input, as that is strangely the actual fan speed! The minimum and maximum speeds are given by fan1_min and fan1_max. If the minimum speed is reported as 0 or 1, ignore it. For MacBook Pros with Core 2 Duo processors the minimum fan speed should be 2000. The maximum fan speed is 6200.

So now that we know how to control the fan, we just need some sort of algorithm to choose what the fan speed should be based on the temperature. The MacBook Pro has a whole bunch of temperature sensors, but the ones that matter are for the processors as they are always the highest. These are found in /sys/devices/platform/coretemp.{0,1}/temp1_input (you may need to load the coretemp module). Montoring these during basic usage shows the average temperatures of the two processors is around 40-45C during idle, 50-55C with basic web browsing and 60-65C when watching a HD movie (at least in warm Australian ambient temperatures).

To save battery on a laptop, I think that the fan should not come on when the computer is doing anything less intensive than watching a movie, so I set that fan to kick in at 65C. This coincides with what Mac OSX does. From OSX, it appears that the fans should hit full speed at 80C and the speed builds up exponentially to that point. The formula I use for changing the fan speed when the temperature is increasing is:

temp <= 65:
   speed = max(current_speed, 2000)
65 < temp < 80:
   step = (6200 - 2000) / ( (80 - 65) * (80 - 64) / 2 )
   speed = max(current_speed, ceil(2000 + (temp - 65) * (temp - 64) / 2 * step))
temp >= 80:
   speed = 6200

When the temperature is decreasing, I prefer to keep the fan going slightly longer to force the temperature down to low levels as quickly as possible. I push it back down to 55C using this formula:

temp >= 80:
   speed = 6200
55 < temp < 80:
   step = (6200 - 2000) / ( (80 - 55) * (80 - 54) / 2 )
   speed = min(current_speed, floor(6200 - (80 - temp) * (81 - temp) / 2 * step)
temp <= 55:
   speed = 2000

Here is a graphic of what that looks like (red = increasing, blue = decreasing):

fan speed

Grap the source code here. It assumes two processors and a single fan (not true for all MacBook Pros…). For Arch Linux users, there is also a PKGBUILD and daemon (mbpfan) for ease of use. I am lazy, so there is very little error checking in the code. It works for me but use at your own risk…

Update (2011-08-11): MBP Fan Daemon Update

2 thoughts on “Simple MacBook Pro Fan Daemon

  1. Hey, I love your script, I have updated it to work with my macbook and made some other changes:

    – Works with macbook 6,2 (and probably broke old compat, needs fixing)
    – No longer requires coretemp module
    – Has basic error checking and falls back to high speed when it cant find a temp
    – Sets the min fan speed instead of using manual speed control. This has the same general effect however is safer in the event of a crash of the daemon.

    All changes made to your original source should be considered public domain work (so you can retain sole copyright). I would love to setup a launchpad project with your approval.

    Source: http://paste2.org/p/862259

    • I am fine with a project being set-up on launchpad around this. Will send you an email.