简介:面向高通平台音频开发初学者与驱动调试工程师的入门手册,聚焦Audio软硬件系统框架与Bringup全流程,帮助读者建立从硬件组件到HAL层的整体认知,解决上手阶段不知从何查起、各层配置如何衔接的问题。资源包共1个docx文档,约2.61MB,以图文混排形式组织章节,便于按模块顺序阅读与对照调试。内容涵盖CODEC功能、SLIMbus、PIL、GPIO等硬件要点,以及PIL加载、声卡注册、上电时序与复位、软硬件匹配、GPIO配置、外部芯片集成、audio通路配置等Bringup检查项,并延伸至kernel层Device tree、系统层音频属性列表与HAL层Device table的配置说明。已有2972人学习,适合作为排查音频链路问题的速查参考与入门学习材料。
1. 高通平台 audio 入门:一份 2017 年的 bringup 手册为什么现在还能翻
手里拿到一份高通平台 audio 入门手册,V1.0,2017 年 7 月定稿,目录从软硬件框架一路铺到 ACDB 校准、QXDM 抓 log、寄存器读写,最后还附了 msm8909 和 msm8996 两个平台的问题集。很多人第一反应是「太老了,msm8974 的代码路径现在谁还看」。但真正做过高通 audio bringup 的人会告诉你,这套排查顺序——PIL 有没有加载、SLIMbus 起没起来、声卡注册没有、codec 上电时序对不对——放到今天任何一个带 WCD 系列 codec 的板子上,依然是同一套骨架。变的只是总线从 SLIMbus 换成了 SoundWire,DTS 节点名字换了,mixer path 从 xml 挪到了别的配置形式,底层那套「FE/BE DAI + AFE/ADM/ASM」的模型没动。
这份手册的价值不在于它教你某个具体寄存器地址,而在于它把「从零到能出声」拆成了一条可执行的检查链,并且每个环节都给了对应的调试手段:怎么 dump SLIMbus 从设备寄存器、怎么读 WCD9335/934x 的 codec 寄存器、怎么用 QXDM 对 audio path 的 log code。对刚接手一个高通音频板子、声卡死活注册不上、或者 speaker 没声但耳机正常的工程师来说,这份东西能直接当排查清单用。适合谁:做高通平台 BSP/audio 驱动、需要独立完成 audio bringup、或者被「mic 无输入」「speaker 无输出」这类问题卡住的从业者。下面按手册的实际结构,把能抄作业的部分拆开讲。
2. 软硬件框架与代码地图:先搞清楚声音从哪走到哪
2.1 硬件链路:CODEC、SLIMbus 与差分输出
高通平台的音频硬件链路,核心是 AP 侧通过一条低速控制总线去配置 codec,再通过数字音频接口传 PCM 数据。手册里把硬件部分拆成 HW 框架和 CODEC 功能两块,实际 bringup 时你真正要盯的是三样东西:codec 本身(WCD 系列)、连接 AP 和 codec 的总线(老平台 SLIMbus,新平台 SoundWire)、以及 codec 到外部功放/喇叭的模拟通路。
手册里专门花篇幅讲了单端输出和差分输出的区别,这不是凑字数。Speaker 一般走差分输出,mic 走单端输入。差分输出的两个端子各有自己的基准,共模噪声在接收端被抵消,所以电压差变化小、抗干扰强;单端输出以共同地线为基准,受干扰时一线变化而 GND 不变,压差变化大。这个知识点在排查「speaker 有底噪」「mic 录进来全是啸叫」时非常关键——很多底噪问题不是 codec 配置错,是模拟走线把差分当单端用了,或者磁珠选型不对。手册后面 msm8909 问题集里就有一条「WCD9326 磁珠问题导致声卡注册失败」,磁珠这种无源器件能把声卡注册搞挂,说明硬件链路和软件枚举是强耦合的,别一上来就怀疑驱动。
2.2 软件分层与代码位置:用户空间、kernel、HAL 各管什么
软件架构按手册的划分是驱动层、内核层、系统层、HAL 层。落到代码位置,这份手册给了一张很实用的地图,我按现在还能对上的路径整理成表:
| 层次 | 典型路径 | 作用 |
|---|---|---|
| 用户空间 HAL | hardware/qcom/audio/hal/ | audio 硬件抽象层,mixer path、device table 都在这 |
| tinyalsa 工具 | external/tinyalsa/ | tinymix、tinyplay、tinycap,调试必备 |
| AudioFlinger | frameworks/av/services/audioflinger/ | 用户空间音频流管理 |
| 内核 machine driver | kernel/sound/soc/msm/ | msm8***.c,把 FE/BE DAI 串起来 |
| 内核平台驱动 | kernel/sound/soc/msm/qdsp6v2/ | FE/BE DAI、AFE/ADM/ASM、voice 驱动 |
| 总线驱动 | kernel/drivers/slimbus/ | SLIMbus 控制器与从设备 |
| 设备树 | kernel/arch/arm/boot/dts/ | msm8***-*.dts / dtsi |
| codec 驱动 | kernel/sound/soc/codecs/ | wcd9320.c、wcd9xxx-mbhc.c 等 |
这张表的意义在于:出问题时你能快速判断该去哪一层找。声卡没注册,先看 dts 和 codec 驱动 probe;注册了但没声,看 HAL 的 mixer path 和 FE/BE 路由;有声音但通路不对,用 tinymix 逐项查。手册里还提到 ACDB 相关代码在 vendor/qcom/proprietary/mm-audio/,这是校准数据库,音质、增益、降噪的参数都从这里下发,后面第 4 章会专门讲。
提示:路径里的 msm8974、msm8*** 是手册成文时的平台代号,换平台后目录结构大体一致,但具体文件名会变,别照抄文件名,照抄分层思路。
3. Audio bringup 实操:从 PIL 到 mixer path 的检查链
3.1 八步检查链:每一步失败长什么样
手册把 bringup 流程拆成 8 个检查点,这个顺序不是随便排的,是从「固件加载」到「通路配置」的依赖顺序,前一步没过,后一步基本不用看。我按实操习惯重新组织一下,并补上每步失败时的典型现象:
- PIL 是否成功加载。Peripheral Image Loader 负责把外设固件(包括 ADSP)加载进内存。PIL 失败,ADSP 起不来,后面所有 audio 相关的东西都是空中楼阁。现象:dmesg 里一堆 adsp 相关的 timeout,声卡根本不出现。
- SLIMbus 是否 UP。总线没起来,codec 枚举不到。现象:slimbus 控制器 probe 成功但从设备列表为空。
- 声卡是否注册。看
/proc/asound/cards有没有对应 card。没有就是 machine driver 或 codec probe 失败。 - codec 上电时序与复位。供电、reset gpio、时钟顺序错一个,codec 内部状态机就不对。现象:寄存器能读但值全是 0 或全 F。
- 软硬件是否匹配。固件版本、codec 型号、板级配置要对得上。
- GPIO 配置。使能脚、复位脚、功放使能脚,方向和张态错一个就静音。
- 集成外部芯片模块。外挂 DSP、功放、模拟开关,I2C/GPIO 控制要通。
- 配置 audio 通路。前面都通了,最后才是 mixer path 把 FE 和 BE 连起来。
这条链的血泪经验是:不要跳步。我见过有人声卡没注册就去改 mixer path xml,改了两天发现是 dts 里 codec 的 reg 地址写错。也见过 SLIMbus 没 UP 就去查 codec 寄存器,读出来全是 0 还以为是 codec 坏了。
3.2 kernel 层:device tree 里 audio 节点怎么写
kernel 层 bringup 的核心是 device tree。手册 2.2.1 节讲 dts,虽然没贴完整节点,但结合高通平台常见写法,一个 codec 挂 SLIMbus 的节点大致长这样:
&slimbus { status = "okay"; wcd_codec: wcd9xxx-codec@1 { compatible = "qcom,wcd9xxx-codec"; reg = <0x1>; /* SLIMbus 从设备地址,必须和硬件 strapping 一致 */ qcom,cdc-rst-gpio = <&tlmm 64 0>; /* 复位脚,极性按硬件定 */ qcom,cdc-micbias-cfilt-mv = <2700>; qcom,cdc-vdd-buck-supply = <&pm8994_s4>; qcom,cdc-vdd-rxtx-supply = <&pm8994_s4>; qcom,cdc-vdd-io-supply = <&pm8994_s4>; qcom,cdc-vdd-mic-bias-supply = <&pm8994_l19>; qcom,cdc-mclk-clk-rate = <9600000>; qcom,cdc-static-supplies = "cdc-vdd-buck", "cdc-vdd-io"; qcom,cdc-dmic-sample-rate = <4800000>; }; };这段的关键参数:reg是 SLIMbus 从设备地址,硬件上靠地址引脚 strapping 决定,写错就枚举不到;qcom,cdc-rst-gpio的极性和时序必须和 codec datasheet 对;几路 supply 对应 codec 内部不同电源域,少一路可能表现为部分功能正常部分功能异常(比如 playback 正常 record 不行)。改完 dts 重新编译 dtb,fastboot flash dtbo或对应分区,重启后先看dmesg | grep -i wcd有没有 probe 成功。
3.3 系统层与 HAL 层:属性、device table 与 mixer path
系统层手册列了 audio 相关的系统属性列表,这类属性在system.prop或vendor.prop里,常见的有采样率、deep buffer 开关、voice 相关配置。改属性最直接的验证是getprop | grep audio看生效值,注意有些属性是开机时读一次,改完必须重启,别指望setprop立刻生效。
HAL 层两块:device table 和 mixer path。device table 定义系统里有哪些音频设备(speaker、headphone、mic、bt 等),每个设备对应哪个 backend、走哪条通路。mixer path 则是把上层的一个 use case(比如「播放音乐到 speaker」)翻译成一串 kcontrol 设置。手册 2.5 节给了 mixer path xml 的定义方式,2.5.2 节讲用 ADB 调试 route。实操上,改完 mixer path 最有效的验证手段是:
# 看当前所有 mixer 控件 tinymix # 手动把某个控件设成目标值,验证通路是否通 tinymix "RX1 MIX1 INP1" "RX1" tinymix "RX1 Digital Volume" 84 # 直接播一个 wav 验证 tinyplay /data/test.wav -D 0 -d 0tinymix不带参数列出所有控件和当前值,这是排查 route 问题的黑匣子。如果tinyplay能出声但上层应用没声,问题在 HAL 的 mixer path 或 device table;如果tinyplay也没声,问题在 kernel 层或更下面。这个二分法能省掉大量时间。
注意:
tinyplay的-D是 card 号,-d是 device 号,先用cat /proc/asound/cards和cat /proc/asound/pcm确认,别硬编码。
4. 避坑与排查:那些让 bringup 卡三天的常见问题
4.1 声卡注册失败:先查磁珠和 BusID
手册 msm8909 问题集里两条很典型。第一条:WCD9326 磁珠问题导致声卡注册失败。现象是 codec 完全枚举不到,dmesg 里 SLIMbus 从设备列表为空。原因不是驱动,是供电回路的磁珠选型或焊接问题,导致 codec 上电异常。解决:量 codec 各路供电,对照 datasheet 确认磁珠的额定电流和直流电阻,换料或补焊。这条提醒我们,声卡注册失败先排除硬件供电,别一头扎进 dts。
第二条:WSA8815 BusID 问题导致声卡注册失败。WSA881x 是智能功放,挂 SLIMbus 时 BusID 靠硬件配置,配错就枚举不到。现象是主 codec 正常但功放设备缺失。解决:核对原理图上 BusID 的 strapping 电阻,和 dts 里的 reg 对齐。
4.2 speaker 无输出:xml 改了没生效
msm8996 问题集里有一条「speaker 无输出(xml 修改无效)」。现象很迷惑:改了 mixer path xml,重新编译刷机,speaker 还是没声。原因通常是改的 xml 没被真正打包进镜像,或者 HAL 加载的是另一份配置(不同 target 对应不同 xml),也可能是 route 被上层策略覆盖。解决:先确认镜像里实际生效的 xml 路径和内容(解包 vendor 分区看),再用tinymix手动设 route 验证硬件通路本身是通的,最后才回头查 HAL 的加载逻辑。这个「先手动验证硬件、再查软件配置」的顺序,能避免在配置层反复空转。
4.3 mic 无输入:偏置和通路两头查
mic 无输入的排查要分两头:一头是 micbias 有没有供上,另一头是 capture 通路有没有配通。现象是录音全是静音或极低电平。原因可能是 micbias 电压没配、micbias 对应的 cfilt 电容没焊、ADC 输入 mux 选错、或者 capture 的 FE/BE 没连。解决:先用tinymix查 micbias 相关控件值,再用tinycap直接抓一段看波形,配合寄存器 dump 确认 ADC 是否在采。手册第 5 章给了读 SLIMbus 从设备和 WCD codec 寄存器的方法,寄存器级确认是最后一道防线。
4.4 寄存器读写:别在错误的总线状态上读
手册 3.1 节列了一堆寄存器读写方法:SLIMbus slave dump、SLIMbus slave 读写、WCD codec 读写、SoundWire slave/master dump 和读写、WSA881x 读写。这些命令的前提是总线已经 UP、设备已经枚举。常见翻车是总线没起来就去读,读回全 0 或全 F,然后误判 codec 坏了。正确顺序永远是:先确认总线状态,再 dump 设备列表,最后才读写具体寄存器。另外写寄存器前一定先读回原值备份,codec 有些寄存器写错会导致上电时序异常,得重新上下电才能恢复。
4.5 log 抓不全:QXDM 和 kernel log 各管一段
手册第 6 章和第 11 章讲 log:kernel debug、framework debug、system debug、QXDM 里开 audio/voice log code。常见问题是只看 kernel log 就下结论,但很多 route 和策略问题发生在 HAL 或 AudioFlinger 层,kernel 里干干净净。反过来只看上层 log,又看不到 codec 寄存器和总线状态。实操习惯是三层一起抓:dmesg看驱动和总线,logcat看 HAL 和 framework,QXDM 看 ADSP 和 modem 侧的 voice 通路。手册 10 章给了 QXDM 代码对照表,audio path 和 voice Tx/Rx path 的 log code 分开,抓 voice 问题时要确认抓的是 mDSP 那条路径。
5. ACDB 校准与进阶验证:让声音从「能响」到「能听」
bringup 做到能出声只是及格线,音质、增益、降噪这些要靠 ACDB(Audio Calibration Database)。手册第 4 章讲 ACDB 校准,核心动作是 adding a device:创建 ACDB device ID 和对应的 calibration data。每个音频设备(每种 speaker、每种 mic、每种耳机)在 ACDB 里都有独立 ID,校准数据按 ID 存。新增一个设备时,先在 ACDB 工具里建 ID,再把增益、滤波、降噪参数挂上去,最后确保 HAL 和 kernel 侧引用的 device ID 一致。ID 对不上,表现就是「通路通了但声音不对」——音量偏小、频响怪、或者降噪没生效。
验证校准是否生效,我一般走三步。第一步,用tinymix把数字增益设到固定值,tinyplay播一段扫频或粉噪,录音回采看频响是否平坦。第二步,对比校准前后同一段的电平差异,确认 ACDB 参数确实下发了。第三步,切不同设备(speaker/headphone)确认各自 ID 对应的参数独立生效。手册里 msm8909 和 msm8996 的问题集虽然老,但「xml 修改无效」这类问题的排查思路,放到 ACDB 上同样适用:先确认配置真的进了镜像,再确认运行时真的加载了。
寄存器级验证是最后的手段。手册 3.1.10 节讲 WCD9335/934x codec 寄存器读写,3.1.5 到 3.1.8 讲 SoundWire slave/master 的 dump 和读写。这些命令在确认「codec 内部某个模块到底有没有被配起来」时无可替代。比如怀疑某个 ADC 没开,直接读对应使能寄存器,比猜 mixer path 快得多。但记住前面说的:读之前确认总线 UP、设备枚举,写完备份原值。
| 验证层次 | 手段 | 能确认什么 |
|---|---|---|
| 应用层 | 播放/录音 App | 端到端是否可用 |
| HAL 层 | logcat + mixer path 检查 | route 和 device table 是否正确 |
| 内核层 | dmesg + /proc/asound | 声卡、PCM、DAI 状态 |
| 寄存器层 | SLIMbus/SoundWire/codec 读写 | 硬件模块实际配置值 |
| 校准层 | ACDB 参数对比 + 频响回采 | 音质参数是否生效 |
从那以后我每次接手一块新板子的 audio bringup,都强制按「PIL → 总线 → 声卡 → 上电时序 → GPIO → 通路 → 校准」这个顺序走一遍,哪怕看起来某一步肯定没问题,也要用命令确认一次,因为翻车最多的就是「我以为它起来了」。这份手册的目录本身就是一张排查地图,建议把它当 checklist 用,而不是当教材从头读到尾。希望帮到你。
本文还有配套的精品资源,点击获取