Linux-surface没声音:RT5645的解决方法

快速解决

Surface 3(同样适用于Cherry Trail / Bay Trail平台依赖SSF或SOF驱动和RT5645系列Codec的迷你主机、平板、开发板),安装Linux后无声,可能是因为缺少sof-firmware。如果你遇到这个问题,可以先执行sudo pacman -S sof-firmware, 重启后测试。

排查时序及相应操作

  1. Mute=0,Volume=100, unknown ——> sound=0:系统未静音,但无声
    • alsamixer查看声卡及静音状态
    • speaker-test
  2. Mute=0,Volume=100, pipewire=D_State,unknown ——> sound=0:管道已损坏,播放请求可能未送达ALSA层
    • fuser -v /dev/snd/*
    • killall -9 pipewire pipewire-pulse wireplumber 2>/dev/null
    • 解决:lsmod grep -E "snd|rt5645|cht|byt" | awk '{print $1}' | xargs sudo modprobe -r//卸载相关音频驱动模块
    • 上一步lsmod grep -E报错,返回fatal: module sne_hrtimer is in use
    • 解决:sudo pacman -Rdd pipewire
  3. Mute=0,Volume=100, PalseAudio=1(pactl=1), unknown ——> sound=0:PalseAudio正常运行,但仍无声
  4. Mute=0,Volume=100, PalseAudio=1(pactl=1), hw:1,0/plughw:1,0=0(ALSA_Device=0), unknown ——> sound=0:ALSA硬件接口未成功打开
    • pulseaudio -vvv --log-time=1 2>&1 | tee pulse-log.txt//查看pulseAudio详细日志
    • pactl load-module module-alsa-card device_id=1 name="platform-cht-bsw-rt5645" card_name="alsa_card.platform-cht-bsw-rt5645" tsched=0 use_ucm=0=>报错:模块初始化失败
  5. Mute=0,Volume=100, PalseAudio=1(pactl=1), ALSA_Device=0, ASoc=-16(dmesg错误码) ——> sound=0:pactl能连接,但内核ASoC框架未能正确初始化
    • sudo dmesg | grep -iE "rt5645|cht|audio| snd|asoc"
  6. Mute=0,Volume=100, PalseAudio=1, hw:1,0/plughw:CARD=chtrt:5645=0/pactl=1, ASoc=1 ——> sound=1

解决后复盘

Q1. PipeWire陷入D状态是因为缺失sof-firmware吗,也就是说现在我可以切换到PipeWire吗?因为paru -Syu会报PipeWire和PulseAudio冲突

是的,根源是同一个问题,但因果关系需要理清。

PipeWire 调用 ALSA → ALSA 尝试通过 DSP 驱动初始化音频路径 → DSP 固件缺失导致驱动卡住 → 进程陷入 D 状态。

你后来安装sof-firmware后,DSP 能正常初始化了,因此 PipeWire 理论上可以正常工作。

关于切换:你现在可以切换到 PipeWire。

paru -Syu报冲突是因为pipewire-pulsepulseaudio都提供了pulseaudio这个虚拟功能,它们不能同时安装。选择其一即可。

如果你决定切换:

# 1. 移除 PulseAudiosudopacman-Rddpulseaudio pulseaudio-alsa# 2. 安装 PipeWiresudopacman-Spipewire pipewire-pulse wireplumber# 3. 启用服务systemctl--userenable--nowpipewire pipewire-pulse wireplumber

建议先备份当前的~/.config/pulse/,以防需要回退。如果你不确定哪个更稳定,可以先保留 PulseAudio,以后再决定是否切换。

Q2. /etc/asound.conf 、HiFi.conf等手动添加的UCM conf有用吗,UCM和sof-firmware是什么关系?

答案:现在这些配置文件大多无用了,可以删除。

sof-firmware是“硬件固件”,它让 DSP 芯片能正常工作,属于“能不能出声”的基础条件,是决定性的。
UCM(Use Case Manager)配置文件是“路由描述”,它告诉 ALSA/PulseAudio 如何把音频数据从 DSP 路由到扬声器或耳机,属于“怎么出声”的配置,是调节性的。

它们的关系是:

  • 先有sof-firmware:DSP 驱动能启动,hw:1,0能打开,speaker-test -D plughw:1,0能出声。
  • 然后 UCM 才有意义:告诉系统“播放音乐时走扬声器,插耳机时切到耳机”。

在问题解决前,UCM 配置之所以无效,是因为 DSP 根本就没初始化成功;固件补上后,ALSA 的默认路径通常已经能工作。你可以先测试speaker-test -D plughw:1,0 -c 2 -t wav,如果出声,就不需要额外配置。

Q3: 我怎么知道自己的硬件是否缺少sof-firmware

ls /usr/lib/firmware/intel/sof-*.ri
ls /usr/lib/firmware/intel/sof/sof-*.ri
如果没有任何输出,说明固件未安装。

应用调用链(数据流):

【设备树/ACPI解析】:在硬件发现阶段作用,读取硬件拓扑,确定“谁挂在谁下面”

应用(Speaker-test 、 VLC) -----------------用户调用音频的渠道

音频服务(PulseAudio / PipeWire)---------------用户态音频服务

ALSA用户态库(libasound.so)---------------------用户态库

系统调用(open / ioctl)------------------------------进入内核的大门

ALSA核心(snd_pcm_open)-----------------------ALSA核心层

ASoC框架(动态管道DPCM)------------------------决定“数据怎么走”/【DPCM管道:根据UCM/路由决定数据走哪条路

Platform驱动(sst_mfld_platform)--------------CPU侧的音频接口

DSP固件(SOF / SST)--------------------------------DSP上运行的代码

DSP硬件(Intel SST)---------------------------------硬件

DMA引擎(内存 DSP之间的数据搬运)------------不经过CPU的数据通道

Codec驱动(snd_soc_rt5645)---------------------Codec侧的驱动

I2C控制通道(设置Codec寄存器)------------------控制(设置音量、切换输入源)

RT5645芯片(Codec芯片)---------------------------编解码硬件

I2S音频总线(音频数据流)---------------------------数据通道(传输音频数据)

物理扬声器 / 耳机接口

linux层级表

问题通常出现在Layer 2

Layer包含组件音频问题中涉及的部分
1硬件层CPU、内存、磁盘、GPU、网卡、I2S总线、扬声器、耳机插孔I2S总线/扬声器/耳机插孔、rt5645芯片
2内核与固件层Linux kernel、firmware、内核模块、设备节点!缺失Intel DSP所需固件sof-firmware -> DSP固件未加载导致-16错误 -> 内核模块资源泄漏
内核模块【snd_soc_rt5645(Codec驱动)、snd_soc_cht_bsw_rt5645(平台驱动/DPCM)、sst_mfld_platform(DSP驱动)、snd_hrtimer(ALSA的HRtimer后端的内核模块计时器)】、Intel SST DSP固件(fw-sst-0f28. bin)、设备节点/dev/snd/*
3核心系统服务与IPC层systemed、dbus、udev、polkit、elogind服务启动顺序、权限问题 | 通常不直接导致音频故障
4硬件抽象与输入层udev、evdev、libinput、Mesa、DRM/KMS不直接涉及音频
4.5系统调用/用户态驱动接口层ALSA lib(用户态)
5图形显示服务层Wayland compositor或X11不涉及
6UI工具包Qt、GTK、EFL、SPL2不涉及
7桌面环境与外壳层Gnome shell/ KDE Plasma shell/LXDE、会话管理不涉及
8用户应用层浏览器、编辑器、媒体播放器、绘图软件speaker-test、PulseAudio / PipeWire | 音频服务配置、应用层参数协商

用图论&线代的角度来看这个问题

用逻辑状态编码和状态迁移图来表示这个过程:
stateDSP1Codec0DPCM0Mute0Audio0\begin{array} {}&{state}\\ \hline {DSP}&{1}\\ {Codec}&{0}\\ {DPCM}&{0}\\ {Mute}&{0}\\ {Audio}&{0}\\ \end{array}DSPCodecDPCMMuteAudiostate10000
注:矩阵状态对应的dmesg错误:
DPCM:-16错误
DSP:sof-firmware加载日志
Audio:pcmC1D0p是否出现/是否出声

转换矩阵T,在GF(2)的情况下1+1=0, 可以实现XOR逻辑
[1000010000010000000100101]\begin{bmatrix} 1&0&0&0&0\\ 1&0&0&0&0\\ 0&1&0&0&0\\ 0&0&0&0&1\\ 0&0&1&0&1\\ \end{bmatrix}1100000100000010000000011
(即DSP和Codec都依赖于sof-firmware;Audio依赖于DPCM和Mute)

对每个State,进行
St+1=T∗StS_{t+1}=T*S_tSt+1=TSt

比如,对S0S_0S0时刻有[10000]\begin{bmatrix} 1\\ 0\\ 0\\ 0\\ 0\\ \end{bmatrix}10000
由此可得下一个时间步S1S_1S1S1=T∗S0S_1=T*S_0S1=TS0
运算可得S1S_1S1[11000]\begin{bmatrix} 1\\ 1\\ 0\\ 0\\ 0\\ \end{bmatrix}11000
下一个时间步S2S_2S2[11100]\begin{bmatrix} 1\\ 1\\ 1\\ 0\\ 0\\ \end{bmatrix}11100
下一个时间步S3S_3S3[11101]\begin{bmatrix} 1\\ 1\\ 1\\ 0\\ 1\\ \end{bmatrix}11101

至此,我算是用这个音频问题摸了摸线代和Linux系统的门,后续连蓝牙耳机我切了Pipewire很顺利就完成了,其实也可以给矩阵再添一行Headphone,我感觉运行太顺畅了没有实感就不加了——只能说喜欢搞冷门硬件的垃圾佬多少都有点M在身上的。
感谢DeepSeek老师的帮助和我面对反复报错也没崩的毅力,赞美D老师,垃圾佬手里最顺手的夹子