xref: /OK3568_Linux_fs/kernel/Documentation/sound/soc/dapm.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun===================================================
2*4882a593SmuzhiyunDynamic Audio Power Management for Portable Devices
3*4882a593Smuzhiyun===================================================
4*4882a593Smuzhiyun
5*4882a593SmuzhiyunDescription
6*4882a593Smuzhiyun===========
7*4882a593Smuzhiyun
8*4882a593SmuzhiyunDynamic Audio Power Management (DAPM) is designed to allow portable
9*4882a593SmuzhiyunLinux devices to use the minimum amount of power within the audio
10*4882a593Smuzhiyunsubsystem at all times. It is independent of other kernel PM and as
11*4882a593Smuzhiyunsuch, can easily co-exist with the other PM systems.
12*4882a593Smuzhiyun
13*4882a593SmuzhiyunDAPM is also completely transparent to all user space applications as
14*4882a593Smuzhiyunall power switching is done within the ASoC core. No code changes or
15*4882a593Smuzhiyunrecompiling are required for user space applications. DAPM makes power
16*4882a593Smuzhiyunswitching decisions based upon any audio stream (capture/playback)
17*4882a593Smuzhiyunactivity and audio mixer settings within the device.
18*4882a593Smuzhiyun
19*4882a593SmuzhiyunDAPM spans the whole machine. It covers power control within the entire
20*4882a593Smuzhiyunaudio subsystem, this includes internal codec power blocks and machine
21*4882a593Smuzhiyunlevel power systems.
22*4882a593Smuzhiyun
23*4882a593SmuzhiyunThere are 4 power domains within DAPM
24*4882a593Smuzhiyun
25*4882a593SmuzhiyunCodec bias domain
26*4882a593Smuzhiyun      VREF, VMID (core codec and audio power)
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun      Usually controlled at codec probe/remove and suspend/resume, although
29*4882a593Smuzhiyun      can be set at stream time if power is not needed for sidetone, etc.
30*4882a593Smuzhiyun
31*4882a593SmuzhiyunPlatform/Machine domain
32*4882a593Smuzhiyun      physically connected inputs and outputs
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun      Is platform/machine and user action specific, is configured by the
35*4882a593Smuzhiyun      machine driver and responds to asynchronous events e.g when HP
36*4882a593Smuzhiyun      are inserted
37*4882a593Smuzhiyun
38*4882a593SmuzhiyunPath domain
39*4882a593Smuzhiyun      audio subsystem signal paths
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun      Automatically set when mixer and mux settings are changed by the user.
42*4882a593Smuzhiyun      e.g. alsamixer, amixer.
43*4882a593Smuzhiyun
44*4882a593SmuzhiyunStream domain
45*4882a593Smuzhiyun      DACs and ADCs.
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun      Enabled and disabled when stream playback/capture is started and
48*4882a593Smuzhiyun      stopped respectively. e.g. aplay, arecord.
49*4882a593Smuzhiyun
50*4882a593SmuzhiyunAll DAPM power switching decisions are made automatically by consulting an audio
51*4882a593Smuzhiyunrouting map of the whole machine. This map is specific to each machine and
52*4882a593Smuzhiyunconsists of the interconnections between every audio component (including
53*4882a593Smuzhiyuninternal codec components). All audio components that effect power are called
54*4882a593Smuzhiyunwidgets hereafter.
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun
57*4882a593SmuzhiyunDAPM Widgets
58*4882a593Smuzhiyun============
59*4882a593Smuzhiyun
60*4882a593SmuzhiyunAudio DAPM widgets fall into a number of types:-
61*4882a593Smuzhiyun
62*4882a593SmuzhiyunMixer
63*4882a593Smuzhiyun	Mixes several analog signals into a single analog signal.
64*4882a593SmuzhiyunMux
65*4882a593Smuzhiyun	An analog switch that outputs only one of many inputs.
66*4882a593SmuzhiyunPGA
67*4882a593Smuzhiyun	A programmable gain amplifier or attenuation widget.
68*4882a593SmuzhiyunADC
69*4882a593Smuzhiyun	Analog to Digital Converter
70*4882a593SmuzhiyunDAC
71*4882a593Smuzhiyun	Digital to Analog Converter
72*4882a593SmuzhiyunSwitch
73*4882a593Smuzhiyun	An analog switch
74*4882a593SmuzhiyunInput
75*4882a593Smuzhiyun	A codec input pin
76*4882a593SmuzhiyunOutput
77*4882a593Smuzhiyun	A codec output pin
78*4882a593SmuzhiyunHeadphone
79*4882a593Smuzhiyun	Headphone (and optional Jack)
80*4882a593SmuzhiyunMic
81*4882a593Smuzhiyun	Mic (and optional Jack)
82*4882a593SmuzhiyunLine
83*4882a593Smuzhiyun	Line Input/Output (and optional Jack)
84*4882a593SmuzhiyunSpeaker
85*4882a593Smuzhiyun	Speaker
86*4882a593SmuzhiyunSupply
87*4882a593Smuzhiyun	Power or clock supply widget used by other widgets.
88*4882a593SmuzhiyunRegulator
89*4882a593Smuzhiyun	External regulator that supplies power to audio components.
90*4882a593SmuzhiyunClock
91*4882a593Smuzhiyun	External clock that supplies clock to audio components.
92*4882a593SmuzhiyunAIF IN
93*4882a593Smuzhiyun	Audio Interface Input (with TDM slot mask).
94*4882a593SmuzhiyunAIF OUT
95*4882a593Smuzhiyun	Audio Interface Output (with TDM slot mask).
96*4882a593SmuzhiyunSiggen
97*4882a593Smuzhiyun	Signal Generator.
98*4882a593SmuzhiyunDAI IN
99*4882a593Smuzhiyun	Digital Audio Interface Input.
100*4882a593SmuzhiyunDAI OUT
101*4882a593Smuzhiyun	Digital Audio Interface Output.
102*4882a593SmuzhiyunDAI Link
103*4882a593Smuzhiyun	DAI Link between two DAI structures
104*4882a593SmuzhiyunPre
105*4882a593Smuzhiyun	Special PRE widget (exec before all others)
106*4882a593SmuzhiyunPost
107*4882a593Smuzhiyun	Special POST widget (exec after all others)
108*4882a593SmuzhiyunBuffer
109*4882a593Smuzhiyun	Inter widget audio data buffer within a DSP.
110*4882a593SmuzhiyunScheduler
111*4882a593Smuzhiyun	DSP internal scheduler that schedules component/pipeline processing
112*4882a593Smuzhiyun	work.
113*4882a593SmuzhiyunEffect
114*4882a593Smuzhiyun	Widget that performs an audio processing effect.
115*4882a593SmuzhiyunSRC
116*4882a593Smuzhiyun	Sample Rate Converter within DSP or CODEC
117*4882a593SmuzhiyunASRC
118*4882a593Smuzhiyun	Asynchronous Sample Rate Converter within DSP or CODEC
119*4882a593SmuzhiyunEncoder
120*4882a593Smuzhiyun	Widget that encodes audio data from one format (usually PCM) to another
121*4882a593Smuzhiyun	usually more compressed format.
122*4882a593SmuzhiyunDecoder
123*4882a593Smuzhiyun	Widget that decodes audio data from a compressed format to an
124*4882a593Smuzhiyun	uncompressed format like PCM.
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun(Widgets are defined in include/sound/soc-dapm.h)
128*4882a593Smuzhiyun
129*4882a593SmuzhiyunWidgets can be added to the sound card by any of the component driver types.
130*4882a593SmuzhiyunThere are convenience macros defined in soc-dapm.h that can be used to quickly
131*4882a593Smuzhiyunbuild a list of widgets of the codecs and machines DAPM widgets.
132*4882a593Smuzhiyun
133*4882a593SmuzhiyunMost widgets have a name, register, shift and invert. Some widgets have extra
134*4882a593Smuzhiyunparameters for stream name and kcontrols.
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun
137*4882a593SmuzhiyunStream Domain Widgets
138*4882a593Smuzhiyun---------------------
139*4882a593Smuzhiyun
140*4882a593SmuzhiyunStream Widgets relate to the stream power domain and only consist of ADCs
141*4882a593Smuzhiyun(analog to digital converters), DACs (digital to analog converters),
142*4882a593SmuzhiyunAIF IN and AIF OUT.
143*4882a593Smuzhiyun
144*4882a593SmuzhiyunStream widgets have the following format:-
145*4882a593Smuzhiyun::
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun  SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert),
148*4882a593Smuzhiyun  SND_SOC_DAPM_AIF_IN(name, stream, slot, reg, shift, invert)
149*4882a593Smuzhiyun
150*4882a593SmuzhiyunNOTE: the stream name must match the corresponding stream name in your codec
151*4882a593Smuzhiyunsnd_soc_codec_dai.
152*4882a593Smuzhiyun
153*4882a593Smuzhiyune.g. stream widgets for HiFi playback and capture
154*4882a593Smuzhiyun::
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun  SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1),
157*4882a593Smuzhiyun  SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1),
158*4882a593Smuzhiyun
159*4882a593Smuzhiyune.g. stream widgets for AIF
160*4882a593Smuzhiyun::
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun  SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
163*4882a593Smuzhiyun  SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun
166*4882a593SmuzhiyunPath Domain Widgets
167*4882a593Smuzhiyun-------------------
168*4882a593Smuzhiyun
169*4882a593SmuzhiyunPath domain widgets have a ability to control or affect the audio signal or
170*4882a593Smuzhiyunaudio paths within the audio subsystem. They have the following form:-
171*4882a593Smuzhiyun::
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun  SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls)
174*4882a593Smuzhiyun
175*4882a593SmuzhiyunAny widget kcontrols can be set using the controls and num_controls members.
176*4882a593Smuzhiyun
177*4882a593Smuzhiyune.g. Mixer widget (the kcontrols are declared first)
178*4882a593Smuzhiyun::
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun  /* Output Mixer */
181*4882a593Smuzhiyun  static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = {
182*4882a593Smuzhiyun  SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0),
183*4882a593Smuzhiyun  SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0),
184*4882a593Smuzhiyun  SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
185*4882a593Smuzhiyun  };
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun  SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
188*4882a593Smuzhiyun	ARRAY_SIZE(wm8731_output_mixer_controls)),
189*4882a593Smuzhiyun
190*4882a593SmuzhiyunIf you don't want the mixer elements prefixed with the name of the mixer widget,
191*4882a593Smuzhiyunyou can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same
192*4882a593Smuzhiyunas for SND_SOC_DAPM_MIXER.
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun
195*4882a593SmuzhiyunMachine domain Widgets
196*4882a593Smuzhiyun----------------------
197*4882a593Smuzhiyun
198*4882a593SmuzhiyunMachine widgets are different from codec widgets in that they don't have a
199*4882a593Smuzhiyuncodec register bit associated with them. A machine widget is assigned to each
200*4882a593Smuzhiyunmachine audio component (non codec or DSP) that can be independently
201*4882a593Smuzhiyunpowered. e.g.
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun* Speaker Amp
204*4882a593Smuzhiyun* Microphone Bias
205*4882a593Smuzhiyun* Jack connectors
206*4882a593Smuzhiyun
207*4882a593SmuzhiyunA machine widget can have an optional call back.
208*4882a593Smuzhiyun
209*4882a593Smuzhiyune.g. Jack connector widget for an external Mic that enables Mic Bias
210*4882a593Smuzhiyunwhen the Mic is inserted:-::
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun  static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event)
213*4882a593Smuzhiyun  {
214*4882a593Smuzhiyun	gpio_set_value(SPITZ_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
215*4882a593Smuzhiyun	return 0;
216*4882a593Smuzhiyun  }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun  SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias),
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun
221*4882a593SmuzhiyunCodec (BIAS) Domain
222*4882a593Smuzhiyun-------------------
223*4882a593Smuzhiyun
224*4882a593SmuzhiyunThe codec bias power domain has no widgets and is handled by the codecs DAPM
225*4882a593Smuzhiyunevent handler. This handler is called when the codec powerstate is changed wrt
226*4882a593Smuzhiyunto any stream event or by kernel PM events.
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun
229*4882a593SmuzhiyunVirtual Widgets
230*4882a593Smuzhiyun---------------
231*4882a593Smuzhiyun
232*4882a593SmuzhiyunSometimes widgets exist in the codec or machine audio map that don't have any
233*4882a593Smuzhiyuncorresponding soft power control. In this case it is necessary to create
234*4882a593Smuzhiyuna virtual widget - a widget with no control bits e.g.
235*4882a593Smuzhiyun::
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun  SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0),
238*4882a593Smuzhiyun
239*4882a593SmuzhiyunThis can be used to merge to signal paths together in software.
240*4882a593Smuzhiyun
241*4882a593SmuzhiyunAfter all the widgets have been defined, they can then be added to the DAPM
242*4882a593Smuzhiyunsubsystem individually with a call to snd_soc_dapm_new_control().
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun
245*4882a593SmuzhiyunCodec/DSP Widget Interconnections
246*4882a593Smuzhiyun=================================
247*4882a593Smuzhiyun
248*4882a593SmuzhiyunWidgets are connected to each other within the codec, platform and machine by
249*4882a593Smuzhiyunaudio paths (called interconnections). Each interconnection must be defined in
250*4882a593Smuzhiyunorder to create a map of all audio paths between widgets.
251*4882a593Smuzhiyun
252*4882a593SmuzhiyunThis is easiest with a diagram of the codec or DSP (and schematic of the machine
253*4882a593Smuzhiyunaudio system), as it requires joining widgets together via their audio signal
254*4882a593Smuzhiyunpaths.
255*4882a593Smuzhiyun
256*4882a593Smuzhiyune.g., from the WM8731 output mixer (wm8731.c)
257*4882a593Smuzhiyun
258*4882a593SmuzhiyunThe WM8731 output mixer has 3 inputs (sources)
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun1. Line Bypass Input
261*4882a593Smuzhiyun2. DAC (HiFi playback)
262*4882a593Smuzhiyun3. Mic Sidetone Input
263*4882a593Smuzhiyun
264*4882a593SmuzhiyunEach input in this example has a kcontrol associated with it (defined in example
265*4882a593Smuzhiyunabove) and is connected to the output mixer via its kcontrol name. We can now
266*4882a593Smuzhiyunconnect the destination widget (wrt audio signal) with its source widgets.
267*4882a593Smuzhiyun::
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun	/* output mixer */
270*4882a593Smuzhiyun	{"Output Mixer", "Line Bypass Switch", "Line Input"},
271*4882a593Smuzhiyun	{"Output Mixer", "HiFi Playback Switch", "DAC"},
272*4882a593Smuzhiyun	{"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
273*4882a593Smuzhiyun
274*4882a593SmuzhiyunSo we have :-
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun* Destination Widget  <=== Path Name <=== Source Widget, or
277*4882a593Smuzhiyun* Sink, Path, Source, or
278*4882a593Smuzhiyun* ``Output Mixer`` is connected to the ``DAC`` via the ``HiFi Playback Switch``.
279*4882a593Smuzhiyun
280*4882a593SmuzhiyunWhen there is no path name connecting widgets (e.g. a direct connection) we
281*4882a593Smuzhiyunpass NULL for the path name.
282*4882a593Smuzhiyun
283*4882a593SmuzhiyunInterconnections are created with a call to:-
284*4882a593Smuzhiyun::
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun  snd_soc_dapm_connect_input(codec, sink, path, source);
287*4882a593Smuzhiyun
288*4882a593SmuzhiyunFinally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and
289*4882a593Smuzhiyuninterconnections have been registered with the core. This causes the core to
290*4882a593Smuzhiyunscan the codec and machine so that the internal DAPM state matches the
291*4882a593Smuzhiyunphysical state of the machine.
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun
294*4882a593SmuzhiyunMachine Widget Interconnections
295*4882a593Smuzhiyun-------------------------------
296*4882a593SmuzhiyunMachine widget interconnections are created in the same way as codec ones and
297*4882a593Smuzhiyundirectly connect the codec pins to machine level widgets.
298*4882a593Smuzhiyun
299*4882a593Smuzhiyune.g. connects the speaker out codec pins to the internal speaker.
300*4882a593Smuzhiyun::
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun	/* ext speaker connected to codec pins LOUT2, ROUT2  */
303*4882a593Smuzhiyun	{"Ext Spk", NULL , "ROUT2"},
304*4882a593Smuzhiyun	{"Ext Spk", NULL , "LOUT2"},
305*4882a593Smuzhiyun
306*4882a593SmuzhiyunThis allows the DAPM to power on and off pins that are connected (and in use)
307*4882a593Smuzhiyunand pins that are NC respectively.
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun
310*4882a593SmuzhiyunEndpoint Widgets
311*4882a593Smuzhiyun================
312*4882a593SmuzhiyunAn endpoint is a start or end point (widget) of an audio signal within the
313*4882a593Smuzhiyunmachine and includes the codec. e.g.
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun* Headphone Jack
316*4882a593Smuzhiyun* Internal Speaker
317*4882a593Smuzhiyun* Internal Mic
318*4882a593Smuzhiyun* Mic Jack
319*4882a593Smuzhiyun* Codec Pins
320*4882a593Smuzhiyun
321*4882a593SmuzhiyunEndpoints are added to the DAPM graph so that their usage can be determined in
322*4882a593Smuzhiyunorder to save power. e.g. NC codecs pins will be switched OFF, unconnected
323*4882a593Smuzhiyunjacks can also be switched OFF.
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun
326*4882a593SmuzhiyunDAPM Widget Events
327*4882a593Smuzhiyun==================
328*4882a593Smuzhiyun
329*4882a593SmuzhiyunSome widgets can register their interest with the DAPM core in PM events.
330*4882a593Smuzhiyune.g. A Speaker with an amplifier registers a widget so the amplifier can be
331*4882a593Smuzhiyunpowered only when the spk is in use.
332*4882a593Smuzhiyun::
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun  /* turn speaker amplifier on/off depending on use */
335*4882a593Smuzhiyun  static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
336*4882a593Smuzhiyun  {
337*4882a593Smuzhiyun	gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
338*4882a593Smuzhiyun	return 0;
339*4882a593Smuzhiyun  }
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun  /* corgi machine dapm widgets */
342*4882a593Smuzhiyun  static const struct snd_soc_dapm_widget wm8731_dapm_widgets =
343*4882a593Smuzhiyun	SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event);
344*4882a593Smuzhiyun
345*4882a593SmuzhiyunPlease see soc-dapm.h for all other widgets that support events.
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun
348*4882a593SmuzhiyunEvent types
349*4882a593Smuzhiyun-----------
350*4882a593Smuzhiyun
351*4882a593SmuzhiyunThe following event types are supported by event widgets.
352*4882a593Smuzhiyun::
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun  /* dapm event types */
355*4882a593Smuzhiyun  #define SND_SOC_DAPM_PRE_PMU	0x1 	/* before widget power up */
356*4882a593Smuzhiyun  #define SND_SOC_DAPM_POST_PMU	0x2		/* after widget power up */
357*4882a593Smuzhiyun  #define SND_SOC_DAPM_PRE_PMD	0x4 	/* before widget power down */
358*4882a593Smuzhiyun  #define SND_SOC_DAPM_POST_PMD	0x8		/* after widget power down */
359*4882a593Smuzhiyun  #define SND_SOC_DAPM_PRE_REG	0x10	/* before audio path setup */
360*4882a593Smuzhiyun  #define SND_SOC_DAPM_POST_REG	0x20	/* after audio path setup */
361