mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-13 00:17:02 +04:00
realtek: use autonomous LM63 fan control on DGS-1210-28P/MP
Previously, fan control on D-Link DGS-1210-28P/MP switches was handled
by a user-space script (`fan_ctrl.sh`) triggered via cron every 5
minutes due to missing kernel sysfs writable attributes for PWM
frequency and hysteresis.
The `fan_ctrl.sh` contained a string-truncation comparison logic bug
(temp1_input was truncated while PSU_THRESH was not) that kept the fan
locked at a static 156 PWM (61%) rate regardless of temperature.
Also, since hwmon0 (cpu_thermal) appeared, it changed the order of hwmon
devices and broke fan_ctrl.sh PWM control, keeping it always stopped.
With commit 89ef8aaf3e ("kernel: backport lm63 enhancements"),
`pwm1_freq` and `pwm1_auto_point_temp_hyst` are now writable, enabling
full autonomous LUT hardware fan management on the LM63 chip.
Transition to autonomous hardware fan control:
- Configure LM63 Look-up Table (LUT) via `/etc/init.d/hwmon_fancontrol`
using the OEM register settings:
* PWM Frequency: ~7826 Hz (PFR divisor 23)
* Point 1: > 0°C -> PWM 28/46, 155/255 (~60.8% duty cycle)
* Point 2: > 51°C -> PWM 46/46, 255/255 (100% duty cycle)
* Points 3-8: > 127°C -> PWM 255/255 (chip defaults for unused points)
* Hysteresis: 3°C (3000 mC)
- Add `04_dlinkfan_migration` migration script to purge `fan_ctrl.sh` from
crontab during sysupgrade.
The LM63 PWM resolution depends on the PFR divisor setting (2 * PFR).
With PFR set to 23 (matching OEM ~7826 Hz), full scale is 46 (0x2e). The
sysfs interface maps 0-255 to 0-46, meaning the OEM defaults 28 (0x1c)
and 46 (0x2e) translate to sysfs values 155 (~60.8% duty cycle) and 255
(100% duty cycle). Those values match the old fan_ctrl.sh temperature range
and duty cycle.
Fixes: ab3f92e86481 ("realtek: add fan controller support to D-Link DGS-1210-28MP")
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/24869
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>
This commit is contained in:
1 parent
7a1684be88
commit
d3290efad9
4 files changed
+68
-39
No files matched your search
@@ -35,6 +35,41 @@ plasmacloud_common() {
|
||||
echo 2 > "$path_to_hwmon/pwm2_enable"
|
||||
}
|
||||
|
||||
dlink_dgs_1210() {
|
||||
local path_to_hwmon="$(find -L /sys/bus/i2c/devices/4-004c -type d -maxdepth 2 -mindepth 2 -name 'hwmon*' || true)"
|
||||
|
||||
if [ -z "$path_to_hwmon" ]; then
|
||||
logger -t hwmon_fancontrol "LM63 hwmon interface not found on i2c 4-004c (kmod lm63 loaded?)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Set to manual mode temporarily to allow LUT and frequency setup
|
||||
echo 1 > "$path_to_hwmon/pwm1_enable"
|
||||
|
||||
# Configure PWM frequency (~7826 Hz / PFR divisor 23) matching OEM defaults
|
||||
echo 7826 > "$path_to_hwmon/pwm1_freq"
|
||||
|
||||
# Point 1: If temp > 0 C, set fan speed to PWM 155/255 (OEM default 0x1c)
|
||||
echo 0 > "$path_to_hwmon/pwm1_auto_point1_temp"
|
||||
echo $((0x1c * 255 / 46)) > "$path_to_hwmon/pwm1_auto_point1_pwm"
|
||||
|
||||
# Point 2: If temp > 51 C, set fan speed to PWM 255/255 (OEM default 0x2e)
|
||||
echo 51000 > "$path_to_hwmon/pwm1_auto_point2_temp"
|
||||
echo $((0x2e * 255 / 46)) > "$path_to_hwmon/pwm1_auto_point2_pwm"
|
||||
|
||||
# Point 3-8: Set the chip default values for unused points as reboot does not clean them
|
||||
for p in 3 4 5 6 7 8; do
|
||||
echo 127000 > "$path_to_hwmon/pwm1_auto_point${p}_temp"
|
||||
echo 255 > "$path_to_hwmon/pwm1_auto_point${p}_pwm"
|
||||
done
|
||||
|
||||
# Hysteresis: Set 3 C (3000 mC) hysteresis for LUT (OEM default 0x03)
|
||||
echo 3000 > "$path_to_hwmon/pwm1_auto_point_temp_hyst"
|
||||
|
||||
# Switch to hardware auto mode
|
||||
echo 2 > "$path_to_hwmon/pwm1_enable"
|
||||
}
|
||||
|
||||
dlink_dgs_1250() {
|
||||
local path_temp_hwmon="$(find /sys/devices/platform/i2c-gpio-4/i2c-4/4-0048/hwmon/ -type d -maxdepth 1 -mindepth 1 -name 'hwmon*')"
|
||||
local path_fan_hwmon="$(find /sys/devices/platform/gpio-fan/hwmon/ -type d -maxdepth 1 -mindepth 1 -name 'hwmon*')"
|
||||
@@ -92,6 +127,10 @@ boot() {
|
||||
plasmacloud,psx28)
|
||||
plasmacloud_common
|
||||
;;
|
||||
d-link,dgs-1210-28p-f|\
|
||||
d-link,dgs-1210-28mp-f)
|
||||
dlink_dgs_1210
|
||||
;;
|
||||
d-link,dgs-1250-28x)
|
||||
dlink_dgs_1250
|
||||
;;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2024 openwrt.org
|
||||
#
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
board=$(board_name)
|
||||
|
||||
case "$board" in
|
||||
d-link,dgs-1210-28p-f|d-link,dgs-1210-28mp-f)
|
||||
# Enable fan control
|
||||
FAN_CTRL='/sys/class/hwmon/hwmon0'
|
||||
echo 1 > "$FAN_CTRL/pwm1_enable"
|
||||
|
||||
# Set fan script execution in crontab
|
||||
grep -s -q fan_ctrl.sh /etc/crontabs/root && exit 0
|
||||
|
||||
echo "# dlink fan script runs every 5 minutes" >> /etc/crontabs/root
|
||||
echo "*/5 * * * * /sbin/fan_ctrl.sh" >> /etc/crontabs/root
|
||||
|
||||
# Execute one time after initial flash (instead of waiting 5 min for cron)
|
||||
/sbin/fan_ctrl.sh
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
CRON_FILE="/etc/crontabs/root"
|
||||
LINE1="# dlink fan script runs every 5 minutes"
|
||||
LINE2="*/5 * * * * /sbin/fan_ctrl.sh"
|
||||
|
||||
case "$(board_name)" in
|
||||
d-link,dgs-1210-28p-f|d-link,dgs-1210-28mp-f)
|
||||
[ -f "$CRON_FILE" ] || exit 0
|
||||
|
||||
# Remove legacy user-space fan_ctrl script from crontab
|
||||
if grep -x -F -q "$LINE1" "$CRON_FILE" && grep -x -F -q "$LINE2" "$CRON_FILE"; then
|
||||
grep -v -x -F "$LINE1" "$CRON_FILE" | grep -v -x -F "$LINE2" > "${CRON_FILE}.tmp"
|
||||
mv "${CRON_FILE}.tmp" "$CRON_FILE"
|
||||
[ -s "$CRON_FILE" ] || rm -f "$CRON_FILE"
|
||||
|
||||
/etc/init.d/cron restart 2>/dev/null
|
||||
|
||||
# if the user changed it, just warn (fan_ctrl.sh is gone anyway).
|
||||
elif grep -E -q '^[[:space:]]*[^#].*fan_ctrl\.sh' "$CRON_FILE"; then
|
||||
logger -t dlinkfan_migration -p user.err "Custom fan_ctrl.sh entry found in $CRON_FILE. Leaving file untouched!"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PSU_TEMP=$(cut -c1-2 /sys/class/hwmon/hwmon0/temp1_input)
|
||||
|
||||
FAN_CTRL='/sys/class/hwmon/hwmon0/pwm1'
|
||||
|
||||
PSU_THRESH=51000
|
||||
|
||||
if [ "$PSU_TEMP" -ge "$PSU_THRESH" ];then
|
||||
echo "250" > $FAN_CTRL
|
||||
else
|
||||
echo "156" > $FAN_CTRL
|
||||
fi
|
||||
Reference in new issue
Block a user