主要分为以下几类:
pcmC0D0p —— Playback
pcmC0D0c —— Capture
controlC0 —— Control,比如各种音频控件开关、音量增益等
一套嵌入式硬件平台(Machine)包含了平台AP(Platform)和音频CODEC芯片(Codec),对应ASoC的三个设备驱动。这三个设备分别注册各自功能的dev设备,但都是以内核platform设备模型来创建.
https://blog.csdn.net/RadianceBlau/article/details/79432661
https://blog.csdn.net/u014310046/article/details/53671853
https://blog.csdn.net/longwang155069/article/details/53392769
ASOC音频架构
为了实现上述的新feature,ASOC将嵌入式音频系统分为三大类可重复使用的驱动程序: Platform, Machine, Codec。
Codec类: Codec即编解码芯片的驱动,此Codec驱动是和平台无关,包含的功能有: 音频的控制接口,音频读写IO接口,以及DAPM的定义等。如果需要的话,此Codec类可以在BT,FM,MODEM模块中不做修改的使用。因此Codec就是一个可重复使用的模块,同一个Codec在不同的SOC中可以使用。
Platform类: 可以理解为某款SOC平台,平台驱动中包括音频DMA引擎驱动,数字接口驱动(I2S, AC97, PCM)以及该平台相关的任何音频DSP驱动。同样此Platform也可以重用,在不同的Machine中可以直接重复使用。
Machine类: Machine可以理解为是一个桥梁,用于在Codec和Platform之间建立联系。此Machine指定了该机器使用那个Platform,那个Codec,最终会通过Machine建立两者之间的联系。
ASoC把音频系统同样分为3大部分:Machine,Platform/CPU和Codec。
Platform :
一般是指某一个SoC平台,比如MT6582, MT6595, MT6752等等,与音频相关的通常包含该SoC中的Clock、AFE、I2S、DMA等等。
Codec : 字面上的意思就是编解码器,Codec里面包含了I2S接口、DAC、ADC、Mixer、PA(功放),通常包含多种输入(Mic、Line-in、I2S、PCM)和多个输出(耳机、喇叭、听筒,Line-out),Codec和Platform一样,是可重用的部件。
Machine :
绑定platform driver和codec driver 。
一、Machine设备驱动 :
Machine设备可以看成是一块嵌入式主板(Board) 或者一块声卡。machine设备驱动是ASoC驱动框架的入口, 主要功能是负责platform/cpu和codec之间的连接和控制,或者响应独立于Platform功能和Codec功能之外的特殊音频事件,如平台GPIO控制外置功放等,这些属于machine本身的特定操作代码,都会放到machine驱动里。
Machine设备驱动的主要功能是定义各种DAI(Digital Audio Interface) links,它的作用是把platform/cpu和codec设备驱动连接起来,形成完整的音频通路。
machine设备的初始化是整个ASoC驱动的入口。 machine设备的probe()会调用snd_soc_register_card()去注册声卡,然后在snd_soc_instantiate_card()里实例化声卡设备的时候,调用Platform和Codec设备各自的probe(),完成这两个设备的初始化。
sound/soc/mediatek/common_int/mtk-soc-machine.c
"mediatek,audio"
.probe = mt_soc_snd_init,
platform_set_drvdata(pdev, &mt_snd_soc_card_mt);
static struct snd_soc_card mt_snd_soc_card_mt = {
.name = "mt-snd-card",
.dai_link = mt_soc_dai_common,
.num_links = ARRAY_SIZE(mt_soc_dai_common),
};
snd_soc_register_card
snd_soc_instantiate_card
1. 根据num_links的值,进行DAIs的bind工作。第一步先bind cpu侧的dai
snd_soc_find_dai 此函数会在component_list链表中先找到相同的name,然后在component->dai_list中查找是否有相同的dai_name。此处的component_list是在注册codec和platform中的时候设置的。会在codec和platform的时候会详细介绍。在此处找到注册的cpu_dai之后,存在snd_soc_pcm_runtime中的cpu_dai中。
2. 然后根据codec的数据,寻找codec侧的dai。
snd_soc_find_dai
然后将找到的codec侧的dai也同样赋值给snd_soc_pcm_runtime中的codec_dai中。
3.在platform_list链表中查找platfrom,根据dai_link中的platform_name域。如果没有platform_name,则设置为"snd-soc-dummy"
这样查找完毕之后,snd_soc_pcm_runtime中存储了查找到的codec, dai, platform。
4. 接着初始化注册的codec cache&