HUAWEI MateBook D 15 2022(BoF-XX-PCB)Ubuntu Linux 外放无声修复
本文摘要
HUAWEI MateBook D 15 2022(BoF-XX-PCB)在 Ubuntu 中已识别 ES8336 声卡和 Speakers 输出,但内置扬声器依旧无声。本文根据 DMI、ACPI 与 I²C 检查,将问题定位到 HWSP0001 外置功放未正确初始化,并记录如何核对总线和器件、写入实测寄存器配置,再用 systemd 在开机及睡眠恢复后自动初始化,同时保留 GNOME/PipeWire 的扬声器与蓝牙切换。
AI 辅助声明:这篇文章由 AI 协助整理排查过程和技术说明。机型、系统输出、I²C 读写结果与外放是否恢复,均来自这台电脑的实际检查;结论只对本文记录的 BoF-XX-PCB 设备成立。
Ubuntu 上这台 HUAWEI MateBook D15 长期没有外放声音,这个问题我一直搁着。最近想到 Codex 的 Linux 桌面客户端已经推出一段时间了,我也该试着把这个老问题认真查一遍,于是从机器实际识别到的声卡和播放链路开始排查。
我手头正好有一份名字看起来很对口的 HUAWEI_MateBook_D_15_2022_ISST_10.29.0.7767.zip,但里面实际只有 ISST_10.29.0.7767.exe。它是 Windows 安装程序,不能当成 Linux 驱动加载。继续检查后发现,Linux 已经识别出 ES8336 播放设备和 PipeWire 的 Speakers 输出。真正的问题落在另一个设备上:主板还暴露了独立的 HWSP0001 功放,而它的初始化状态不对。把匹配的寄存器配置写回左右两颗功放后,我听到了外放声音;后来又把这一步做成开机和睡眠恢复时自动执行的服务。
先把机器型号说清楚
华为官网支持设备列表把 BoF 对应到 HUAWEI MateBook D 15 2022 12 代酷睿版。这台机器装 Linux 后,DMI 返回的是更具体的 BoF-XX 和 BoF-XX-PCB,版本为 M1010。所以下文的结论以系统实际报告的主板名为准,不把所有 MateBook D15 都当成同一块板。华为官方型号列表
| 项目 | 本机实测 |
|---|---|
| 产品线 | HUAWEI MateBook D 15 2022 12 代酷睿版(官方系列代码 BoF) |
| DMI 产品名 / 版本 | BoF-XX / M1010 |
| DMI 主板名 | BoF-XX-PCB |
| 系统 | Ubuntu 26.04.1 LTS |
| 当前内核 | 7.0.0-38-generic |
| 音频控制器 | Intel Alder Lake PCH-P HDA,PCI ID 8086:51c8 |
| codec / 声卡 | Everest ES8336,ALSA 卡 sofessx8336 |
| 另一个音频相关设备 | ACPI HWSP0001:00,I²C bus 3 上的 0x58、0x5b |
这些字段都可以在本机读取。遇到同系列电脑时,也建议先记下自己的实际值:产品名一样,不代表 DMI、音频 codec、功放和接线方式都一样。
cat /sys/class/dmi/id/{sys_vendor,product_name,product_version,board_name,board_version}lspci -nnk | grep -i -A 4 'audio'cat /proc/asound/cardswpctl status声卡已经出现,为什么外放还是没声音
本机的音频控制器由 sof-audio-pci-intel-tgl 驱动。内核日志显示 SOF 固件 intel/sof/sof-adl.ri 和 sof-adl-es8336-dmic2ch-ssp0.tplg 拓扑均已加载,ALSA 也创建了 sof-essx8336 卡;PipeWire 里有内置 Speakers sink。speaker-test 可以打开 PCM 并持续播放测试音,但机身扬声器听不到声音。
这一步很关键:“音频流写进了 PCM”不等于“扬声器已经发声”。 它只能证明上层播放流和声卡设备能工作,模拟输出端、外置功放和扬声器本身仍要单独验证。
我也检查了之前那个 sof-es8336-fix.conf。启动日志确实出现 quirk mask 0xa0,但当时外放仍然无声,所以这份 quirk 配置没有解决实际问题。它不是本次最终修复;本次持久化脚本也不会改它。
继续看 ACPI 和 I²C 后,发现声卡之外还有 HWSP0001:00。它在 sysfs 中映射到 I²C bus 3,两个功放地址是 0x58 和 0x5b,并且没有已绑定的内核 I²C 驱动。读取两边的寄存器后,左右器件都显示:寄存器 0x00 为 0x5a,寄存器 0x01 为 0x38。在这台机器上,这组状态与静音故障同时出现。
让外放恢复的寄存器配置
我参考了 Linux 音频邮件列表里一份针对华为 BOD-WXX9 的 RFC 实验补丁,以及社区对另一块 D15 主板 BOD-WXX9-PCB-B4 的调查。两者都提到 HWSP0001,但目标主板和 I²C bus 编号并不是我的 BoF-XX。因此我没有照搬对方的 GPIO 编号或总线号,而是先在本机确认设备路径、地址和寄存器状态,再做临时寄存器初始化,并通过实际听音确认效果。Linux 邮件列表 RFC;BOD-WXX9 社区调查
本机实测的配置如下。脚本会把这些值分别写到 0x58 和 0x5b:
| 寄存器 | 写入值 | 本机读回情况 |
|---|---|---|
0x01 |
0x69 |
0x69 |
0x03 |
0x16 |
仍读为 0x0c |
0x04 |
0x80 |
0x80 |
0x05 |
0x0c |
0x0c |
0x06 |
0x11 |
0x11 |
0x07 |
0x93 |
0x93 |
0x09 |
0x0b |
0x0b |
0x0b |
0x4b |
0x4b |
0x0c |
0x00 |
0x00 |
0x0d |
0x77 |
0x77 |
0x0f |
0x51 |
0x51 |
0x10 |
0x58 |
0x58 |
0x58 |
0x00 |
0x00 |
0x59 |
0x80 |
仍读为 0x00 |
需要特别说明:0x03 和 0x59 的写入命令返回成功,但读回值没有变成配置表里的数值。因此持久化脚本不会把这两个寄存器当成通过读回校验;它保留这两次写入,是因为本机完整应用这组配置后,寄存器 0x01 变为 0x69,且我实际听到了内置扬声器发声。这里记录的是本机观察,不推断这两个寄存器在所有板子上的含义。
我当时重新播放 440 Hz 测试音,随后确认机身外放恢复。这才是本次成功判据;只看到 i2cset 没报错并不足以证明已经修好。
在桌面声音设置里先选中内置 Speakers 并确认没有静音,再用 ALSA 直接播放测试音。speaker-test 会一直循环,听完按 Ctrl+C 停止:
speaker-test -D 'plughw:CARD=sofessx8336,DEV=0' -c 2 -t sine -f 440整理成 MIT 开源仓库,并做成持久修复
我把初始化脚本、systemd oneshot 服务、睡眠恢复钩子、安装/卸载脚本和硬件诊断说明整理到公开仓库:matebook-bofxx-audio-fix,采用 MIT License。
脚本并不是无条件往 I²C 写数据。每次运行前,它都会核对:
| 检查项 | 必须匹配的本机状态 |
|---|---|
| 厂商、产品、主板 | HUAWEI、BoF-XX、BoF-XX-PCB |
| 功放设备路径 | HWSP0001:00 位于 bus 3 |
| I²C 驱动状态 | 设备没有绑定内核驱动,避免与驱动争用 |
| 两个 I²C 地址 | 0x58 和 0x5b 的寄存器 0x00 都读为 0x5a |
| 初始/已修复状态 | 寄存器 0x01 只能是已观察到的 0x38 或 0x69 |
核验不通过时,脚本记录错误并停止写入。通过时才向两个地址重放配置,然后逐项检查可读回的寄存器。卸载入口只移除这个项目安装的 service、resume hook 和脚本;它不碰系统里其它音频配置,也不把功放寄存器写回旧的静音状态。
git clone https://github.com/xingwangzhe/matebook-bofxx-audio-fix.gitcd matebook-bofxx-audio-fixpkexec bash "$(pwd)/scripts/install.sh"开机服务负责启动时初始化,systemd sleep hook 在睡眠恢复后调用同一个硬件检查脚本。本机验证过服务启动成功,也做过一次恢复路径模拟:将功放状态临时置回已观察到的静音值,再调用恢复 hook,确认寄存器状态重新恢复。我没有在这次排查里实际让机器睡眠再唤醒,所以这一项仍建议安装后自行完整验证。
卸载命令:
pkexec /usr/local/sbin/matebook-hwsp-uninstall蓝牙和扬声器输出仍由桌面音频管理
修复脚本只操作 HWSP0001 的 I²C 寄存器。它不运行 wpctl 或 pactl,不更改 WirePlumber/PipeWire 配置,不设置默认输出,也不禁用蓝牙。
安装后检查 wpctl status,本机仍分别列出了内置 Speakers sink 和一个蓝牙 sink;检查默认 sink 时,它仍指向蓝牙输出。也就是说,脚本没有把系统音频路由强行锁到内置扬声器。需要切换时,仍从 GNOME 的声音设置里选择蓝牙设备或内置扬声器。本文没有把“设备列出来”冒充成“我完整测试了每个蓝牙设备的音质”,蓝牙播放本身仍取决于设备连接和 PipeWire 状态。
其它华为主板遇到类似问题,先做这几步
华为笔记本的产品名不等于主板型号。D15、D14 等同一系列也可能使用不同平台、codec、功放、GPIO 和 ACPI 拓扑。建议按这个顺序排查:
| 步骤 | 先确认什么 | 不要据此直接推断什么 |
|---|---|---|
| 1 | DMI 的厂商、产品名、主板名、版本 | 不要只凭“MateBook D15”套用别人的脚本 |
| 2 | lspci -nnk、/proc/asound/cards、wpctl status |
有声卡节点不等于物理扬声器一定有声 |
| 3 | 内核日志里的驱动、SOF firmware、topology、codec probe | 不要因为网上有人编译了内核,就先换内核 |
| 4 | ACPI 是否出现 ESSX8336、HWSP0001 等设备,sysfs 把设备映射到哪个 I²C bus |
设备名称相同也不保证 bus、GPIO、两颗地址相同 |
| 5 | 确认设备未被驱动占用后,按目标板资料做受控只读检查 | 不要用 i2cset -f 对陌生地址试写,更不要盲目电源循环 GPIO |
| 6 | 小范围验证一个有来源的寄存器配置,并用耳朵确认前后变化 | 一台机器恢复不代表相同品牌或同一产品线都适用 |
社区 BOD-WXX9 方案使用的是 bus 2 和 GPIO 267;本机的 HWSP0001 则映射到 bus 3。这个差异正好说明为什么不能只复制一个型号相似的命令。更重要的是,那份 Linux 内核邮件仍是 RFC 讨论,不是已经合并、适用于所有华为机器的官方驱动;RFC 自己也说明寄存器恢复配置是经验性的,并需要更多硬件验证。
如果你的电脑外放无声但声卡节点存在,先区分是 UCM/音量路由、codec GPIO、耳机检测,还是独立功放初始化。把 wpctl status、内核日志、DMI 和 ACPI/I²C 映射整理出来,往往比盲目重装所谓“Linux 声卡驱动”更快接近问题本身。
参考资料
- 华为官方支持设备列表:MateBook D 15 2022 12 代酷睿版与 BoF 产品代码
- Linux sound 邮件列表:HWSP0001 支持 RFC
- BOD-WXX9-PCB-B4 社区功放排查和脚本
- 本次修复代码、安装/卸载脚本与 MIT License
HUAWEI MateBook D 15 2022(BoF-XX-PCB)Ubuntu Linux 外放无声修复
作者:xingwangzhe
本文链接:https://xingwangzhe.fun/posts/matebook-d15-bofxx-hwsp0001-no-speaker/
本文采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
留言评论