首页/目录/全部文章

全部文章

八个专题的源码、算法与协议笔记都在这里。

笔记列表

RK3588 平台音频拓扑与使用场景详解

RK3588 平台音频拓扑与使用场景详解

源码路径rk3588/kernel-6.1/sound/soc/rockchip/ + 板级 DTS
文档目录linuxDoc/sound/


目录


一、SoC 音频 IP 概览

IP 驱动 compatible 常见用途
I2S/TDM rockchip,rk3588-i2s-tdm Line-out、Codec、HDMI I2S
PDM rockchip,rk3588-pdm 板载数字麦
SPDIF rockchip,rk3588-spdif 数字音频输出
VAD rockchip,rk3588-vad 低功耗语音唤醒
Codec digital rockchip,rk3588-codec-digital SoC 侧数字音频控制

DLP/multi_dais 可用于部分语音、聚合和回环场景(见 04)。本分支 rockchip_asrc.c 没有 RK3588 compatible,不能把它当作 RK3588 固有模块。


二、典型拓扑

播放采集用户态 PCMI2S/TDM DAIES8388 CodecHDMI CodecHDMI 控制器PDM 麦克风PDM DAIPCM capture

设备树(概念):

  • i2s@... 节点 + sound 简单声卡或 rockchip,multicodecs
  • pinctrl 配置 I2S 引脚
  • clocksmclkhclk 来自 CRU

具体节点名以 arch/arm64/boot/dts/rockchip/rk3588-*.dts(i) 为准。


三、SeagullYpcEncode / 编解码

场景 音频栈
HDMI 输出监视器(带扬声器) HDMI I2S + rockchip_hdmi
模拟耳机/Line-out I2S + 外置 Codec
USB 摄像头麦克风 usb-audio(独立)
纯视频编解码(无音频轨) 可不加载音频模块
语音对讲 / 唤醒 PDM + VAD(若产品启用)

MPP/VPU 处理 H.264/H.265 不替代 ALSA;音轨 mux 在 容器/GStreamer 完成,HDMI 音频仍走内核声卡。


四、配置与调试

1
2
3
4
5
6
7
8
9
10
11
# 内核
zcat /proc/config.gz | grep -E 'SND|SOC|ROCKCHIP'

# 用户态
aplay -l
arecord -l
cat /proc/asound/cards
dmesg | grep -iE 'asoc|rockchip-i2s|hdmi-codec'

# 格式测试
speaker-test -D hw:0,0 -c 2
问题 方向
无声卡 CONFIG_SND_SOC_ROCKCHIP、DT status = "okay"
播放无声音 DAPM 路由、功放 GPIO、amixer 静音
HDMI 无音频 DRM 绑定、hdmi-codec link、显示器 EDID
采样率不对 hw_params、MCLK/BCLK 分频;若板级确有外部转换再查 ASRC

五、与显示/电源关系

  • HDMI 音频 依赖 DRM HDMI 先完成模式设置;时钟可能共享 CRU/HDMICTRL
  • runtime PM:DAI 驱动常用 pm_runtime;空闲 DAPM 下电降低功耗
  • 编解码高负载 时 CPU 调度影响 音频 xrun(underrun),与 kernel/sched 相关,非 VPU 驱动本身

关联文档

  • 总览
  • 02 ASoC DAPM
  • 既有笔记:linuxDoc/sound/rk3588-kernel-6.1-sound声卡架构分析.md

ALSA PCM 运行状态机与数据路径

ALSA PCM 运行状态机与数据路径

1. 对象

1
2
3
4
5
6
snd_card
└─ snd_pcm
├─ playback snd_pcm_str
└─ capture snd_pcm_str
└─ snd_pcm_substream
└─ snd_pcm_runtime

runtime 保存 hw constraints、format/rate/channels、buffer/period、状态、hw_ptr/appl_ptr、wait queue 和 mmap control/status。

2. 设备打开

1
2
3
4
5
6
7
8
9
open("/dev/snd/pcmC0D0p")
-> snd_open()
-> registered minor f_ops
-> snd_pcm_playback_open()
-> snd_pcm_open()
-> snd_pcm_open_substream()
-> runtime allocation
-> ops->open()
-> constraint refinement

同一 PCM device 可有多个 substream,但硬件/ASoC link 常只暴露一个。

3. 配置

