Mini 311 Fan Control

Posted by matt


About a year ago now, I figured out how to control the fan on the Mini 311. Just recently, I got round to documenting this and writing a simple Linux kernel module to allow fan control. This page covers the kernel module, which you can download below. If you are more interested in the lower level details, they are on a separate page.

Just to be absolutely clear about what this module does - it allows you or your software to easily control the fan and get fan-related information. It does not provide automatic fan control (at least not over that which is provided already by hardware). So, if for example, you want your fan to come on when your CPU reaches 60 degrees celcius (probably not a good idea) then you will have to write a small program to periodically read from the module, and set the speed when appropriate.

The following instructions should work for most Debian based distributions, and I have provided example output from my system.

Building the Module

I'm assuming you already have gcc and kernel headers installed on your system. In which case, building the module should simply be a case of extracting the files and running make. Note that the module should build without warnings under kernel 2.6.36, but probably not with much older kernels due to changes in the driver model.

>$ tar xf hp311fan_kmodule.tar.gz
>$ cd hp311fan_kmodule
>$ make
make -C /lib/modules/2.6.36-1.slh.2-aptosid-686/build M=/home/matt/hp311fan_kmodule modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.36-1.slh.2-aptosid-686'
  CC [M]  /home/matt/hp311fan_kmodule/hp311fan.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/matt/hp311fan_kmodule/hp311fan.mod.o
  LD [M]  /home/matt/hp311fan_kmodule/hp311fan.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.36-1.slh.2-aptosid-686'

Testing the Module

Before installing the module, you might want to test it. If so, try this as the root user:

>$ insmod ./hp311fan.ko
>$ cat /dev/fanctl
HP311 Fan Control:
        CPU Temperature: 49 C
        Fan Speed:       1875 RPM
        Fan Control:     hardware
        Fan Level (0-7): 1

>$ rmmod hp311fan

Loading the Module at Boot Time

First make the module available to your kernel. Copy it to where modules are stored on your system, and run depmod. For example, you might issue the following commands as the root user :

>$ cp hp311fan.ko /lib/modules/`uname -r`/kernel/drivers/platform/x86/
>$ depmod -a

Exactly how you get the module to load at boot time might depend on your distribution. I added the following line to /etc/rc.local:

modprobe hp311fan

By default, the module loads with the fan under hardware control. If you want to set the fan to a particular speed level during boot, you can pass this as a parameter to the module like so:

modprobe hp311fan init_level=3

Alternatively, you could have added another line which writes to the device:

modprobe hp311fan
echo "3" > /dev/fanctl

By default udev will make the fanctl device accessible only to the root user, which is probably not what you want. This behaviour can be modified with a very simple udev rule. Place the following line in a file /etc/udev/rules.d/10-local.rules:

KERNEL=="fanctl", MODE="0666"

Using the Module from the Command Line

To get some fan-related information, read from /dev/fanctl. For example:

>$ cat /dev/fanctl
HP311 Fan Control:
        CPU Temperature: 49 C
        Fan Speed:       1875 RPM
        Fan Control:     hardware
        Fan Level (0-7): 1

There are three control modes. By default, the fan is automatically hardware controlled. This is the mode the fan runs in when the module has not been loaded, and it is also the default mode for when the module starts. The second mode disables the fan completely, and the remaining and perhaps most interesting mode is a fixed speed level from 0 to 7. (Note that level 0 is dependent on the BIOS setting 'Fan always on' - see more details).

So, to set the fan speed to level 7, we simply write the character '7' to /dev/fanctl.

>$ echo "7" > /dev/fanctl

To set mode to automatic, write the character 'A' and to disable the fan, write 'X'.

Using the Module from Your Program

It is also easy to control the fan from your program using ioctl calls. Some example code is provided in ioctl_example.c which is included with the module. You can compile and run this from within the module directory using:

>$ gcc ioctl_example.c -o test
>$ ./test

By using ioctl calls you can retrieve CPU temperature and fan speed from the module in a much more convenient manner than you would by parsing the output message. You can also set the fan mode this way.

File attachments: