[BPI-R4] CPU fan setup

I saw following patch in openwrt.git shortlog:

mediatek: fix PWM fan on BPi-R4

I rebuilt the snapshot, but unfortunately the fan still always spinning. I’m using:

cat /sys/class/thermal/thermal_zone0/temp

to read the temperature and

echo 47000 > /sys/class/thermal/thermal_zone0/trip_point_2_temp

to write the temp threshold. When I read the status:

cat /sys/class/thermal/cooling_device0/cur_state

it is reporting 0 (fun off), but fun is still spinning.

Have you looked what trip_point2 is? Afaik you have to change trip_point 4 or 3 as these are the lowest trips

Hi Frank, I did not know about ne two more trip points. Thanks However I set in thermal_zone_0:

trip_point 0 to 80000
trip_point 1 to 70000
trip_point 2 to 56000
trip_point 3 to 55000
trip_point 4 to 54000

temperature of thermal_zone_0 is 33122 and fan still spinning. Status of “cooling device 0” still 0 off but spinning. Seems trip points not working or I’m doing something wrong. Also set trip point 4 to 30000 and the status went to 1 (fan on) So it seems the status 0 is not interrupting the power on fan plug.

Yes thats what i have expected…whats wrong here?

Why should it do that? Thermal trips handling fan nothing else yet…maybe we get passive (cpu trotteling) cooling working.

The emergency shotdown is hardcoded in lvts driver at 115°C

In BPI-R3 the trip point_2 was the threshold for the fan to spin or not. When temeperature more than the theshold it was spinning when under the threshold the fan was not spinning. In BPI-R4 always spinning at the same maximum speed. May be I do not understand how PWM works… Changing the rotation speed according to the various trip points? A mistery for me… :smile: Frank clarify how should work.

Create a shell command file and write these into shell command file:

if [ -d /sys/devices/pwm-fan ]; then
FAN_CTRL=/sys/devices/pwm-fan/hwmon/hwmon0/pwm1
elif [ -d /sys/devices/platform/pwm-fan ]; then
FAN_CTRL=/sys/devices/platform/pwm-fan/hwmon/hwmon0/pwm1
else
exit 0
fi

run this shell file:

chmod +x yourFileName.sh && ./yourFileName.sh

finally use this command:

echo 180 > /sys/devices/platform/pwm-fan/hwmon/hwmon0/pwm1

Hello i have used echo 180 > /sys/devices/platform/pwm-fan/hwmon/hwmon0/pwm1 then my fan go up. after a few seconds its go back to 80. its look like a fancontrol is active. is the fan controlled by the driver or by a linux programm? and can i change the settings?

BTW: If you’re curious about that open-top case: That’s a parametric OpenSCAD 3D-printable case I’m working on. I’ll post it here (and Github) when it’s done (still haven’t coded the front plate yet). When it’s done you’ll be able to specify how much space you want above/below the board, whether and where you want antenna holes, whether or not to include various mounting options, etc. Neat feature: I made it so you can feel/press the WPS and Reset buttons via little flexure tabs/buttons (no need to get a needle hehe) :+1:

A very old comment I just stumbled across, but did you ever get the case finished or still have the files for however far you got on it you’d share?

BPI R4 over-temperature reboot will slow down the fan speed, I recommend writing

echo 180 > /sys/devices/platform/pwm-fan/hwmon/hwmon0/pwm1

script to the /etc/rc.local file

I am using the Banana Pi Ubuntu 24.04 for this board and looking for a way to control the CPU heat sink fan speed.

FWIW, I came across a shell script in the BPI-R4 doc, scroll down to Heat sink in the link below:

CPU heat sink fan control

Caveat: you may have to change some of the filenames in the script, based on what the kernel creates:

# ls -l /sys/class/pwm/pwmchip0/
device/    export     npwm       power/     subsystem/ uevent     unexport

Hope this helps :vulcan_salute:t4:

Anyone got PWM6 working? That’s the one on the header pin 7 (not the PWM0 used for CPU fan control). I’ve exported every available PWM chans (1 to 7) and tried setting different value to period/duty_cycle/enable without any success.

I can control same pin as the GPIO62 (512+62=574 channel in the sysfs) through the sysfs, it works by setting OUTPUT direction and by setting or clearing bit level goes HIGH/LOW.

But if I try to change those values on any/all of the PWM channels, pin just stays at the same level it was. If I try to control it after reboot, it stays in the HI-Z (INPUT ?), if I try to set it HIGH or LOW via GPIO controls, it stays there. Either it’s something missing on the DTS, or wrong registers in the driver… or well I’m doing something wrong.

PS: pwm0 channel doesn’t exports, which is fine because it’s taken by hwmon for pwmfan. But I doubt it can affect other channels, because they are exported just fine and channel 0 reports it’s busy on an attempt to export.