用户态顺序:

  1. HW_REFINE 探测可行参数;
  2. HW_PARAMS 确定 access/format/rate/channels/buffer/period;
  3. 分配 DMA buffer;
  4. 驱动 hw_params 配置 DAI/DMA;
  5. SW_PARAMS 设置 start/stop threshold、avail_min、silence;
  6. PREPARE 清状态并准备硬件。

ALSA constraint 求交确保 CPU DAI、codec DAI、platform DMA 与 machine policy 都能接受参数。

4. 状态

1
2
3
4
5
6
7
OPEN -> SETUP -> PREPARED -> RUNNING
\ |
\ v
-> XRUN
RUNNING <-> PAUSED
RUNNING -> DRAINING -> SETUP
SUSPENDED / DISCONNECTED

非法状态 ioctl 返回 EBADFD 等;XRUN 后通常需 prepare 恢复。

5. Playback

1
2
3
4
5
6
7
8
userspace write/mmap
-> appl_ptr advances
-> START threshold reached / explicit start
-> trigger(START)
-> cyclic DMA reads ring buffer -> I2S FIFO
-> period IRQ/callback
-> snd_pcm_period_elapsed()
-> update hw_ptr + wake poll

若 DMA 消费追上 appl_ptr,发生 underrun。

6. Capture

1
2
3
PDM/I2S FIFO -> cyclic DMA writes ring
-> period callback -> hw_ptr advances
-> userspace read/mmap consumes -> appl_ptr

若 producer 覆盖未读取数据,发生 overrun。

7. Pointer

驱动 pointer() 返回当前 DMA hardware position(frame)。Core 结合 boundary 处理环绕并校验跳变。错误 pointer、丢 period callback 或 IRQ 延迟均可能造成 XRUN/hw_ptr 异常。

8. mmap

ALSA 映射:

  • DMA data buffer;
  • status page;
  • control page。

用户态直接读写 ring,但必须使用正确内存屏障和同步协议。mmap 减少 syscall/copy,不代表 DMA 一定 cache coherent。

9. 锁

  • PCM open mutex;
  • runtime stream lock:atomic PCM 使用 spinlock,nonatomic PCM 使用 mutex;
  • group/link lock;
  • card controls/files 锁;
  • ASoC runtime/card mutex。

period callback 多在 DMA tasklet/IRQ 类上下文,不能执行可睡眠操作。

10. 关键文件

  • core/pcm.c
  • core/pcm_native.c
  • core/pcm_lib.c
  • core/pcm_memory.c
  • core/memalloc.c
  • core/pcm_dmaengine.c

11. 观测

1
2
3
4
5
cat /proc/asound/cards
cat /proc/asound/pcm
cat /proc/asound/card0/pcm0p/sub0/status
cat /proc/asound/card0/pcm0p/sub0/hw_params
aplay --dump-hw-params -D hw:0,0 /dev/zero

ASoC 组件绑定与 DAI Link

ASoC 组件绑定与 DAI Link

1. 三层不是三个固定驱动

ASoC 把声卡拆为:

  • CPU component/DAI:I2S/TDM/PDM/SPDIF 控制器;
  • codec component/DAI:模拟 codec、数字 codec、HDMI codec;
  • platform PCM:DMA 数据搬运;
  • machine/card:连接、时钟策略、routing、jack。

一个 component 可同时提供多个 DAI 和 controls。

2. 核心对象

对象 作用
snd_soc_component_driver component 回调和 controls/DAPM 描述
snd_soc_component 已注册实例
snd_soc_dai_driver DAI playback/capture capability
snd_soc_dai DAI 实例
snd_soc_card 整张板级声卡
snd_soc_dai_link CPU/platform/codec 连接
snd_soc_pcm_runtime 一条 link 的绑定运行时

3. 注册与绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
CPU/codec platform/i2c probe
-> devm_snd_soc_register_component()
-> component + DAI enter global registry

machine probe
-> devm_snd_soc_register_card()
-> snd_soc_bind_card()
-> match dai_link components
-> soc_probe_link_components()
-> soc_init_pcm_runtime()
-> soc_new_pcm()
-> snd_soc_pcm_dai_new()
-> snd_card_register()

组件 probe 顺序不确定;缺少任何 DAI/component 时 card 可 defer probe。

