I’m building a cooling solution for the BPI-R4 that will have a fan moving air through the entire enclosure, and I’d like the fan RPM to follow several thermal zones–the SoC, WiFi PHYs, SFP modules, and the NVMe SSD. I know mt7988a.dtsi is the place to look in. But, it’s an unfamiliar territory for me, so, rather than trying to figure it out on my own, I’d appreciate an advice.
I also suspect that mt7988a-bananapi-bpi-r4.dtsi would be a better place for the new code, as it is device-specific.
This is what I start with in mt7988a.dtsi.
thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <1000>;
polling-delay = <1000>;
thermal-sensors = <&lvts 0>;
trips {
cpu_trip_crit: crit {
temperature = <125000>;
hysteresis = <2000>;
type = "critical";
};
cpu_trip_hot: hot {
temperature = <120000>;
hysteresis = <2000>;
type = "hot";
};
cpu_trip_active_high: active-high {
temperature = <115000>;
hysteresis = <2000>;
type = "active";
};
cpu_trip_active_med: active-med {
temperature = <85000>;
hysteresis = <2000>;
type = "active";
};
cpu_trip_active_low: active-low {
temperature = <40000>;
hysteresis = <2000>;
type = "active";
};
};
cooling-maps {
cpu-active-high {
/* active: set fan to cooling level 2 */
cooling-device = <&fan 3 3>;
trip = <&cpu_trip_active_high>;
};
cpu-active-low {
/* active: set fan to cooling level 1 */
cooling-device = <&fan 2 2>;
trip = <&cpu_trip_active_med>;
};
cpu-passive {
/* passive: set fan to cooling level 0 */
cooling-device = <&fan 1 1>;
trip = <&cpu_trip_active_low>;
};
};
};
};
I’d also like to connect the fan tachometer to GPIO to be able to read the RPM, but all of the pins on the 26-pin GPIO header seem to have a specific function. What am I missing here?
I figured a better solution would be to use the GPIO header to both power and control the fan with a simple userspace script. It polls every temp sensor found in /sys/class/hwmon and sets the fan speed according to the highest reading. Works fell so far.
#!/bin/sh
# PWM configuration
PWM_PIN="/sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore/pinmux-select"
PWM_CHIP="/sys/class/pwm/pwmchip0"
PWM_GROUP="$PWM_CHIP/pwm6"
# Initialize PWM
echo "pwm6_0 pwm" > "$PWM_PIN"
if [ ! -d "$PWM_GROUP" ]; then
echo 6 > "$PWM_CHIP/export"
fi
# Set frequency to 10 kHz (100000 ns period) and enable PWM
echo 100000 > "$PWM_GROUP/period"
echo 1 > "$PWM_GROUP/enable"
# Set duty cycle
set_duty_cycle() {
echo "$1" > "$PWM_GROUP/duty_cycle"
}
# Choose duty cicle based on temperature
choose_duty_cycle() {
temp=$1
# Full speed if temp >= 60°C
if [ "$temp" -ge 60000 ]; then
set_duty_cycle 100000
# Mid speed if temp >= 45°C
elif [ "$temp" -ge 45000 ]; then
set_duty_cycle 50000
# Low speed if temp < 45°C
else
set_duty_cycle 30000
fi
}
# Loop through all hwmon directories for highest temperature
get_temperature() {
max_temp=0
for hwmon in /sys/class/hwmon/hwmon*/temp*_input; do
if [ -f "$hwmon" ]; then
temp=$(cat "$hwmon")
if [ "$temp" -gt "$max_temp" ]; then
max_temp=$temp
fi
fi
done
choose_duty_cycle $max_temp
}
# Run continuously
while true; do
get_temperature
sleep 5 # Check every 5 seconds
done
Maybe this could help you for reading the rpm. got the same problems last week and made a package to return the RPM by GPIO. It also can return the value for collectd. But this is not for setting the speed
Thank you, I’ll check it out. Although, now that I’m using the only PWM pin on the GPIO header to set the speed I wonder if any of the other pins can be repurposed for reading.
Yes, i do the same reading the rpm from both fans at different GPIO pins (splitted ground from the cpu pwm fan and put rpm and second ground to gpio header, second is “simpler”, just connect rpm (i took 17-fan1 and 18-fan2) and others to GPIOs)
For example with my tool you than can read out the rpm by calling gpio-fan-rpm --gpio=17 or both to get (multi threaded) results from both at the same time gpio-fan-rpm --gpio=17 --gpio=18
By 17 and 8 you mean GPI017 12C-1 SCL and GPI018_I2C_1_SDA on the GPIO header pinout diagram? I’m surprised those can be removed from their I2C function and repurposed (if they were indeed hardwired to begin with).
Yes, i have them on those both. The SCL and SDA is not used if you don’t configure it for. You can take a nice look which gpios are possible with gpioctl from OpenWRT. There you can list all lines from the gpiochip0
Not sure if it works on a running system to compile. I made it inside the openwrt build environment. There it should work. Just have to figure out how i can create mutli arch packages then i can give an ipk as download. I think Sunday is a good day for this
The file which is missing is from the openwrt build environment. A good starting point for building yourself would be to get a docker image with a build environment for openwrt (there are many out there) or make a build env at your host. Copy source to /package/, make menuconfig, Check Utilities for gpio fan package and set to m or *. After this make package/gpio-fan-rpm/compile
Omg, i am a bit stupid today, forgot we are in the BPI R4 Forum I am switching often between OpenWRT and this forum, sorry You can get my ipk - just have to force install cause of hash mismatch if you dont want build yourself