08.音频系统:第003课_Linux音频驱动程序:第008节_DAPM的情景分析_构造过程

本文详细解析了Linux声卡驱动中DAPM(Digital Audio Processing Model)的工作原理,通过具体实例展示了kcontrols、widgets和paths的构建过程,以及它们之间的连接方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上小节我们讲解了route_path添加过程分析,该小节我们进行DAPM的情景的情景分析,即讲解几个例子。下面是一个图示(看起来比较混乱,不过没有关系,可以当做接线部分不存在,然后再讲解的过程中慢慢观看):
在这里插入图片描述
下面,我们将围绕上图示进行讲解:
在linux系统中,其会用一个结构体去表示一个硬件,其中结构体snd_soc_card就表示我们的声卡,其中有两个链表,分别为widgets,snd_card(controls链表),paths。我们看看这些链表是怎么构造出来的。打开rt5651.c文件,我们先讲解普通的kcontrols。

在源码中,找到如下:

static const struct snd_kcontrol_new rt5651_snd_controls[] = {
	/* Headphone Output Volume */
	SOC_DOUBLE_TLV("HP Playback Volume", RT5651_HP_VOL,
		RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, 39, 1, out_vol_tlv),
	/* OUTPUT Control */
	SOC_DOUBLE_TLV("OUT Playback Volume", RT5651_LOUT_CTRL1,
		RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, 39, 1, out_vol_tlv),
			......
};

我们把其中1,2项的名字都标注在图中的controls下面,用蓝色字体。我们在开发板执行tinymix命令,可以看到与其一一对应。

在snd_soc_card卡中还存在widgets链表,其如何使用的:

static const struct snd_soc_dapm_widget rt5651_dapm_widgets[] = {
	......
	/* Input Lines */
	SND_SOC_DAPM_INPUT("IN2P"),
	SND_SOC_DAPM_INPUT("IN2N"),
	/* Boost */
	SND_SOC_DAPM_PGA_E("BST2", RT5651_PWR_ANLG2,RT5651_PWR_BST2_BIT, 0, NULL, 0, rt5651_bst2_event,SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
	SND_SOC_DAPM_MIXER("RECMIXL", RT5651_PWR_MIXER, RT5651_PWR_RM_L_BIT, 0,rt5651_rec_l_mix, ARRAY_SIZE(rt5651_rec_l_mix)),
	SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0),
	......
}

同上,使用蓝色字体在图中标出。

下面我们看看paths:

static const struct snd_soc_dapm_route rt5651_dapm_routes[] = {
	{"IN2P", NULL, "LDO"},		
	{"IN2P", NULL, "MIC2"},
	{"IN2N", NULL, "MIC2"},
	{"BST2", NULL, "IN2P"},
	{"BST2", NULL, "IN2N"},
	{"RECMIXL", "BST2 Switch", "BST2"},
	{"ADC L", NULL, "RECMIXL"},
}

根据以上我们可以规划出一天路线:
在这里插入图片描述
图中使用红色箭头线表示,

前面提到snd_soc_dapm_widget中包含了kcontrol_new,我们查看:

/* Analog Input Mixer */
static const struct snd_kcontrol_new rt5651_rec_l_mix[] = {
	SOC_DAPM_SINGLE("INL1 Switch", RT5651_REC_L2_MIXER,
			RT5651_M_IN1_L_RM_L_SFT, 1, 1),
	SOC_DAPM_SINGLE("BST3 Switch", RT5651_REC_L2_MIXER,
			RT5651_M_BST3_RM_L_SFT, 1, 1),
	SOC_DAPM_SINGLE("BST2 Switch", RT5651_REC_L2_MIXER,
			RT5651_M_BST2_RM_L_SFT, 1, 1),
	SOC_DAPM_SINGLE("BST1 Switch", RT5651_REC_L2_MIXER,
			RT5651_M_BST1_RM_L_SFT, 1, 1),
};
SND_SOC_DAPM_MIXER("RECMIXL", RT5651_PWR_MIXER, RT5651_PWR_RM_L_BIT, 0,
			   rt5651_rec_l_mix, ARRAY_SIZE(rt5651_rec_l_mix)),

可以看到其包含了4个kcontrol_new,与我们分析的一致,下面我们看看他们是如何构建path的,前面我们提到,通过snd_soc_dapm_route生成path如下步骤:
1.根据name找到widget。
2.构造path
3.设置path->connet

现在我们通过:

static const struct snd_soc_dapm_route rt5651_dapm_routes[] = {
	{"IN2P", NULL, "LDO"},		
	{"IN2P", NULL, "MIC2"},
	{"IN2N", NULL, "MIC2"},
	{"BST2", NULL, "IN2P"},
	{"BST2", NULL, "IN2N"},
	{"RECMIXL", "BST2 Switch", "BST2"},
	{"ADC L", NULL, "RECMIXL"},
}

可以作出如下框图:
在这里插入图片描述
这样,就有和我们前面分析的
在这里插入图片描述
路线是一致的,其中path的状态是可以查看的,通过执行tinymix,如果为off代表connect=0,没有连接,on则代表connect=1,已经连接。而且他们的名字为sink的名字加上kcontrol的名字。如:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江南才尽,年少无知!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值