• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

ALSA框架学习笔记3声卡注册流程代码

武飞扬头像
Joker524_
帮助6

以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回调;

二、代码分析

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层播放音频,调节音量的流程,在后续文章中再分析。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfhfejj
系列文章
更多 icon
同类精品
更多 icon
继续加载