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

发布时间:2024-06-20  

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;         /*循环、双向链表*/

};


2)CODEC IO操作、动态音频电源管理以及时钟、PLL等控制

在(1)中的snd_soc_codec 结构体是对CODEC本身I/O控制以及动态音频电源管理(Dynamic Audio Power Management,DAPM)的描述。它描述I2C、SPI或AC’97如何读写CODEC寄存器并容纳DAPM链表,核心成员为read()、write()、hw_write()、hw_read()、dapm_widgets、dapm_paths等。

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

/* SoC Audio Codec */

struct snd_soc_codec {

        char *name;

        struct module *owner;

        struct mutex mutex;

        struct device *dev;

        struct snd_soc_device *socdev;

 

        struct list_head list;

 

        /* callbacks */

        int (*set_bias_level)(struct snd_soc_codec *,

                                  enum snd_soc_bias_level level);

 

        /* runtime */

        struct snd_card *card;

        struct snd_ac97 *ac97;  /* for ad-hoc ac97 devices */

        unsigned int active;

        unsigned int pcm_devs;

        void *private_data;

 

        /* codec IO */

        void *control_data; /* codec control (i2c/3wire) data */

        unsigned int (*read)(struct snd_soc_codec *, unsigned int);

        int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);

        int (*display_register)(struct snd_soc_codec *, char *,

                                    size_t, unsigned int);

        int (*volatile_register)(unsigned int);

        int (*readable_register)(unsigned int);

        hw_write_t hw_write;

        unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);

        void *reg_cache;

        short reg_cache_size;

        short reg_cache_step;

 

        /* dapm */

        u32 pop_time;

        struct list_head dapm_widgets;

        struct list_head dapm_paths;

        enum snd_soc_bias_level bias_level;

        enum snd_soc_bias_level suspend_bias_level;

        struct delayed_work delayed_work;

 

        /* codec DAI's */

        struct snd_soc_dai *dai;

        unsigned int num_dai;

 

#ifdef CONFIG_DEBUG_FS

        struct dentry *debugfs_reg;

        struct dentry *debugfs_pop_time;

        struct dentry *debugfs_dapm;

#endif

};

在(1)中的snd_soc_dai_ops结构体则描述CODEC的时钟、PLL以及各式设置,主要包括set_sysclk()、set_pll()、set_clkdiv()、set_fmt()等成员函数。

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

/*

 * Digital Audio Interface.

 *

 * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97

 * operations and capabilities. Codec and platform drivers will register this

 * structure for every DAI they have.

 *

 * This structure covers the clocking, formating and ALSA operations for each

 * interface.

 */

struct snd_soc_dai_ops {

        /*

         * DAI clocking configuration, all optional.

         * Called by soc_card drivers, normally in their hw_params.

         */    /*DAI时钟配置*/

        int (*set_sysclk)(struct snd_soc_dai *dai,

                  int clk_id, unsigned int freq, int dir);

        int (*set_pll)(struct snd_soc_dai *dai,

                  int pll_id, unsigned int freq_in, unsigned int freq_out);

        int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);

 

        /*

         * DAI format configuration

         * Called by soc_card drivers, normally in their hw_params.

         */      /*DAI格式设置*/

        int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);

        int (*set_tdm_slot)(struct snd_soc_dai *dai,

                  unsigned int tx_mask, unsigned int rx_mask,

                  int slots, int slot_width);

        int (*set_tristate)(struct snd_soc_dai *dai, int tristate);

 

        /*

         * DAI digital mute - optional.

         * Called by soc-core to minimise any pops.

         */     /*数字静音*/

        int (*digital_mute)(struct snd_soc_dai *dai, int mute);

 

        /*

         * ALSA PCM audio operations - all optional.

         * Called by soc-core during audio PCM operations.

         */    /*在操作PCM时由soc-core调用进行PCM操作*/

          /*音频流开始采集和播放时的一些动作*/

        int (*startup)(struct snd_pcm_substream *,

                  struct snd_soc_dai *);    /*启动*/

        void (*shutdown)(struct snd_pcm_substream *,

                  struct snd_soc_dai *);    /*关闭*/

        int (*hw_params)(struct snd_pcm_substream *,

                  struct snd_pcm_hw_params *, struct snd_soc_dai *);  /*硬件参数设置*/

        int (*hw_free)(struct snd_pcm_substream *,

                  struct snd_soc_dai *);    /*硬件参数释放*/

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>