Commit | Line | Data |
---|---|---|
77190f03 | 1 | =================================================== |
eb1a6af3 LG |
2 | Dynamic Audio Power Management for Portable Devices |
3 | =================================================== | |
4 | ||
77190f03 TI |
5 | Description |
6 | =========== | |
eb1a6af3 | 7 | |
7c4dbbd8 MB |
8 | Dynamic Audio Power Management (DAPM) is designed to allow portable |
9 | Linux devices to use the minimum amount of power within the audio | |
610277ca LC |
10 | subsystem at all times. It is independent of other kernel power |
11 | management frameworks and, as such, can easily co-exist with them. | |
eb1a6af3 | 12 | |
7c4dbbd8 MB |
13 | DAPM is also completely transparent to all user space applications as |
14 | all power switching is done within the ASoC core. No code changes or | |
15 | recompiling are required for user space applications. DAPM makes power | |
16 | switching decisions based upon any audio stream (capture/playback) | |
17 | activity and audio mixer settings within the device. | |
eb1a6af3 | 18 | |
dd5f36e5 LC |
19 | DAPM is based on two basic elements, called widgets and routes: |
20 | ||
21 | * a **widget** is every part of the audio hardware that can be enabled by | |
22 | software when in use and disabled to save power when not in use | |
23 | * a **route** is an interconnection between widgets that exists when sound | |
24 | can flow from one widget to the other | |
25 | ||
26 | All DAPM power switching decisions are made automatically by consulting an | |
27 | audio routing graph. This graph is specific to each sound card and spans | |
28 | the whole sound card, so some DAPM routes connect two widgets belonging to | |
29 | different components (e.g. the LINE OUT pin of a CODEC and the input pin of | |
30 | an amplifier). | |
31 | ||
32 | The graph for the STM32MP1-DK1 sound card is shown in picture: | |
33 | ||
34 | .. kernel-figure:: dapm-graph.svg | |
35 | :alt: Example DAPM graph | |
36 | :align: center | |
37 | ||
38 | DAPM power domains | |
39 | ================== | |
eb1a6af3 | 40 | |
3233a68f | 41 | There are 4 power domains within DAPM: |
eb1a6af3 | 42 | |
77190f03 TI |
43 | Codec bias domain |
44 | VREF, VMID (core codec and audio power) | |
45 | ||
eb1a6af3 LG |
46 | Usually controlled at codec probe/remove and suspend/resume, although |
47 | can be set at stream time if power is not needed for sidetone, etc. | |
48 | ||
77190f03 TI |
49 | Platform/Machine domain |
50 | physically connected inputs and outputs | |
51 | ||
eb1a6af3 LG |
52 | Is platform/machine and user action specific, is configured by the |
53 | machine driver and responds to asynchronous events e.g when HP | |
54 | are inserted | |
55 | ||
77190f03 TI |
56 | Path domain |
57 | audio subsystem signal paths | |
58 | ||
eb1a6af3 LG |
59 | Automatically set when mixer and mux settings are changed by the user. |
60 | e.g. alsamixer, amixer. | |
61 | ||
77190f03 TI |
62 | Stream domain |
63 | DACs and ADCs. | |
64 | ||
eb1a6af3 LG |
65 | Enabled and disabled when stream playback/capture is started and |
66 | stopped respectively. e.g. aplay, arecord. | |
67 | ||
eb1a6af3 | 68 | |
77190f03 TI |
69 | DAPM Widgets |
70 | ============ | |
eb1a6af3 | 71 | |
3233a68f | 72 | Audio DAPM widgets fall into a number of types: |
eb1a6af3 | 73 | |
77190f03 TI |
74 | Mixer |
75 | Mixes several analog signals into a single analog signal. | |
76 | Mux | |
77 | An analog switch that outputs only one of many inputs. | |
78 | PGA | |
79 | A programmable gain amplifier or attenuation widget. | |
80 | ADC | |
81 | Analog to Digital Converter | |
82 | DAC | |
83 | Digital to Analog Converter | |
84 | Switch | |
85 | An analog switch | |
86 | Input | |
87 | A codec input pin | |
88 | Output | |
89 | A codec output pin | |
90 | Headphone | |
91 | Headphone (and optional Jack) | |
92 | Mic | |
93 | Mic (and optional Jack) | |
94 | Line | |
95 | Line Input/Output (and optional Jack) | |
96 | Speaker | |
97 | Speaker | |
98 | Supply | |
99 | Power or clock supply widget used by other widgets. | |
100 | Regulator | |
101 | External regulator that supplies power to audio components. | |
102 | Clock | |
103 | External clock that supplies clock to audio components. | |
104 | AIF IN | |
105 | Audio Interface Input (with TDM slot mask). | |
106 | AIF OUT | |
107 | Audio Interface Output (with TDM slot mask). | |
108 | Siggen | |
109 | Signal Generator. | |
110 | DAI IN | |
111 | Digital Audio Interface Input. | |
112 | DAI OUT | |
113 | Digital Audio Interface Output. | |
114 | DAI Link | |
115 | DAI Link between two DAI structures | |
116 | Pre | |
117 | Special PRE widget (exec before all others) | |
118 | Post | |
119 | Special POST widget (exec after all others) | |
8a70b454 LG |
120 | Buffer |
121 | Inter widget audio data buffer within a DSP. | |
122 | Scheduler | |
123 | DSP internal scheduler that schedules component/pipeline processing | |
124 | work. | |
125 | Effect | |
126 | Widget that performs an audio processing effect. | |
127 | SRC | |
128 | Sample Rate Converter within DSP or CODEC | |
129 | ASRC | |
130 | Asynchronous Sample Rate Converter within DSP or CODEC | |
131 | Encoder | |
132 | Widget that encodes audio data from one format (usually PCM) to another | |
133 | usually more compressed format. | |
134 | Decoder | |
135 | Widget that decodes audio data from a compressed format to an | |
136 | uncompressed format like PCM. | |
137 | ||
eb1a6af3 LG |
138 | |
139 | (Widgets are defined in include/sound/soc-dapm.h) | |
140 | ||
630a1b3b LG |
141 | Widgets can be added to the sound card by any of the component driver types. |
142 | There are convenience macros defined in soc-dapm.h that can be used to quickly | |
143 | build a list of widgets of the codecs and machines DAPM widgets. | |
eb1a6af3 LG |
144 | |
145 | Most widgets have a name, register, shift and invert. Some widgets have extra | |
146 | parameters for stream name and kcontrols. | |
147 | ||
148 | ||
77190f03 TI |
149 | Stream Domain Widgets |
150 | --------------------- | |
eb1a6af3 | 151 | |
7c4dbbd8 | 152 | Stream Widgets relate to the stream power domain and only consist of ADCs |
630a1b3b LG |
153 | (analog to digital converters), DACs (digital to analog converters), |
154 | AIF IN and AIF OUT. | |
eb1a6af3 | 155 | |
3233a68f | 156 | Stream widgets have the following format: |
77190f03 | 157 | :: |
eb1a6af3 | 158 | |
77190f03 TI |
159 | SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert), |
160 | SND_SOC_DAPM_AIF_IN(name, stream, slot, reg, shift, invert) | |
eb1a6af3 | 161 | |
7c4dbbd8 | 162 | NOTE: the stream name must match the corresponding stream name in your codec |
eaf84bda | 163 | snd_soc_dai_driver. |
eb1a6af3 LG |
164 | |
165 | e.g. stream widgets for HiFi playback and capture | |
77190f03 | 166 | :: |
eb1a6af3 | 167 | |
77190f03 TI |
168 | SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1), |
169 | SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1), | |
eb1a6af3 | 170 | |
630a1b3b | 171 | e.g. stream widgets for AIF |
77190f03 | 172 | :: |
630a1b3b | 173 | |
77190f03 TI |
174 | SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), |
175 | SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | |
630a1b3b | 176 | |
eb1a6af3 | 177 | |
77190f03 TI |
178 | Path Domain Widgets |
179 | ------------------- | |
eb1a6af3 | 180 | |
7c4dbbd8 | 181 | Path domain widgets have a ability to control or affect the audio signal or |
3233a68f | 182 | audio paths within the audio subsystem. They have the following form: |
77190f03 | 183 | :: |
eb1a6af3 | 184 | |
77190f03 | 185 | SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls) |
eb1a6af3 LG |
186 | |
187 | Any widget kcontrols can be set using the controls and num_controls members. | |
188 | ||
189 | e.g. Mixer widget (the kcontrols are declared first) | |
77190f03 | 190 | :: |
eb1a6af3 | 191 | |
77190f03 TI |
192 | /* Output Mixer */ |
193 | static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = { | |
194 | SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), | |
195 | SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), | |
196 | SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), | |
197 | }; | |
eb1a6af3 | 198 | |
77190f03 | 199 | SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls, |
eb1a6af3 LG |
200 | ARRAY_SIZE(wm8731_output_mixer_controls)), |
201 | ||
8d84c197 | 202 | If you don't want the mixer elements prefixed with the name of the mixer widget, |
ca9c1aae IM |
203 | you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same |
204 | as for SND_SOC_DAPM_MIXER. | |
eb1a6af3 | 205 | |
630a1b3b | 206 | |
77190f03 TI |
207 | Machine domain Widgets |
208 | ---------------------- | |
eb1a6af3 LG |
209 | |
210 | Machine widgets are different from codec widgets in that they don't have a | |
211 | codec register bit associated with them. A machine widget is assigned to each | |
630a1b3b LG |
212 | machine audio component (non codec or DSP) that can be independently |
213 | powered. e.g. | |
eb1a6af3 | 214 | |
77190f03 TI |
215 | * Speaker Amp |
216 | * Microphone Bias | |
217 | * Jack connectors | |
eb1a6af3 LG |
218 | |
219 | A machine widget can have an optional call back. | |
220 | ||
221 | e.g. Jack connector widget for an external Mic that enables Mic Bias | |
3233a68f | 222 | when the Mic is inserted:: |
eb1a6af3 | 223 | |
77190f03 TI |
224 | static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event) |
225 | { | |
fec12a62 | 226 | gpio_set_value(SPITZ_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event)); |
eb1a6af3 | 227 | return 0; |
77190f03 | 228 | } |
eb1a6af3 | 229 | |
77190f03 | 230 | SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias), |
eb1a6af3 LG |
231 | |
232 | ||
77190f03 TI |
233 | Codec (BIAS) Domain |
234 | ------------------- | |
eb1a6af3 | 235 | |
534e0cd8 | 236 | The codec bias power domain has no widgets and is handled by the codec DAPM |
630a1b3b LG |
237 | event handler. This handler is called when the codec powerstate is changed wrt |
238 | to any stream event or by kernel PM events. | |
eb1a6af3 LG |
239 | |
240 | ||
77190f03 TI |
241 | Virtual Widgets |
242 | --------------- | |
eb1a6af3 | 243 | |
7d0e7610 | 244 | Sometimes widgets exist in the codec or machine audio graph that don't have any |
7c4dbbd8 MB |
245 | corresponding soft power control. In this case it is necessary to create |
246 | a virtual widget - a widget with no control bits e.g. | |
77190f03 | 247 | :: |
eb1a6af3 | 248 | |
67c7666f | 249 | SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
eb1a6af3 | 250 | |
534e0cd8 | 251 | This can be used to merge two signal paths together in software. |
eb1a6af3 | 252 | |
36de8c0e LC |
253 | Registering DAPM controls |
254 | ========================= | |
255 | ||
d40e8219 LC |
256 | In many cases the DAPM widgets are implemented statically in a ``static |
257 | const struct snd_soc_dapm_widget`` array in a codec driver, and simply | |
258 | declared via the ``dapm_widgets`` and ``num_dapm_widgets`` fields of the | |
259 | ``struct snd_soc_component_driver``. | |
260 | ||
261 | Similarly, routes connecting them are implemented statically in a ``static | |
262 | const struct snd_soc_dapm_route`` array and declared via the | |
263 | ``dapm_routes`` and ``num_dapm_routes`` fields of the same struct. | |
264 | ||
265 | With the above declared, the driver registration will take care of | |
266 | populating them:: | |
36de8c0e LC |
267 | |
268 | static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = { | |
269 | SND_SOC_DAPM_OUTPUT("SPKN"), | |
270 | SND_SOC_DAPM_OUTPUT("SPKP"), | |
271 | ... | |
272 | }; | |
273 | ||
274 | /* Target, Path, Source */ | |
275 | static const struct snd_soc_dapm_route wm2000_audio_map[] = { | |
276 | { "SPKN", NULL, "ANC Engine" }, | |
277 | { "SPKP", NULL, "ANC Engine" }, | |
278 | ... | |
279 | }; | |
280 | ||
281 | static const struct snd_soc_component_driver soc_component_dev_wm2000 = { | |
282 | ... | |
283 | .dapm_widgets = wm2000_dapm_widgets, | |
284 | .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets), | |
d40e8219 LC |
285 | .dapm_routes = wm2000_audio_map, |
286 | .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), | |
36de8c0e LC |
287 | ... |
288 | }; | |
289 | ||
290 | In more complex cases the list of DAPM widgets and/or routes can be only | |
d40e8219 | 291 | known at probe time. This happens for example when a driver supports |
36de8c0e LC |
292 | different models having a different set of features. In those cases |
293 | separate widgets and routes arrays implementing the case-specific features | |
294 | can be registered programmatically by calling snd_soc_dapm_new_controls() | |
295 | and snd_soc_dapm_add_routes(). | |
eb1a6af3 LG |
296 | |
297 | ||
77190f03 TI |
298 | Codec/DSP Widget Interconnections |
299 | ================================= | |
eb1a6af3 | 300 | |
630a1b3b LG |
301 | Widgets are connected to each other within the codec, platform and machine by |
302 | audio paths (called interconnections). Each interconnection must be defined in | |
7d0e7610 | 303 | order to create a graph of all audio paths between widgets. |
7c4dbbd8 | 304 | |
630a1b3b LG |
305 | This is easiest with a diagram of the codec or DSP (and schematic of the machine |
306 | audio system), as it requires joining widgets together via their audio signal | |
307 | paths. | |
eb1a6af3 | 308 | |
057acfb4 | 309 | For example the WM8731 output mixer (wm8731.c) has 3 inputs (sources): |
eb1a6af3 | 310 | |
77190f03 TI |
311 | 1. Line Bypass Input |
312 | 2. DAC (HiFi playback) | |
313 | 3. Mic Sidetone Input | |
eb1a6af3 | 314 | |
057acfb4 LC |
315 | Each input in this example has a kcontrol associated with it (defined in |
316 | the example above) and is connected to the output mixer via its kcontrol | |
317 | name. We can now connect the destination widget (wrt audio signal) with its | |
318 | source widgets. :: | |
eb1a6af3 LG |
319 | |
320 | /* output mixer */ | |
321 | {"Output Mixer", "Line Bypass Switch", "Line Input"}, | |
322 | {"Output Mixer", "HiFi Playback Switch", "DAC"}, | |
323 | {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, | |
324 | ||
057acfb4 | 325 | So we have: |
eb1a6af3 | 326 | |
77190f03 TI |
327 | * Destination Widget <=== Path Name <=== Source Widget, or |
328 | * Sink, Path, Source, or | |
329 | * ``Output Mixer`` is connected to the ``DAC`` via the ``HiFi Playback Switch``. | |
eb1a6af3 LG |
330 | |
331 | When there is no path name connecting widgets (e.g. a direct connection) we | |
332 | pass NULL for the path name. | |
333 | ||
057acfb4 | 334 | Interconnections are created with a call to:: |
eb1a6af3 | 335 | |
77190f03 | 336 | snd_soc_dapm_connect_input(codec, sink, path, source); |
eb1a6af3 | 337 | |
057acfb4 | 338 | Finally, snd_soc_dapm_new_widgets() must be called after all widgets and |
eb1a6af3 LG |
339 | interconnections have been registered with the core. This causes the core to |
340 | scan the codec and machine so that the internal DAPM state matches the | |
341 | physical state of the machine. | |
342 | ||
343 | ||
77190f03 TI |
344 | Machine Widget Interconnections |
345 | ------------------------------- | |
eb1a6af3 LG |
346 | Machine widget interconnections are created in the same way as codec ones and |
347 | directly connect the codec pins to machine level widgets. | |
348 | ||
349 | e.g. connects the speaker out codec pins to the internal speaker. | |
77190f03 | 350 | :: |
eb1a6af3 LG |
351 | |
352 | /* ext speaker connected to codec pins LOUT2, ROUT2 */ | |
353 | {"Ext Spk", NULL , "ROUT2"}, | |
354 | {"Ext Spk", NULL , "LOUT2"}, | |
355 | ||
356 | This allows the DAPM to power on and off pins that are connected (and in use) | |
357 | and pins that are NC respectively. | |
358 | ||
359 | ||
77190f03 TI |
360 | Endpoint Widgets |
361 | ================ | |
eb1a6af3 LG |
362 | An endpoint is a start or end point (widget) of an audio signal within the |
363 | machine and includes the codec. e.g. | |
364 | ||
77190f03 TI |
365 | * Headphone Jack |
366 | * Internal Speaker | |
367 | * Internal Mic | |
368 | * Mic Jack | |
369 | * Codec Pins | |
eb1a6af3 | 370 | |
630a1b3b LG |
371 | Endpoints are added to the DAPM graph so that their usage can be determined in |
372 | order to save power. e.g. NC codecs pins will be switched OFF, unconnected | |
373 | jacks can also be switched OFF. | |
eb1a6af3 LG |
374 | |
375 | ||
77190f03 TI |
376 | DAPM Widget Events |
377 | ================== | |
eb1a6af3 | 378 | |
ce5a4f10 LC |
379 | Widgets needing to implement a more complex behaviour than what DAPM can do |
380 | can set a custom "event handler" by setting a function pointer. An example | |
381 | is a power supply needing to enable a GPIO:: | |
eb1a6af3 | 382 | |
ce5a4f10 LC |
383 | static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, |
384 | struct snd_kcontrol *kcontrol, int event) | |
77190f03 | 385 | { |
ce5a4f10 LC |
386 | if (SND_SOC_DAPM_EVENT_ON(event)) |
387 | gpiod_set_value_cansleep(gpio_pa, true); | |
388 | else | |
389 | gpiod_set_value_cansleep(gpio_pa, false); | |
390 | ||
391 | return 0; | |
77190f03 | 392 | } |
eb1a6af3 | 393 | |
ce5a4f10 LC |
394 | static const struct snd_soc_dapm_widget st_widgets[] = { |
395 | ... | |
396 | SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0, | |
397 | sof_es8316_speaker_power_event, | |
398 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | |
399 | }; | |
eb1a6af3 | 400 | |
ce5a4f10 | 401 | See soc-dapm.h for all other widgets that support events. |
eb1a6af3 LG |
402 | |
403 | ||
77190f03 TI |
404 | Event types |
405 | ----------- | |
eb1a6af3 LG |
406 | |
407 | The following event types are supported by event widgets. | |
77190f03 TI |
408 | :: |
409 | ||
410 | /* dapm event types */ | |
411 | #define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */ | |
412 | #define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */ | |
413 | #define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */ | |
414 | #define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */ | |
415 | #define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */ | |
416 | #define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */ |