以Amlogic V918D为例,介绍驱动如何将设备树中的声卡节点注册为声卡设备
一、设备树中的声卡节点
/* Audio Related start */
auge_sound {
compatible = "amlogic, auge-sound-card";
aml-audio-card,name = "AML-AUGESOUND";
...
aml-audio-card,dai-link@0 {
...
};
aml-audio-card,dai-link@1 {
...
};
...
aml-audio-card,dai-link@7 {
...
};
};
/* Audio Related end */
声卡名为"AML-AUGESOUND",下面有8个dai-link,每一个dai-link下面都有cpu dai和codec dai设备节点。每个dai-link都会被注册为一个pcm设备,这里先列出简化的流程:
->aml_card_probe
->devm_snd_soc_register_card
->snd_soc_register_card
->snd_soc_bind_card
->snd_soc_instantiate_card
->soc_link_init
->soc_new_pcm
->snd_pcm_new
从上一遍文章知道cpu dai和codec dai都被注册为了component,可以猜想:
1、生成pcm设备就是根据dai-link,分别找到cpu dai和codec dai对应的component,然后建立联系;
2、对pcm进行操作时,比如open(),一定会同时触发cpu dai的open和codec dai的open回调;
二、代码分析文章来源:https://www.toymoban.com/news/detail-596356.html
static int aml_card_probe(struct platform_device *pdev)
{
/* 1. 统计"dai-link"子节点的个数num,也即最终会生成pcm设备的个数 */
/* 2. 给dai_link[num]分配内存空间 */
/* 3. 解析声卡节点的各个属性,以及每个dai-link子节点的各类属性 */
/* 4. 关联结构体,见下图一 */
/* 5. 注册声卡 */
devm_snd_soc_register_card(&pdev->dev, &priv->snd_card)
{
snd_soc_register_card(card)
{
snd_soc_bind_card(card)
{
snd_soc_instantiate_card(card)
{
/* 5.1 遍历声卡下的所有dai_link */
for_each_card_prelinks(card, i, dai_link) {
/* 根据dai_link下的codec/cpu/platform去查找对应的component */
ret = soc_init_dai_link(card, dai_link);
...
}
/* 5.2 遍历声卡下的所有dai_link */
for_each_card_prelinks(card, i, dai_link) {
/* dai_link下的component和pcm绑定,就是确定了pcm下cpu dai对应的component和codec dai对应的component。 */
ret = soc_bind_dai_link(card, dai_link);
...
}
/* 5.3 new一个card */
ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, card->owner, 0, &card->snd_card);
/* 5.4 调card的probe函数 */
card->probe(card);
/* 5.5 遍历component调用其driver的probe。(component->driver->probe) */
ret = soc_probe_link_components(card);
/* 5.6 调用绑定在pcm上的cpu dai和codec dai。(dai->driver->probe)*/
ret = soc_probe_link_dais(card);
/* 5.7 创建pcm设备*/
for_each_card_rtds(card, rtd)
{
soc_link_init(card, rtd)
{
ret = soc_new_pcm(rtd, num);
}
}
/* 5.8 注册card */
ret = snd_card_register(card->snd_card);
}
}
}
}
/* 6. 添加kcontrols,主要是针对CPU DAI的kcontrols,或者说平台根据自身硬件设定好的,一般不需要用户修改。用户主要关注注册在CODEC上的kcontrols。 */
aml_card_add_controls(&priv->snd_card)
/* 7. 处理音效相关,比如EQ、DRC等 */
card_add_effects_init(&priv->snd_card)
/* 8. 添加kcontrols */
snd_soc_add_card_controls(&priv->snd_card, snd_user_controls,
ARRAY_SIZE(snd_user_controls));
}
图一:
三、总结
1、声卡的注册流程一般是SOC侧负责,在适配新的codec的时候,一般也不需要去动这块流程。它像是一个框架,开放给用户去定制的部分就是设备树中相关的dai节点;
2、在声卡的驱动中,会看到很多地方在注册DAPM的kcontrol(设备中可以通过timymix查看和设置)。codec也可以在自己的driver中注册增加自己的kcontrol;
3、kcontrol有啥用呢?首先这个东西是给用户层开放的直接设置声卡参数的,比如用tinymix工具通过设置各个kcontrol的属性,去调式音频链路。那Android里会不会用这个呢?目前没有看到类似应用;
4、一开始有个疑问:Android设备调音量的时候,会不会设置到codec的硬件上?查阅后发现实际上并不会,Andorid调节的媒体音量、闹钟音量等都是数字音量,是在streamVolume上实现的。关于Android层播放音频,调节音量的流程,在后续文章中再分析。文章来源地址https://www.toymoban.com/news/detail-596356.html
到了这里,关于ALSA框架学习笔记3:声卡注册流程(代码解析)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!