上小节我们讲解了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的名字。如: