欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ASOC框架(二)

程序员文章站 2022-07-06 09:37:40
...

前言

在前面ASOC框架(一)我们知道ASOC被分为Machine,Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的代码,ASoC的一切都从Machine驱动开始,包括声卡的注册,绑定Platform和Codec驱动等等,我们之前说过写一个ALSA声卡驱动的步骤有如下三步:

1 . snd_card_create 
2 . 初始化:创建逻辑设备 snd_pcm_new
3 . snd_card_register

我们说过ASOC已经是对ALSA的封装,所以以上步骤我们可以不用自己去做,ASOC帮我们做好了,我们往下看

代码分析

1.platform
1.1

s3c24xx-i2s.c : 把s3c24xx_i2s_dai放入链表dai_list, .name = "s3c24xx-iis",
s3c24xx_iis_dev_probe
  snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai);
    list_add(&dai->list, &dai_list);

1.2

sound/soc/samsung/dma.c:把samsung_asoc_platform放入了链表platform_list, .name = "samsung-audio",
samsung_asoc_platform_probe
  snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform);
    list_add(&platform->list, &platform_list);

2.codec
2.1

uda134x.c
uda134x_codec_probe
  snd_soc_register_codec(&pdev->dev,&soc_codec_dev_uda134x, &uda134x_dai, 1);
      struct snd_soc_codec *codec;
      codec->driver = codec_drv; = &soc_codec_dev_uda134x
      
      snd_soc_register_dais(dev, dai_drv, num_dai); // uda134x_dai
        list_add(&dai->list, &dai_list); : 把uda134x_dai放入了链表dai_list
        list_add(&codec->list, &codec_list);

上面的注册就形成了下面的链表,我们应该选择哪个DAI,哪个platform,哪个code来作为我们的声卡呢,这就是通过machine部分来决定的,我们下面看到machine部分
ASOC框架(二)

machine部分

ASoC把声卡注册为Platform Device,我们以装配有uda134x的一款Samsung的开发板SMDK为例子做说明,我们看到初始化入口soc_probe()
ASOC框架(二)
私有数据

static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
  .name = "UDA134X",
  .stream_name = "UDA134X",
  .codec_name = "uda134x-codec",
  .codec_dai_name = "uda134x-hifi",
  .cpu_dai_name = "s3c24xx-iis",
  .ops = &s3c24xx_uda134x_ops,
  .platform_name  = "samsung-audio",
};

该函数获取私有数据,然后注册该私有数据,我们看到snd_soc_register_card函数

int snd_soc_register_card(struct snd_soc_card *card)
{  
    ......
	card->rtd = devm_kzalloc(card->dev,
				 sizeof(struct snd_soc_pcm_runtime) *
				 (card->num_links + card->num_aux_devs),
				 GFP_KERNEL);
	for (i = 0; i < card->num_links; i++)
		card->rtd[i].dai_link = &card->dai_link[i];
	list_add(&card->list, &card_list);
	snd_soc_instantiate_cards();//实例化声卡
}

我们进去snd_soc_instantiate_cards函数看看

static void snd_soc_instantiate_cards(void)
{
	struct snd_soc_card *card;
	list_for_each_entry(card, &card_list, list)
		snd_soc_instantiate_card(card);
}

我们进去snd_soc_instantiate_card函数看后发现,该函数首先利用card->instantiated来判断该卡是否已经实例化,如果已经实例化则直接返回,否则遍历每一对dai_link,进行codec,platform,dai的绑定工作,在源码里面,CPU这一侧有很多个DAI,在声卡芯片这边有不同的声卡芯片,我们具体要用哪个DAI,哪个声卡,就需要进行绑定工作,根据我们的私有数据中的名字从中找到我们需要绑定的,接着会调用 snd_card_create , snd_pcm_new,snd_card_register

相关标签: 视频监控