☰
RK3399平台ES7210+ES8156声卡移植与调试全记录
2026/10/5 4:19:12 网站建设 项目流程

接手这块板子的时候,项目需求听起来很简单:RK3399 Android 平台上要多挂一套声卡,ES7210 做录音,ES8156 做播放,系统起来之后录音、播放能正常跑通。但真做起来才发现,这活儿从内核驱动、设备树、machine driver,一路牵扯到 Android 的 HAL 层和 mixer 路由配置。这篇文章把这次 ES7210+ES8156 声卡移植与测试的完整过程、关键细节和踩坑记录整理出来,给正在搞 RK3399 或类似瑞芯微平台的 BSP、音频驱动工程师做个参考。

这套方案在智能会议终端、远场语音交互设备里很常见,ES7210 是一颗四通道 ADC,专门用来接麦克风阵列做远场拾音,ES8156 是一颗立体声 DAC,负责播放提示音和本地音频。两者分开部署,比传统单颗 codec 在麦克风通道数、增益调节、底噪控制上灵活得多。整个调试链路从内核启动时的 I2C 探测,到 tinyplay/tinycap 底层录音放音,再到 Android 上层 App 调用,任一层出问题都会导致功能异常。下面按我的实际操作顺序来复盘。

1. 方案背景与整体架构拆解

1.1 ES7210 和 ES8156 这两颗芯片分别负责什么

ES7210 是 Everest Semiconductor 的四通道音频 ADC,支持 I2S/TDM 输出,采样率覆盖 8kHz 到 192kHz,信噪比标称能做到 102dB 左右。它常见于四麦克风阵列的采集场景,比如会议麦克风、智能音箱的远场语音模块。四路模拟输入可以接四颗 MEMS 麦克风或模拟麦克风,通过 TDM 模式把四个通道的数据依次送出。控制接口是 I2C,芯片的采样率、通道映射、PGA 增益、MIC bias 都可以通过寄存器配置。

ES8156 则是同厂的立体声 DAC,支持 I2S/TDM 输入,内部带耳机放大器或线路输出,比较适合做设备播放端的音频输出。控制接口同样是 I2C,ACL/DRC、动态范围控制、EQ 这类音效功能也都有,只是实际嵌入式项目里大部分时候只用它的基础 DAC 通路。ES8156 的模拟输出可以直接接喇叭功放,或者接耳机接口。

这套组合和常见的单颗音频 codec 最大的区别是:采集和回放在物理上是两颗独立芯片,各管一摊,互不占用资源。如果你用 ES8316 或 WM8960 这类二合一 codec,通常只有两路麦克风输入,想做成四麦阵列就得外挂模拟开关或专用 ADC,电路和驱动都会更绕。ES7210 + ES8156 则直接把采集通道拉到四路,且 ADC 的底噪、串扰指标比普通 codec 内置 ADC 更好,回放部分也独立,非常适合理清“拾音归拾音、播放归播放”的产品形态。

1.2 为什么选择 RK3399 平台做这套声卡方案

RK3399 在智能设备里的存量很大,双路 A72 加四路 A53 的性能对于 Android 系统和音频处理算法绰绰有余。它的 I2S 接口资源也比较丰富,I2S0 支持多声道 TDM 模式,可以同时承载播放和录音两条数据流,正好匹配 ES7210 四路采集加 ES8156 立体声回放的需求。

另一个原因是 Android 系统对音频设备的抽象层已经非常成熟,只要底层 ALSA 驱动把声卡节点注册好,HAL 层就能自动探测到新的 ALSA 设备,再通过 mixer 控件和路径配置文件把路由关系理顺。相比 Linux 桌面端,Android 上做声卡移植的最大工作量反而不在内核驱动本身,而是要让音频策略文件、混音路由和声卡节点对齐,这一步很多人容易忽略。

1.3 这套方案要用到哪些软件层次

从系统架构来看,声卡设备真正跑起来涉及四个层面:

  • 内核层:ES7210、ES8156 两个 codec 驱动,RK3399 I2S 控制器驱动,以及一个把它们绑定在一起的 machine driver。
  • 设备树层:I2C 地址、I2S 引脚、时钟频率、codec 之间的连接关系、DAPM 路由都在这里。
  • ALSA 用户空间层:/proc/asound 下的声卡节点、tinymix 看到的 kcontrol 控件、tinyplay/tinycap 这些测试工具。
  • Android 音频 HAL 层:audio_policy_configuration.xml 里的输入输出设备定义、audio_platform_info.xml 的声卡映射、mixer_paths.xml 的通路和音量化配置。

