一、WM8960音频编解码芯片

1. 介绍

WM8960是欧胜公司(wolfson)的一款低功耗、高质量的立体声音频编解码芯片。

其内部集成D类喇叭功放,每个通道可以驱动一个1W喇叭(8Ω),内部集成3个立体声输入源,可以灵活配置,拥有一路完整的麦克风接口。

WM8960内部ADC和DAC都为24位,主要特性如下:

  • DAC的SNR(信噪比)为98dB,ADC的SNR(信噪比)为94dB
  • 3D增强
  • 立体声D类功放
  • 集成耳机接口、麦克风接口
  • 采样率支持8K、11.025K、12K、16K、22.05K、24K、32K、44.1K、48K

2. 框图


(1)WM8960输入接口

此部分是WM8960提供的输入接口,作为立体声音频输入源,一共提供了三路,分别是LINPUT1/RINPUT1、LINPUT2/RINPUT2、LINPUT3/RINPUT3。

(2)WM8960输出接口

此部分是WM8960提供的输出接口,比如输出给耳机或喇叭,SPK_LP/SPK_LN用于连接左声道的喇叭、SPK_RP/SPK_RN用于连接右声道的喇叭,两个声道各支持接1W的8Ω喇叭。HP_L/HP_R用于连接耳机。

(3)WM8960数字音频接口

此部分用于和主控制器连接,支持I2S格式,有6条控制信号:

  • ADCDAT:ADC数据输出引脚,采集到的音频数据转换为数字信号以后通过此引脚传输给主控制器;
  • ADCLRC:ADC数据帧时钟,用于切换左右声道数据,此信号的频率就是采样率;
  • DACDAT:DAC数据输入引脚,主控制器将数字信号输入给WM8960的ADC;
  • DACLRC:DAC数据帧时钟;
  • BCLK:位时钟,用于同步
  • MCLK:主时钟,需要外部提供,MCLK的频率等于采样率的265或384倍;

(4)WM8960控制接口

此部分是一个标准的I2C接口,用于配置WM8960内部寄存器。

二、I2S总线协议

1. 总线用途

imx6ull与wm8960数字音频总线的连接使用I2C总线协议。

I2S总线是由飞利浦提出的一种用于数字音频设备之间进行音频数据传输的总线,可以在主控制器和CODEC芯片之间传输音频数据。

2. 总线协议简述

I2S总线协议一般需要三条信号线:

  • SCK:串行时钟信号,也成为位时钟(BCLK),音频数据的每一位数据都对应一个SCK。

立体声都是双声道的,因此SCK=2 x 采样率 x 采样位数,比如44.1KHz、16bit的音频,SCK=1.4112MHz。

  • WS:字段(声道)选择信号,也成为LRCK,或者帧时钟,用于切换左右声道数据,WS=1表示正在传输左声道的数据,WS=0表示正在传输右声道的数据,WS的频率=采样率。
  • SD:串行数据信号,是实际的音频数据,数据的最高位先开始传输。

如果要同时实现录音和放音,则需要两条数据线,分别用于录音数据和放音数据。

此外,为了使音频CODEC芯片与主控制器之间更好的同步,会引入主时钟信号MCLK,一般使采样率的256倍或384倍。

三、imx6ull的SAI接口

imx6ull提供了SAI外设,全称Synchronous Audio Interface,同步音频接口,是一个全双工、支持帧同步的串行接口,支持I2S、AC97、TDM、音频DSP等。


正点原子Alpha开发板上imx6ull与wm8960芯片的连接原理图如下:

四、WM8960的设备树节点描述

1. 添加i2c设备节点

绑定文档:Documentation/devicetree/bindings/sound/wm8960.txt。

文档给出的示例节点如下:

codec: wm8960@1a {compatible = "wlf,wm8960";reg = <0x1a>;wlf,shared-lrclk;};

因为NXP官方开发板也使用的是wm8960,所以节点已经添加好了,在i2c2节点下:

2. 添加sai设备节点

绑定文档:Documentation/devicetree/bindings/sound/fsl-sai.txt。

文档中给出的示例节点如下:

sai2: sai@40031000 {compatible = "fsl,vf610-sai";reg = <0x40031000 0x1000>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_sai2_1>;clocks = <&clks VF610_CLK_PLATFORM_BUS>, <&clks VF610_CLK_SAI2>, <&clks 0>, <&clks 0>;clock-names = "bus", "mclk1", "mclk2", "mclk3";dma-names = "tx", "rx";dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>, <&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>;big-endian;lsb-first;};

NXP官方描述的节点如下:

其中pinctrl_sai2描述了SAI接口的引脚复用情况:

其中pinctrl_sai2_hp_det_b描述了一个普通GPIO引脚,用于检测耳机是否插入

WM8960支持耳机检测,当耳机插入时通过耳机播放,当耳机拔出时使用喇叭播放。

3. 添加sound节点描述

NXP官方已经描述了sound节点,如下:

其中一些比较重要的属性有:

  • compatible:兼容性,用于匹配驱动
  • model:声卡名称
  • cpu-dai:CPU DAI(Digital Audio Interface)句柄
  • audio-codec:音频解码芯片句柄
  • asrc-controller:asrc控制器,Asynchronous Sample Rate Converters,异步采样频率转换器
  • hp-det:耳机插入检测引脚设置(第一个参数是WM8960检测引脚,第二个参数是检测电平,0-高电平表示耳机插入)
  • audio-routing:音频器件的一系列连接设置,第一个字符串是连接的sink,第二个是连接的source

五、使能内核的WM8960驱动

make menuconfig

1. 取消 ALSA模拟 OSS API

2. 使能 I.MX6ULL的 WM8960驱动

开启这两项:

这两项分别的说明如下:


配置完保存退出,看一下与原来配置文件的差异:

使用新的.config覆盖原来的配置文件。

六、测试

编译内核:

make -j16

使用新的内核和设备树启动,启动日志可以看到声卡相关的:
再看看启动过程中打印出的alsa设备列表:

查看设备文件:

这些设备文件就是ALSA音频驱动框架对应的设备文件,作用如下:

  • controlC0:用于声卡控制,C0表示声卡0
  • pcmC0D0c和pcmC0D0c:用于录音的pcm设备,其中的“C0D0”和“C0D1”分别表示声卡0中的设备0和设备1,最后的字母c是capture的缩写,表示录音
  • pcmC0D0p和pcmC0D0p:用于播放的pcm设备,其中的“C0D0”和“C0D1”分别表示声卡0中的设备0和设备1,最后的字母p是playback的缩写,表示放音
  • timer:定时器

音频驱动正常使能之后,还不能直接播放音乐或者录音,还需要移植alsa-lib和alsa-utils这两个软件。