ALSA-DAPM
所谓 widget,其实可以理解为是 kcontrol 的进一步升级和封装,她同样是指音频系统中的某个部件,比如 mixer,mux,输入输出引脚,电源供应器等等,甚至,我们可以定义虚拟的 widget,例如 playback stream widget。widget 把 kcontrol 和动态电源管理进行了有机的结合,同时还具备音频路径的连结功能,一个 widget 可以与它相邻的 widget 有某种动态的连结关系。在 DAPM 框架中,widget 用结构体 snd_soc_dapm_widget 来描述:
amixer 工作流程
参考 tinymix 的使用流程
常用操作
1 | #define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info) |
驱动的注册
1 | snd_ctl_create //创建控件管理结构 |
控件 (元素) 的添加
1 | snd_soc_add_codec_controls |
kcontrol
1 | struct snd_kcontrol_new { |
kcontrol 的命名
kcontrol 的作用由名称来区分,对于名称相同的 kcontrol,则使用 index 区分。name 定义的标准是 “SOURCE DIRECTION FUNCTION” 即 “源 方向 功能”,SOURCE 定义了 kcontrol 的源,如 “Master”、“PCM” 等;DIRECTION 则为 “Playback”、“Capture” 等,如果 DIRECTION 忽略,意味着 Playback 和 capture 双向;FUNCTION 则可以是 “Switch”、“Volume” 和 “Route” 等。
内核说明文档:
1 | This document describes standard names of mixer controls. |
Documentation/sound/alsa/ControlNames.txt
widget
- codec 域
比如 VREF 和 VMID 等提供参考电压的 widget,这些 widget 通常在 codec 的 probe/remove 回调中进行控制,当然,在工作中如果没有音频流时,也可以适当地进行控制它们的开启与关闭。
- platform 域
位于该域上的 widget 通常是针对平台或板子的一些需要物理连接的输入 / 输出接口,例如耳机、扬声器、麦克风,因为这些接口在每块板子上都可能不一样,所以通常它们是在 machine 驱动中进行定义和控制,并且也可以由用户空间的应用程序通过某种方式来控制它们的打开和关闭。
- 音频路径域
一般是指 codec 内部的 mixer、mux 等控制音频路径的 widget,这些 widget 可以根据用户空间的设定连接关系,自动设定他们的电源状态。
- 音频数据流域
是指那些需要处理音频数据流的 widget,例如 ADC、DAC 等等。
数据结构
snd_soc_dapm_type
1 | /* dapm widget types */ |
snd_soc_dapm_widget
1 | /* dapm widget */ |
dapm
先注册 widget, 而后逐一进行初始化处理
注册
1 | int snd_soc_register_component(struct device *dev, |
数据结构:
1 | struct snd_soc_component_driver { |
注册流程:
1 | snd_soc_register_component |
初始化流程:
1 | snd_soc_register_card |
连接:
1 | snd_soc_register_card |
更新寄存器:
1 | dapm_power_widgets |
Add Controls
1 | snd_soc_add_codec_controls |
sound/soc/soc-core.c
作用:
Add Widgets
Add Route
相关术语
MIXER
Mixer - Mixes several analog signals into a single analog signal.
Mixer 可以混合多个输入到输出
MUX
Mux - An analog switch that outputs only one of many inputs.
Mux 只能从多个输入里选择一个作为输出
dapm widget 链表更新
- 初始化的时候,snd_soc_instantiate_card 里调用 snd_soc_dapm_new_widgets,最终会调用 dapm_power_widgets
- 在用户空间通过 tinymix 设置路径,在 SOC_DAPM_ENUM 中的 put 或者 get 函数最终会调用 dapm_power_widgets
- 在用户空间通过 tinyplay 播放或者录音是的 soc_pcm_prepare 和 soc_pcm_close,最终会调用 dapm_power_widgets