描述:

  • CPU DAI;
  • codec DAI(可多个);
  • platform;
  • stream name;
  • format/master/inversion;
  • playback/capture only;
  • nonatomic;
  • dynamic/no_pcm;
  • trigger order;
  • init/ops/fixup。

Device Tree machine driver把 phandle 和属性转换为 dai_link。

5. PCM open

1
2
3
4
5
6
ALSA snd_pcm open
-> soc_pcm_open()
-> component open
-> CPU/codec DAI startup()
-> machine ops->startup()
-> merge runtime constraints

close 以对应顺序 shutdown 并释放 active/refcount。

6. hw_params

1
2
3
4
5
soc_pcm_hw_params()
-> machine hw_params
-> codec DAI hw_params
-> CPU DAI hw_params
-> component/platform hw_params

实际顺序受 ASoC 版本和 link 配置影响;驱动不应依赖未声明的全局顺序。

7. prepare/trigger

trigger 同时控制 component、codec DAI、CPU DAI。对于 playback,通常先使 DMA/FIFO 进入一致状态再启动时钟,避免 underrun/pop;capture 顺序可能相反。link 可配置 trigger order。

8. DPCM

Dynamic PCM 将:

  • Front-End:用户可见 PCM;
  • Back-End:真实硬件 link,

分离。DAPM route 决定 FE 与哪些 BE 连接,适合复杂 SoC mixer、多输出、DSP。dpcm_path_get()、runtime update 和 BE hw_params 协调共享后端。

9. PM

ASoC card suspend/resume 协调:

  • active streams;
  • DAPM;
  • codec bias;
  • component PM;
  • jack wake;
  • regcache;
  • pmdown_time。

runtime PM 通常在具体控制器/codec 驱动管理 clock/reset/regulator。

10. 常见绑定失败

  • CPU/codec DAI name 不匹配;
  • sound-dai phandle 错;
  • codec I2C probe 失败;
  • missing clocks/resets;
  • machine driver未启用;
  • DAI format/master 双方冲突;
  • deferred probe 永久等待供应者。

DAPM、Control、Jack 与 Topology

DAPM、Control、Jack 与 Topology

1. ALSA Control

core/control.c 管理 snd_kcontrol

  • integer/boolean/enum/bytes/IEC958;
  • info/get/put
  • card control device;
  • change notification;
  • TLV dB scale。

amixer/alsactl 操作 control,不直接操作 PCM 数据流。

2. ASoC controls

soc-ops.c 提供 SOC_SINGLE/SOC_ENUM/SOC_DAPM 等宏对应的通用 get/put,通常通过 regmap 访问 codec/控制器寄存器。put 应只在值变化时返回 1,以便发送通知。

3. DAPM 图

Widget 类型:

  • input/output;
  • ADC/DAC;
  • mixer/mux;
  • PGA;
  • supply/regulator/clock;
  • AIF in/out;
  • MICBIAS;
  • PRE/POST。

Route 表示 source -> sink,并可受 mixer switch/mux selection 控制。

4. 电源计算

1
2
3
4
5
6
stream start or control change
-> mark graph dirty
-> discover connected endpoints
-> compute powered widgets
-> sequence PRE_PMU/POST_PMU
-> register update / event callbacks

关闭时按反向安全顺序执行 PRE_PMD/POST_PMD。DAPM 不只是省电,也控制模拟 pop 和必要时钟。

5. Bias level

Codec bias 常见:

  • OFF
  • STANDBY
  • PREPARE
  • ON

machine/codec 可覆盖 set_bias_level。错误 regulator/MCLK 顺序会造成爆音、寄存器访问失败或待机功耗。

6. Jack

soc-jack.c / core/jack.c

  • headphone/microphone/button bits;
  • GPIO/extcon/codec IRQ;
  • debounce;
  • ALSA control/input event;
  • DAPM pin enable/disable。

RK machine driver可能使用 extcon 获取 Type-C/HDMI 或耳机状态。

7. Topology

soc-topology.c 加载用户态 topology firmware,动态建立:

  • controls;
  • widgets/routes;
  • DAIs/links;
  • private data。

主要用于 DSP/复杂平台。固件 parser 处理不可信长度时必须严格校验;版本需与驱动匹配。

8. 调试

1
2
3
4
amixer -c 0 contents
alsactl store
cat /sys/kernel/debug/asoc/cards
find /sys/kernel/debug/asoc -maxdepth 3 -type f

