sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget"/translations/zh_CN/sound/soc/dapmmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/zh_TW/sound/soc/dapmmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/it_IT/sound/soc/dapmmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/ja_JP/sound/soc/dapmmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/ko_KR/sound/soc/dapmmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/sp_SP/sound/soc/dapmmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhsection)}(hhh](htitle)}(h3Dynamic Audio Power Management for Portable Devicesh]h3Dynamic Audio Power Management for Portable Devices}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhThe graph for the STM32MP1-DK1 sound card is shown in picture:h]h>The graph for the STM32MP1-DK1 sound card is shown in picture:}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubkfigure kernel_figure)}(hhh]hfigure)}(hhh]himage)}(hT.. kernel-figure:: dapm-graph.svg :alt: Example DAPM graph :align: center h]h}(h]h ]h"]h$]h&]altExample DAPM graphurisound/soc/dapm-graph.svg candidates}j^jsuh1jhjhhhKubah}(h]h ]h"]h$]h&]aligncenteruh1jhjubah}(h]h ]h"]h$]h&]uh1jhhhhhhhNubh)}(hbYou can also generate compatible graph for your sound card using `tools/sound/dapm-graph` utility.h](hAYou can also generate compatible graph for your sound card using }(hjhhhNhNubhtitle_reference)}(h`tools/sound/dapm-graph`h]htools/sound/dapm-graph}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh utility.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK&hhhhubeh}(h] descriptionah ]h"] descriptionah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hDAPM power domainsh]hDAPM power domains}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK*ubh)}(h&There are 4 power domains within DAPM:h]h&There are 4 power domains within DAPM:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK,hjhhubhdefinition_list)}(hhh](hdefinition_list_item)}(hCodec bias domain VREF, VMID (core codec and audio power) Usually controlled at codec probe/remove and suspend/resume, although can be set at stream time if power is not needed for sidetone, etc. h](hterm)}(hCodec bias domainh]hCodec bias domain}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK2hjubh definition)}(hhh](h)}(h'VREF, VMID (core codec and audio power)h]h'VREF, VMID (core codec and audio power)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK/hjubh)}(hUsually controlled at codec probe/remove and suspend/resume, although can be set at stream time if power is not needed for sidetone, etc.h]hUsually controlled at codec probe/remove and suspend/resume, although can be set at stream time if power is not needed for sidetone, etc.}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK1hjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhK2hjubj)}(hPlatform/Machine domain physically connected inputs and outputs Is platform/machine and user action specific, is configured by the machine driver and responds to asynchronous events e.g when HP are inserted h](j)}(hPlatform/Machine domainh]hPlatform/Machine domain}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK9hj=ubj)}(hhh](h)}(h'physically connected inputs and outputsh]h'physically connected inputs and outputs}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK5hjOubh)}(hIs platform/machine and user action specific, is configured by the machine driver and responds to asynchronous events e.g when HP are insertedh]hIs platform/machine and user action specific, is configured by the machine driver and responds to asynchronous events e.g when HP are inserted}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK7hjOubeh}(h]h ]h"]h$]h&]uh1jhj=ubeh}(h]h ]h"]h$]h&]uh1jhhhK9hjhhubj)}(hPath domain audio subsystem signal paths Automatically set when mixer and mux settings are changed by the user. e.g. alsamixer, amixer. h](j)}(h Path domainh]h Path domain}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK?hjzubj)}(hhh](h)}(haudio subsystem signal pathsh]haudio subsystem signal paths}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhjzubeh}(h]h ]h"]h$]h&]uh1jhhhK?hjhhubj)}(hStream domain DACs and ADCs. Enabled and disabled when stream playback/capture is started and stopped respectively. e.g. aplay, arecord. h](j)}(h Stream domainh]h Stream domain}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKFhjubj)}(hhh](h)}(hDACs and ADCs.h]hDACs and ADCs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKBhjubh)}(hkEnabled and disabled when stream playback/capture is started and stopped respectively. e.g. aplay, arecord.h]hkEnabled and disabled when stream playback/capture is started and stopped respectively. e.g. aplay, arecord.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKFhjhhubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]dapm-power-domainsah ]h"]dapm power domainsah$]h&]uh1hhhhhhhhK*ubh)}(hhh](h)}(h DAPM Widgetsh]h DAPM Widgets}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKIubh)}(h/Audio DAPM widgets fall into a number of types:h]h/Audio DAPM widgets fall into a number of types:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKKhjhhubj)}(hhh](j)}(h?Mixer Mixes several analog signals into a single analog signal.h](j)}(hMixerh]hMixer}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKMhj$ubj)}(hhh]h)}(h9Mixes several analog signals into a single analog signal.h]h9Mixes several analog signals into a single analog signal.}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKNhj6ubah}(h]h ]h"]h$]h&]uh1jhj$ubeh}(h]h ]h"]h$]h&]uh1jhhhKMhj!ubj)}(h:Mux An analog switch that outputs only one of many inputs.h](j)}(hMuxh]hMux}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKOhjSubj)}(hhh]h)}(h6An analog switch that outputs only one of many inputs.h]h6An analog switch that outputs only one of many inputs.}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKPhjeubah}(h]h ]h"]h$]h&]uh1jhjSubeh}(h]h ]h"]h$]h&]uh1jhhhKOhj!hhubj)}(h8PGA A programmable gain amplifier or attenuation widget.h](j)}(hPGAh]hPGA}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKQhjubj)}(hhh]h)}(h4A programmable gain amplifier or attenuation widget.h]h4A programmable gain amplifier or attenuation widget.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKRhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKQhj!hhubj)}(hADC Analog to Digital Converterh](j)}(hADCh]hADC}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKShjubj)}(hhh]h)}(hAnalog to Digital Converterh]hAnalog to Digital Converter}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKThjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKShj!hhubj)}(hDAC Digital to Analog Converterh](j)}(hDACh]hDAC}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKUhjubj)}(hhh]h)}(hDigital to Analog Converterh]hDigital to Analog Converter}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKVhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKUhj!hhubj)}(hSwitch An analog switchh](j)}(hSwitchh]hSwitch}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKWhjubj)}(hhh]h)}(hAn analog switchh]hAn analog switch}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKXhj!ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKWhj!hhubj)}(hInput A codec input pinh](j)}(hInputh]hInput}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKYhj>ubj)}(hhh]h)}(hA codec input pinh]hA codec input pin}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKZhjPubah}(h]h ]h"]h$]h&]uh1jhj>ubeh}(h]h ]h"]h$]h&]uh1jhhhKYhj!hhubj)}(hOutput A codec output pinh](j)}(hOutputh]hOutput}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK[hjmubj)}(hhh]h)}(hA codec output pinh]hA codec output pin}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK\hjubah}(h]h ]h"]h$]h&]uh1jhjmubeh}(h]h ]h"]h$]h&]uh1jhhhK[hj!hhubj)}(h'Headphone Headphone (and optional Jack)h](j)}(h Headphoneh]h Headphone}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK]hjubj)}(hhh]h)}(hHeadphone (and optional Jack)h]hHeadphone (and optional Jack)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK^hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhK]hj!hhubj)}(hMic Mic (and optional Jack)h](j)}(hMich]hMic}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK_hjubj)}(hhh]h)}(hMic (and optional Jack)h]hMic (and optional Jack)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK`hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhK_hj!hhubj)}(h*Line Line Input/Output (and optional Jack)h](j)}(hLineh]hLine}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKahjubj)}(hhh]h)}(h%Line Input/Output (and optional Jack)h]h%Line Input/Output (and optional Jack)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKbhj ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKahj!hhubj)}(hSpeaker Speakerh](j)}(hSpeakerh]hSpeaker}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKchj)ubj)}(hhh]h)}(hSpeakerh]hSpeaker}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKdhj;ubah}(h]h ]h"]h$]h&]uh1jhj)ubeh}(h]h ]h"]h$]h&]uh1jhhhKchj!hhubj)}(h:Supply Power or clock supply widget used by other widgets.h](j)}(hSupplyh]hSupply}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKehjXubj)}(hhh]h)}(h3Power or clock supply widget used by other widgets.h]h3Power or clock supply widget used by other widgets.}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhjjubah}(h]h ]h"]h$]h&]uh1jhjXubeh}(h]h ]h"]h$]h&]uh1jhhhKehj!hhubj)}(hERegulator External regulator that supplies power to audio components.h](j)}(h Regulatorh]h Regulator}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKghjubj)}(hhh]h)}(h;External regulator that supplies power to audio components.h]h;External regulator that supplies power to audio components.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKghj!hhubj)}(h=Clock External clock that supplies clock to audio components.h](j)}(hClockh]hClock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKihjubj)}(hhh]h)}(h7External clock that supplies clock to audio components.h]h7External clock that supplies clock to audio components.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKjhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKihj!hhubj)}(h2AIF IN Audio Interface Input (with TDM slot mask).h](j)}(hAIF INh]hAIF IN}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKkhjubj)}(hhh]h)}(h+Audio Interface Input (with TDM slot mask).h]h+Audio Interface Input (with TDM slot mask).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKlhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKkhj!hhubj)}(h4AIF OUT Audio Interface Output (with TDM slot mask).h](j)}(hAIF OUTh]hAIF OUT}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKmhjubj)}(hhh]h)}(h,Audio Interface Output (with TDM slot mask).h]h,Audio Interface Output (with TDM slot mask).}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKnhj&ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKmhj!hhubj)}(hSiggen Signal Generator.h](j)}(hSiggenh]hSiggen}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKohjCubj)}(hhh]h)}(hSignal Generator.h]hSignal Generator.}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKphjUubah}(h]h ]h"]h$]h&]uh1jhjCubeh}(h]h ]h"]h$]h&]uh1jhhhKohj!hhubj)}(h%DAI IN Digital Audio Interface Input.h](j)}(hDAI INh]hDAI IN}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKqhjrubj)}(hhh]h)}(hDigital Audio Interface Input.h]hDigital Audio Interface Input.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKrhjubah}(h]h ]h"]h$]h&]uh1jhjrubeh}(h]h ]h"]h$]h&]uh1jhhhKqhj!hhubj)}(h'DAI OUT Digital Audio Interface Output.h](j)}(hDAI OUTh]hDAI OUT}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKshjubj)}(hhh]h)}(hDigital Audio Interface Output.h]hDigital Audio Interface Output.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKthjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKshj!hhubj)}(h,DAI Link DAI Link between two DAI structuresh](j)}(hDAI Linkh]hDAI Link}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKuhjubj)}(hhh]h)}(h#DAI Link between two DAI structuresh]h#DAI Link between two DAI structures}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKvhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKuhj!hhubj)}(h/Pre Special PRE widget (exec before all others)h](j)}(hPreh]hPre}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKwhjubj)}(hhh]h)}(h+Special PRE widget (exec before all others)h]h+Special PRE widget (exec before all others)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKxhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKwhj!hhubj)}(h0Post Special POST widget (exec after all others)h](j)}(hPosth]hPost}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKyhj.ubj)}(hhh]h)}(h+Special POST widget (exec after all others)h]h+Special POST widget (exec after all others)}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKzhj@ubah}(h]h ]h"]h$]h&]uh1jhj.ubeh}(h]h ]h"]h$]h&]uh1jhhhKyhj!hhubj)}(h3Buffer Inter widget audio data buffer within a DSP.h](j)}(hBufferh]hBuffer}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK{hj]ubj)}(hhh]h)}(h,Inter widget audio data buffer within a DSP.h]h,Inter widget audio data buffer within a DSP.}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK|hjoubah}(h]h ]h"]h$]h&]uh1jhj]ubeh}(h]h ]h"]h$]h&]uh1jhhhK{hj!hhubj)}(hSScheduler DSP internal scheduler that schedules component/pipeline processing work.h](j)}(h Schedulerh]h Scheduler}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK~hjubj)}(hhh]h)}(hIDSP internal scheduler that schedules component/pipeline processing work.h]hIDSP internal scheduler that schedules component/pipeline processing work.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK~hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhK~hj!hhubj)}(h7Effect Widget that performs an audio processing effect.h](j)}(hEffecth]hEffect}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjubj)}(hhh]h)}(h0Widget that performs an audio processing effect.h]h0Widget that performs an audio processing effect.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKhj!hhubj)}(h-SRC Sample Rate Converter within DSP or CODECh](j)}(hSRCh]hSRC}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjubj)}(hhh]h)}(h)Sample Rate Converter within DSP or CODECh]h)Sample Rate Converter within DSP or CODEC}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKhj!hhubj)}(h;ASRC Asynchronous Sample Rate Converter within DSP or CODECh](j)}(hASRCh]hASRC}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjubj)}(hhh]h)}(h6Asynchronous Sample Rate Converter within DSP or CODECh]h6Asynchronous Sample Rate Converter within DSP or CODEC}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj+ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKhj!hhubj)}(hoEncoder Widget that encodes audio data from one format (usually PCM) to another usually more compressed format.h](j)}(hEncoderh]hEncoder}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjHubj)}(hhh]h)}(hgWidget that encodes audio data from one format (usually PCM) to another usually more compressed format.h]hgWidget that encodes audio data from one format (usually PCM) to another usually more compressed format.}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjZubah}(h]h ]h"]h$]h&]uh1jhjHubeh}(h]h ]h"]h$]h&]uh1jhhhKhj!hhubj)}(heDecoder Widget that decodes audio data from a compressed format to an uncompressed format like PCM. h](j)}(hDecoderh]hDecoder}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjwubj)}(hhh]h)}(h[Widget that decodes audio data from a compressed format to an uncompressed format like PCM.h]h[Widget that decodes audio data from a compressed format to an uncompressed format like PCM.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjwubeh}(h]h ]h"]h$]h&]uh1jhhhKhj!hhubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubh)}(h1(Widgets are defined in include/sound/soc-dapm.h)h]h1(Widgets are defined in include/sound/soc-dapm.h)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hWidgets can be added to the sound card by any of the component driver types. There are convenience macros defined in soc-dapm.h that can be used to quickly build a list of widgets of the codecs and machines DAPM widgets.h]hWidgets can be added to the sound card by any of the component driver types. There are convenience macros defined in soc-dapm.h that can be used to quickly build a list of widgets of the codecs and machines DAPM widgets.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hwMost widgets have a name, register, shift and invert. Some widgets have extra parameters for stream name and kcontrols.h]hwMost widgets have a name, register, shift and invert. Some widgets have extra parameters for stream name and kcontrols.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hhh](h)}(hStream Domain Widgetsh]hStream Domain Widgets}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hStream Widgets relate to the stream power domain and only consist of ADCs (analog to digital converters), DACs (digital to analog converters), AIF IN and AIF OUT.h]hStream Widgets relate to the stream power domain and only consist of ADCs (analog to digital converters), DACs (digital to analog converters), AIF IN and AIF OUT.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h,Stream widgets have the following format: ::h]h)Stream widgets have the following format:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh literal_block)}(htSND_SOC_DAPM_DAC(name, stream name, reg, shift, invert), SND_SOC_DAPM_AIF_IN(name, stream, slot, reg, shift, invert)h]htSND_SOC_DAPM_DAC(name, stream name, reg, shift, invert), SND_SOC_DAPM_AIF_IN(name, stream, slot, reg, shift, invert)}hj sbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1j hhhKhjhhubh)}(h`NOTE: the stream name must match the corresponding stream name in your codec snd_soc_dai_driver.h]h`NOTE: the stream name must match the corresponding stream name in your codec snd_soc_dai_driver.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h4e.g. stream widgets for HiFi playback and capture ::h]h1e.g. stream widgets for HiFi playback and capture}(hj# hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj )}(hrSND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1), SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1),h]hrSND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1), SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1),}hj1 sbah}(h]h ]h"]h$]h&]j j uh1j hhhKhjhhubh)}(he.g. stream widgets for AIF ::h]he.g. stream widgets for AIF}(hj? hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj )}(hSND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),h]hSND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),}hjM sbah}(h]h ]h"]h$]h&]j j uh1j hhhKhjhhubeh}(h]stream-domain-widgetsah ]h"]stream domain widgetsah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(hPath Domain Widgetsh]hPath Domain Widgets}(hjf hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjc hhhhhKubh)}(hPath domain widgets have a ability to control or affect the audio signal or audio paths within the audio subsystem. They have the following form: ::h]hPath domain widgets have a ability to control or affect the audio signal or audio paths within the audio subsystem. They have the following form:}(hjt hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjc hhubj )}(hBSND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls)h]hBSND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls)}hj sbah}(h]h ]h"]h$]h&]j j uh1j hhhKhjc hhubh)}(hLAny widget kcontrols can be set using the controls and num_controls members.h]hLAny widget kcontrols can be set using the controls and num_controls members.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjc hhubh)}(h7e.g. Mixer widget (the kcontrols are declared first) ::h]h4e.g. Mixer widget (the kcontrols are declared first)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjc hhubj )}(hX/* 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)),h]hX/* 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)),}hj sbah}(h]h ]h"]h$]h&]j j uh1j hhhKhjc hhubh)}(hIf you don't want the mixer elements prefixed with the name of the mixer widget, you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same as for SND_SOC_DAPM_MIXER.h]hIf you don’t want the mixer elements prefixed with the name of the mixer widget, you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same as for SND_SOC_DAPM_MIXER.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjc hhubeh}(h]path-domain-widgetsah ]h"]path domain widgetsah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(hMachine domain Widgetsh]hMachine domain Widgets}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hMachine widgets are different from codec widgets in that they don't have a codec register bit associated with them. A machine widget is assigned to each machine audio component (non codec or DSP) that can be independently powered. e.g.h]hMachine widgets are different from codec widgets in that they don’t have a codec register bit associated with them. A machine widget is assigned to each machine audio component (non codec or DSP) that can be independently powered. e.g.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hhh](j)}(h Speaker Amph]h)}(hj h]h Speaker Amp}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubj)}(hMicrophone Biash]h)}(hj h]hMicrophone Bias}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubj)}(hJack connectors h]h)}(hJack connectorsh]hJack connectors}(hj$ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubeh}(h]h ]h"]h$]h&]j]j^uh1hhhhKhj hhubh)}(h0A machine widget can have an optional call back.h]h0A machine widget can have an optional call back.}(hj> hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(h_e.g. Jack connector widget for an external Mic that enables Mic Bias when the Mic is inserted::h]h^e.g. Jack connector widget for an external Mic that enables Mic Bias when the Mic is inserted:}(hjL hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj )}(hstatic 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),h]hstatic 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),}hjZ sbah}(h]h ]h"]h$]h&]j j uh1j hhhKhj hhubeh}(h]machine-domain-widgetsah ]h"]machine domain widgetsah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(hCodec (BIAS) Domainh]hCodec (BIAS) Domain}(hjs hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjp hhhhhKubh)}(hThe codec bias power domain has no widgets and is handled by the codec DAPM event handler. This handler is called when the codec powerstate is changed wrt to any stream event or by kernel PM events.h]hThe codec bias power domain has no widgets and is handled by the codec DAPM event handler. This handler is called when the codec powerstate is changed wrt to any stream event or by kernel PM events.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjp hhubeh}(h]codec-bias-domainah ]h"]codec (bias) domainah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(hVirtual Widgetsh]hVirtual Widgets}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hSometimes widgets exist in the codec or machine audio graph that don't have any corresponding soft power control. In this case it is necessary to create a virtual widget - a widget with no control bits e.g. ::h]hSometimes widgets exist in the codec or machine audio graph that don’t have any corresponding soft power control. In this case it is necessary to create a virtual widget - a widget with no control bits e.g.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj )}(h>SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),h]h>SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),}hj sbah}(h]h ]h"]h$]h&]j j uh1j hhhKhj hhubh)}(h@This can be used to merge two signal paths together in software.h]h@This can be used to merge two signal paths together in software.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubeh}(h]virtual-widgetsah ]h"]virtual widgetsah$]h&]uh1hhjhhhhhKubeh}(h] dapm-widgetsah ]h"] dapm widgetsah$]h&]uh1hhhhhhhhKIubh)}(hhh](h)}(hRegistering DAPM controlsh]hRegistering DAPM controls}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hIn many cases the DAPM widgets are implemented statically in a ``static const struct snd_soc_dapm_widget`` array in a codec driver, and simply declared via the ``dapm_widgets`` and ``num_dapm_widgets`` fields of the ``struct snd_soc_component_driver``.h](h?In many cases the DAPM widgets are implemented statically in a }(hj hhhNhNubhliteral)}(h+``static const struct snd_soc_dapm_widget``h]h'static const struct snd_soc_dapm_widget}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh6 array in a codec driver, and simply declared via the }(hj hhhNhNubj )}(h``dapm_widgets``h]h dapm_widgets}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh and }(hj hhhNhNubj )}(h``num_dapm_widgets``h]hnum_dapm_widgets}(hj! hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh fields of the }(hj hhhNhNubj )}(h#``struct snd_soc_component_driver``h]hstruct snd_soc_component_driver}(hj3 hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hSimilarly, routes connecting them are implemented statically in a ``static const struct snd_soc_dapm_route`` array and declared via the ``dapm_routes`` and ``num_dapm_routes`` fields of the same struct.h](hBSimilarly, routes connecting them are implemented statically in a }(hjK hhhNhNubj )}(h*``static const struct snd_soc_dapm_route``h]h&static const struct snd_soc_dapm_route}(hjS hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjK ubh array and declared via the }(hjK hhhNhNubj )}(h``dapm_routes``h]h dapm_routes}(hje hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjK ubh and }(hjK hhhNhNubj )}(h``num_dapm_routes``h]hnum_dapm_routes}(hjw hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjK ubh fields of the same struct.}(hjK hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hTWith the above declared, the driver registration will take care of populating them::h]hSWith the above declared, the driver registration will take care of populating them:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hj hhubj )}(hXstatic const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("SPKN"), SND_SOC_DAPM_OUTPUT("SPKP"), ... }; /* Target, Path, Source */ static const struct snd_soc_dapm_route wm2000_audio_map[] = { { "SPKN", NULL, "ANC Engine" }, { "SPKP", NULL, "ANC Engine" }, ... }; static const struct snd_soc_component_driver soc_component_dev_wm2000 = { ... .dapm_widgets = wm2000_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets), .dapm_routes = wm2000_audio_map, .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), ... };h]hXstatic const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("SPKN"), SND_SOC_DAPM_OUTPUT("SPKP"), ... }; /* Target, Path, Source */ static const struct snd_soc_dapm_route wm2000_audio_map[] = { { "SPKN", NULL, "ANC Engine" }, { "SPKP", NULL, "ANC Engine" }, ... }; static const struct snd_soc_component_driver soc_component_dev_wm2000 = { ... .dapm_widgets = wm2000_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets), .dapm_routes = wm2000_audio_map, .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), ... };}hj sbah}(h]h ]h"]h$]h&]j j uh1j hhhMhj hhubh)}(hXIn more complex cases the list of DAPM widgets and/or routes can be only known at probe time. This happens for example when a driver supports different models having a different set of features. In those cases separate widgets and routes arrays implementing the case-specific features can be registered programmatically by calling snd_soc_dapm_new_controls() and snd_soc_dapm_add_routes().h]hXIn more complex cases the list of DAPM widgets and/or routes can be only known at probe time. This happens for example when a driver supports different models having a different set of features. In those cases separate widgets and routes arrays implementing the case-specific features can be registered programmatically by calling snd_soc_dapm_new_controls() and snd_soc_dapm_add_routes().}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM%hj hhubeh}(h]registering-dapm-controlsah ]h"]registering dapm controlsah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(h!Codec/DSP Widget Interconnectionsh]h!Codec/DSP Widget Interconnections}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhM.ubh)}(hWidgets are connected to each other within the codec, platform and machine by audio paths (called interconnections). Each interconnection must be defined in order to create a graph of all audio paths between widgets.h]hWidgets are connected to each other within the codec, platform and machine by audio paths (called interconnections). Each interconnection must be defined in order to create a graph of all audio paths between widgets.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM0hj hhubh)}(hThis is easiest with a diagram of the codec or DSP (and schematic of the machine audio system), as it requires joining widgets together via their audio signal paths.h]hThis is easiest with a diagram of the codec or DSP (and schematic of the machine audio system), as it requires joining widgets together via their audio signal paths.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM4hj hhubh)}(hFFor example the WM8731 output mixer (wm8731.c) has 3 inputs (sources):h]hFFor example the WM8731 output mixer (wm8731.c) has 3 inputs (sources):}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM8hj hhubhenumerated_list)}(hhh](j)}(hLine Bypass Inputh]h)}(hj h]hLine Bypass Input}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM:hj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubj)}(hDAC (HiFi playback)h]h)}(hj h]hDAC (HiFi playback)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM;hj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubj)}(hMic Sidetone Input h]h)}(hMic Sidetone Inputh]hMic Sidetone Input}(hj3 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM<hj/ ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix.uh1j hj hhhhhM:ubh)}(hEach input in this example has a kcontrol associated with it (defined in the example above) and is connected to the output mixer via its kcontrol name. We can now connect the destination widget (wrt audio signal) with its source widgets. ::h]hEach input in this example has a kcontrol associated with it (defined in the example above) and is connected to the output mixer via its kcontrol name. We can now connect the destination widget (wrt audio signal) with its source widgets.}(hjR hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM>hj hhubj )}(h/* output mixer */ {"Output Mixer", "Line Bypass Switch", "Line Input"}, {"Output Mixer", "HiFi Playback Switch", "DAC"}, {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},h]h/* output mixer */ {"Output Mixer", "Line Bypass Switch", "Line Input"}, {"Output Mixer", "HiFi Playback Switch", "DAC"}, {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},}hj` sbah}(h]h ]h"]h$]h&]j j uh1j hhhMChj hhubh)}(h So we have:h]h So we have:}(hjn hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMHhj hhubh)}(hhh](j)}(h9Destination Widget <=== Path Name <=== Source Widget, orh]h)}(hj h]h9Destination Widget <=== Path Name <=== Source Widget, or}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMJhj ubah}(h]h ]h"]h$]h&]uh1hhj| hhhhhNubj)}(hSink, Path, Source, orh]h)}(hj h]hSink, Path, Source, or}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMKhj ubah}(h]h ]h"]h$]h&]uh1hhj| hhhhhNubj)}(hO``Output Mixer`` is connected to the ``DAC`` via the ``HiFi Playback Switch``. h]h)}(hN``Output Mixer`` is connected to the ``DAC`` via the ``HiFi Playback Switch``.h](j )}(h``Output Mixer``h]h Output Mixer}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh is connected to the }(hj hhhNhNubj )}(h``DAC``h]hDAC}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh via the }(hj hhhNhNubj )}(h``HiFi Playback Switch``h]hHiFi Playback Switch}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMLhj ubah}(h]h ]h"]h$]h&]uh1hhj| hhhhhNubeh}(h]h ]h"]h$]h&]j]j^uh1hhhhMJhj hhubh)}(hhWhen there is no path name connecting widgets (e.g. a direct connection) we pass NULL for the path name.h]hhWhen there is no path name connecting widgets (e.g. a direct connection) we pass NULL for the path name.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMNhj hhubh)}(h-Interconnections are created with a call to::h]h,Interconnections are created with a call to:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMQhj hhubj )}(h6snd_soc_dapm_connect_input(codec, sink, path, source);h]h6snd_soc_dapm_connect_input(codec, sink, path, source);}hj sbah}(h]h ]h"]h$]h&]j j uh1j hhhMShj hhubh)}(hFinally, snd_soc_dapm_new_widgets() must be called after all widgets and interconnections have been registered with the core. This causes the core to scan the codec and machine so that the internal DAPM state matches the physical state of the machine.h]hFinally, snd_soc_dapm_new_widgets() must be called after all widgets and interconnections have been registered with the core. This causes the core to scan the codec and machine so that the internal DAPM state matches the physical state of the machine.}(hj' hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMUhj hhubh)}(hhh](h)}(hMachine Widget Interconnectionsh]hMachine Widget Interconnections}(hj8 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj5 hhhhhM\ubh)}(hMachine widget interconnections are created in the same way as codec ones and directly connect the codec pins to machine level widgets.h]hMachine widget interconnections are created in the same way as codec ones and directly connect the codec pins to machine level widgets.}(hjF hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM]hj5 hhubh)}(hDe.g. connects the speaker out codec pins to the internal speaker. ::h]hAe.g. connects the speaker out codec pins to the internal speaker.}(hjT hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM`hj5 hhubj )}(hq/* ext speaker connected to codec pins LOUT2, ROUT2 */ {"Ext Spk", NULL , "ROUT2"}, {"Ext Spk", NULL , "LOUT2"},h]hq/* ext speaker connected to codec pins LOUT2, ROUT2 */ {"Ext Spk", NULL , "ROUT2"}, {"Ext Spk", NULL , "LOUT2"},}hjb sbah}(h]h ]h"]h$]h&]j j uh1j hhhMchj5 hhubh)}(hpThis allows the DAPM to power on and off pins that are connected (and in use) and pins that are NC respectively.h]hpThis allows the DAPM to power on and off pins that are connected (and in use) and pins that are NC respectively.}(hjp hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMghj5 hhubeh}(h]machine-widget-interconnectionsah ]h"]machine widget interconnectionsah$]h&]uh1hhj hhhhhM\ubeh}(h]!codec-dsp-widget-interconnectionsah ]h"]!codec/dsp widget interconnectionsah$]h&]uh1hhhhhhhhM.ubh)}(hhh](h)}(hEndpoint Widgetsh]hEndpoint Widgets}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMlubh)}(hoAn endpoint is a start or end point (widget) of an audio signal within the machine and includes the codec. e.g.h]hoAn endpoint is a start or end point (widget) of an audio signal within the machine and includes the codec. e.g.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMmhj hhubh)}(hhh](j)}(hHeadphone Jackh]h)}(hj h]hHeadphone Jack}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMphj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubj)}(hInternal Speakerh]h)}(hj h]hInternal Speaker}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMqhj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubj)}(h Internal Mich]h)}(hj h]h Internal Mic}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMrhj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubj)}(hMic Jackh]h)}(hj h]hMic Jack}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMshj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubj)}(h Codec Pins h]h)}(h Codec Pinsh]h Codec Pins}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMthj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubeh}(h]h ]h"]h$]h&]j]j^uh1hhhhMphj hhubh)}(hEndpoints are added to the DAPM graph so that their usage can be determined in order to save power. e.g. NC codecs pins will be switched OFF, unconnected jacks can also be switched OFF.h]hEndpoints are added to the DAPM graph so that their usage can be determined in order to save power. e.g. NC codecs pins will be switched OFF, unconnected jacks can also be switched OFF.}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMvhj hhubeh}(h]endpoint-widgetsah ]h"]endpoint widgetsah$]h&]uh1hhhhhhhhMlubh)}(hhh](h)}(hDAPM Widget Eventsh]hDAPM Widget Events}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@hhhhhM|ubh)}(hWidgets needing to implement a more complex behaviour than what DAPM can do can set a custom "event handler" by setting a function pointer. An example is a power supply needing to enable a GPIO::h]hWidgets needing to implement a more complex behaviour than what DAPM can do can set a custom “event handler” by setting a function pointer. An example is a power supply needing to enable a GPIO:}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM~hj@hhubj )}(hXZstatic int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) gpiod_set_value_cansleep(gpio_pa, true); else gpiod_set_value_cansleep(gpio_pa, false); return 0; } static const struct snd_soc_dapm_widget st_widgets[] = { ... SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0, sof_es8316_speaker_power_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), };h]hXZstatic int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) gpiod_set_value_cansleep(gpio_pa, true); else gpiod_set_value_cansleep(gpio_pa, false); return 0; } static const struct snd_soc_dapm_widget st_widgets[] = { ... SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0, sof_es8316_speaker_power_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), };}hj_sbah}(h]h ]h"]h$]h&]j j uh1j hhhMhj@hhubh)}(h9See soc-dapm.h for all other widgets that support events.h]h9See soc-dapm.h for all other widgets that support events.}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj@hhubh)}(hhh](h)}(h Event typesh]h Event types}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj{hhhhhMubh)}(h:The following event types are supported by event widgets::h]h9The following event types are supported by event widgets:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj{hhubj )}(hX(/* 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 */ #define SND_SOC_DAPM_WILL_PMU 0x40 /* called at start of sequence */ #define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */ #define SND_SOC_DAPM_PRE_POST_PMD (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD) #define SND_SOC_DAPM_PRE_POST_PMU (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU)h]hX(/* 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 */ #define SND_SOC_DAPM_WILL_PMU 0x40 /* called at start of sequence */ #define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */ #define SND_SOC_DAPM_PRE_POST_PMD (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD) #define SND_SOC_DAPM_PRE_POST_PMU (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU)}hjsbah}(h]h ]h"]h$]h&]j j uh1j hhhMhj{hhubeh}(h] event-typesah ]h"] event typesah$]h&]uh1hhj@hhhhhMubeh}(h]dapm-widget-eventsah ]h"]dapm widget eventsah$]h&]uh1hhhhhhhhM|ubeh}(h]3dynamic-audio-power-management-for-portable-devicesah ]h"]3dynamic audio power management for portable devicesah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jjjjjjj j j` j] j j jm jj j j j j j j j j j j j=j:jjjju nametypes}(jjjj j` j jm j j j j j j=jjuh}(jhjhjjj jj] jj jc jj j j jp j j j j j j j j5 j:j jj@jj{u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages](hsystem_message)}(hhh]h)}(hfPossible title underline, too short for the title. Treating it as ordinary text because it's so short.h]hhPossible title underline, too short for the title. Treating it as ordinary text because it’s so short.}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjGubah}(h]h ]h"]h$]h&]levelKtypeINFOlineKsourcehuh1jEhjhhhhhKubjF)}(hhh]h)}(hfPossible title underline, too short for the title. Treating it as ordinary text because it's so short.h]hhPossible title underline, too short for the title. Treating it as ordinary text because it’s so short.}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjcubah}(h]h ]h"]h$]h&]levelKtypej`lineKsourcehuh1jEhjhhhhhKubjF)}(hhh]h)}(hfPossible title underline, too short for the title. Treating it as ordinary text because it's so short.h]hhPossible title underline, too short for the title. Treating it as ordinary text because it’s so short.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj~ubah}(h]h ]h"]h$]h&]levelKtypej`lineKsourcehuh1jEhjhhhhhKubjF)}(hhh]h)}(hfPossible title underline, too short for the title. Treating it as ordinary text because it's so short.h]hhPossible title underline, too short for the title. Treating it as ordinary text because it’s so short.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypej`lineKsourcehuh1jEhjc hhhhhKubjF)}(hhh]h)}(hfPossible title underline, too short for the title. Treating it as ordinary text because it's so short.h]hhPossible title underline, too short for the title. Treating it as ordinary text because it’s so short.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypej`lineMasourcehuh1jEhj5 hhhhhMaubetransform_messages] transformerN include_log] decorationNhhub.