平台 | 内核版本 | 安卓版本 |
---|---|---|
RK3399 | Linux4.4 | Android7.1 |
ALSA DAPM
设计dapm
的主要目的之一,就是希望声卡上的各种部件的电源按需分配,需要的就上电,不需要的就下电,使得整个音频系统总是处于最小的耗电状态,最主要的就是,这一切对用户空间的应用程序是透明的,也就是说,用户空间的应用程序无需关心那个部件何时需要电源,它只要按需要设定好音频路径,播放音频数,暂停或停止,dapm
框架会根据音频路径,完美地对各种部件的电源进行控制,而且精确地按某种顺序进行,防止上下电过程中产生不必要的pop-pop
声
kcontrol
一个kcontrol
代表着一个mixer
(混音器),或是一个mux
(多路开关),或是一个音量控制器等
-
Mixer
控件
Mixer
控件用于音频通道的路由控制,由多个输入和一个输出组成,多个输入可以自由地混合在一起,形成混合后的输出
-
Mux
控件
mux
控件与mixer
控件类似,也是多个输入端和一个输出端的组合控件,与mixer
控件不同的是,mux
控件的多个输入端同时只能有一个被选中 -
SOC_SINGLE
(DAC Stereo Enhancement
)
这种控件只有一个控制量,比如一个开关,Codec
中某个频率,FIFO
大小等
定义一个kcontrol
主要就是定义一个snd_kcontrol_new
结构
struct snd_kcontrol_new {
...
snd_kcontrol_get_t *get;
snd_kcontrol_put_t *put;
...
unsigned long private_value;
};
get | 回调函数用于获取该控件当前的状态值 |
put | 回调函数则用于设置控件的状态值 |
private_value | 字段则根据不同的控件类型有不同的意义 |
比如对于普通的控件,private_value字段可以用来定义该控件所对应的寄存器的地址以及对应的控制位在寄存器中的位置信息
实例
-
SOC_SINGLE(DAC Stereo Enhancement)
这种控件只有一个控制量,比如一个开关,Codec
中某个频率,FIFO大
小等
寄存器描述如下
用寄存器0x32
偏移量0
,最大值7
,描述DAC stereo
SOC_SINGLE("DAC Stereo Enhancement", ES8316_DAC_SET3_REG32, 0, 7, 0)
-
SOC_SINGLE_TLV(Mic Boost)
SOC_SINGLE_TLV
是SOC_SINGLE
的一种扩展,主要用于定义那些有增益控制的控件,例如音量控制器,EQ
均衡器等
寄存器描述如下
对应dB数是0.01dB*1200 = 12dB
static const DECLARE_TLV_DB_SCALE(mic_bst_tlv, 0, 1200, 0);
SOC_SINGLE_TLV("MIC Boost", ES8316_ADC_D2SEPGA_REG24, 0, 1, 0, mic_bst_tlv),
Headphone Mixer Mux
硬件框图如下
寄存器描述如下
文字描述
static const char *const es8316_hpmux_texts[] = {
"lin1-rin1",
"lin2-rin2",
"lin-rin with Boost",
"lin-rin with Boost and PGA"
};
取值范围
static const unsigned int es8316_hpmux_values[] = {0, 1, 2, 3};
用REG13
寄存器偏移4位起来控制左通道,最大值7
,取值见values
数组
static const struct soc_enum es8316_left_hpmux_enum =
SOC_VALUE_ENUM_SINGLE(ES8316_HPMIX_SEL_REG13, 4, 7,
ARRAY_SIZE(es8316_hpmux_texts),
es8316_hpmux_texts,
es8316_hpmux_val
添加到kcontrol
static const struct snd_kcontrol_new es8316_left_hpmux_controls =
SOC_DAPM_VALUE_ENUM("Route", es8316_left_hpmux_enum);
用REG13
寄存器偏移0
位起来控制右通道,最大值7
,取值见values
数组
static const struct soc_enum es8316_right_hpmux_enum =
SOC_VALUE_ENUM_SINGLE(ES8316_HPMIX_SEL_REG13, 0, 7,
ARRAY_SIZE(es8316_hpmux_texts),
es8316_hpmux_texts,
es8316_hpmux_values);
添加到kcontrol
static const struct snd_kcontrol_new es8316_right_hpmux_controls =
SOC_DAPM_VALUE_ENUM("Route", es8316_right_hpmux_enum);
将kcontrol
添加到dapm widget
中,用tinymix
可以看到对应的名字
SND_SOC_DAPM_MUX("Left Hp mux", SND_SOC_NOPM, 0, 0,
&es8316_left_hpmux_controls),
SND_SOC_DAPM_MUX("Right Hp mux", SND_SOC_NOPM, 0, 0,
&es8316_right_hpmux_control
- Analog Input MUX
硬件框图:
寄存器描述
名字
static const char * const es8316_analog_in_txt[] = {
"lin1-rin1",
"lin2-rin2",
"lin1-rin1 with 20db Boost",
"lin2-rin2 with 20db Boost"
};
取值范围
static const unsigned int es8316_analog_in_values[] = {
0,/*1,*/
1,
2,
3
};
用寄存器0x22
第4
位起控制,最大值3
,取值范围见values
数组
static const struct soc_enum es8316_analog_input_enum =
SOC_VALUE_ENUM_SINGLE(ES8316_ADC_PDN_LINSEL_REG22, 4, 3,
ARRAY_SIZE(es8316_analog_in_txt),
es8316_analog_in_txt,
es8316_analog_in_values);
添加到kcontrol
static const struct snd_kcontrol_new es8316_analog_in_mux_controls =
SOC_DAPM_ENUM("Route", es8316_analog_input_enum);
将kcontrol
添加到dapm widget
中,用tinymix
可以看到对应的名字
SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
&es8316_analog_in_mux_controls),