1.概述
DAPM的全称为Dynamic Audio Power Management,动态音频电源管理,其存在的目的就是为了让音频系统工作在最低功耗。
简单来说就是根据数据流的路径来看相关的控件是否需要上电,不在工作音频路径上相关的控件就关闭掉,来降低功耗。
amixer contents 可以看到实例化出来的音频控件
amixer cset cget 在驱动实例化这些控件出来给用户来使用,用户可以在应用层直接的去修改控件的值来达到控制某些功能的目的。
2.snd_kcontrol_new
kernel\include\sound\control.h
damp的基础由snd_kcontrol_new来构建的,一个snd_kcontrol_new就代表这一个最小控件比如一个mux(多路开关),音量控制器等等。
3.ASOC定义的宏
3.1 SOC_SINGLE
只有一个控制量的控件,定义如下。
参数:
xname:控件名字
reg:控件在数据手册对应的寄存器
shift:管理该控件对应寄存器偏移量
max:控件可以设置的最大值
invert:设置值是否为逻辑反。
private_value用到了SOC_SINGLE_VALUE,定义如下。
可以看到这个宏会定义一个soc_mix_control结构体 并且把这个结构体首地址给private_value。
3.2 SOC_SINGLE_TLV
一般用于一些由增益控制的控件,定义如下
其中相比SOC_SINGLE比较不通的地方在于,tlv_array这个字段。
DECLARE_TLV_DB_SCALE 用于定义一个 dB 值映射的 tlv_array,结合对应寄存器说明可以看出范围是-96db,寄存器每增加1,对应的db增加(50*0.01db=0.5db)。
还有一些是double的控件 可以一次控两个寄存器的同一位移,也可以控制同一寄存器的两个不同位移处,这里就不一一举例了,感兴趣可以自己看看。
3.3 Mixer控件
用于音频通道的路由控制,由多个输入和一个输出组成,多个输入可以自由地混合在一起,形成混合后的输出:
所以对应在代码中应该是多个控件的组合
3.4 Mux控件:
类似于mixer,也是多端输入一个输出,但是不同的是mux同时只能有一个输入端被选中soc_enum结构如下。
先定义好text的值。
可以使用下面这些宏来填充结构体的值。
最后利用SOC_ENUM来定义控件。
4.DAPM的基本单元Widget
前面的定义中,虽然可以完成利用SOC Kcontrol完成对音频系统中的各种基本控件进行控制,但是还有一些不足。
(1)无法描述各个snd_kcontrol之间的联系。
(2)没有电源管理机制。
(3)为了防止pop-pop声音,需要用户程序各个kcontrol上下顺序。
(4)当音频路径不再有效时,不能自动关闭该路径上所有的snd_kcontrol。
由此damp框架就诞生了,其实可以理解为对snd_kcontrol的进一步封装,有如下这些类型。
5 widget & route
利用damp的宏对snd_kcontrol进行再封装后,再定义好route就可以交给machie驱动来处理了。