DAPM debugfs 可查看 widgets、routes、power,但路径与内核配置相关。

9. 常见静音原因

  • control muted;
  • DAPM route 名称不匹配;
  • endpoint pin disabled;
  • codec bias 未上电;
  • MCLK/regulator 缺失;
  • jack 状态错误;
  • machine driver没有声明 routing;
  • 音频实际走 HDMI 而用户打开模拟 PCM。

DMAengine PCM 缓冲与实时性

DMAengine PCM 缓冲与实时性

1. 数据路径

1
2
3
4
5
userspace ALSA ring
-> coherent/streaming DMA buffer
-> DMAengine cyclic descriptor
-> Rockchip I2S/PDM/SPDIF FIFO
-> serial pins / codec

Capture 方向相反。

2. 公共层

core/pcm_dmaengine.csoc-generic-dmaengine-pcm.c 提供:

  • DMA channel request;
  • slave config;
  • cyclic prep;
  • submit/issue pending;
  • residue 转 PCM pointer;
  • period callback;
  • pause/resume/terminate;
  • preallocated buffer。

Rockchip I2S/TDM、PDM、SPDIF Kconfig 通常 select SND_SOC_GENERIC_DMAENGINE_PCM

3. DMA data

CPU DAI 通过 snd_soc_dai_init_dma_data() 提供:

  • FIFO physical address;
  • bus width;
  • maxburst;
  • channel name;
  • flags。

hw_params 将 sample format 转 bus width,并建立 dma_slave_config

4. Cyclic DMA

DMA buffer 分成 periods,硬件循环:

1
buffer_bytes = period_bytes * periods

每 period completion 调 snd_pcm_period_elapsed()。过小 period 增加 IRQ/callback 和调度压力;过大增加基础延迟。

5. Pointer

通常根据 DMA residue:

1
pos = buffer_size - residue

DMA controller residue 粒度或延迟会影响时间戳和 avail。驱动需处理 residue=buffer size、环绕和暂停状态。

6. Buffer 分配

ALSA memalloc 支持 coherent DMA、SG、vmalloc 等类型。SoC DMA 常用 coherent buffer,并 mmap 给用户态。是否需要 cache sync 由 DMA API 和架构一致性决定,驱动不能直接假设所有 ARM64 DMA 完全 coherent。

7. XRUN 来源

  • period 太小;
  • CPU 调度/IRQ 延迟;
  • DMA IRQ 被屏蔽;
  • 错误 IRQ affinity;
  • DMA channel contention;
  • FIFO threshold/突发不匹配;
  • clock drift;
  • userspace未及时读写;
  • runtime PM/clock误关;
  • hw pointer错误。

8. 延迟估算

理论环形缓冲时长:

1
2
latency ≈ buffer_frames / sample_rate
period_time = period_frames / sample_rate

实际还包括应用、插件、PulseAudio/PipeWire、调度、codec filter、HDMI sink。

9. 调优

  1. 先用 hw: 绕过软件插件;
  2. 从稳定的大 buffer/period开始;
  3. 逐步减小 period;
  4. 观察 XRUN、CPU、IRQ;
  5. 固定 CPU 频率或 QoS 做对照;
  6. 设置合理实时优先级;
  7. 不把 period 设成 DMA 不支持的 burst/alignment。

10. 观测

1
2
3
4
cat /proc/interrupts
cat /proc/asound/card0/pcm0p/sub0/status
trace-cmd record -e snd_pcm -e dma_fence -e irq
aplay -v --period-size=1024 --buffer-size=4096 test.wav

可用 tracepoint 依本分支配置确认。

I2S/TDM 时钟、格式与 RK3588 控制器

I2S/TDM 时钟、格式与 RK3588 控制器

1. RK3588 驱动

主驱动:sound/soc/rockchip/rockchip_i2s_tdm.c,匹配:

1
rockchip,rk3588-i2s-tdm

旧控制器由 rockchip_i2s.c 支持,RK3588 DTS 中也存在兼容旧 I2S IP 的节点。具体板卡启用哪些节点由 DTS 决定。

2. 信号

  • MCLK:codec/控制器主时钟;
  • BCLK/SCLK:每 bit 时钟;
  • LRCK/FS:frame/左右声道同步;
  • SDI/SDO:数据 lane。

