alsa音频架构2--ASoc (二)

2014-11-24 01:38:45 · 作者: · 浏览: 5
lid 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;
};

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