您的位置:首页 > 其它

音频电源动态管理(一)---国人当自强

2012-12-21 23:16 218 查看
直接来自内核的\Documentation\sound\alsa\soc中dapm.txt

1.描述

音频电源动态管理(DAPM)的目的是为了在音频子系统中允许便携式的linux设备一直使用最小的电量。它独立于其它内核电源管理,因此可以很方便的和其它电源管理系统共存。

DAPM对于所有用户空间的程序也是完全透明的,因为所有的电源开关都是由ASoC core来切换的。用户空间的程序 不需要改变代码和重新编译 。DAPM使得电源开关的切换基于设备的任何的音频流(采集或回放)活动和音频混音器设置之上。

DAPM贯穿于整个machine。它覆盖整个音频子系统的电源控制,包括内部的codec电源模块和machine等级的电源系统。

DAPM中有4个电源相关的域:

1.Codec域--VREF(参考电压),VMID(core codec和音频电源)

通常在codec probe/remove和suspend/resume时被控制,因此可以在侧音不需要电源时在stream time被设置。

2.Platform/Machine 域 -- 是platform/machine和user action相关的输入输出物理连接,由machine driver配置并且响应一不事件。比如HP插入时

3.Path 域 --- 音频子系统的信号路径

当mixer和mux设置被用户改变时自动设置,比如alsamixer,amixer

4.Stream 域 -- DACs和ADCs

当回放和采集流开始或者结束时被相应的使能和禁止,比如aplay,arecord

所有DAPM电源开关的策略由整个machine的一个音频线路图自动控制。这个线路图是和每一个machine相关的,并且由所有音频部件(包括内部的codec部件)的互联系统构成。以后,所有影响电源的音频部件被叫做widget

2.DAPM 部件

DAPM音频部件分为一系列的类型:

Mixer--将一些模拟信号混合为一个单一的模拟信号

Mux--一个控制多路输入但只有一个输出的模拟开关

PGA--一个可编程的增益放大器或者衰减部件

ADC--模拟信号到数字信号转换器

DAC--数字信号到模拟信号转换器

Switch--一个模拟开关

Input--codec的一个输出接口

Output--codec的一个输入接口

Headphone--耳机(和可选的Jack)

Mic--Mic(和可选的Jack)

Line--线路输入/输出(和可选的Jack)

Speaker--扬声器

Supply--被其它部件使用的电源和时钟供应部件

Pre--特殊的前置部件(在所有其它部件前执行)

Post--特殊的后置部件(在所有其它部件后执行)

(Widgets 定义在include/sound/soc-dapm.h)

widgets经常在codec的driver和machine的driver中被添加.在soc-dapm.h中有一些很方便的宏可以用来快速的构建codecs和machines 的一系列的DAPM widgets。

大多数的widgets有一个name,register,shift,和invert。一些widgets有一些用于stream名字和kcontrols的多余的参数。

2.1 Stream Domain Widgets

-------------------------------------

Stream Widgets 和stream power domain相关并且包含ADCs和DACs。

Stream Widgets有如下的格式:

SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert),

注意:stream的名字必须和相应的你snd_soc_codec_dai中codec的stream name 一致

例如。用于HiFi回放和采集的stream widegets

SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1),

SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1),

2.2 Path Domain Widgets

---------------------------------

Path domain wideget 有控制和影响音频子系统中音频信号或音频路径的能力。他们有如下的格式:

SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls)

所有widget kcontrols可以用controls和num_controls 成员设置。

比如.mixer widget(首先定义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)),

如果你不想以mixer widget的name作为mixer元素的名字前缀,你可以使用SND_SOC_DAPM_MIXER_NAMED_CTL宏代替,参数和使用SND_SOC_DAPM_MIXER一样

2.3 Platform/Machine domain Widgets

--------------------------------------------------

Machine widgets和codec widgets不同的是,它们没有codec 寄存器位。一个machine widget和每一个可以被独立的供电的machine音频控件相关(非codec),例如

