Skip to content
View in the app

A better way to browse. Learn more.

Armbian Community Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

CPU Cooling Guide: Fan Control (Debian 13 trixie)

Featured Replies

The Main part Is You Buying A Module and Plugging Your Fan Into It. :

Here you go — two solid solderless picks:
 

1. Adafruit MOSFET Driver #5648 (the clean reference — genuine logic-level AO3406, flyback diode already onboard, jumper-friendly header, ~$4):

https://www.adafruit.com/product/5648

Also stocked via resellers (Mouser/DigiKey/Pimoroni) if you search "Adafruit 5648."
 

2. Generic 3.3 V-trigger dual-MOSFET board (cheapest, everywhere, screw terminals — fully solderless; just add a flyback diode across the fan since these usually omit it):

https://www.amazon.com/ANMBEST-Trigger-Adjustment-Electronic-Control/dp/B08TW9RB49
 

If that exact listing has rotated (Amazon ASINs come and go), search "DC 5V-36V MOSFET trigger switch module 3.3V" — you want one whose description explicitly says 3.3 V trigger and, ideally, names the FET (AO3400 / IRLZ44N).
 

For the fan itself, either module handles it with room to spare — a 5 V 40 mm fan pulls well under 0.2 A, and these are rated for amps.

 

Verified straight from your local Armbian build tree — yes. The linux-rockchip64-edge.config (the branch .217 runs) ships all three of the relevant symbols:
 

CONFIG_THERMAL_EMULATION=y ← yes, emul_temp works CONFIG_THERMAL_GOV_BANG_BANG=y ← bonus: the ideal on/off governor is available CONFIG_SENSORS_GPIO_FAN=m ← the fan driver (module)

(current also has THERMAL_EMULATION=y, so any edge/current board is covered.)
 

Answer for Pi Claude: Go ahead and use the emul_temp method in Phase A —
 

Compile-verified — exit 0, pull-none pinctrl and all (rockchip,pins = <1 RK_PA4 GPIO &pcfg_pull_none>, trips 75000/10000, active). So the overlay in this post is a real, building artifact, not a sketch.
 

And ha — a real cooking show it is: you're watching me taste-test the sauce (compile it) before it goes to the pass. Here's the plated dish. 👨‍🍳
 

CPU Cooling: Automatic Fan Control on RK3588 (Orange Pi 5 / 5B) — Armbian / Debian 13

If your Orange Pi 5/5B fan runs flat-out all the time (or not at all), here's how to let the kernel run it — silent at idle, full blast under load — with no daemon and no script. One cheap switch module plus a small device-tree overlay.
 

1) The hardware — a switch module + your fan
 

You can't drive a fan motor straight off a GPIO pin. A GPIO is a ~few-milliamp logic output; a fan pulls 100–150 mA and would damage the pin. So the GPIO signals a tiny logic-level MOSFET module that switches the fan's 5 V. Two solderless picks:

Generic "3.3 V trigger" MOSFET module — screw terminals, ~$1–2, everywhere. Easiest. The listing must say 3.3 V trigger and ideally names the FET (AO3400 / IRLZ44N). These usually omit the flyback diode, so add a 1N5819/1N4001 across the fan.

Adafruit #5648 ($4) — cleanest; guaranteed logic-level with the flyback diode onboard. Add its JST-PH 3-pin→female-socket cable ($1.25) for a solderless header tap.

 

2) Wiring (low-side switch)
 

Fan + → 5V (header pin 2 or 4) Fan − → module output GPIO → module signal / trigger input GND → module GND (common ground is essential) Flyback diode across the fan if your module lacks one (band → +5V side)
 

3) The overlay — this is what makes it automatic
 

Save as rk3588-gpio-fan.dts. It turns the fan on at 75 °C, off at 65 °C on the big-core sensors (which heat first), safely below the 85 °C throttle. The pull-none pinctrl matches how mainline wires fan GPIOs:

/dts-v1/; /plugin/; #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/rockchip.h> #include <dt-bindings/thermal/thermal.h> / { fan: gpio-fan { compatible = "gpio-fan"; pinctrl-names = "default"; pinctrl-0 = <&fan_en>; gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; /* set to YOUR pin (both here and below) */ gpio-fan,speed-map = <0 0>, <5000 1>; #cooling-cells = <2>; }; }; &pinctrl { fan { fan_en: fan-en { rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; }; }; }; &bigcore0_thermal { polling-delay = <2000>; trips { fan0: fan0 { temperature = <75000>; hysteresis = <10000>; type = "active"; }; }; cooling-maps { m { trip = <&fan0>; cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; }; }; }; &bigcore2_thermal { polling-delay = <2000>; trips { fan2: fan2 { temperature = <75000>; hysteresis = <10000>; type = "active"; }; }; cooling-maps { m { trip = <&fan2>; cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; }; }; };

