概述
现在来实际应用一下DAPM(在ASoC-codec层进行操作),先展示一下效果:
可以看到上面主要包括了三大类型:
1.音量控制
2.Lineout开关
3.DAC-Mixer的通路开关
第一类-带增益音量控制(tlv)
设置好tlv
static const DECLARE_TLV_DB_SCALE(digital_tlv, 0, -96, -5478);
static const unsigned int lineout_tlv[] = {
TLV_DB_RANGE_HEAD(2),
0, 0, TLV_DB_SCALE_ITEM(0, 0, 1),
1, 31, TLV_DB_SCALE_ITEM(-2460, 120, 1),
};
创建control
struct snd_kcontrol_new codec_controls[] = {
SOC_SINGLE_TLV("digital volume", DAC_DPC, DVOL, 0x4E, 1, digital_tlv),
SOC_SINGLE_TLV("lineout volume", DAC_REG, LINEOUT_VOL, 0x2A, 0, lineout_tlv),
};
注:SOC_SINGLE_TLV是用来设置名字、寄存器、便宜、最大值、mute以及tlv的
注册(在platform_driver的probe函数)
ret = snd_soc_add_component_controls(component, codec_controls,
ARRAY_SIZE(codec_controls));
第二类-Lineout开关
带三类-DAC-Mixer的通路开关
这两类一起介绍,因为它们都涉及到了control之间的连接,需要使用到widget
创建Mixer控件
static const struct snd_kcontrol_new left_output_mixer[] = {
SOC_DAPM_SINGLE("DACL Switch", MIXER_REG, LMIX_LDAC, 1, 0),
SOC_DAPM_SINGLE("DACR Switch", MIXER_REG, LMIX_RDAC, 1, 0),
};
static const struct snd_kcontrol_new right_output_mixer[] = {
SOC_DAPM_SINGLE("DACL Switch", MIXER_REG, RMIX_LDAC, 1, 0),
SOC_DAPM_SINGLE("DACR Switch", MIXER_REG, RMIX_RDAC, 1, 0),
};
创建widget
static const struct snd_soc_dapm_widget codec_dapm_widgets[] = {
/* 定义音频输入接口作为通路的起点 */
SND_SOC_DAPM_AIF_IN_E("DACL", "Playback", 0, DAC_REG, DACLEN, 0,
codec_playback_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_AIF_IN_E("DACR", "Playback", 0, DAC_REG, DACREN, 0,
codec_playback_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
/* 定义widget-mixer */
SND_SOC_DAPM_MIXER("OutputL Mixer", MIXER_REG, LMIXEN, 0,
left_output_mixer, ARRAY_SIZE(left_output_mixer)),
SND_SOC_DAPM_MIXER("OutputR Mixer", MIXER_REG, RMIXEN, 0,
right_output_mixer, ARRAY_SIZE(right_output_mixer)),
/* 定义输出引脚,作为通路终点 */
SND_SOC_DAPM_OUTPUT("LINEOUTL"),
SND_SOC_DAPM_OUTPUT("LINEOUTR"),
/* 作为通路的线路输入 */
SND_SOC_DAPM_LINE("LINEOUT", lineout_event),
};
这里涉及到了事件event,也就是自己可以定义一个函数,让它在上电前、后或断电前、后执行,一般就是用于控制对应的寄存器
event的原型
static int lineout_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
执行时机可以在事件函数里面用switch简单地判断
switch (event) {
case:
...
}
既然设计到了音频通路的连接,那么接下来则需要创建通路
创建route
static const struct snd_soc_dapm_route codec_dapm_routes[] = {
/* 设置DAC和mixer直接的通路 */
{"OutputL Mixer", "DACR Switch", "DACR"},
{"OutputL Mixer", "DACL Switch", "DACL"},
{"OutputR Mixer", "DACL Switch", "DACL"},
{"OutputR Mixer", "DACR Switch", "DACR"},
/* 让mixer和输出端点直连 */
{"LINEOUTL", NULL, "OutputL Mixer"},
{"LINEOUTR", NULL, "OutputR Mixer"},
};
添加widget和route(在platform_driver的probe函数)
ret = snd_soc_dapm_new_controls(dapm, codec_dapm_widgets,
ARRAY_SIZE(codec_dapm_widgets));
ret = snd_soc_dapm_add_routes(dapm, codec_dapm_routes,
ARRAY_SIZE(codec_dapm_routes));
最后
以上就是魁梧白猫为你收集整理的DAPM实战应用的全部内容,希望文章能够帮你解决DAPM实战应用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复