深入解析 WM8960 音频驱动:从设备树到内核驱动的完整分析

1. 引言

WM8960 是一款 高性能立体声编解码器(Codec),支持 耳机放大、扬声器驱动、麦克风输入、I²C 控制和 I²S 音频传输。它常用于 嵌入式 Linux 设备,如 NXP i.MX8M Plus EVK,并与 SAI(I²S 控制器) 配合使用。

Linux ASoC(ALSA System-on-Chip) 体系下,WM8960 主要涉及以下组件:

  1. Codec 驱动(WM8960 控制和音频处理)
  2. Platform 驱动(SAI 传输接口)
  3. Machine 驱动(绑定 Codec 和 SAI)

本篇博文将完整剖析 WM8960 音频驱动的实现,涵盖:

  • 设备树(DTS)配置
  • ASoC 框架解析
  • WM8960 Codec 驱动解析
  • 音频数据流管理
  • Machine Driver 详解
  • 调试与测试

在这里插入图片描述


2. 设备树(DTS)解析

设备树(DTS)中,WM8960 主要涉及 I2C 设备注册、音频控制器(SAI)、音频流路径

2.1 注册 WM8960 I2C 设备

&i2c3 {  
    clock-frequency = <400000>;  
    pinctrl-names = "default";  
    pinctrl-0 = <&pinctrl_i2c3>;  
    status = "okay";  

    codec: wm8960@1a {  
        compatible = "wlf,wm8960";  
        reg = <0x1a>;  // WM8960 I2C 地址
        clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK1>;
        clock-names = "mclk";  
        wlf,shared-lrclk;
        wlf,hp-cfg = <3 2 3>;  
        wlf,gpio-cfg = <1 3>;  
        SPKVDD1-supply = <&reg_audio_pwr>;  
    };  
};

解析:

  • compatible = "wlf,wm8960"; → 设备匹配 WM8960 驱动
  • reg = <0x1a>; → 设备 I2C 地址
  • clocks → 配置 mclk 时钟源
  • SPKVDD1-supply → 供电管理

2.2 定义 Sound Card

sound-wm8960 {  
    compatible = "fsl,imx-audio-wm8960";  
    model = "wm8960-audio";  
    audio-cpu = <&sai3>;        // 绑定 SAI3 控制器
    audio-codec = <&codec>;     // 绑定 WM8960 编解码器
    audio-asrc = <&easrc>;      // 绑定 ASRC 进行音频采样率转换
    hp-det-gpio = <&gpio4 28 0>; // 耳机检测 GPIO
    audio-routing =  
        "Headphone Jack", "HP_L",  
        "Headphone Jack", "HP_R",  
        "Ext Spk", "SPK_LP",  
        "Ext Spk", "SPK_LN",  
        "Ext Spk", "SPK_RP",  
        "Ext Spk", "SPK_RN",  
        "LINPUT1", "Mic Jack",  
        "LINPUT3", "Mic Jack",  
        "Mic Jack", "MICB";  
};

解析:

  • audio-cpu = <&sai3>; → 绑定 SAI3 控制器
  • audio-codec = <&codec>; → 绑定 WM8960
  • audio-routing → 定义音频输入/输出路径

2.3 SAI3 配置

&sai3 {  
    assigned-clocks = <&clk IMX8MP_CLK_SAI3>,  
                     <&clk IMX8MP_CLK_SAI3_ROOT>;  
    assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;  
    assigned-clock-rates = <12288000>, <12288000>;  
    status = "okay";  
};
  • MCLK 来源:AUDIO_PLL1
  • assigned-clock-rates 设置 12.288 MHz

3. ASoC 框架解析

ALSA System-on-Chip(ASoC) 框架包含:

  1. Codec Driver(编解码器驱动)sound/soc/codecs/wm8960.c
  2. Platform Driver(SAI 控制器)sound/soc/fsl/fsl_sai.c
  3. Machine Driver(绑定 Codec 和 SAI)sound/soc/fsl/imx-wm8960.c

4. 核心驱动代码

4.1 Codec 驱动

static int wm8960_i2c_probe(struct i2c_client *i2c) {  
    struct wm8960_priv *wm8960;  

    wm8960 = devm_kzalloc(&i2c->dev, sizeof(*wm8960), GFP_KERNEL);  
    wm8960->regmap = devm_regmap_init_i2c(i2c, &wm8960_regmap);  

    return devm_snd_soc_register_component(&i2c->dev,  
            &soc_component_dev_wm8960, &wm8960_dai, 1);  
}
  • I²C 设备初始化
  • 注册 wm8960 组件

4.2 Machine 驱动

static struct snd_soc_dai_link imx_wm8960_dai = {
    .name = "WM8960",
    .stream_name = "WM8960 HiFi",
    .cpu_dai_name = "sai3",
    .codec_dai_name = "wm8960-hifi",
    .platform_name = "fsl-sai",
    .codec_name = "wm8960.1-001a",
};
  • 绑定 SAI3
  • Codec 设备名 wm8960.1-001a

5. 调试与测试

5.1 确认设备是否注册

dmesg | grep wm8960
ls /sys/class/sound
aplay -l

5.2 I2C 设备调试

i2cdetect -y -r 3  # 查看 I2C3 总线设备

5.3 播放音频

aplay -D hw:0,0 test.wav

6. 结论

本文完整解析了 WM8960 音频驱动的实现,包括 设备树、ASoC 框架、核心代码、音频数据流管理、机器驱动和调试方法。开发者可以基于这些内容,深入理解 嵌入式 Linux 音频系统,并在实际项目中 高效调试和优化


适用场景
嵌入式 Linux 音频开发
i.MX8M Plus EVK Yocto 项目
ASoC 体系下的音频调试
Codec + SAI 设备驱动分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值