asoc之行動式裝置的動態音訊電源管理
行動式裝置的動態音訊電源管理
描述
動態音訊電源管理(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 */