任何一个层面差异都会导致功能异常。比如内核驱动起来了,但 Android 不认识这张卡,App 打开录音还会直接报错;或者 HAL 认识声卡了,但 mixer_paths 里没把 ADC PGA 打开,录出来的全是静音。所以整个移植过程不能只盯着内核代码,每一层都要验证。

2. 硬件连接与设备树配置实操

2.1 引脚和信号链路的连接要点

先理清硬件上的连接关系,这是后续所有调试的基础。常规接法是这样的:

ES7210 的 I2C 接 RK3399 某个 I2C 控制器(例如 I2C4),四路模拟输入 MIC1~MIC4 接麦克风阵列。数字音频接口 DOUT 接 RK3399 I2S0 的 RXD 引脚,因为采集方向是芯片输出、SoC 接收;BCLK 和 LRCK 则由 RK3399 I2S0 提供,ES7210 工作在从机模式。除此之外,ES7210 还需要一路 MCLK 主时钟,一般从 RK3399 的 codec 时钟或外部晶振获取。

ES8156 的 I2C 控制线可以和 ES7210 挂在同一条 I2C 总线上,只要地址不冲突就行。数字音频接口 DIN 接 RK3399 I2S0 的 TXD 引脚,同样由 RK3399 提供 BCLK 和 LRCK。模拟输出接功放或耳机。reset 引脚通常由 GPIO 控制,驱动 probe 的时候拉一下,让芯片复位到默认状态。

两路 codec 共用同一组 I2S0 时钟,但数据方向不同,播放走 TXD,录音走 RXD,互不干扰。这里有个很容易踩的坑:如果 ES7210 和 ES8156 接到的是不同的 I2S 控制器,注意下面的坑:如果 ES7210 和 ES8156 接到的是不同的 I2S 控制器,那么两边的 BCLK/LRCK 会由不同的时钟域产生,录音和播放同时进行时容易出现时钟不同步的问题。对于 AEC 回声消除这类需要参考信号的应用,这是致命的。所以尽量让两颗芯片挂在同一个 I2S 控制器的 TX 和 RX 上。

2.2 设备树节点和 codec 驱动加载

准备好硬件之后,就开始改设备树。以 Linux 4.4 或 4.19 内核为例,先在 I2C 节点下增加两颗 codec:

&i2c4 { status = "okay"; /* ADDR 引脚决定的 I2C 地址,实际以 datasheet 为准 */ es7210: es7210@40 { compatible = "everest,es7210"; reg = <0x40>; clocks = <&cru SCLK_I2S0_8CH>; clock-names = "mclk"; assigned-clocks = <&cru SCLK_I2S0_8CH>; assigned-clock-rates = <12288000>; pinctrl-names = "default"; }; es8156: es8156@48 { compatible = "everest,es8156"; reg = <0x48>; clocks = <&cru SCLK_I2S0_8CH>; clock-names = "mclk"; assigned-clocks = <&cru SCLK_I2S0_8CH>; assigned-clock-rates = <12288000>; }; };

这里的 compatible 字符串要和驱动里的 of_match_table 严格对应,ES7210 和 ES8156 两个驱动一般在内核里都注册成了标准 codec driver,probe 时读取 reg 得到 I2C 地址。时钟部分要根据硬件实际连接的 MCLK 频率来配,如果接了 24.576MHz 晶振就配 24576000,如果从 SoC 输出就配置对应的 clock-parent。

然后要把 I2S0 节点配置成开启状态,并确认引脚复用正确:

