音频系统概述
音频系统通过数据+控制总线与CODEC连接,控制通路用I2C,数据通常为I2S,框图如图1所示。
I2C:寄存器读写,用于配置CODEC控制通路。
I2S:音频数据传输,通常与platform驱动配合实现dma数据搬运。
图1 音频系统框图
ALSA驱动总的结构体即snd_soc_card。
/* SoC card */
struct snd_soc_card {
const char *name;
...
int (*probe)(struct snd_soc_card *card);
int (*late_probe)(struct snd_soc_card *card);
int (*remove)(struct snd_soc_card *card);
/* the pre and post PM functions are used to do any PM work before and
* after the codec and DAI's do any PM work. */
int (*suspend_pre)(struct snd_soc_card *card);
int (*suspend_post)(struct snd_soc_card *card);
int (*resume_pre)(struct snd_soc_card *card);
int (*resume_post)(struct snd_soc_card *card);
...
/* CPU <--> Codec DAI links */
struct snd_soc_dai_link *dai_link; /* predefined links only */
int num_links; /* predefined links only */
...
};
该结构体在Machine驱动中通过snd_soc_register_card注册到ALSA,snd_soc_card成员dai_link中指定codec_name, platform_name,从而实现与platform, codec驱动的绑定,框图如图2所示。
图2 ALSA驱动框图
Machine驱动:该驱动实现snd_soc_card的定义与注册,并通过指定snd_soc_dai_link中的codec_name, platform_name, codec_dai_name, platform_dai_name从而实现与其它各个驱动组件的绑定。
Platform驱动:向ALSA platform_list注册snd_soc_platform_driver,并通过snd_soc_ops暴露其音频能力,
Codec驱动:向ALSA codec_list注册snd_soc_codec_driver,linux5.10有所调整,通过注册devm_snd_soc_register_component挂载自己的音频能力,但是原理类似,通常codec驱动还需要注册kcontrol, widget, route等通路信息。