常见:

1
2
BCLK = sample_rate * slots * slot_width
MCLK = sample_rate * mclk_fs

例如 48 kHz × 2 × 32 = 3.072 MHz BCLK。

3. 格式

snd_soc_dai_set_fmt() 组合:

  • I2S;
  • Left/Right Justified;
  • DSP_A/DSP_B;
  • clock inversion;
  • CPU/codec bit/frame clock master。

双方 master 设置冲突会无时钟或总线争用。

4. TDM

set_tdm_slot() 指定:

  • TX/RX slot mask;
  • slots;
  • slot width。

channel 与 slot 不完全等同。多 lane 模式将 slots 分布到多个 data pin,需 DTS pinctrl 和驱动 lane 配置一致。

5. hw_params

驱动典型步骤:

  1. 根据 format 选 sample width;
  2. 配置 channel/slot;
  3. 计算 BCLK div;
  4. 设置 MCLK;
  5. 写 CKR/TXCR/RXCR 等寄存器;
  6. 设置 FIFO/DMA;
  7. 对称 rate/channel 约束。

时钟无法精确整除时应返回错误,不能静默使用错误采样率。

6. Trigger

START/RESUME/PAUSE_RELEASE:

  • 启 DMA request;
  • 启 TX/RX;
  • 清 FIFO/状态;
  • 处理同步启动。

STOP/SUSPEND/PAUSE_PUSH 反向关闭。播放停止过早关时钟可能截断最后样本。

7. TRCM

rockchip_trcm.c 支持 TX/RX common clock / 同步模式,使双向流共享时钟并协调启动。SND_SOC_ROCKCHIP_I2S_TDM 会选择 TRCM 支持。

使用场景:

  • 全双工同步;
  • codec要求连续时钟;
  • 多 DAI 同步。

代价是方向之间参数约束更强。

8. Clock/GRF

RK3588 音频还涉及:

  • CRU clock parents/dividers;
  • reset;
  • GRF/IO mux;
  • pinctrl;
  • assigned-clocks/rates/parents;
  • power domain。

驱动 probe 成功不代表引脚和外部 codec 已有正确时钟。

9. 常见故障

现象 检查
无 BCLK/LRCK master、clock、trigger、pinctrl
速率偏差 MCLK parent/divider、PLL family
声道错位 slot mask/width、format
噪声 word length、inversion、RGM? 实为音频 pin 时序
只单向工作 DMA、SDI/SDO pin、TRCM
hw_params EINVAL rate/format/channel/clock 不可满足

PDM、S/PDIF、VAD、ASRC 与数字音频

PDM、S/PDIF、VAD、ASRC 与数字音频

1. PDM

rockchip_pdm.c 匹配 rockchip,rk3588-pdm,面向数字麦克风 capture:

  • 多 channel;
  • PDM clock;
  • CIC/FIR/decimation;
  • sample rate;
  • DMA FIFO;
  • high-pass/gain(按 IP)。

rockchip_pdm_v2.c 是另一版 PDM 控制器,但本树直接标明的 RK3588 compatible 位于 rockchip_pdm.c,不能仅因文件名较新就假设板卡使用 v2。

2. S/PDIF TX/RX

  • rockchip_spdif.c:TX,RK3588 compatible;
  • rockchip_spdifrx.c:RX,DTS 可使用 RK3588 + RK3308 fallback;
  • IEC958 channel status;
  • compressed bitstream passthrough;
  • DMA;
  • recovered clock(RX)。

用户态透传 AC3/DTS 时数据格式和接收设备能力必须匹配,不能按普通 PCM 调音量。

3. Digital codec

soc/codecs/rk_codec_digital.c 匹配:

1
rockchip,rk3588-codec-digital

它表示 SoC 内数字音频 codec/路由控制,不等同于完整外置模拟 codec。模拟耳机/扬声器仍可能需要 I2C codec、amp、regulator 和 machine routing。

4. VAD

rockchip_vad.c 匹配 RK3588,并有 rk3588_addr_map 描述可监听音频源。目标是在低功耗/持续捕获场景检测语音活动。

涉及:

  • source selection;
  • SRAM/ring buffer;
  • threshold;
  • preprocessing;
  • wakeup;
  • 与 PDM/I2S capture 协调。

本树按 ARM/ARM64/Thumb 选择 VAD preprocess 汇编。

