首页 > 系统服务 > 详细

Linux声卡驱动——ASoC

时间:2019-05-24 16:33:22      阅读:58      评论:0      收藏:0      [点我收藏+]

标签:http   oid   nbsp   mage   sdn   for   在一起   不同   sun   

一、ASoC简介

  ASoC(Alsa System on Chaip),也称为移动设备中的ALSA。是建立在标准ALSA驱动层上,为了更好地支持嵌入式处理器和移动设备中的音频Codec的一套软件体系。ASoC不能单独存在,他只是建立在标准ALSA驱动上的一个它必须和标准的ALSA驱动框架相结合才能工作。


二、ASoC硬件架构

  嵌入式设备中的音频系统(ASoC)可以被划分为板载硬件(Machine)、Soc(Platform)、Codec三大部分,如下图所示:

技术分享图片

Machine:是指某款单板,包含特定的外设,为CPU、Codec提供了一个载体,Machine驱动几乎是不可重用的。

Platform:一般是指某一个SoC平台,可以理解为某款Soc,具有I2S,AC97音频接口等,内部有时钟,DMA单元用于传输音频数据。

Codec:音频编解码器,Codec里面包含了I2S接口、D/A、A/D、Mixer、PA(功放),通常包含多种输入(Mic、Line-in、I2S、PCM)和多个输出(耳机、喇叭、听筒,Line-out),一般Soc可通过I2C来控制codec芯片。

 

三、ASoC软件架构

  对应于硬件,软件驱动上也分Machine驱动、Platform驱动、Codec驱动三大部分,其中Platform驱动用于驱动Soc端的音频相关模块,Codec驱动用于驱动音频编解码器,的Machine驱动负责Platform驱动和Codec驱动之间的耦合以及部分和设备或板子特定的代码。

Platform驱动:

  只与特定的Soc有关,实现Soc的音频DMA驱动和Soc端的dai接口驱动,注册的所有platform驱动都会挂载在全局platform_list链表上。注册的Soc端的cpu_dai接口驱动挂载在全局dai_list上。只要指定了SoC,就会有一个对应的Platform,它只与SoC相关,与Machine无关,这样我们就可以把Platform抽象出来,使得同一款SoC不用做
任何的改动,就可以用在不同的Machine中。

Codec驱动:

  只与Codec编解码器驱动有关,与Soc和Machine无关。所有注册的Codec驱动都会挂载在全局codec_list链表上,注册的Codec端的dai接口驱动挂载在全局dai_list上。Codec和Platform一样,要实现为可重用的部件,同一个Codec可以被不同的Machine使用。嵌入式Codec驱动通常通过I2C对编解码芯片进行控制。

Machine驱动:

   用于将Platform驱动和Codec驱动关联在一起,通过snd_soc_dai_link中的名字指定使用哪个Platform驱动,使用哪个Soc端的dai接口,使用哪个Codec驱动,使用Codec上的哪个dai接口。同时也做一些特定于单板的操作。只要是与Soc和Codec驱动无关的操作,都应该放在Machine驱动中。Machine驱动中注册的and_codec_card放在全局card_list链表上。ASoC的一切都从Machine驱动开始,包括声卡的注册,绑定Platform和Codec驱动等等。


涉及的三个驱动中涉及的全局链表

//soc-core.c中
struct list_head card_list;     /*Machine驱动注册的snd_codec_card放在这个链表上*/
struct list_head dai_list;         /*sound\soc\samsung\I2s.c中使用snd_soc_register_dai注册的cpu_dai会放在这上面,codec中注册的codec端的dai也会挂在这上面*/
struct list_head platform_list; /*注册的Soc的platform驱动在这个链表上*/
struct list_head codec_list;     /*音频编解码芯片驱动注册的codec挂载在这个链表上*/

snd_soc_card是整个ASoc的核心结构体。

 

四、ASoC架构中的Machine驱动

1.核心结构体
snd_soc_dai_link
snd_soc_card

2.注册
//设备端:
struct snd_soc_dai_link tiny4412_wm8960_dai_link;
struct snd_soc_card myalsa_card;

tiny4412_wm8960_init
    platform_set_drvdata(&asoc_dev, &myalsa_card);

//驱动端:
soc_probe(struct platform_device *pdev) //soc-core.c
    snd_soc_register_card(card);

  Machine驱动负责处理单板特有的一些控件和音频事件。单独的Platform和Codec驱动是不能工作的,它必须由Machine驱动把它们结合在一起才能完成整个设备的音频处理工作。snd_soc_dai_link则负责关联Platform和Codec。

  snd_soc_card代表着Machine驱动中要注册的声卡设备,(也就是tiny4412_wm8960.c,它只是平台设备的设备端,在设备端构造snd_soc_card,在驱动端
注册这个card,驱动端是soc-core.c)

  snd_soc_dai_link中,指定了Platform、Codec、codec_dai、cpu_dai的名字,稍后Machine驱动将会利用这些名字去匹配已经在系统中注册的platform,codec,dai,这些注册的部件都是在另外相应的Platform驱动和Codec驱动的代码文件中定义的,这样看来,Machine驱动的设备初始化代码无非就是选择合适Platform和Codec以及dai,用他们填充以上几个数据结构,然后注册Platform设备即可。当然还要实现连接Platform和Codec的dai_link对应的ops实现。

  通过snd_soc_register_card,为snd_soc_pcm_runtime数组申请内存,每一个dai_link对应snd_soc_pcm_runtime数组的一个单元,然后把snd_soc_card中的dai_link配置复制到相应的snd_soc_pcm_runtime中,最后,大部分的工作都在snd_soc_instantiate_card中实现,包括调用soc_bind_dai_link()来解析struct snd_soc_dai_link来关联各个设备。

  Machine驱动的初始化,codec和dai的注册,都会调用snd_soc_instantiate_cards()进行一次声卡和codec,dai,platform的匹配绑定过程,这里所说的绑定,正如Machine驱动一文中所描述,就是通过3个全局链表,按名字进行匹配,把匹配的codec,dai和platform实例赋值给声卡中用于描述每组关联关系的snd_soc_pcm_runtime结构中。一旦通过Machine驱动将Codec、Platform绑定成功,就会依次调用各个组件的probe()回调函数,调用关系依次是:
  CPU dai接口的:snd_soc_dai_driver.probe()
  Codec驱动的:snd_soc_codec_driver.probe()
  Platform驱动的:snd_soc_platform_driver.probe()
  Codec dai接口的:snd_soc_dai_driver.probe()
详细调用过程见soc_probe_dai_link()

snd_soc_instantiate_card(struct snd_soc_card *card)
    //通过snd_soc_dai_link中的name构建关联关系
    soc_bind_dai_link(card, i);
    //对每一条链路调用各个组件的probe()
    soc_probe_dai_link(struct snd_soc_card *card, int num)
    //如果codec驱动有多个codec_conf配置,machine驱动可以通过snd_soc_card选择一个
    //走上了ALSA的老路了
    snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, card->owner, 0, &card->snd_card);
    //若Machine驱动中指定了card的probe()则调用
    card->probe(card);
    snd_soc_add_controls
    snd_soc_dapm_add_routes
    snd_card_register

 

五、ASoC架构中的Codec驱动

1.核心结构体
snd_soc_codec
snd_soc_codec_driver
snd_soc_dai
snd_soc_dai_driver

2.注册
//wm8960.c
snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8960, &wm8960_dai, 1);

  ASoC中的一个重要设计原则就是要求Codec驱动是平台无关的,它包含了一些音频的控件(Controls),音频接口,DAMP(动态音频电源管理)的定义和某些Codec IO功能。为了保证硬件无关性,任何特定于平台和机器的代码都要移到Platform和Machine驱动中。

所有的Codec驱动都要提供以下特性:
  Codec DAI 和 PCM的配置信息;
  Codec的IO控制方式(I2C,SPI等);
  Mixer和其他的音频控件;
  Codec的ALSA音频操作接口;
必要时,也可以提供以下功能:
  DAPM描述信息;
  DAPM事件处理程序;
  DAC数字静音控制

snd_soc_codec/snd_soc_codec_driver代表了Codec驱动(也就是wm8960.c),snd_soc_register_codec()同时注册了codec和codec端的dai。

 

六、ASoC架构中的Platform驱动

1.核心结构体
snd_soc_platform
snd_soc_platform_driver
snd_soc_dai
snd_soc_dai_driver

2.注册
注册platform驱动:
//dma.c
snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform);
注册cpu_dai驱动:
//i2s.c
i2s_alloc_dai(pdev, false);
snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv);

它包含了该SoC平台的音频DMA和音频接口的配置和控制(I2S,PCM,AC97等等);它也不能包含任何与单板相关的代码。

  Platform驱动的主要作用是完成音频数据的管理,最终通过CPU的数字音频接口(DAI)把音频数据传送给Codec进行处理,最终由Codec输出驱动耳机或者是喇叭的音信信号。

  在具体实现上,ASoC有把Platform驱动分为两个部分:snd_soc_platform_driver和snd_soc_dai_driver。其中,platform_driver负责管理音频数据,把音频数据通过dma或其他操作传送至cpu dai中,dai_driver则主要完成cpu一侧的dai的参数配置,同时也会通过一定的途径把必要的dma等参数与snd_soc_platform_driver进行交互。

  CPU端的dai驱动通常对应Soc的一个或几个I2S/PCM接口的驱动

 

七、总结

  注意各个驱动的分工,就大致知道每个模块需要提供哪些钩子函数,这钩子函数应该由谁调用。比如Codec应该提供自己的各个控制接口给Machine驱动程序调用,Platform驱动也应该提供自己的驱动接口给Machine驱动调用。

  自己编写驱动的时候需要提供Machine驱动的设备端,若Codec驱动还没有,则还需要提供codec的驱动。一般platform驱动是Soc厂商已经提供好的,Codec驱动是音频编解码芯片供应商提供好的。因此,我们的工作就是编写Machine驱动和适配Codec芯片到我们的单板上。

 

 

 

 

参考:

Linux ALSA声卡驱动之五:移动设备中的ALSA: https://blog.csdn.net/michaelcao1980/article/details/78228630
Linux ALSA声卡驱动之六:ASoC架构中的Machine: https://blog.csdn.net/droidphone/article/details/7231605
Linux ALSA声卡驱动之七:ASoC架构中的Codec: https://blog.csdn.net/DroidPhone/article/details/7283833
Linux ALSA声卡驱动之八:ASoC架构中的Platform: https://blog.csdn.net/droidphone/article/details/7316061

 

Linux声卡驱动——ASoC

标签:http   oid   nbsp   mage   sdn   for   在一起   不同   sun   

原文:https://www.cnblogs.com/hellokitty2/p/10918742.html

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4
打开技术之扣,分享程序人生!
             

鲁公网安备 37021202000002号