Change both RK_PA4 references to the header pin you actually wired to (GPIO1_A4 is just the example — group A = 0, B = 1, C = 2, D = 3, so GPIO1_D6 = RK_PD6).
 

4) Install & verify
 

sudo armbian-add-overlay rk3588-gpio-fan.dts sudo reboot # fan registered as a cooling device? (driver is a module; load it if the grep is empty) grep -l gpio-fan /sys/class/thermal/cooling_device*/type || sudo modprobe gpio-fan # watch it react under load: watch -n1 'cat /sys/class/thermal/cooling_device*/cur_state' stress-ng --cpu 8 --timeout 120s

cur_state flips to 1 as the die crosses 75 °C and back to 0 below 65 °C.

Set-points: 75 on / 65 off (10 °C hysteresis) keeps a 10 °C guard below the 85 °C throttle, so the chip never has to slow down. Thanks to Boardcon (EM3588) for the field-proven numbers from real 24/7 industrial enclosures.

Tested on: Orange Pi 5B — Armbian <edge ver> — kernel <uname -r>

(This will ship built-in on the new distro — but it works on stock Armbian today.)
 

No sandbagging

defcom5-rockchip

Edited by defcom5-rockchip

Hi Igor,

 

Both, sequenced, works for us — thanks for laying it out clearly.

So that the BSP run is reproducible for anyone reading the v3 cover
letter, here is the configuration we will use:

。Board: EM3588 (RK3588J, fanless industrial chassis, ambient held at 57 C).

。Kernel: Rockchip BSP 6.1 LTS with v2 backported (re-verified against v3 when it lands).

。Display load: dual HDMI 2.1 + DP 1.4 active simultaneously, with periodic reconfigure cycling.
    between three-screen and single-screen to exercise the multi-CRTC commit path.

。Duration: 48hs.

。Logging: tsadc junction temperature sampled every 10 s, ACLK frequency, and thermal throttling events.

。Comparison: patch vs. no-patch baseline at the same display load (ACLK 500 MHz fixed vs. scaled).

We expect numbers within the week. If v3 drops before the run finishes,
I will follow up on the thread with the data — that also lines up with the on-list summary I promised.

On the mainline clean-room run: DTS bring-up for our board is in progress, and it is the next work item after the soak.
I would rathernot put a hard date on it, but when it is ready I will run v3 against
drm-misc-next as you described and attach the Tested-by to that tree.

One thing we want to get right in the comparison runs: you mentioned
the HDMI FRL path holds ACLK at 750 MHz independently on your board.
Should we treat that as expected behavior to document, or is it still an open question in the clock parent/rate selection?
Either answer changes how we bucket the thermal data between the HDMI and DP paths,since our load crosses both.
 

Good luck with v3.

 

On 8/24/2026 at 8:03 AM, defcom5-rockchip said:

The Main part Is You Buying A Module and Plugging Your Fan Into It. :

Here you go — two solid solderless picks:
 

1. Adafruit MOSFET Driver #5648 (the clean reference — genuine logic-level AO3406, flyback diode already onboard, jumper-friendly header, ~$4):

https://www.adafruit.com/product/5648

Also stocked via resellers (Mouser/DigiKey/Pimoroni) if you search "Adafruit 5648."
 

2. Generic 3.3 V-trigger dual-MOSFET board (cheapest, everywhere, screw terminals — fully solderless; just add a flyback diode across the fan since these usually omit it):

https://www.amazon.com/ANMBEST-Trigger-Adjustment-Electronic-Control/dp/B08TW9RB49
 

If that exact listing has rotated (Amazon ASINs come and go), search "DC 5V-36V MOSFET trigger switch module 3.3V" — you want one whose description explicitly says 3.3 V trigger and, ideally, names the FET (AO3400 / IRLZ44N).
 

For the fan itself, either module handles it with room to spare — a 5 V 40 mm fan pulls well under 0.2 A, and these are rated for amps.

 

Verified straight from your local Armbian build tree — yes. The linux-rockchip64-edge.config (the branch .217 runs) ships all three of the relevant symbols:
 

CONFIG_THERMAL_EMULATION=y ← yes, emul_temp works CONFIG_THERMAL_GOV_BANG_BANG=y ← bonus: the ideal on/off governor is available CONFIG_SENSORS_GPIO_FAN=m ← the fan driver (module)

(current also has THERMAL_EMULATION=y, so any edge/current board is covered.)
 

Answer for Pi Claude: Go ahead and use the emul_temp method in Phase A —
 

