基于mini2440的UDA1341音频驱动架构分析

Mini2440开发板

Kernel:linux 2.6.32.2

音频基于i2s总线接口(和l3总线接口对混音器进行设置)

Linux ASoC音频设备驱动

ASoC驱动的组成

ASoC(ALSA System on Chip)是ALSA在SoC方面的发展和演变,它在本质上仍然属于ALSA,但是在ALSA架构的基础上对CPU相关的代码和CODEC相关的代码进行了分离。其原因是,采用传统ALSA架构的情况下,同一型号的CODEC工作于不同的CPU时,需要不同的驱动,这不符合代码重用的要求。

ASoC主要由3部分组成。

(1)CODEC驱动。这一部分只关心CODEC本身,与CPU平台相关的特性不由此部分操作。

(2)平台驱动。这一部分只关心CPU本身,不关心CODEC。它主要处理两个问题:DMA引擎和SoC集成的PCM、I2S或AC’97数字接口的控制。

(3)板驱动。也称为machine驱动,这一部分将平台驱动和CODEC驱动绑定在一起,描述了板一级的硬件特征。

在以上3部分中,1和2基本上都可以仍然是通用的驱动了,也就是说,CODEC驱动认为自己可以连接任意CPU,而CPU的I2S、PCM、或AC’97接口对应的平台驱动则认为自己可以连接任意符合接口类型的CODEC,只有3是不通用的,由特性的电路板上具体的CPU和CODEC确定,因此它很像一个插座,上面插上了CODEC和平台这两个插头。

在以上三部分之上的是ASoC核心层,由内核源代码中的sound/soc/soc-core.c实现,查看其源代码发现它完全是一个传统的ALSA驱动。因此,对于基于ASoC架构的声卡驱动而言,alsa-lia以及ALSA的一系列utility仍然是可用的,如amixer、aplay均无需针对ASoC进行任何改动。而ASoC的用户编程方法也和ALSA完全一致。

内核源代码的Documentation/sound/slsa/soc目录包含了ASoC相关的文档。

1.ASoC CODEC驱动

在ASoC架构下,CODEC驱动负责如下工作:

(1)CODEC DAI(Digital Audio Interfaces)和配置PCM,由结构体snd_soc_dai来描述,形容playback、capture的属性以及DAI接口的操作。

位于内核源代码include/sound/soc-dai.h

/*

 * Digital Audio Interface runtime data.

 *

 * Holds runtime data for a DAI.

 */

struct snd_soc_dai {

        /* DAI description */      /*DAI的描述*/

        char *name;

        unsigned int id;

        int ac97_control;

 

        struct device *dev;

        void *ac97_pdata;  /* platform_data for the ac97 codec */ /*ac97平台数据*/

 

        /* DAI callbacks */

        int (*probe)(struct platform_device *pdev,

                      struct snd_soc_dai *dai);

        void (*remove)(struct platform_device *pdev,

                        struct snd_soc_dai *dai);

        int (*suspend)(struct snd_soc_dai *dai);

        int (*resume)(struct snd_soc_dai *dai);

 

        /* ops */

        struct snd_soc_dai_ops *ops;

 

        /* DAI capabilities */        /*DAI的能力*/

        struct snd_soc_pcm_stream capture;  /*录音*/

        struct snd_soc_pcm_stream playback;  /*放音*/

        unsigned int symmetric_rates:1;

 

        /* DAI runtime info */      /*DAI运行时的信息*/

        struct snd_pcm_runtime *runtime;

        struct snd_soc_codec *codec;

        unsigned int active;

        unsigned char pop_wait:1;

        void *dma_data;

 

        /* DAI private data */      /*DAI私有数据*/

        void *private_data;

 

        /* parent platform */      /*父平台*/

        struct snd_soc_platform *platform;

 

        struct list_head list;         /*循环、双向链表*/

};

相关推荐