--扬声器放大器

--Microphone Bias

--Jack 连接器

一个machine widget可以有一个可选的回调函数。

例如,对于一个外部的Mic,Jack connector widget在mic插入的时候使能Mic Bias

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),

2.4 Codec Domain

------------------------

codec power domain 没有widgets,它被codec DAPM时间处理函数处理。这个处理函数在codec 的powerstate被任何stream event或内核PM 事件改变时调用。

2.5 Virtual Widgets

------------------------

一些widgets存在于没有任何相应软件电源控制的codec或者machine音频位图。这种情况下需要创建一个虚拟的widget---一个没有控制bits的widget。例如

SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0),

这可以被用于在软件上合并signal paths在一起。

在所有的widget被定义之后,他们可以通过调用snd_soc_dapm_new_control()被独立的添加到DAPM子系统。

3.Codec Widget Interconnections(相互连接)

=================================

Widgets在codec和machine上通过audio paths相互连接。每一个连接必须被定义以便在widgets间创建一个所有

音频路径的map

建立codec或者machine音频系统的是很简单的,这是因为它需要通过他们的音频信号路径 把widget组合在一起

e.g., from the WM8731 output mixer (wm8731.c)

WM8731输出mixer有3个输入(源)

1. Line Bypass Input--------------------线路旁路输入

2. DAC (HiFi playback)-----------------DAC(HiFi 回放)

3. Mic Sidetone Input-------------------Mic 侧音输入

这个例子中每一个输入都有一个与之相关的kcontrol(在上面定义)并且通过kcontrol name和输出mixer相连。我们现在可以和用它们的源widgets和destination widget(wrt 音频信号)来连接 /* output mixer */

{"Output Mixer", "Line Bypass Switch", "Line Input"},

{"Output Mixer", "HiFi Playback Switch", "DAC"},

{"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},

因此我们有: Destination Widget <=== Path Name <=== Source Widget

或者: Sink, Path, Source

或者: "Output Mixer" 通过"HiFi Playback Switch"和"DAC"连接

当没有path name和widgets(比如一个直接的连接)相连接时,我们使用NULL作为path name 通过下列函数来创建连接 snd_soc_dapm_connect_input(codec, sink, path, source);

最后,当所有的widgets和连接已经呗注册进内核时我们应当调用snd_soc_dapm_new_widgets(codec) 这会使得内核遍历codec和machine,因此内部的DAPM状态会和物理的machine状态匹配

3.1 Machine Widget Interconnections

-------------------------------------------------

machine widget的连接创建方式和codec一样,并且直接将codec的pins连接到machine level 的 widgets 例如。连接speaker 输出编码pins到内部的speaker

/*ext speaker 连接到codec pins LOUT2,ROUT2*/

{"Ext Spk", NULL , "ROUT2"},

{"Ext Spk", NULL , "LOUT2"},

这样会让DAPM为已经连接的pin和独立NC的pin上电和关闭

4 Endpoint Widgets

===================

一个endpoint是machine内部一个音频信号的开始或者结束点(widget)并且包含codec。例如

o Headphone Jack

o Internal Speaker

o Internal Mic

o Mic Jack

o Codec Pins

当一个codec pin 为NC时,它可以通过如下的函数来标记为没有使用 snd_soc_dapm_set_endpoint(codec, "Widget Name", 0); 最后一个参数是0时为inactive,是1时为active.这样这个pin和它的输入widget不会上电 也不会耗费电量

5 DAPM Widget Events

====================

一些widgets可以在PM事件的DAPM core中注册他们的偏好。 比如.一个有放大器的Speaker注册一个widget这样amplifier可以在speaker使用 的时候才上电

/*打开和关闭amplifier 使用如下的函数*/

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;

}

/*相应的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中查看支持events的所有widgets

5.1 Event types

---------------------

evevt widgets支持如下的event 类型

/* 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 */

参考 http://blog.csdn.net/sepnic/article/details/6331884
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: