5. 创建声卡

 代码位置 sound/soc/generic/simple-card.c

static int asoc_simple_card_probe(struct platform_device *pdev)
{...ret = devm_snd_soc_register_card(dev, card);...
}

 asoc_simple_card_probe -> devm_snd_soc_register_card -> snd_soc_register_card

int snd_soc_register_card(struct snd_soc_card *card)
{int i, ret;struct snd_soc_pcm_runtime *rtd;if (!card->name || !card->dev)return -EINVAL;for (i = 0; i < card->num_links; i++) {struct snd_soc_dai_link *link = &card->dai_link[i];ret = soc_init_dai_link(card, link);if (ret) {dev_err(card->dev, "ASoC: failed to init link %s\n",link->name);return ret;}}...
}

soc_init_dai_link执行后,会出现下面红框内的链接

 继续分析

asoc_simple_card_probe -> devm_snd_soc_register_card -> snd_soc_register_card -> snd_soc_instantiate_card -> soc_bind_dai_link

int snd_soc_register_card(struct snd_soc_card *card)
{...dev_set_drvdata(card->dev, card);snd_soc_initialize_card_lists(card);INIT_LIST_HEAD(&card->dai_link_list);card->num_dai_links = 0;INIT_LIST_HEAD(&card->rtd_list);card->num_rtd = 0;INIT_LIST_HEAD(&card->dapm_dirty);INIT_LIST_HEAD(&card->dobj_list);card->instantiated = 0;mutex_init(&card->mutex);mutex_init(&card->dapm_mutex);ret = snd_soc_instantiate_card(card);...}
}static int snd_soc_instantiate_card(struct snd_soc_card *card)
{struct snd_soc_pcm_runtime *rtd;struct snd_soc_dai_link *dai_link;int ret, i, order;mutex_lock(&client_mutex);mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);/* check whether any platform is ignore machine FE and using topology */soc_check_tplg_fes(card);/* bind DAIs */for (i = 0; i < card->num_links; i++) {ret = soc_bind_dai_link(card, &card->dai_link[i]);if (ret != 0)goto base_error;}...
}static int soc_bind_dai_link(struct snd_soc_card *card,struct snd_soc_dai_link *dai_link)
{struct snd_soc_pcm_runtime *rtd;struct snd_soc_dai_link_component *codecs = dai_link->codecs;struct snd_soc_dai_link_component cpu_dai_component;struct snd_soc_component *component;struct snd_soc_dai **codec_dais;struct device_node *platform_of_node;const char *platform_name;int i;if (dai_link->ignore)return 0;dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name);if (soc_is_dai_link_bound(card, dai_link)) {dev_dbg(card->dev, "ASoC: dai link %s already bound\n",dai_link->name);return 0;}/* 创建rtd */rtd = soc_new_pcm_runtime(card, dai_link);if (!rtd)return -ENOMEM;cpu_dai_component.name = dai_link->cpu_name;cpu_dai_component.of_node = dai_link->cpu_of_node;cpu_dai_component.dai_name = dai_link->cpu_dai_name;rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component);if (!rtd->cpu_dai) {dev_info(card->dev, "ASoC: CPU DAI %s not registered\n",dai_link->cpu_dai_name);goto _err_defer;}/* 关联cpu */snd_soc_rtdcom_add(rtd, rtd->cpu_dai->component);rtd->num_codecs = dai_link->num_codecs;/* Find CODEC from registered CODECs */codec_dais = rtd->codec_dais;for (i = 0; i < rtd->num_codecs; i++) {codec_dais[i] = snd_soc_find_dai(&codecs[i]);if (!codec_dais[i]) {dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",codecs[i].dai_name);goto _err_defer;}snd_soc_rtdcom_add(rtd, codec_dais[i]->component);}/* Single codec links expect codec and codec_dai in runtime data */rtd->codec_dai = codec_dais[0];/* if there's no platform we match on the empty platform */platform_name = dai_link->platform_name;if (!platform_name && !dai_link->platform_of_node)platform_name = "snd-soc-dummy";/* find one from the set of registered platforms */list_for_each_entry(component, &component_list, list) {platform_of_node = component->dev->of_node;if (!platform_of_node && component->dev->parent->of_node)platform_of_node = component->dev->parent->of_node;if (dai_link->platform_of_node) {if (platform_of_node != dai_link->platform_of_node)continue;} else {if (strcmp(component->name, platform_name))continue;}/* 关联codec*/snd_soc_rtdcom_add(rtd, component);}soc_add_pcm_runtime(card, rtd);return 0;_err_defer:soc_free_pcm_runtime(rtd);return  -EPROBE_DEFER;
}

asoc_simple_card_probe -> devm_snd_soc_register_card -> snd_soc_register_card -> snd_soc_instantiate_card -> snd_soc_add_dai_link

 

static int snd_soc_instantiate_card(struct snd_soc_card *card)
{/* add predefined DAI links to the list */for (i = 0; i < card->num_links; i++) snd_soc_add_dai_link(card, card->dai_link+i);...
}

主要是将dai_link挂载到card的dai_link上面,上图已经连接


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部