便携式设备的动态音频电源管理
描述
动态音频电源管理(DAPM)旨在允许便携式Linux设备始终使用音频子系统中的最小功率。它独立于其他内核PM,因此可以轻松地与其他PM系统共存。
DAPM对所有用户空间应用程序也完全透明,因为所有电源切换都在ASoC核心内完成。用户空间应用程序不需要更改代码或重新编译。DAPM根据设备内的任何音频流(捕获/回放)活动和音频混合器设置做出功率切换决策。
DAPM横跨整个机器。它涵盖了整个音频子系统中的电源控制,包括内部编解码器电源块和机器级电源系统。
DAPM中有4个电源域
编解码器偏置域
VREF,VMID(核心编解码器和音频功率)
通常在编解码器探测/删除和暂停/恢复时控制,但如果侧音不需要电源等,则可以在流时间设置。
平台/机器领域
物理连接的输入和输出
平台/机器和用户操作是否特定,由机器驱动程序配置并响应异步事件,例如插入HP时
路径域
音频子系统信号路径
当用户更改混音器和多路复用器设置时自动设置。例如alsamixer,amixer。
流域
DAC和ADC。
分别启动和停止流播放/捕获时启用和禁用。例如aplay,arecord。
所有DAPM电源切换决策都是通过查阅整台机器的音频路由图自动完成的。此映射特定于每台计算机,包含每个音频组件(包括内部编解码器组件)之间的互连。所有影响力的音频组件在下文中称为小部件。
DAPM小部件
音频DAPM小部件分为多种类型: -
混合器
将多个模拟信号混合为单个模拟信号。
复用器
模拟开关,仅输出多个输入中的一个。
PGA
可编程增益放大器或衰减小部件。
ADC
模数转换器
DAC
数模转换器
开关
模拟开关
输入
编解码器输入引脚
产量
编解码器输出引脚
耳机
耳机(和可选插孔)
话筒
麦克风(和可选的杰克)
线
线路输入/输出(和可选插孔)
扬声器
扬声器
供应
其他小部件使用的电源或时钟供应小部件。
调节器
外部稳压器为音频组件供电。
时钟
外部时钟,为音频组件提供时钟。
AIF IN
音频接口输入(带TDM插槽掩码)。
AIF OUT
音频接口输出(带TDM插槽掩码)。
Siggen
信号发生器。
戴恩
数字音频接口输入。
戴出来
数字音频接口输出。
DAI Link
DAI两个DAI结构之间的链接
预
特殊的PRE小部件(exec在所有其他之前)
岗位
特殊的POST小部件(exec跟随所有其他小部件)
缓冲
DSP内的小部件音频数据缓冲器。
调度
DSP内部调度程序,用于调度组件/流水线处理工作。
影响
执行音频处理效果的小部件。
SRC
DSP或CODEC中的采样率转换器
ASRC
DSP或CODEC中的异步采样率转换器
编码器
将音频数据从一种格式(通常为PCM)编码为另一种格式(通常为压缩格式)的小工具。
解码器
将音频数据从压缩格式解码为未压缩格式(如PCM)的小组件。
(小部件在include / sound / soc-dapm.h中定义)
可以通过任何组件驱动程序类型将小组件添加到声卡。soc-dapm.h中定义了便利宏,可用于快速构建编解码器和机器DAPM小部件的小部件列表。
大多数小部件都有名称,寄存器,移位和反转。一些小部件有流名称和kcontrols的额外参数。
流域小部件
流小部件与流功率域相关,仅由ADC(模数转换器),DAC(数模转换器),AIF IN和AIF OUT组成。
流小部件具有以下格式: -
SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert),
SND_SOC_DAPM_AIF_IN(name, stream, slot, reg, shift, invert)
注意:流名称必须与编解码器snd_soc_codec_dai中的相应流名称匹配。
例如用于HiFi播放和捕获的流小部件
SND_SOC_DAPM_DAC(“HiFi DAC”,“HiFi Playback”,REG,3,1),
SND_SOC_DAPM_ADC(“HiFi ADC”,“HiFi Capture”,REG,2,1),
例如AIF的流小部件
SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1),
SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1),
路径域小部件
路径域小部件具有控制或影响音频子系统内的音频信号或音频路径的能力。它们具有以下形式: -
SND_SOC_DAPM_PGA(name,reg,shift,invert,controls,num_controls)
可以使用controls和num_controls成员设置任何窗口小部件kcontrols。
例如混音器小部件(首先声明kcontrols)
/* Output Mixer */
static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = {
SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0),
SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0),
SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
};
SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
ARRAY_SIZE(wm8731_output_mixer_controls)),
如果您不希望混音器元素以混音器小部件的名称为前缀,则可以使用SND_SOC_DAPM_MIXER_NAMED_CTL。参数与SND_SOC_DAPM_MIXER相同。
机器域小部件
机器小部件与编解码器小部件的不同之处在于它们没有与它们相关联的编解码器寄存器位。机器小部件被分配给可以独立供电的每个机器音频组件(非编解码器或DSP)。例如
机器小部件可以具有可选的回叫。
例如,用于外接麦克风的插孔连接器小部件,可在插入麦克风时启用麦克风偏置: - :
static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event)
{
gpio_set_value(SPITZ_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
return 0;
}
SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias),
编解码器(BIAS)域
编解码器偏置电源域没有小部件,由编解码器DAPM事件处理程序处理。当编解码器powerstate被更改为任何流事件或内核PM事件时,将调用此处理程序。
虚拟小工具
有时,编解码器或机器音频映射中存在没有任何相应软功率控制的小部件。在这种情况下,有必要创建一个虚拟小部件 - 一个没有控制位的小部件,例如
SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0),
这可以用于在软件中合并到信号路径。
在定义了所有小部件之后,可以通过调用snd_soc_dapm_new_control()将它们单独添加到DAPM子系统。
编解码器/ DSP小部件互连
小部件通过音频路径(称为互连)在编解码器,平台和机器内相互连接。必须定义每个互连,以便创建窗口小部件之间所有音频路径的映射。
这对于编解码器或DSP(以及机器音频系统的原理图)的图表来说是最简单的,因为它需要通过其音频信号路径将小部件连接在一起。
例如,来自WM8731输出混音器(wm8731.c)
WM8731输出混音器有3个输入(源)
- 线路旁路输入
- DAC(HiFi播放)
- 麦克风侧音输入
此示例中的每个输入都有一个与之关联的kcontrol(在上面的示例中定义),并通过其kcontrol名称连接到输出混合器。我们现在可以将目标窗口小部件(wrt音频信号)与其源窗口小部件连接起来。
/* output mixer */
{"Output Mixer", "Line Bypass Switch", "Line Input"},
{"Output Mixer", "HiFi Playback Switch", "DAC"},
{"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
所以我们有: -
- 目标小部件<===路径名称<===源小部件,或
- 接收器,路径,源或
Output Mixer
DAC
通过连接到。HiFi Playback Switch
当没有连接小部件的路径名(例如直接连接)时,我们为路径名传递NULL。
通过调用以下方式创建互连: -
snd_soc_dapm_connect_input(codec, sink, path, source);
最后,必须在向核心注册所有小部件和互连后调用snd_soc_dapm_new_widgets(编解码器)。这会导致核心扫描编解码器和机器,以便内部DAPM状态与机器的物理状态相匹配。
机器小部件互连
机器小部件互连的创建方式与编解码器相同,并直接将编解码器引脚连接到机器级小部件。
例如,将扬声器输出编解码器引脚连接到内部扬声器。
/* ext speaker connected to codec pins LOUT2, ROUT2 */
{"Ext Spk", NULL , "ROUT2"},
{"Ext Spk", NULL , "LOUT2"},
这允许DAPM分别接通和断开连接(和使用中)的引脚和NC的引脚。
端点小部件
端点是机器内音频信号的起点或终点(小部件),并包括编解码器。例如
- 耳机插孔
- 内部发言人
- 内置麦克风
- 麦克杰克
- 编解码器针脚
端点将添加到DAPM图表中,以便可以确定其使用情况以节省电量。例如,NC编解码器引脚将关闭,未连接的插孔也可以关闭。
DAPM小部件事件
一些小部件可以在PM事件中注册他们对DAPM核心的兴趣。例如,带放大器的扬声器注册小部件,因此放大器只能在spk使用时供电。
/* turn speaker amplifier on/off depending on use */
static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
{
gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
return 0;
}
/* corgi machine dapm widgets */
static const struct snd_soc_dapm_widget wm8731_dapm_widgets =
SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event);
有关支持事件的所有其他小部件,请参阅soc-dapm.h。
事件类型
事件窗口小部件支持以下事件类型。
/* dapm event types */
#define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */
#define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */
#define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */
#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */
#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */
#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */
下一个 以前