ASOC框架(二)

前言在前面ASOC框架(一)我们知道ASOC被分为Machine,Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的代码,ASoC的一切都从Machine驱动开始,包括声卡的注册,绑定Platform和Codec驱动等等,我们之前说过写一个ALSA声卡驱动的步骤有如下三步:1 . snd_card_create 2 . 初始化:创建逻辑设备 snd_pcm_new3 . snd_card_register我们说过AS
摘要由CSDN通过智能技术生成

前言

在前面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部分
在这里插入图片描述

machine部分

ASoC把声卡注册为Platform Device,我们以装配有uda134x的一款Samsung的开发板SMDK为例子做说明,我们看到初始化入口soc_probe()
在这里插入图片描述
私有数据

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值