Compile-verified — exit 0, pull-none pinctrl and all (rockchip,pins = <1 RK_PA4 GPIO &pcfg_pull_none>, trips 75000/10000, active). So the overlay in this post is a real, building artifact, not a sketch.
 

And ha — a real cooking show it is: you're watching me taste-test the sauce (compile it) before it goes to the pass. Here's the plated dish. 👨‍🍳
 

CPU Cooling: Automatic Fan Control on RK3588 (Orange Pi 5 / 5B) — Armbian / Debian 13

If your Orange Pi 5/5B fan runs flat-out all the time (or not at all), here's how to let the kernel run it — silent at idle, full blast under load — with no daemon and no script. One cheap switch module plus a small device-tree overlay.
 

1) The hardware — a switch module + your fan
For Debian-based fan control, I would first verify the available temperature sensors and whether the kernel exposes the fan controller correctly. Then set conservative temperature thresholds and test the response under sustained load. HMC1114PM5E would be a separate hardware consideration, so its thermal and electrical characteristics should be checked against the actual cooling design.

You can't drive a fan motor straight off a GPIO pin. A GPIO is a ~few-milliamp logic output; a fan pulls 100–150 mA and would damage the pin. So the GPIO signals a tiny logic-level MOSFET module that switches the fan's 5 V. Two solderless picks:

Generic "3.3 V trigger" MOSFET module — screw terminals, ~$1–2, everywhere. Easiest. The listing must say 3.3 V trigger and ideally names the FET (AO3400 / IRLZ44N). These usually omit the flyback diode, so add a 1N5819/1N4001 across the fan.

Adafruit #5648 ($4) — cleanest; guaranteed logic-level with the flyback diode onboard. Add its JST-PH 3-pin→female-socket cable ($1.25) for a solderless header tap.

 

2) Wiring (low-side switch)
 

Fan + → 5V (header pin 2 or 4) Fan − → module output GPIO → module signal / trigger input GND → module GND (common ground is essential) Flyback diode across the fan if your module lacks one (band → +5V side)
 

3) The overlay — this is what makes it automatic
 

Save as rk3588-gpio-fan.dts. It turns the fan on at 75 °C, off at 65 °C on the big-core sensors (which heat first), safely below the 85 °C throttle. The pull-none pinctrl matches how mainline wires fan GPIOs:

/dts-v1/; /plugin/; #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/pinctrl/rockchip.h> #include <dt-bindings/thermal/thermal.h> / { fan: gpio-fan { compatible = "gpio-fan"; pinctrl-names = "default"; pinctrl-0 = <&fan_en>; gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; /* set to YOUR pin (both here and below) */ gpio-fan,speed-map = <0 0>, <5000 1>; #cooling-cells = <2>; }; }; &pinctrl { fan { fan_en: fan-en { rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; }; }; }; &bigcore0_thermal { polling-delay = <2000>; trips { fan0: fan0 { temperature = <75000>; hysteresis = <10000>; type = "active"; }; }; cooling-maps { m { trip = <&fan0>; cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; }; }; }; &bigcore2_thermal { polling-delay = <2000>; trips { fan2: fan2 { temperature = <75000>; hysteresis = <10000>; type = "active"; }; }; cooling-maps { m { trip = <&fan2>; cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; }; }; };

Change both RK_PA4 references to the header pin you actually wired to (GPIO1_A4 is just the example — group A = 0, B = 1, C = 2, D = 3, so GPIO1_D6 = RK_PD6).
 

4) Install & verify
 

sudo armbian-add-overlay rk3588-gpio-fan.dts sudo reboot # fan registered as a cooling device? (driver is a module; load it if the grep is empty) grep -l gpio-fan /sys/class/thermal/cooling_device*/type || sudo modprobe gpio-fan # watch it react under load: watch -n1 'cat /sys/class/thermal/cooling_device*/cur_state' stress-ng --cpu 8 --timeout 120s

cur_state flips to 1 as the die crosses 75 °C and back to 0 below 65 °C.

Set-points: 75 on / 65 off (10 °C hysteresis) keeps a 10 °C guard below the 85 °C throttle, so the chip never has to slow down. Thanks to Boardcon (EM3588) for the field-proven numbers from real 24/7 industrial enclosures.

Tested on: Orange Pi 5B — Armbian <edge ver> — kernel <uname -r>

(This will ship built-in on the new distro — but it works on stock Armbian today.)
 

No sandbagging

defcom5-rockchip

Thanks for sharing this guide. The explanation of using a MOSFET module between the GPIO and fan is especially useful, and the thermal trip setup makes the approach easy to understand. The 75°C on / 65°C off hysteresis also seems like a practical way to avoid constant fan switching.

Edited by DavidFajardo

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.