5. ASRC

rockchip_asrc.c 提供 asynchronous sample-rate conversion,在不同时钟域/采样率间转换。本分支 match table 只有 rk3506-asrcrk3576-asrc没有 rk3588-asrc;因此不能把该驱动列为 RK3588 原生 ASRC。只有板级存在独立兼容硬件或其它转换路径时,才能按实际拓扑讨论 ASRC。

ASRC 能处理时钟域差异,但会增加:

  • pipeline latency;
  • 算法资源;
  • format/rate 限制;
  • 质量验证需求。

6. DLP

rockchip_dlp.c + rockchip_dlp_pcm.c 实现数字 loopback PCM,把输入路径回送/抓取用于测试、回声参考或调试。它不是通用用户态软件 loopback。

7. Multi-DAI

rockchip_multi_dais.c 聚合多个 DAI,rockchip_multi_dais_pcm.c 协调 PCM。适合多控制器/多 lane 同步,但要求 rate、buffer、trigger 和 pointer 一致。

8. SAI

rockchip_sai.c 声明高 channel 能力(Kconfig 最多 128 channel),属于独立 SAI IP;本树 RK3588 DTS 没有 SAI 控制器实例,因此不应归入 RK3588 音频 IP。

9. 调试

1
2
3
4
5
arecord --dump-hw-params -D hw:0,0
iecset -c 0
cat /proc/asound/pcm
cat /sys/kernel/debug/clk/clk_summary
cat /proc/interrupts

PDM 无数据优先查 clock/pinctrl/DMIC 供电;S/PDIF RX 优先查输入锁定和 recovered clock。

HDMI/DP 音频与 DRM 协同

HDMI/DP 音频与 DRM 协同

1. 跨子系统

HDMI/DP 音频不是 sound/ 单目录闭环:

1
2
3
4
5
6
7
ALSA PCM
-> ASoC machine/link
-> Rockchip I2S/SPDIF CPU DAI
-> hdmi-codec component
-> DRM HDMI/DP audio callbacks
-> display controller/bridge/PHY
-> sink

显示驱动负责 hotplug、EDID/ELD 和链路状态;音频驱动负责 PCM/DAI。

2. 相关代码

  • soc/codecs/hdmi-codec.c:通用 HDMI codec;
  • soc/rockchip/rockchip_hdmi.c:Rockchip HDMI machine;
  • core/pcm_drm_eld.c:ELD 辅助;
  • DRM 侧 HDMI/DP controller/bridge。

rockchip_hdmi_dp.crockchip_cdndp.c 等文件没有进入本分支 sound/soc/rockchip/Makefile,不属于 RK3588 可构建的活跃路径。

3. ELD

ELD 从 sink EDID 音频能力生成,包含:

  • supported rates;
  • channels;
  • coding types;
  • speaker allocation;
  • monitor identity。

ALSA hw constraints 应与当前 sink 能力求交。热插拔后能力可变化。

4. hw_params

HDMI codec 配置:

  • sample rate;
  • sample width;
  • channels;
  • IEC channel allocation;
  • audio infoframe;
  • N/CTS 或等效时钟参数。

同时 CPU DAI 必须产生匹配 I2S/SPDIF 数据。

5. Hotplug

拔线或 mode set 期间可能:

  • jack 状态变化;
  • ELD invalid;
  • PCM disconnect/stop;
  • 音频静音;
  • 重新配置 display clock。

应用应处理设备暂时不可用,不能假设 card number 与 sink 能力永久固定。

6. DP

DP 音频通过 SDP 等机制承载,依赖 DP link training 与 DRM connector。驱动文件存在不代表当前 RK3588 板级 DP controller/bridge 已启用。

本树常见 RK3588 连接是:

1
2
DP0: rockchip,hdmi machine -> spdif_tx2 -> dp0 codec DAI
DP1: rockchip,hdmi machine -> spdif_tx5 -> dp1 codec DAI

板级 DTS 常配置 mclk-fs = <512>。HDMI0/1 通常改走 I2S5/I2S6,并常见 mclk-fs = <128>;这些数值是本树板级配置,不是所有 HDMI/DP 硬件的通用常量。

7. eARC

ARC/eARC 是电视回传音频,与普通 SoC 向显示器发送 HDMI playback 不同。是否支持取决于 HDMI controller、PHY、codec/machine 和 DTS;不能由 rockchip_hdmi.c 单独推断。

