嵌入式linux ASoC架构声卡驱动开发

嵌入式linux ASoC架构声卡驱动开发

文章目录

  • 嵌入式linux ASoC架构声卡驱动开发
    • 需求分析
    • ASoC架构下声卡驱动代码结构
      • codec驱动
        • snd_soc_register_codec分析
      • 平台驱动
      • 板驱动
        • devm_snd_soc_register_card函数分析

需求分析

基于linux操作系统,使用ASoC框架,将系统中的音频文件从扬声器中播放出来。
嵌入式linux ASoC架构声卡驱动开发_第1张图片

首先,各种格式的音频文件,mp3,wav,FLAC,都是将模拟量以一定的规范进行了编码,才能保存下来的,所以对应的你需要一个播放器。播放器会将音频解码成i2s数据,然后向CPU外部传输。

扬声器只能接受模拟信号,所以需要一个数字信号处理芯片(DSP digital signal process)将i2s转换成模拟信号,这个DSP芯片从系统的角度理解就是声卡,除了将数字信号转换成模拟信号,有点DSP还具有放大、调音等功能。

ASoC架构下声卡驱动代码结构

ASoC架构下,添加一块声卡需要三个部分:

  • codec驱动,也就是DSP芯片的驱动,负责直接对DSP进行控制的代码在这一部分驱动中。
  • 平台驱动,这部分内容和名字一样,只和CPU这个平台有关,只关心CPU内部对i2s信号相关的处理,这部分代码一般由CPU的厂商负责写好。
  • board驱动,板级驱动,也就是针对你的开发板部分的代码,这部分代码主要负责将你的CPU和DSP绑定起来。
    嵌入式linux ASoC架构声卡驱动开发_第2张图片

平台驱动由CPU厂商提供,DSP也可以找到对应厂商给的demo,这两部分都是可以复用的代码,只有板驱动,需要亲力亲为,编写一个dai link将平台驱动和DSP驱动绑定起来,

codec驱动

驱动代码的位置: kernel/sound/soc/codecs
包含重要结构体的头文件

  1. kernel/include/sound/soc.h
  2. kernel/include/sound/soc-dai.h
  3. kernel/sound/soc/soc-core.c

codec驱动的几项核心工作:

  1. 映射i2c regmap,方便对DSP进行读写
  2. 按照DSP的规定时序上电
  3. 写入DSP初始化配置
  4. 封装DSP的控制接口
  5. 通过snd_soc_register_codec将DSP注册进系统

snd_soc_register_codec分析

snd_soc_register_codec函数是codec驱动的核心,他将一个codec结构体和DAI驱动结构体注册进系统,这两个结构体封装了这一片DSP的控制API。
四个参数的说明:

  • device
    codec设备的i2c驱动实体,用于设备最开始时的probe,保存一些gpio的信息和其他私有数据,以便其他地方能够控制到codec的一些硬件设施。

  • snd_soc_codec_driver结构体
    主要包含codec的硬件控制接口和与系统相关的控制接口,比如codec的probe,后续系统注册声卡时会再来调用这个codec的probe函数,在此函数中进行一些具体的初始化操作,比如remove接口,卸载声卡是需要调用remove去释放声卡所占用的资源,remap的获取和读写操作,注册声卡的controls,wedgets,routes,具体的可以看soc.h头文件中的定义。

  • snd_soc_dai_driver
    主要包含 codec的dai的控制接口,dai就是Digital Audio Interface,也就是说,这一片DPS芯片的音频控制的相关接口在这里。除了snd_soc_dai的注册移除重启等,通过snd_soc_dai_ops结构体封装的音频操作接口,通过snd_soc_pcm_stream注册声卡的录音播放功能的具体参数,比如录音时的通道数,采样率,都是在此指定。

  • Number of DAIs
    DAI的数量

平台驱动

只关心cpu部分的操作,一般由CPU厂家写好这部分代码。
这部分要实现CUP中i2s的具体操作。

板驱动

这部分代码用于描述电路板,用于绑定板子上的CPU和DSP,也就是上面的codec和platform
核心结构体:snd_soc_dai_link

板驱动的核心工作:
绑定平台驱动和codec驱动

devm_snd_soc_register_card函数分析

板驱动通过这个函数注册一块声卡,这个函数第二个参数就是结构体snd_soc_card,这个结构体中填充了关于这块声卡的描述。
声卡里的dai_link成员变量,在这里指定codec和平台驱动的名字,同时snd_soc_ops成员中包含了一些声卡的控制接口,比如传输的带宽,添加dai支持的流媒体格式。

你可能感兴趣的:(linux,alsa,驱动程序)