中文 | English
SteamOS(Decky Loader)下的 OneXFly F1 Pro / HX 370 掌机 EC 控制插件。
覆盖两组功能:充电控制(旁路供电开关 + 充电上限)与 风扇控制(五档模式 + 自定义温度曲线)。
仓库:https://github.com/Phioly/F1Pro-EC-Control
旧名
F1 Pro Battery Control已改名。 Decky 会把新旧两份当成两个不同的插件, 升级时请先按文末「从旧版本升级」一节卸载旧插件。
当前版本:v0.6.14 · 适用:SteamOS + Decky Loader · 不涉及 TDP / CPU 调度(可与 SimpleDeckyTDP 共存)
界面语言:跟随 Steam 客户端 —— 简体 / 繁体中文显示中文,其余语言一律英文。
只想装上用?直接看 安装 → 从旧版本升级。 遇到问题?先看 故障排查,再看 日志位置。
- 功能 —— 两张表:写入的内核值、界面长什么样
- 前提条件 —— 需要什么内核、什么设备
- 安装 —— ZIP 安装 / 一键脚本 / 手动拷贝 / 卸载,含 从旧版本升级
- 使用 —— 状态行显示什么、充电上限与各模式的关系、界面
- 风扇控制 —— 五档模式、自定义曲线、
pwm1_enable取值是驱动相关的、行为约定 - 日志位置 —— 出问题去哪拿日志
- 故障排查 —— 现象 → 原因 对照表
- 许可
| 功能 | 写入的内核值 | 说明 |
|---|---|---|
| 🔋 正常充电 | auto |
正常充电,并遵循充电上限 |
| ⚡ 开机旁路 | inhibit-charge-awake |
唤醒时停止充电、由电源直接供电;进入睡眠 / 关机后解除该抑制,接电照常充电并遵循充电上限(F1 Pro oxpec 驱动的具体行为,见下) |
| 🔌 始终旁路 | inhibit-charge |
运行、睡眠、关机都不充电,适合长期插电 |
| 🔢 充电上限 | charge_control_end_threshold |
50 / 60 / 70 / 80 / 85 / 90 / 95 %,另有「不限制」 |
| 🌀 风扇控制 | oxp_ec 的 pwm1 / pwm1_enable |
自动 / 静音 / 均衡 / 性能 / 自定义,五点(温度→PWM)曲线 |
| ♻️ 启动恢复 | — | Decky 启动时重新应用上次保存的模式、上限与风扇模式(可关闭) |
| 🔔 错误提示 | — | 仅操作失败时弹出通知;成功切换静默无提示 |
- 每次写入后都会重新读取内核节点确认是否真正生效,未生效会明确报错而不是假装成功。
- 状态每 5 秒自动轮询,界面上看到的就是内核里的真实状态。
- 充电控制不依赖 HHD / Anatase / Loadout;不写 TDP / CPU 调度
(不碰
platform_profile、EPP 等节点),可以与 SimpleDeckyTDP 共存。 - 风扇控制只读写
oxp_ec的pwm1/pwm1_enable,温度只读k10temp, 同样不碰 TDP。详见下方「风扇控制」。 - 需要以 root 运行:
plugin.json的flags必须是["root"](不是_root——_root不是有效写法,decky-loader 只做"root" in flags的精确匹配,写成_root会被降权, 表现为界面正常但每次写入都EACCES)。
插件依赖标准 Linux power_supply 接口:
cat /sys/class/power_supply/BAT0/charge_behaviourF1 Pro 上正常应输出类似:
auto inhibit-charge [inhibit-charge-awake]
方括号内是当前生效值。若这条命令报"没有那个文件",说明当前内核没有提供充电控制驱动, 插件会在界面顶部直接提示,而不会静默失效。
这一段很重要,因为两者不是一回事,混在一起会得出错误结论。
① 内核 ABI 的通用定义(Documentation/ABI/testing/sysfs-class-power)只到这一层:
| 取值 | ABI 上的定义 |
|---|---|
auto |
正常充电,并遵循充电上限 |
inhibit-charge-awake |
仅设备处于唤醒(awake)状态时禁止充电 |
inhibit-charge |
任何状态下都禁止充电 |
ABI 对 inhibit-charge-awake 只界定了"唤醒时禁止",并没有承诺睡眠 / 关机后会发生什么、
更没有承诺这时候还遵循不遵循充电上限——那是各机型驱动自己的实现细节,不能一概而论。
② F1 Pro 的实际行为来自 drivers/platform/x86/oxpec.c(OneXPlayer EC 驱动,F1 归入 oxp_fly):
该驱动把 charge_behaviour 直接映射到 EC 的充电抑制寄存器,并单独处理
charge_control_end_threshold。在 F1 Pro 上实测表现为:
设备唤醒时暂停充电;进入睡眠 / 关机后解除唤醒状态的充电抑制, 因此接电时会恢复充电,充电上限由 EC 的 threshold 设置控制。
所以"开机旁路睡眠后会恢复充电并停在设定上限"是 oxpec + EC 的具体行为,
不是 charge_behaviour 这个 ABI 的通用承诺。换一台用别的驱动实现同一 ABI 的机器,
睡眠后的行为完全可能不同。
下文「充电上限与各模式的关系」那节给出的是 ② 的寄存器级细节(F1 Pro 特有), 不要把那张表当成 Linux 的通用规则。
- 把
F1ProECControl-v0.6.14.zip传到掌机。 - 打开 Decky → 设置(齿轮)→ 开发者 → 打开「Developer Mode」。
- 在该页面选择 Install Plugin from ZIP(或把 zip 的本地路径粘贴到 "Install from URL"),选中 zip。
- 回到 QAM,插件列表中会出现 F1Pro EC Control。
在 SteamOS 桌面模式下解压后执行:
chmod +x install.sh
./install.sh脚本会把插件复制到 ~/homebrew/plugins/ 并重启 Decky。
sudo cp -r "F1Pro EC Control" ~/homebrew/plugins/
sudo systemctl restart plugin_loadersudo rm -rf ~/homebrew/plugins/"F1Pro EC Control"
sudo systemctl restart plugin_loader设置文件位于 ~/homebrew/settings/F1Pro EC Control/f1pro-ec-control.json,可一并删除。
旧名 F1 Pro Battery Control 与新名是两个独立的插件:Decky 按文件夹名区分,
不改名的话 QAM 里会同时出现两个条目,而它们都会去抢同一个 EC —— 两个控制线程
互相覆盖 pwm1,风扇会抽搐。
两种做法选一种:
A. 先卸载旧插件(推荐)
sudo rm -rf ~/homebrew/plugins/"F1 Pro Battery Control"
sudo systemctl restart plugin_loader然后在 Decky 里按上面的方式安装新版。旧设置文件(~/homebrew/settings/F1 Pro Battery Control/)
可以直接删掉——新插件用新的设置目录,不会读取它:
rm -rf ~/homebrew/settings/"F1 Pro Battery Control"B. 用一键脚本:install.sh 会自动清理旧目录(见脚本里的 LEGACY_PLUGIN_NAMES)。
旧设置目录仍需按上面那行手动删。
Decky 运行的是
dist/index.js。从本仓库的源码目录直接拷贝时,务必确认dist/已随仓库一起拷过去, 否则插件会装上但界面空白。
QAM → Decky → F1Pro EC Control:
- 电池状态:容量,以及
状态 · 功率 · 上限 N%状态行(插电且电池不充不放时状态为供电中),下方是当前生效的充电模式。 - 充电模式:三个按钮,当前生效的那个前面会显示 ✓。
- 充电上限:下拉选择。选「不限制」会写入 100% 解除限制。
- 设置:控制 Decky 启动时是否自动恢复。
- 诊断:显示实际使用的电池节点、外接电源节点、内核
status原始值、charge_behaviour原始字符串、power_now原始值、上限节点是否存在—— 排查内核差异时把这部分内容发出来即可。
Decky 的 toaster 除了在右下角弹出,还会把通知塞进 Steam 的通知中心。所以只要每次切换都提示, 通知中心里很快就会堆成一长串「已切换为…」。
本插件只在操作失败时提示,而且失败提示故意保留在通知中心,方便事后回看错误原因 (失败很少发生,不会堆积)。成功切换不弹任何通知——因为每次写入后后端都会重读内核节点, 界面上的模式和上限本身就是内核里的真实状态,已经起到反馈作用了。
失败通知的标题固定为 F1Pro EC Control。
install.sh 用 sudo cp 写入插件目录,因此复制完成后会执行一次:
sudo chown -R "$TARGET_OWNER:$TARGET_GROUP" "$DEST_DIR"否则文件属主会是 root:root。插件自身虽然以 root 运行(flags: ["root"]),
但 Decky 还要以普通用户身份去列目录、读资源、做更新与删除,root 属主会让这些操作受限。
属主按三级回退确定(越靠前越准):SUDO_USER → 源码目录的属主(stat)→ $USER。
中间那级不是多余的:脚本若以 root 身份运行(su -、systemd 调用),
SUDO_USER 和 USER 都会是 root,这时直接用 ${SUDO_USER:-$USER} 会静默失效。
状态行格式为 状态 · 功率 · 上限 N%,功率只在电池确实在充/放电时出现:
| 显示 | 出现时机 | 示例 |
|---|---|---|
充电中 · 45.9 W |
正在充电 | 充电中 · 45.9 W · 上限 100% |
供电中 |
外接电源在带整机、电池不充不放:旁路模式(开机旁路 / 始终旁路),或正常充电模式下电池已到设定上限 | 供电中 · 上限 100% |
放电中 · -37.6 W |
拔掉充电线,或正常充电模式下电池在放电 | 放电中 · -37.6 W · 上限 100% |
已充满 |
充满、电池不再取电 | 已充满 · 上限 100% |
未知 |
读不到内核 status |
未知 · 上限 100% |
供电中 把两种来源合并了,因为它们的物理状态完全一样——适配器供整机、电池闲置。
区别只在"为什么没在充电"(内核禁止 vs 已到上限),而这个信息就写在其下一行的
「当前模式」里,不需要在状态行重复一遍。所以判据是:
外接电源在线,且内核没有报充电/放电。
后三种(供电中 / 已充满 / 未知)不显示瓦数:这些情况下电池电流≈0,
power_now 不再有实时意义,读数往往停留在切换前的旧值,显示出来只会误导。
唯一的例外:外接电源确认已断开(读到
online = 0)却仍报Not charging, 这是自相矛盾的读数。此时不硬说成"供电中",显示未充电——除非遇到硬件异常, 这种情况不会出现。
显示的是内核 power_now 的原始读数(单位 µW,插件换算为 W),也就是电池这一侧的功率:
- 正值 = 电流流入电池(正在充电),例如
充电中 · 46.0 W - 负值 = 电流流出电池(正在放电),例如
放电中 · -37.6 W
负号是插件补的:ACPI 电池驱动(
drivers/acpi/battery.c)会把_BST的 rate 取绝对值(battery->rate_now = abs((s16)battery->rate_now)),所以从这个节点读到的power_now永远是正数,方向只能依据status判断。插件在status为Discharging时补上负号,若内核本来就给了负值则原样保留。
它不是充电器/适配器的输入功率。插着电时这个数字通常明显小于充电器端的功率计: 适配器要先供整机运行,剩下的才充进电池。例如实测中充电器端为 62.7 W 时, 电池侧约 46 W —— 差额就是整机功耗。
要判断旁路是否真的生效,请看充电器端的功率计(适配器端降到个位数、 ≈ 整机空载功耗,就说明旁路成功了),插件里的瓦数在旁路时不显示。
拔掉充电线后旁路自然失去意义,状态行恢复为 放电中 · -37.6 W 这样的真实读数。
下表和结论都是 F1 Pro 上 oxpec 驱动的实现,不是 Linux 通用语义(区别见上文「语义边界」)。
充电模式和充电上限都由 OneXPlayer EC 驱动 drivers/platform/x86/oxpec.c 写进 EC 寄存器,
两者是独立的,不存在"旁路时上限就失效"这种简单关系:
| EC 寄存器 | auto |
inhibit-charge-awake |
inhibit-charge |
|---|---|---|---|
0xA4 充电抑制(bit0 = 唤醒时抑制,bit1 = 关机时也抑制) |
0x00 |
0x01 |
0x03 |
0xA3 充电上限 |
被遵循 | 仅睡眠 / 关机时被遵循 | 永不充电,因此不起作用 |
- 正常充电(
auto,抑制位0x00):0xA4不抑制,充电决定权交给 EC 的上限逻辑, 充到设定上限后停。 - 开机旁路(
inhibit-charge-awake,抑制位0x01):只置"唤醒时抑制"这一位, 唤醒期间 EC 不充电;睡眠 / 关机时该位不再生效,EC 按0xA3的阈值照常充电。 - 始终旁路(
inhibit-charge,抑制位0x03):把"唤醒时抑制"和"关机时抑制"两位都置上, EC 在任何状态下都不进入充电流程,因此上限确实没有实际作用。
也就是说,只有「始终旁路」这一种模式下上限才是空转的;正常充电与开机旁路都会被 EC 执行。 插件因此不在界面上为上限附加任何说明。
风扇与充电由同一个 EC 驱动 drivers/platform/x86/oxpec.c 负责,它注册的 hwmon 设备名是
oxp_ec,只暴露三个属性:fan1_input(转速)、pwm1(占空比 0–255)、pwm1_enable。
驱动没有温度通道,所以 CPU 温度取自 AMD 的 k10temp(temp1_input,Tctl)。
节点一律按 hwmon 的 name 查找,不依赖 hwmon 编号——编号会随内核版本和驱动绑定顺序变化
(hwmon4/hwmon5 可能变成 hwmon3/hwmon7)。
- 主页按
电池 → 充电模式 → 充电上限 → 风扇 → 设置 → 诊断单页滚动排列。 风扇区块直接给:CPU 温度 / 转速 / 当前 PWM、当前模式与控制方式, 以及五个模式按钮(自动 / 静音 / 均衡 / 性能 / 自定义)—— 打游戏时想换曲线档位不必先进子页面。 - 五个模式按钮每个独占一行,宽度与「编辑风扇曲线」一致。
这里刻意不用网格:两列平铺在真机上先后踩到两个坑 ——
裸
1fr时ButtonItem(layout="below")内部的 min-content 宽度会把列撑破、 整行超出 QAM 面板(最右侧按钮被裁掉);改成minmax(0, 1fr)后不再撑破, 但相邻两个按钮的底色块会互相重叠、文字叠在一起。ButtonItem内部还有一层插件控制不到的宽度约束,所以不再和它较劲。 - 只有编辑曲线才进独立子页面。子页面不再重复展示风扇状态与风扇模式 (主页已经有了),进去直接是五点曲线编辑,然后是 「保存为自定义并应用」,最后是曲线预设(应用静音 / 均衡 / 性能曲线 + 还原默认曲线)。
- 预设按钮只是把曲线载入滑杆,不直接写 EC。此前点「应用静音曲线」会切到 静音模式(EC 按预设跑),但滑杆上还是原来那条曲线 —— 用户看到的和实际在跑的不是一回事。现在预设只填滑杆值,让用户看清这条曲线 长什么样、还能接着微调;真正生效统一由「保存为自定义并应用」完成。 「还原默认曲线」同理,只是把后端给出的默认种子曲线填回滑杆。
- 页面切换用的是插件内部的
view状态,没有引入 Decky Router —— 一个子页面不值得 多一层路由依赖。 - 曲线用 5 组滑杆编辑(每组一个「温度」+ 一个「PWM」),不依赖图表 / 拖拽库。 真正的二维曲线图属于后续可选项,当前版本优先保证控件行为稳定可预期。
- 温度滑杆夹在左右邻居之间:每个节点的可用范围是
[左邻居+1, 右邻居-1], 边界直接写在滑杆标签上。越界值滑不出来,比滑完再报错体验好; 相邻节点贴到一起时该滑杆会自动置灰。 - 曲线顺序错了就报错,绝不自动重排:早期实现会把节点按温度
sort一遍再保存, 于是用户把节点 1 从 40°C 滑到 55°C、越过节点 2 的 50°C 之后, 曲线被静默重排成[50°C, 75] / [55°C, 40]—— 温度是递增了,但 PWM 倒挂了 (45°C 给 40、50°C 给 75),等于悄悄改乱了用户的设置。现在改为按原样校验递增性, 不合格就提示并拒绝保存,不替用户猜。 - 拖动滑杆时不会被 5 秒轮询覆盖:只有用户没动过曲线时才把服务端值同步到界面, 否则轮询会把拖到一半的滑杆拽回旧值。
- 切预设模式时本地曲线立刻跟着换:点「静音 / 均衡 / 性能」会同步把滑杆设成该预设的 节点值,不必等下一轮轮询(最长 5 秒)才看到变化。切「自动 / 自定义」时不动曲线—— 自动没有曲线,自定义的曲线交给服务端回填,本地擅自改会覆盖用户正在编辑的内容。
- 风扇不可用(机型没有这些节点、或驱动身份无法确认)时,整块降级成一行原因, 不会摆一排点不动的按钮,也不会每 5 秒弹一次错误。
- 点「保存并应用」会先保存曲线、再切到「自定义」模式;这样曲线一定是生效的, 而不是"存了但没在用"。
- 预设按钮(静音 / 均衡 / 性能)的作用是把风扇切到该模式,不是把曲线复制成自定义。
| 写入值 | oxpec(本机) |
旧驱动 drivers/hwmon/oxp-sensors.c |
|---|---|---|
1 |
手动 PWM | 手动 PWM |
2 |
EC 自动控制 | EINVAL |
0 |
切手动并把 PWM 拉到 255 满速 | EC 自动控制 |
写错不会报错,但会让 EC 卡在手动满速。因此插件先确认本机驱动身份(电池节点上是否有
charge_behaviour / 充电上限,这是 oxpec 独有的)才允许写风扇;确认不了就禁用风扇写入,
宁可不控制也不猜。
这道门禁每一步都查,不只是入口查一次:控制线程会在后台长时间运行,期间硬件判据可能
变化(电池节点消失、驱动被替换),所以 _fan_step() 本身也重新确认一次——写错
pwm1_enable 是静默的,多查一次的成本远低于把 EC 留在手动满速的风险。
还有一个读回陷阱:驱动读 pwm1_enable 时,手动模式下且 PWM 恰好为 255 时返回 0 而不是 1
(Return 0 if at full fan speed, 1 otherwise)。所以判断"是否处于手动"必须接受 {0, 1},
只认 1 会在风扇满速时把已成功的操作误判为失败。
- 自动:交还 EC,写
pwm1_enable = 2。 - 静音 / 均衡 / 性能 / 自定义:写
pwm1_enable = 1,此后按「CPU 温度 → 五点曲线 → 线性插值 → PWM」每 3 秒调整一次。 - 写入死区:只有目标 PWM 与当前 PWM 的差值 ≥ 8 才真的写 EC,否则温度抖动会不停写寄存器。 死区只作用于曲线插值的结果,不会拦截下面这条安全保护。
- 安全保护:CPU 达到 85 °C 一律满速 255,任何自定义曲线都不能覆盖它, 并且无条件写入、不受写入死区约束。理由:安全阈值附近曲线插值本身可能已经很高 (例如 84.8 °C 插值出 252),跳到 85 °C 时目标 255 与当前值只差 3,会被死区挡下; 而只要插值结果仍在 250 附近,之后每一轮都会继续被挡——风扇永远到不了满速, 安全保护形同虚设。写一次 255 的开销远低于让 CPU 在 85 °C 以上吹不到满速。
- 控制权自愈:如果 EC 或其它工具把
pwm1_enable改回自动,插件下一轮会重新切回手动 (否则继续写pwm1是无效的,界面会显示"手动"但实际是自动)。 - 失败也必定交还 EC:切换模式或曲线时任何一步出错,都会停掉控制线程、把
pwm1_enable写回2、并把保存的模式改回「自动」。绝不留"已写入手动 PWM 但没有 任何东西在控制它"的状态——那比直接交给 EC 危险。保存的模式也一并改回自动, 否则下次启动还会照着手动模式再恢复一次。 - 失败路径同样要过门禁:控制线程的异常分支不自己写
pwm1_enable,而是统一走_fan_fail_safe(),由它重新查一次驱动身份。原因是异常来源之一就是门禁失效本身—— 那一刻驱动身份已无法确认,而pwm1_enable的取值语义是驱动相关的,再写2有可能被 其它驱动解释成手动。门禁失效时 fail-safe 不写任何风扇节点,这正是需要的语义。 - 交还 EC 时不做"看起来已经是自动"的提前返回:
sysfs读回可能滞后于 EC 寄存器, 只凭一次读回值就跳过写入,会把风扇留在手动状态。一律写出期望值再确认; 多写一次「自动」是幂等的,代价远小于漏写。 - 夺回控制权后要确认:发现 EC 已收回自动并重新写
pwm1_enable = 1之后,必须_wait_for确认真的回到手动。写入被静默忽略时,不确认的话后续pwm1写入全是空转 ——界面显示手动、温度也在读,但 PWM 根本没生效。 - 交还 EC 的时机:切回「自动」、插件卸载、以及插件启动时发现 EC 被留在手动。
最后一条是安全兜底:上一次插件崩溃或被
kill -9时卸载钩子不会执行,EC 会停在手动 PWM, 那种状态下风扇不跟温度走、85 °C 保护也失效,所以启动时无条件纠正——不受「启动自动恢复」 开关影响。 - 自定义曲线为五个
[温度 °C, PWM]节点,温度必须按原样严格递增(乱序会报错, 不会自动重排);范围 30–100 °C / 40–255。 「自定义」的初始曲线只是可编辑的起点,不是推荐曲线。 - 最低 PWM 是 40,本插件不提供完全停转(0 PWM)。即使温度低到 30 °C, 曲线下限也是 40 —— 所以看到「30 °C → PWM 40」是设计如此,不是 bug。 这么做是考虑到掌机在低负载下仍需基础风量带走内存/供电模块的积热, 而 F1 Pro 的 EC 在 0 PWM 时的行为不完全可控。需要散热彻底停转的话, 请切回「自动」交给 EC 自己判断。
- 校验失败不会碰控制状态:节点温度填重了只是提示"不能重复",风扇继续按旧曲线跑—— 用户可能正在手动模式下调曲线,不该因为填错一个数就把控制权交还 EC。 只有"应用"环节失败才走上面的交还 EC 兜底。
插件日志(Decky 自动清理,只保留最新 5 个按时间命名的 .log):
ls -lt ~/homebrew/logs/"F1Pro EC Control"/
tail -n 150 ~/homebrew/logs/"F1Pro EC Control"/*.logDecky 本体日志(加载失败、插件崩溃会出现在这里):
journalctl -u plugin_loader -b --no-pager | tail -n 200排查时把这两处的内容一起发出来即可。
| 现象 | 原因 / 处理 |
|---|---|
| 界面显示"未找到支持充电控制的电池节点" | 内核没有 charge_behaviour,需要带 oxpec / 充电控制驱动的内核 |
| 三个模式按钮都是灰的 | 看诊断区的 charge_behaviour 原始字符串,确认内核支持哪些取值 |
| 上限下拉框是灰的 | 没有 charge_control_end_threshold 节点 |
| 提示"没有权限写入电池控制节点" | plugin.json 的 flags 里没有 "root"(写成 _root 不生效 —— decky-loader 只做 "root" in flags 的精确匹配,_root 会被降权:界面正常但写入全 EACCES),或插件不是通过 Decky 加载的 |
| 提示"内核拒绝了写入" | 内核/EC 不接受该值,报错会带上具体 errno |
| 改了上限但电量还在涨 | 开机旁路在睡眠 / 关机时仍会充电(F1 Pro oxpec 行为),属正常;只有「始终旁路」才完全不充电 |
| 旁路接电时看不到瓦数 | 预期行为:供电中 不显示数字,请改看充电器端功率计 |
| 插着电、已到上限时显示「供电中」 | 预期行为:适配器在带整机、电池不充不放,与旁路接电是同一种物理状态 |
| 显示「未充电」 | 罕见兜底:外接电源节点报已断开、内核却仍报 Not charging。核对诊断区的「外接电源」与 status 两行 |
| 显示「已充满」但上限不是 100% | 内核把"已停在上限"报成了 Full(而不是 Not charging)。看诊断区 status 确认 |
MIT,见 LICENSE。
| 用途 | 链接 |
|---|---|
| 源码仓库 / 提 Issue | https://github.com/Phioly/F1Pro-EC-Control |
| 下载发布包(ZIP) | https://github.com/Phioly/F1Pro-EC-Control/releases |
| Decky Loader | https://github.com/SteamDeckHomebrew/decky-loader |
| 内核 oxpec 驱动(风扇 / 电池的底层实现) | https://github.com/torvalds/linux/blob/master/drivers/platform/x86/oxpec.c |
内核 ACPI 电池驱动(power_now 符号的来源) |
https://github.com/torvalds/linux/blob/master/drivers/acpi/battery.c |
hwmon pwm1_enable 通用文档(注意:oxpec 与它不一致,见上文) |
https://docs.kernel.org/hwmon/sysfs-interface.html |