8. 常见故障

现象 定位
无 HDMI card ASoC machine、hdmi-codec、DRM component
card 有但无声 sink ELD、mixer、I2S route、infoframe
只支持 2ch ELD 或 machine constraints
插拔后失败 DRM hotplug、ELD 更新、应用重开
切分辨率断音 mode set/clock 重配
多 HDMI 口选错 connector 与 dai_link 映射

9. 观测

1
2
3
4
5
6
cat /proc/asound/cards
aplay -L
cat /proc/asound/card*/eld*
cat /sys/class/drm/card*-*/status
cat /sys/class/drm/card*-*/edid > /tmp/edid.bin
dmesg | grep -Ei 'hdmi|displayport|eld|asoc|audio'

ALSA Control、MIDI、Compress 与其它接口

ALSA Control、MIDI、Compress 与其它接口

1. ALSA Core 范围

sound/core/Makefile 构建基础 snd,并按 Kconfig 加入 PCM、timer、rawmidi、sequencer、hwdep、compress 等模块。

2. Minor 与 file operations

core/sound.c 管理 ALSA minor:

  • control;
  • PCM playback/capture;
  • timer;
  • sequencer;
  • hwdep;
  • rawmidi。

snd_register_device() 注册具体 fops;snd_open() 按 minor 转交。card disconnect 后已有 fd 必须安全失败并等待引用释放。

3. Control

control.c

  • kcontrol add/remove/replace;
  • element info/read/write;
  • event subscription;
  • TLV;
  • power state;
  • compat ioctl。

control 节点也是枚举声卡与读取 card info 的主要接口。

4. Timer

timer.c 提供 ALSA timer,可由系统 timer、PCM period 或硬件 timer 驱动。sequencer 和应用可订阅。它不同于音频 DMA 本身。

5. RawMIDI

rawmidi.c 提供 MIDI byte stream:

  • input/output substream;
  • ring buffer;
  • trigger/drain;
  • poll;
  • timestamp/params。

USB MIDI 在 sound/usb/midi.c,SoC 产品未必使用。

6. Sequencer

core/seq/ 提供事件化 MIDI:

  • client/port;
  • queue/timer;
  • routing/subscription;
  • kernel/user clients;
  • synth integration。

其复杂度和攻击面明显高于 RawMIDI,嵌入式不需要时可关闭 Kconfig。

7. HWDEP

hwdep.c 为硬件专有 ioctl/read/write/mmap 提供通道。ABI 由具体驱动定义,不应作为通用 PCM API。

8. Compress offload

compress_offload.c 对压缩音频 DSP/offload 提供:

  • codec capability;
  • set_params;
  • trigger;
  • timestamp/pointer;
  • drain/partial drain;
  • metadata。

ASoC 桥接在 soc-compress.c。普通 RK3588 I2S PCM 与视频 MPP 编解码不因此自动成为 compress offload。

9. OSS compatibility

core/oss/ 和顶层 sound_core.c 保留 OSS/兼容设备号支持。新应用应使用 ALSA。裁剪系统可关闭 OSSEMUL,减少代码和 legacy ABI。

10. 其它驱动族

目录 作用
usb/ USB Audio Class、MIDI、quirks
hda/ HD Audio core
pci/ PCI 声卡
firewire/ FireWire audio
virtio/xen/ 虚拟音频
soc/ 嵌入式 ASoC
synth/ 软件/硬件 synth

这些都属于源码树,但 RK3588 产品是否启用由 .config 和硬件决定。

11. 生命周期

1
2
3
4
5
6
7
snd_card_new()
-> create control/PCM/etc
-> snd_card_register()
-> userspace opens fds
-> snd_card_disconnect()
-> wake/block new opens
-> snd_card_free_when_closed()

热拔插驱动应先 disconnect,再释放硬件,最后等待 fd 引用。

RK3588 音频设备树、调试与性能调优

RK3588 音频设备树、调试与性能调优

1. 先确认真实拓扑

源码中存在某驱动不等于板级启用。以运行 DTS 和 /proc/device-tree 为准:

1
2
3
4
5
6
machine sound node
├─ CPU sound-dai -> i2s/pdm/spdif
├─ codec sound-dai -> external/internal/hdmi codec
├─ format/master
├─ routing/widgets
└─ clocks/pinctrl/jack/amp

