The ODROID HC4 has a PWM fan built into its transparent case. The Armbian download page suggests to configure fancontrol for fan support – but this only works with Armbian kernels up to around 6.0. With later kernels it seemingly never spins up – or it does, but quicky spins down. With two HDDs plugged into the slots at the top the idle temparature can get up to 60+°C that way. This guide fixes it.
Owners of an ODROID HC4 SoC running the current stable distribution (Armbian Jelly or Bookworm at the time of writing this) and at least one 3.5" HDD generating enough of an inner temperature to warrant concern.
The whole reason for this behavior is the thermal
driver being able to take control of the fan speed. So when fancontrol is run and the fan speed is set according to its config and the current temperature reading, thermal
simply overrides the speed according to the trip point config of the thermal zone. In essence, fancontrol
and the thermal
driver are mutually exclusive. A decision must be made: Which one should take care of the fan?
As written on the Armbian page, create a /etc/fancontrol
file. Edit INTERVAL
, MINTEMP
, MAXTEMP
, MINPWM
and MAXPWM
if you wish to change interval, the trip point and max speed of the fan.
INTERVAL=10
DEVPATH=hwmon0=devices/virtual/thermal/thermal_zone0 hwmon2=devices/platform/pwm-fan
DEVNAME=hwmon0=cpu_thermal hwmon2=pwmfan
FCTEMPS=hwmon2/pwm1=hwmon0/temp1_input
MINTEMP=hwmon2/pwm1=50
MAXTEMP=hwmon2/pwm1=60
MINSTART=hwmon2/pwm1=20
MINSTOP=hwmon2/pwm1=28
MINPWM=hwmon2/pwm1=0
MAXPWM=hwmon2/pwm1=255
Start and enable the fancontrol service.
systemctl enable --now fancontrol.service
Configure thermal
to leave fan control to user space.
echo disabled > /sys/devices/virtual/thermal/thermal_zone0/mode
To persist this across reboots, a udev rule can be written to /etc/udev/rules.d/99-disable-thermal-module.rules
.
SUBSYSTEM=="thermal", ATTR{type}=="cpu-thermal", ATTR{mode}="disabled"
Simply configure the trip points for thermal_zone0
. The defaults are 60°C (active, trip_point_3_temp
), 85°C (passive, trip_point_0_temp
), 95°C (hot, trip_point_1_temp
) and 110°C (critical, trip_point_2_temp
). Note that the values are in millidegrees Celsius.
echo 50000 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_0_temp # "passive" trip point
echo 60000 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_3_temp # "active" trip point
echo 70000 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_1_temp # "hot" trip point
echo 90000 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_2_temp # "critical" trip point
To persist them across reboots, once again a udev rule can be used.
# passive trip point
SUBSYSTEM=="thermal", ATTR{type}=="cpu-thermal", ATTR{trip_point_?_type}=="passive" ATTR{trip_point_?_temp}="50000"
# active trip point
SUBSYSTEM=="thermal", ATTR{type}=="cpu-thermal", ATTR{trip_point_?_type}=="active" ATTR{trip_point_?_temp}="60000"
# hot trip point
SUBSYSTEM=="thermal", ATTR{type}=="cpu-thermal", ATTR{trip_point_?_type}=="hot" ATTR{trip_point_?_temp}="70000"
# critical trip point
SUBSYSTEM=="thermal", ATTR{type}=="cpu-thermal", ATTR{trip_point_?_type}=="critical" ATTR{trip_point_?_temp}="90000"
I've found this method a bit difficult to configure: It spins up the fan to 100% on reaching any trip point other than passive
. The latter ironically does not do passive cooling as the name suggests – the fan stays off upon reaching it. I've yet to find a way how to set fan speed based on the various trip points using the thermal
driver, so for now I recommend the fancontrol
way.