&i2s0 { status = "okay"; #sound-dai-cells = <0>; rockchip,clk-trcm = <1>; pinctrl-names = "default"; pinctrl-0 = <&i2s0_8ch_bus>; };

rockchip,clk-trcm = <1>这个属性很关键,它的作用是让 TX 和 RX 使用同一组时钟,不会出现录音一个时钟、播放一个时钟的错位问题。如果内核版本比较老,这个属性可能叫别的名字,需要看自己内核里的 I2S 控制器驱动支持哪些属性。

2.3 machine driver 如何把两个 codec 串成一张声卡

RK3399 要挂外部 codec,通常还需要一个 machine driver 来定义声卡及 dai_link。为什么不像有些 i.MX 平台那样直接用 simple-audio-card?因为 simple-audio-card 在单颗 codec 场景下好用,ES7210 和 ES8156 是两颗芯片,一个负责 capture、一个负责 playback,用 simple-audio-card 描述起来非常别扭。实践中更可控的方案是自己写一个 platform machine driver,或者在内核里找现成的对照模板,比如 rockchip 平台常见rk3399_es7210_es8156.c这类文件,里面核心要干三件事:

第一,定义声卡名称,比如 “RK_ES7210_ES8156”。这个名字会直接出现在 /proc/asound/cards 里,Android HAL 层的 audio_platform_info.xml 也靠它做声卡匹配。

第二,定义两个 snd_soc_dai_link,一个 playback 链路指向 i2s0 和 es8156,一个 capture 链路指向 i2s0 和 es7210,然后指定 init 函数和 ops,在 init 里设置好 codec 的 DAI 格式(I2S 还是 DSP/TDM 模式)。

第三,配置 DAPM 路由,把 codec 里的Mic Bias、ADC PGA、DAC这些 widget 和声卡层面的事件连接起来。这个不配的话,可能出现“播放有数据但没声音”“录音有电平但全是噪音”这种看似诡异的问题。DAPM 路由本质上是在控制音频链路的电源开关,链路没打通,信号就出不来。

整个 machine driver 写好后,注册成 platform_driver,这个声卡才算在内核里立住。

3. 编译烧录与声卡底层验证

3.1 内核配置和编译注意事项

改完代码之后,先把内核选项核对一遍。需要确认以下几个 config 都打开了:

  • I2S 控制器驱动,一般是 CONFIG_SND_SOC_ROCKCHIP_I2S。
  • ES7210 codec 驱动,一般是 CONFIG_SND_SOC_ES7210。
  • ES8156 codec 驱动,一般是 CONFIG_SND_SOC_ES8156。
  • machine driver,不同类型的平台名字不一样,常见的是 CONFIG_SND_SOC_ROCKCHIP_ES7210_ES8156。

如果用 menuconfig 勾选,位置在Device Drivers -> Sound card support -> Advanced Linux Sound Architecture -> ALSA for SoC audio support下面。编译时注意交叉编译工具链要和内核版本匹配,RK3399 一般是 aarch64 架构,编译命令类似make ARCH=arm64 rockchip_defconfig,然后再make ARCH=arm64 rk3399-xxx.img。

烧录时只需要替换 boot 分区里的 kernel image,不用重刷整个系统。不过有些方案把内核放在 resource 分区或单独 kernel 分区,具体看项目烧录脚本。烧完之后先不急着进 Android,开机后直接看串口或 adb shell 进到底层,先确认cat /proc/asound/cards能不能看到新声卡。

3.2 用 tinymix 检查 Audio 控件和路由通路

声卡节点出来之后,下一步就是看控件。执行tinymix不带参数,会列出这张声卡上所有 kcontrol。常见的控件包括 ES7210 的ADC PGA Gain、MIC Bias、ADC Mux,ES8156 的DAC Volume、DAC Mux等等。第一次执行时不要急着去改,先整体看一遍有哪些控件,心里有个底。

如果一个控件都没有,说明 codec 驱动的 probe 或 DAPM widget 注册有问题,优先查 dmesg。如果只有一半控件,可能是两个 codec 中有一个没正常上电或者 I2C 读取失败。

打开录音通路的基本操作是这样:用 tinymix 把对应声卡的 Capture Mux 切到线路输入,把该打开的 ADC PGA 设置成合适增益,再把 MIC Bias 打开,最后用tinymix "Capture Switch" 1确保不是静音状态。播放通路则要确认 DAC Mux 切到 I2S 输入,DAC Volume 不要是 0,所有涉及 muted 的开关都要打开。

为了方便后续测试,我通常会把常用的一组通路设置整理成一份 shell 脚本,每次重启后在 adb shell 里执行一遍,省得反复敲 tinymix 命令。

3.3 底层录音播放:tinyplay 和 tinycap 的正确用法

底层通路验证优先级很高,因为 Android 上层还没介入,这个时候出问题基本都能确定是内核、设备树或驱动的问题。先用 tinyplay 播放一个 wav 文件:

tinyplay /data/test.wav -D <card> -d <device>

-D指定声卡编号,比如-D 0表示 card0,-d指定设备编号,一般 PCM 播放设备是 0。如果执行后没有报错且喇叭能出声,说明播放链路从 I2S 到 DAC 到功放基本是通的。

录音再用 tinycap:

tinycap /data/test_rec.wav -D <card> -d <device> -c 4 -r 16000 -b 16 -T 5

这里-c 4表示录四个通道,和 ES7210 的四路输入对应,-r 16000是采样率,-T 5是录 5 秒。录完的文件用 adb pull 拉到电脑上,用 Audacity 或 Python 的 wave 模块直接看波形和频谱。

我第一次测这套设备时,tinycap 录出来的文件大小正常,但四个通道全是整齐的直流偏置,几乎没有有效信号。后来排查才发现是 MIC Bias 没开,模拟麦克风根本没有工作点,ADC 量化出来只有底噪和偏置。这类问题在底层用 tinymix 打开对应开关就能解决。

3.4 采样率、位深和 TDM 通道对齐

ES7210 是四通道 ADC,在 TDM 模式下会占用四个 slot。而 ES8156 是双声道 DAC,在 TDM 模式下默认占用两个 slot。如果两个 codec 挂在同一条 I2S 上,需要保证下行数据发送到 ES8156 的 slot 和上行数据从 ES7210 读取的 slot 都正确配置。I2S 模式是另一种情况,LRCK 高电平对应左声道,低电平对应右声道,ES7210 的通道 1 和 2 会分别映射到左右声道,通道 3、4 则要继续通过扩展的 TDM slot 输出。

实际操作中需要根据机器驱动里的snd_soc_dai_set_tdm_slot()配置来决定。比如让 ES8156 只接收 slot 0 和 1 的数据,让 ES7210 在 slot 0 到 3 上输出四个通道。如果 slot 没对齐,典型表现是播放左右声道声音一样但内容互换,或者录音时通道错位,1 通道声音录到了 3 通道上。

还有位深问题。ES7210 和 ES8156 都支持 16/24/32bit,Android 默认的路由配置经常是 16bit,但底层机器驱动设置的 DAI format 可能是 24bit 或 32bit,两边不匹配会出现音量异常、噪声、或者只有某几个通道有声音。建议底层调试阶段统一成 16bit,先把通路跑通再逐步加位深。

4. Android 层配置与上层功能验证

4.1 声卡映射与 audio_policy 配置

底层声卡通了之后,Android HAL 不一定自动认识它。Android 在启动时会扫描 /proc/asound/cards,并根据 HAL 库里的判断逻辑选择使用哪张声卡。大部分平台 HAL 会有固定的声卡优先策略,比如audio_platform_info.xml里强制指定了某个 scard index 或 card name 给 speaker、mic 等设备使用。

实际配置时,先在/vendor/etc/或/system/etc/下找到audio_platform_info.xml,把声卡名加进去,让 HAL 知道这张卡对应的是哪种输出/输入设备:

<audio_platform_info> <acdb_audio_device name="speaker" card_name="RK_ES7210_ES8156"/> </audio_platform_info>

如果平台 HAL 不是这种字符串匹配方式,还需要在代码层面指定声卡索引,那就得改 HAL 的源码。总之目标只有一个:让上层播放/录音调用到新增声卡的 PCM 设备,而不是拿这张卡当摆设。

audio_policy_configuration.xml里的模块配置也需要过一遍。通常 HAL 的音频模块名是固定的,比如primary、usb、a2dp,如果你把声卡挂在 primary 模块下,那么输出设备需要声明 mixPort、devicePort,确保路由引擎能把 AudioTrack 的流导向这张卡的 playback PCM 设备,录音也同理。

一个常见问题:声卡节点在 /proc/asound 里已经存在,但dumpsys audio里看不到对应输出设备,App 播放声音也没有实际输出。这种情况大概率是 policy 配置里没有把 HAL 模块的输出设备和该声卡关联起来,或者 mixer_paths.xml 里没有对应声卡的 route 配置,导致 HAL 打开 PCM 设备后没有设置必要的 kcontrol。

4.2 mixer_paths.xml 和路由配置

mixer_paths.xml是 Android 上音频路由最核心的配置文件。它定义了“在使用某个设备时,需要把哪些 kcontrol 设置成什么值”。以 speaker 设备为例,播放提示音时除了打开底层 PCM 流,还要把 DAC 音量调到合理值、把 DAC Mux 切到正确的输入源、解除静音,这些都可以在mixer_paths.xml的 path 里描述。

<path name="speaker">节里可以写多个<ctl name="XXX" value="YYY" />项,每一项对应一个 tinymix 控件。配置好之后,HAL 在打开输出设备时会自动按顺序设置这些控件,不需要 App 关心底层细节。

录音路径同理,比如path name="mic"里面要设置 ADC PGA Gain、MIC Bias、Capture Mux 等。这套配置的好坏直接影响用户体验,比如回声消除时要屏蔽某个麦克风、会议平板上要开启 AGC 还是关掉 AGC,都靠这里管理。注意修改 mixer_paths.xml 后要重启 audioserver,可以执行:

adb shell stop && adb shell start

或者直接重启系统,否则 HAL 仍然持有旧的路由配置。

4.3 App 层录音播放验证

底层和 HAL 都配置完之后,选一个自带的录音 App 或者简单写个小 Demo 来验证。Android 6.0 以上录音需要动态申请 RECORD_AUDIO 权限,如果直接跑第三方测试 App 没有弹权限授权框,很可能录出来的文件就是空的,这和声卡本身没有关系。

验证播放更简单,随便用系统音乐播放器或者adb shell settings put system播放一个音频文件,听声音是否正常、音量调节是否线性。

我这里有个经验:底层测试通过之后,优先用一个自己写的简单 APK,只做 AudioTrack 循环播放和 AudioRecord 采集,方便定位问题在哪个调用层面。拿一个功能完整的商业 App 来测,一旦没声音你可能分辨不清是权限问题、焦点问题、路由问题还是声卡本身问题。

4.4 录音/播放同时进行的特殊验证

这套 ES7210+ES8156 方案如果只做单边测试很容易掩盖问题。远场语音产品,比如会议音箱,经常要同时录音和播放——人说话,音箱放音乐,算法要实时获取参考信号做回声消除。这时候必须验证一个关键场景:播放音乐的同时启动录音,录到的文件里能否同时包含用户的声音和播放的音乐参考。

如果底层 I2S0 被配置成 TX 和 RX 使用不同时钟域,或者声卡驱动里没有做 clock 同步,播放和录制的采样率会漂移,录出来的文件听感会有回声消除后残留的机器人声。这时检查 dmesg 里有没有clk mismatch相关报错,确认设备树里rockchip,clk-trcm = <1>这个属性有没有真正生效。

我在实际项目中还遇到过一个比较隐蔽的问题:ES7210 的 MIC3、MIC4 在 TDM 模式下需要额外设置通道映射寄存器,否则虽然四个通道都有数据,但通道 3/4 数据其实是通道 1/2 的拷贝。排查方法就是分别对每路麦克风讲话,看录下来的四个通道波形,是否只有对应通道有明显信号。

5. 问题排查与调试技巧实录

5.1 声卡节点没出现 / I2C 探测失败

开机后cat /proc/asound/cards看不到新增声卡,是最常见的问题。第一步不要看驱动代码,先查dmesg | grep -i es7210和dmesg | grep -i es8156,看驱动有没有被 probe。

如果是 I2C 探测失败,一般会有类似es7210 4-0040: ASoC: failed to probe component的日志。这时候先用 i2cdetect 扫描 I2C 总线上有哪些设备:

i2cdetect -y 4

如果总线上扫不到 0x40 或 0x48 地址,说明硬件没接好,或者 codec 没有正常上电。优先量一下芯片电源和 reset 引脚是否处于正常状态。如果 i2cdetect 能扫到但驱动 probe 还是失败,再看设备树里 reg 是否写错,以及 codec 驱动里是否有等待外部时钟稳定这类时序要求。

有个容易忽略的细节:我遇到过代码树上同时存在两个版本的 ES7210 驱动,一个支持旧版寄存器映射,一个支持新版,默认编进内核的那个恰好和硬件版本不匹配,导致读寄存器全是错误值。所以别只信 dmesg 的 probe 成功日志,还要手动用 i2cget 读几个关键寄存器,对比 datasheet 确认寄存器映射正确。

5.2 播放没声音 / 声音异常

播放链路无声的排查顺序我一般是这样的:

  • 先确认 PCM 设备打开成功,tinyplay 不报错。
  • 再用 tinymix 看 DAC 相关控件,比如DAC Mute、DAC Volume,确保不是驱动默认静音。
  • 然后量 BCLK、LRCK、MCLK 三路时钟,确认 I2S 信号到达了 ES8156 引脚。
  • 如果时钟正常,量 ES8156 的模拟输出,看有没有波形。
  • 最后检查功放和喇叭接线。

有杂音则复杂一些。一种常见杂音是 I2S 位宽不匹配导致的沙沙声,比如驱动配置 32bit slots 而 ES8156 实际只认 24bit 有效数据。另一种是电源纹波耦合,ES8156 的 AVDD 如果直接用的 DC-DC,没有加足够的 LC 滤波,耳机或喇叭里会有明显底噪。还有一种情况是 MCLK 频率和采样率不呈整数倍关系,比如用 24.576MHz MCLK 跑 44.1kHz 采样率,时钟没法整除就会出现周期性爆音。

5.3 录音静音 / 声音小 / 通道错位

录音有问题,先区分是硬件还是软件。最简单的方法:拿信号发生器或手机播放一个 1kHz 正弦波,靠近麦克风,用 tinycap 录音,拉到电脑上看频谱和波形。

如果完全没波形,优先查 MIC Bias 和 ADC 是否开启。ES7210 的 MICBIAS 如果不打开,驻极体麦克风是没有任何输出的。如果波形存在但幅度极小,把 PGA 增益调大几档再看,同时注意不要调到接近饱和失真的位置。

通道错位是 TDM 配置问题的高发区。ES7210 四个通道对应哪些 slot,ES8156 播放数据对应哪些 slot,需要根据机器驱动或 codec 驱动里实际设置的参数去核对。如果驱动用的是默认 TDM slot 0-3,而 ES7210 硬件接线上第一个麦克风从第四通道进来,那录出来的人声就会跑到第三个或第四个通道上。

5.4 调试工具和排查套路总结

针对 RK3399 Android 音频调试,我习惯准备一套工具组合:

  • i2cdetect和i2cget:查 I2C 设备是否在线、寄存器值是否合理。
  • tinymix:查所有 kcontrol,手动设置控件来验证某段通路。
  • tinyplay和tinycap:绕过 HAL 直接操作 ALSA 设备,验证底层通路。
  • cat /proc/asound/cards和cat /proc/asound/pcm:看声卡注册情况和 PCM 设备列表。
  • dmesg:看内核驱动报错。
  • dumpsys media.audio_flinger:Android 层音频流和设备状态。
  • 示波器/逻辑分析仪:量 MCLK、BCLK、LRCK、I2S_DATA,是定位硬件问题最直接的手段。

调试顺序也有讲究:先底层后上层,先单端后同时。底层 tinyplay 能出声、tinycap 能录到清晰信号之后,再去改 Android HAL 配置,否则一旦上层有问题,你会上下两层来回猜。

还有一个习惯我强烈建议:每次改完设备树或驱动,先抓一份 dmesg 完整保存下来,改之前和改之后对比,很多问题就是靠这种对比日志快速定位的。尤其是涉及到 codec 驱动 probe 时序、时钟通知链、DAPM 上下电这些环节,光看含义模糊的报错根本猜不出是哪里出了问题。

几点个人体会

这次 RK3399 Android 平台增加 ES7210+ES8156 声卡的移植任务,从底层 I2C 探测、设备树修改、machine driver 编写,到 Android 层音频策略配置和 App 功能验证,整个流程走下来最大的感受是:这种多 codec 方案比单颗 codec 复杂一个量级,并不是“把自己驱动编进去就完事”,而是要保证从 codec 引脚到 Android 录音 App 的整条链路每个环节都对齐。底层工具和 dmesg 日志是最可靠的伙伴,遇到问题先在 ALSA 层验证,别急着改上层。

最后再分享一个小技巧:如果你要适配的平台上自制 machine driver 从零写比较费劲,先在内核里搜一下有没有现成的sound/soc/rockchip/rk3399_es7210_es8156.c或类似文件,很多 SDK 里已经带了这套模板,基于现成文件改 slot 配置、改引脚、改声卡名,比自己从 snd_soc_dai_link 开始写要稳得多。等整个链路跑通之后,回头再看这套方案的设计逻辑,就会明白为什么厂商要拿两颗独立芯片来做采集和回放了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询