2. RK3588 SoC 节点

rk3588s.dtsi 包含多组:

  • I2S/TDM;
  • legacy I2S;
  • PDM;
  • S/PDIF TX/RX;
  • VAD;
  • digital codec。

多数默认 disabled,由板级 DTS 选择,避免引脚和时钟冲突。

本树 rockchip_linux_defconfig 已启用 I2S/TDM、PDM、SPDIF/SPDIFRX、HDMI machine 等,但没有显式启用旧 SND_SOC_ROCKCHIP_I2S 和 VAD。因此使用 RK3588 的 I2S2/I2S3 旧 IP 或 VAD 时,必须检查最终 .config,不能只看 DTS 节点。

3. DTS 核对清单

  • status = "okay"
  • compatible 与驱动 match;
  • clocksclock-names
  • assigned clock parent/rate;
  • resets;
  • DMA phandle/name;
  • pinctrl;
  • power domain;
  • CPU/codec sound-dai
  • dai-format
  • bitclock/frame master;
  • TDM slots/masks;
  • audio-routing;
  • GPIO amp/mute/jack;
  • codec I2C address/regulator/MCLK。

4. 启动检查

1
2
3
4
5
6
zcat /proc/config.gz | grep -E 'CONFIG_SND|ROCKCHIP'
dmesg | grep -Ei 'snd|asoc|audio|i2s|pdm|spdif|codec|defer'
cat /proc/asound/cards
cat /proc/asound/pcm
aplay -l
arecord -l

若 card 不出现,先查 probe/bind;若 card 出现但无声,再查 params、route、clock 和物理信号。

5. 分层测试

  1. aplay -l 确认设备;
  2. --dump-hw-params 确认能力;
  3. hw:C,D 排除插件;
  4. 固定 48 kHz/S16_LE/2ch;
  5. 观察 BCLK/LRCK/data;
  6. 检查 DMA IRQ;
  7. 再启用 PipeWire/PulseAudio/GStreamer。

6. XRUN

1
2
3
cat /proc/asound/card0/pcm0p/sub0/status
cat /proc/interrupts
top -H

调优顺序:

  • 增大 period/buffer;
  • 查 realtime throttling;
  • 查 IRQ/CPU affinity;
  • 查 cpufreq/idle;
  • 查 DMA contention;
  • 查 clock drift/ASRC;
  • 查应用是否及时供数。

不要先通过无限增大 buffer 掩盖驱动 pointer/IRQ 错误。

7. 低延迟

  • 使用 hw:
  • 选硬件原生 rate/format;
  • 2~4 periods 起步;
  • realtime thread + memory lock;
  • 避免运行时频繁 clock/power切换;
  • 将音频 IRQ 和应用线程放到负载稳定 CPU;
  • 验证 thermal throttling。

低延迟与低功耗相冲突,应以 XRUN 和端到端测量决定。

8. 多媒体边界

RKMPP/VPU 处理压缩视频/图像,不负责 ALSA PCM 调度。容器中的 AAC/Opus 等通常由用户态/其他解码器解码后送 ALSA;只有显式 compress/DSP offload 才绕开普通 PCM。

9. HDMI

  • DRM connector 必须 connected;
  • ELD 必须有效;
  • mode set 后重新验证;
  • sink 只报 2ch 时不能强制多声道;
  • 多 HDMI/DP connector 要确认 card/device 映射。

10. PDM/VAD

  • 检查 DMIC clock 和 pinctrl;
  • 验证 channel mapping;
  • 关闭 AGC/HPF 做基线;
  • VAD 阈值需在真实噪声环境标定;
  • suspend wake 要验证 wakeup-source 和电源域。

11. 动态调试

1
2
3
mount -t debugfs none /sys/kernel/debug
echo 'file sound/soc/* +p' > /sys/kernel/debug/dynamic_debug/control
echo 'file sound/soc/rockchip/* +p' > /sys/kernel/debug/dynamic_debug/control

量产环境谨慎开启,日志会改变实时性。

12. 结论

RK3588 音频问题应按“card 绑定 → hw_params → clock/pin → DMA/IRQ → route/codec → 用户态”逐层定位。只看 aplay 错误或只改 mixer,通常无法定位跨 ASoC、clock、DMA、DRM 的问题。