struct snd_soc_dapm_widget 是ALSA的 SoC(System on Chip)音频代码中用于表示DAPM(Dynamic Audio Power Management)中一个节点(widget)的数据结构。每一个 snd_soc_dapm_widget 结构体实例代表一个DAPM widget,它可能是一个输入、输出、混音器、多路复用器(MUX)、放大器(PGA)等。
以下是 snd_soc_dapm_widget 的数据结构及其字段说明:
struct snd_soc_dapm_widget {
const char *name; // 节点名称
enum snd_soc_dapm_type id; // 节点类型
const char *sname; // 对应的声卡控件名称
unsigned int reg; // 控制寄存器地址
unsigned int shift; // 控制寄存器中对应的位
unsigned int mask; // 控制寄存器中该域的掩码
int dapm_flags; // DAPM控件的标志
int on_val; // 打开时寄存器值
int off_val; // 关闭时寄存器值
const struct snd_kcontrol_new *kcontrol_news; // 新增的内核控件
int num_kcontrols; // 内核控件的数量
struct snd_kcontrol **kcontrol; // 内核控件数组
enum snd_soc_dapm_event event; // 事件类型
int (*event_handler)( struct snd_soc_dapm_widget *, struct snd_kcontrol *, int); // 事件处理函数
unsigned int power_check; // 电源状态检查
// 诸如反向依赖这类更复杂的东西
struct snd_kcontrol *kcontrol_hw;
struct snd_soc_dapm_context *dapm; // 关联到的DAPM上下文
struct list_head list; // 用于关联所有的DAPM widgets
struct list_head power_list; // 用于电源管理的列表节点
struct list_head idle_bias_off_list; // 用于空闲偏置关闭的列表节点
};
struct snd_soc_dapm_widget {
const char *name; // 节点名称
enum snd_soc_dapm_type id; // 节点类型
const char *sname; // 对应的声卡控件名称
unsigned int reg; // 控制寄存器地址
unsigned int shift; // 控制寄存器中对应的位
unsigned int mask; // 控制寄存器中该域的掩码
int dapm_flags; // DAPM控件的标志
int on_val; // 打开时寄存器值
int off_val; // 关闭时寄存器值
const struct snd_kcontrol_new *kcontrol_news; // 新增的内核控件
int num_kcontrols; // 内核控件的数量
struct snd_kcontrol **kcontrol; // 内核控件数组
enum snd_soc_dapm_event event; // 事件类型
int (*event_handler)( struct snd_soc_dapm_widget *, struct snd_kcontrol *, int); // 事件处理函数
unsigned int power_check; // 电源状态检查
// 诸如反向依赖这类更复杂的东西
struct snd_kcontrol *kcontrol_hw;
struct snd_soc_dapm_context *dapm; // 关联到的DAPM上下文
struct list_head list; // 用于关联所有的DAPM widgets
struct list_head power_list; // 用于电源管理的列表节点
struct list_head idle_bias_off_list; // 用于空闲偏置关闭的列表节点
};
接下来逐个解释 snd_soc_dapm_widget 中的重要字段:
基本属性
name:
节点名称。用于标识这个节点(widget)在DAPM系统中的名称。
id:
节点类型。是一个枚举类型 enum snd_soc_dapm_type,表示节点的类型(如输入、输出、混音器、MUX等)。常见的类型包括:
SND_SOC_DAPM_AIF_IN
SND_SOC_DAPM_AIF_OUT
SND_SOC_DAPM_DAC
SND_SOC_DAPM_ADC
SND_SOC_DAPM_MIC
SND_SOC_DAPM_SPK
sname:
对应声卡控件的名称。这个字段用于指定如何在用户层控制这个节点。
控制寄存器
reg:
控制寄存器的地址。这是DAPM节点用于控制电源状态的寄存器地址。
shift:
控制寄存器中的位移量,表示控制此节点的位在寄存器中的位置。
mask:
控制寄存器中该域的掩码,用于对寄存器的特定位进行操作。
控制值
on_val:
打开时的寄存器值。表示当节点处于激活状态时,寄存器的值。
off_val:
关闭时的寄存器值。表示当节点处于关闭状态时,寄存器的值。
内核控件
kcontrol_news:
新增的内核控件数组。定义音频控件的数组,例如音量、增益等。
num_kcontrols:
内核控件的数量。用于指明控件数组的长度。
kcontrol:
内核控件数组的指针。用于存储控件的实际实例。
事件处理
event:
事件类型。表示与节点相关的不同事件类型,例如节点打开、关闭等。
event_handler:
事件处理函数。指向一个函数,这个函数在事件发生时被调用,它接受三个参数:struct snd_soc_dapm_widget *, struct snd_kcontrol *, int(事件类型)。
电源管理
power_check:
用于检查电源状态的标志。
复杂属性
kcontrol_hw:
硬件控件的指针。用于更复杂的硬件控制。
dapm:
指向关联的DAPM上下文的指针。
list:
用于关联所有DAPM widgets 的列表节点。
power_list:
用于电源管理的列表节点。
idle_bias_off_list:
用于空闲偏置关闭模式的列表节点。
使用示例
以下是如何定义一个简单的 snd_soc_dapm_widget 实例的示例:
static const struct snd_soc_dapm_widget my_widgets[] = {
SND_SOC_DAPM_INPUT("Mic"), // 定义一个输入节点,名称为 "Mic"
SND_SOC_DAPM_OUTPUT("Speaker"), // 定义一个输出节点,名称为 "Speaker"
SND_SOC_DAPM_ADC("ADC", "Capture"), // 定义一个ADC节点,用于音频捕获
SND_SOC_DAPM_DAC("DAC", "Playback"), // 定义一个DAC节点,用于音频回放
SND_SOC_DAPM_PGA("Pre-Amp", SND_SOC_NOPM, 0, 0, NULL, 0), // 定义一个放大器节点,用于信号增益
SND_SOC_DAPM_MIXER("Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), // 定义一个混音器节点
SND_SOC_DAPM_MUX("Input Select", SND_SOC_NOPM, 0, 0, NULL, 0), // 定义一个多路复用器节点
SND_SOC_DAPM_SWITCH("Mute Switch", SND_SOC_NOPM, 0, 0, NULL, 0) // 定义一个静音开关节点
};
static const struct snd_soc_dapm_widget my_widgets[] = {
SND_SOC_DAPM_INPUT("Mic"), // 定义一个输入节点,名称为 "Mic"
SND_SOC_DAPM_OUTPUT("Speaker"), // 定义一个输出节点,名称为 "Speaker"
SND_SOC_DAPM_ADC("ADC", "Capture"), // 定义一个ADC节点,用于音频捕获
SND_SOC_DAPM_DAC("DAC", "Playback"), // 定义一个DAC节点,用于音频回放
SND_SOC_DAPM_PGA("Pre-Amp", SND_SOC_NOPM, 0, 0, NULL, 0), // 定义一个放大器节点,用于信号增益
SND_SOC_DAPM_MIXER("Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), // 定义一个混音器节点
SND_SOC_DAPM_MUX("Input Select", SND_SOC_NOPM, 0, 0, NULL, 0), // 定义一个多路复用器节点
SND_SOC_DAPM_SWITCH("Mute Switch", SND_SOC_NOPM, 0, 0, NULL, 0) // 定义一个静音开关节点
};
总结
struct snd_soc_dapm_widget 是ALSA SoC DAPM系统中用于表示各种音频组件的核心数据结构。理解和正确使用这一数据结构对于有效编写和调试ALSA音频驱动是至关重要的。通过管理这些widget,DAPM能够高效地控制音频信号路径中的电源状态,实现节能和性能优化。