Answering myself. Sounds like this recent commit might fix the issue: mediatek: pinctrl-mt7988: add missing PWM pingroups · openwrt/openwrt@2cbd230 · GitHub Noticed that pin 62 was just added by this commit for PWM6 function. Will try it soon.

I finally got it working. Spent a lot of time trying to figure it out because I wasn’t familiar with the pinctrl/pinmux sysfs interface and a weird thing that in fact pinmux-pins in the sysfs holds only boot-time information on pins configs. If you select function for a pin group via pinmux-select nothing just seems to happen. Not a single message in dmesg (while it will log an error if you put incorrect group/function name) and pinmux-pins pseudofile still reads as “pin 62 (JTAG_JTRST_N): UNCLAIMED”. But in fact, if you just ignore it and go to the pwm sysfs interface, export pwm6, set period/duty/enable it will be running normally. I’ve read generated PWM values with multimeter and it reads exactly the same frequency/duty cycle (and an average voltage) values, as I expect from my settings.

Pinmux controls located in the /sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore and the PWM control at /sys/class/pwm/pwmchip0

How to enable PWM6 on GPIO62 pin. You’ll need to be on the very latest snapshot at the moment. Commit I’ve mentionned above adds new pwmN_0 groups, and PWM6 function on GPIO62 pin are on the pwm6_0 group. You can check every available pin group and function by reading /sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore/pinmux-functions.

echo "pwm6_0 pwm" > /sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore/pinmux-select # Enable PWM function on the pin group pwm6_0 (GPIO62)
echo 6 > /sys/class/pwm/pwmchip0/export # export PWM ch 6 to the sysfs interface
echo 100000 > /sys/class/pwm/pwmchip0/pwm6/period # Set freq to 10 kHz (100000 ns period)
echo 40000 > /sys/class/pwm/pwmchip0/pwm6/duty_cycle # Set duty cycle to 40% (40000 ns active)
echo 1 > /sys/class/pwm/pwmchip0/pwm6/enable # Run PWM

/sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore/pinmux-pins provides useful info, but remember it only holds boot-time values (probably from DTS) and won’t change to reflect live adjustments. Other files there provide some other useful info, everything except for the pinmux-select are read-only text info so it’s safe to cat them.

Side effect: I was curious how much current load a GPIO pin of the MT7988 can source/sink. Read through open datasheet and registers but it lists only voltage range in electrical characteristcs chapter and no references to max current at all. But I was surprised to find out that the values are reported in the pinconf-pins file of the pinctrl sysfs interface. For those who might be interested it reports 4mA for every GPIO pin for me. This:

root@BPI-R4:~# head -n3 /sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore
/pinconf-pins
Pin config settings per pin
Format: pin (name): configs
pin 0 (UART2_RXD): input bias pull up (102 ohms), output drive strength (4 mA), input enabled, input schmitt enabled, pu-adv (2)

Output drive strength are the same for every GPIO pin. But it changes in input values, at least in pull direction (up/down) and resistance.

2 Likes

Hello, but when you don’t have /sys/class/thermal/thermal_zone0 how do you check the temperature? Thank you.

Why don’t you have this? Which kernel/image do you use?

It is possible to measure with infrared thermometer,but this is only outside temp not internal chip temp which would be a bit higher.

I’m building my own image with OpenWRT from the 24.10 branch and the MTK SDK. I can see and control the PWM fan but I don’t get the thermal_zone0, only a bunch o cooling_devices. Any clue?

i guess dts there misses thermal_trips or option hwmon_* is missing

Uhm, interestingly, I built an openwrt image (24.10 branch) without the MTK SDK/feeds and the thermal_zone0 is there.
I also assumed that SDK provided some better support for the wifi card but… that’s not the case so now I wonder why do I need include it anymore…

Interesting, but somehow expected - MediaTek tends to initially implement things “their way”. I don’t think there are any advantages on using MTK feeds/SDK right now, as upstream has nearly every feature ported right now. Probably only WED and ipsec crypto offloading which was recently added on the MediaTek git, but WED are partially supported by the upstream already.

Last time I’ve compared vanilla OpenWRT build and older OpenWRT with 5.4 kernel from Sinovoip, the one with proprietary WiFi drivers - upstream OpenWRT snapshot got me about 10% better WiFI throughput. And that 5.4 branch was supposed to have more advanced WiFI driver (the one with proprietary blobs I guess), at least it had MLO and was more feature-complete.

But probably even if it didn’t had thermal_zone, maybe /sys/class/hwmon/hwmon0/temp1_input was available?

Side-question: Anyone knows if there is a way to add/modify thermal zones on the installed system without having to modify device tree files?