unsigned int rate;
long pmdown_time;
/* runtime devices */
struct snd_pcm *pcm; //pcm结构体
struct snd_soc_codec *codec; //codec设备
struct snd_soc_platform *platform; //soc平台设备
struct snd_soc_dai *codec_dai; //dai设备 codec
struct snd_soc_dai *cpu_dai; //dai设备 cpu
struct delayed_work delayed_work;
};
struct snd_soc_pcm_runtime {
struct device dev; //设备文件
struct snd_soc_card *card; //soc声卡设备
struct snd_soc_dai_link *dai_link; //dai link
unsigned int complete:1;
unsigned int dev_registered:1;
/* Symmetry data - only valid if symmetry is being enforced */
unsigned int rate;
long pmdown_time;
/* runtime devices */
struct snd_pcm *pcm; //pcm结构体
struct snd_soc_codec *codec; //codec设备
struct snd_soc_platform *platform; //soc平台设备
struct snd_soc_dai *codec_dai; //dai设备 codec
struct snd_soc_dai *cpu_dai; //dai设备 cpu
struct delayed_work delayed_work;
};
snd_soc_pcm_runtime结构体中包含一个snd_pcm结构体,所以可以认为它是pcm声卡设备的一个封装,其次他也是Asoc各个组件的一个关系网点
3.soc声卡设备的匹配过程
在sound/soc/soc-core.c中定义了一个平台设备驱动
[cpp] static struct platform_driver soc_driver = {
.driver = {
.name = "soc-audio",
.owner = THIS_MODULE,
.pm = &soc_pm_ops,
},
.probe = soc_probe,
.remove = soc_remove,
};
static struct platform_driver soc_driver = {
.driver = {
.name = "soc-audio",
.owner = THIS_MODULE,
.pm = &soc_pm_ops,
},
.probe = soc_probe,
.remove = soc_remove,
};我们知道平台设备驱动和平台设备的匹配靠.driver.name名字,也就是在另一处代码中必须定义了平台设备platform_device且设备名必须为"soc-audio",
这样平台设备和驱动才能匹配,才会调用平台驱动的probe方法,既soc_probe
所以一般声卡的驱动程序中会按以下格式设计平台设备
[cpp] int ret;
static struct platform_device *xxx;
xxx=platform_device_alloc("soc-audio", 0); //分配平台驱动
//平台资源的添加
ret=platform_device_add(xxx); //添加平台设备
if(ret)
platform_device_put(xxx); //增加引用计数
int ret;
static struct platform_device *xxx;
xxx=platform_device_alloc("soc-audio", 0); //分配平台驱动
//平台资源的添加
ret=platform_device_add(xxx); //添加平台设备
if(ret)
platform_device_put(xxx); //增加引用计数
4.匹配调用的probe方法soc_probe
[cpp] static int soc_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev); //获取soc声卡设备
int ret = 0;
/* Bodge while we unpick instantiation */
card->dev = &pdev->dev;
INIT_LIST_HEAD(&card->dai_dev_list); //初始化dai_dev_list链表
INIT_LIST_HEAD(&card->codec_dev_list); //初始化codec_dev_list链表
INIT_LIST_HEAD(&card->platform_dev_list); //初始化platform_dev_list链表
ret = snd_soc_register_card(card); //注册soc声卡设备
if (ret != 0) {
dev_err(&pdev->dev, "Failed to register card\n");
return ret;
}
return 0;
}
static int soc_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev); //获取soc声卡设备
int ret = 0;
/* Bodge while we unpick instantiation */
card->dev = &pdev->dev;
INIT_LIST_HEAD(&card->dai_dev_list); //初始化dai_dev_list链表
INIT_LIST_HEAD(&card->codec_dev_list); //初始化codec_dev_list链表
INIT_LIST_HEAD(&card->platform_dev_list); //初始化platform_dev_list链表
ret = snd_soc_register_card(card); //注册soc声卡设备
if (ret != 0) {
dev_err(&pdev->dev, "Failed to register card\n");
return ret;
}
return 0;
}这里调用了snd_soc_register