尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

IMX6ULL WM8960 的移植——前置介绍

IMX6ULL WM8960 的移植——前置介绍 IMX6ULL WM8960 的移植——前置介绍这个仓库已经开源所有教程主线内核移植跑新版本imx-linux/uboot都在这里或者一起来尝试跑7.1的Linux欢迎各位大佬观摩喜欢的话点个⭐昨天刚更新仓库地址https://github.com/Awesome-Embedded-Learning-Studio/imx-forge静态网页https://awesome-embedded-learning-studio.github.io/imx-forge/前言WM8960 为什么也不自己写RTC、goodix 两章我们开了「分析型」的头主线驱动太成熟重写没意义不如拆开读懂。音频这章接着走这条路——而且理由更硬。WM8960 是 Wolfson现 Cirrus Logic的一颗立体声音频 codeci.MX6ULL ALPHA 板上用它做耳机/喇叭输出和麦克风输入。主线内核对它的支持是完整三层sound/soc/codecs/wm8960.c1591 行—— codec 驱动管 WM8960 的所有寄存器、音频通路、DAPMsound/soc/fsl/fsl_sai.c1900 行—— cpu_dai 驱动管 i.MX6ULL 这端的 SAI2 数字音频接口sound/soc/fsl/fsl-asoc-card.c1112 行—— machine 驱动把上面俩缝成一张声卡这三颗驱动被 NXP、主线社区、无数 i.MX 板子反复验证过。正点原子教程里那套自己写的imx-wm8960.cmachine 驱动在主线的fsl-asoc-card面前就是「重新发明轮子」——fsl-asoc-card一个 machine 驱动兼容 WM8960/WM8962/SGTL5000/CS42XX8/TLV320AIC3x 一大家子 codec你板子这颗 WM8960 它本来就支持。所以这章的任务把这三颗驱动拆给你看再上板让耳机出声。驱动本体一行都不用你敲。提示理清 Linux ASoC「machine codec cpu_dai platform」四件套各自的角色看懂 alpha 板的音频硬件链路SAI2 怎么连 WM8960、MCLK 哪来的、耳机/喇叭/麦克风怎么走线理解为什么正点原子的imx-wm8960.c该被主线fsl-asoc-card取代。音频为什么是「四件套」按键、触摸那些驱动基本是「一个驱动搞定一颗 IC」。音频不一样——一块声卡从软件看是四个角色分工合作这正是 ASoCALSA System on Chip子系统要解决的角色干什么alpha 板对应主线驱动machinecard「缝纫机」把 cpu_dai 和 codec 按某种拓扑缝成一张声卡定义 DAI 格式、时钟、音频通路 routingsound-wm8960节点fsl-asoc-card.ccpu_daiCPU 这端的数字音频接口驱动串行音频总线传 PCM 数据 位/帧时钟SAI2 接口fsl_sai.ccodec外接音频芯片驱动控制模拟通路麦克风→ADC、DAC→耳机/喇叭、寄存器、DAPMWM8960I2C 0x1awm8960.cplatform音频数据搬运工DMA 把内存里的 PCM 数据搬到 SAI2、再喂给 codecimx-pcm-dmaimx-pcm-dma.c被 fsl_sai 自动 select为什么要分四块因为同一颗 cpu_daiSAI2可以接不同 codecWM8960、SGTL5000……同一颗 codec 也能被不同 cpu_dai 驱动。分层 复用换 codec 只换 codec 驱动 设备树节点machine 和 cpu_dai 不用动。fsl-asoc-card就是利用这套分层一个 machine 驱动通吃 N 种 codec。说明把声卡想象成一个乐队**platformDMA**是搬运乐谱的助理**cpu_daiSAI2**是 CPU 这端的指挥棒打节拍、传音符**codecWM8960**是真正的乐手把数字音符变成模拟声波**machinecard**是乐队经理——它不发声但它决定「谁和谁组乐队、按什么谱子演」。少任何一块乐队都转不起来。02 节 会把这四件套的软件绑定关系snd_soc_card/snd_soc_dai_link/snd_soc_dai/snd_soc_codec_driver掰开讲。这里先有个全景就行。alpha 板音频链路全景纸上谈兵结束看看 alpha 板上这条链路物理上怎么连。WM8960 和 i.MX6ULL 之间有两根总线I2C1 (控制面配寄存器) i.MX6ULL ─────────────────────────── WM8960 (codec, 0x1a) ─────────────────────────── SAI2 (数据面传音频 时钟)I2C1地址 0x1a控制通道。CPU 通过它读写 WM8960 的寄存器音量、静音、通路选择、上电。这条线和 08 章 AP3216C 的 I2C 套路完全一样。注意是 I2C1不是原版资料的 I2C2——alpha 板实测 WM8960 AP3216C 都在 I2C1goodix 才在 I2C205 节 有这个坑的详解。SAI2数据通道。五根信号线TX_BCLK位时钟、TX_SYNC帧/字选择、TX_DATACPU→codec 的播放数据、RX_DATAcodec→CPU录音用、MCLK主时钟。这里有个反直觉的点时钟角色上BCLK 和 LRCLK 由 WM8960 产生、SAI2 反而是从这叫 codec-master 模式而MCLK 由 CPU 产生送给 codec——03 节拆CARD_WM8960分支时你会看到DAIFMT_CBP_CFP就是这层意思02 节 会把主从关系彻底讲透。不过有个事情还是要说明一下的笔者的 alpha 板上 SAI2 没有独占引脚是复用了 JTAG 那组脚TDI/TDO/TRST/TCK/TMS → SAI2_TX_BCLK/TX_SYNC/TX_DATA/RX_DATA/MCLK。所以设备树pinctrl_sai2里你会看到MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK这种「JTAG 脚变 SAI 脚」的映射——别觉得眼熟就以为还能用 JTAG 调试那组脚已经被音频征用了。时钟怎么来i.MX6ULL 内部有个音频 PLLPLL4分频出12.288MHz从 MCLK 脚送给 WM8960。为什么是 12.288MHz因为12288000 48000 × 25648kHz 采样率、256 倍过采样WM8960 拿这个 MCLK 内部分频就能直接生成所有需要的时钟不用再启 codec 内部的 PLL——省事。这条时钟路由 04 节 会深挖。模拟那侧alpha 板上 WM8960 接了三路耳机Headphone左右声道HP_L/HP_R有耳机检测引脚hp-det-gpioGPIO5_IO04喇叭Ext Spk外部功放SPK_LP/LN/RP/RN桥接负载麦克风Mic Jack / AMICLINPUT2/3、RINPUT1/2WM8960 提供 MICB 偏置电压设备树里audio-routing那一串字符串就是定义这些模拟通路的连接关系——05 节 逐行解读。为什么不用正点原子的 imx-wm8960.c正点原子教程草稿 ch65的方案是自己写一个imx-wm8960.c当 machine 驱动配合主线wm8960.ccodec 和fsl_sai.c。这条路能跑但没必要——主线早就有fsl-asoc-card.c这个通用 machine 驱动compatible fsl,imx-audio-wm8960就是给 WM8960 准备的。两份 machine 驱动干的是同一件事定义 dai_link、设 DAI 格式、注册 card但fsl-asoc-card更通用一份代码兼容十几种 codec、维护更勤主线社区在养、还顺手支持 ASRC异步采样率转换。自写的imx-wm8960.c只能接 WM8960 一颗。所以本项目Issue #43 的修复明确复用主线fsl-asoc-card不移植imx-wm8960.c。这章我们就拆主线这套。你也省得去维护一份「抄过来就再没动过」的 machine 驱动。WM8960 能力速览拆代码前先知道这颗芯片能干什么采样率8kHz – 48kHz电话质量到 CD 质量足够再高就得换 codec 了采样精度16 / 20 / 24 / 32 bit通道立体声2 通道播放 录音模拟接口3 路立体声输入LINPUT1/2/3、RINPUT1/2/3、立体声耳机输出HP_L/R、桥接喇叭输出SPK_L/R、单独的 OUT3片上ADC、DAC、麦克风偏置MICBIAS、可编程增益PGA、混音器、3D 增强、ALC自动电平控制这些能力在wm8960.c里全是 DAPM widget 和 kcontrol音量/静音那种用户态能调的控件。amixer看到的Headphone、Speaker、PCM Playback Volume那些就是从这里来的。
返回列表