Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 1 | Dynamic Audio Power Management for Portable Devices |
| 2 | =================================================== |
| 3 | |
| 4 | 1. Description |
| 5 | ============== |
| 6 | |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 7 | Dynamic Audio Power Management (DAPM) is designed to allow portable |
| 8 | Linux devices to use the minimum amount of power within the audio |
| 9 | subsystem at all times. It is independent of other kernel PM and as |
| 10 | such, can easily co-exist with the other PM systems. |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 11 | |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 12 | DAPM is also completely transparent to all user space applications as |
| 13 | all power switching is done within the ASoC core. No code changes or |
| 14 | recompiling are required for user space applications. DAPM makes power |
| 15 | switching decisions based upon any audio stream (capture/playback) |
| 16 | activity and audio mixer settings within the device. |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 17 | |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 18 | DAPM spans the whole machine. It covers power control within the entire |
| 19 | audio subsystem, this includes internal codec power blocks and machine |
| 20 | level power systems. |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 21 | |
| 22 | There are 4 power domains within DAPM |
| 23 | |
| 24 | 1. Codec domain - VREF, VMID (core codec and audio power) |
| 25 | Usually controlled at codec probe/remove and suspend/resume, although |
| 26 | can be set at stream time if power is not needed for sidetone, etc. |
| 27 | |
| 28 | 2. Platform/Machine domain - physically connected inputs and outputs |
| 29 | Is platform/machine and user action specific, is configured by the |
| 30 | machine driver and responds to asynchronous events e.g when HP |
| 31 | are inserted |
| 32 | |
| 33 | 3. Path domain - audio susbsystem signal paths |
| 34 | Automatically set when mixer and mux settings are changed by the user. |
| 35 | e.g. alsamixer, amixer. |
| 36 | |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 37 | 4. Stream domain - DACs and ADCs. |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 38 | Enabled and disabled when stream playback/capture is started and |
| 39 | stopped respectively. e.g. aplay, arecord. |
| 40 | |
Matt LaPlante | 01dd2fb | 2007-10-20 01:34:40 +0200 | [diff] [blame] | 41 | All DAPM power switching decisions are made automatically by consulting an audio |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 42 | routing map of the whole machine. This map is specific to each machine and |
| 43 | consists of the interconnections between every audio component (including |
| 44 | internal codec components). All audio components that effect power are called |
| 45 | widgets hereafter. |
| 46 | |
| 47 | |
| 48 | 2. DAPM Widgets |
| 49 | =============== |
| 50 | |
| 51 | Audio DAPM widgets fall into a number of types:- |
| 52 | |
| 53 | o Mixer - Mixes several analog signals into a single analog signal. |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 54 | o Mux - An analog switch that outputs only one of many inputs. |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 55 | o PGA - A programmable gain amplifier or attenuation widget. |
| 56 | o ADC - Analog to Digital Converter |
| 57 | o DAC - Digital to Analog Converter |
| 58 | o Switch - An analog switch |
| 59 | o Input - A codec input pin |
| 60 | o Output - A codec output pin |
| 61 | o Headphone - Headphone (and optional Jack) |
| 62 | o Mic - Mic (and optional Jack) |
| 63 | o Line - Line Input/Output (and optional Jack) |
| 64 | o Speaker - Speaker |
Mark Brown | 246d0a1 | 2009-04-22 18:24:55 +0100 | [diff] [blame] | 65 | o Supply - Power or clock supply widget used by other widgets. |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 66 | o Pre - Special PRE widget (exec before all others) |
| 67 | o Post - Special POST widget (exec after all others) |
| 68 | |
| 69 | (Widgets are defined in include/sound/soc-dapm.h) |
| 70 | |
| 71 | Widgets are usually added in the codec driver and the machine driver. There are |
Matt LaPlante | d919588 | 2008-07-25 19:45:33 -0700 | [diff] [blame] | 72 | convenience macros defined in soc-dapm.h that can be used to quickly build a |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 73 | list of widgets of the codecs and machines DAPM widgets. |
| 74 | |
| 75 | Most widgets have a name, register, shift and invert. Some widgets have extra |
| 76 | parameters for stream name and kcontrols. |
| 77 | |
| 78 | |
| 79 | 2.1 Stream Domain Widgets |
| 80 | ------------------------- |
| 81 | |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 82 | Stream Widgets relate to the stream power domain and only consist of ADCs |
| 83 | (analog to digital converters) and DACs (digital to analog converters). |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 84 | |
| 85 | Stream widgets have the following format:- |
| 86 | |
| 87 | SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert), |
| 88 | |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 89 | NOTE: the stream name must match the corresponding stream name in your codec |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 90 | snd_soc_codec_dai. |
| 91 | |
| 92 | e.g. stream widgets for HiFi playback and capture |
| 93 | |
| 94 | SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1), |
| 95 | SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1), |
| 96 | |
| 97 | |
| 98 | 2.2 Path Domain Widgets |
| 99 | ----------------------- |
| 100 | |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 101 | Path domain widgets have a ability to control or affect the audio signal or |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 102 | audio paths within the audio subsystem. They have the following form:- |
| 103 | |
| 104 | SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls) |
| 105 | |
| 106 | Any widget kcontrols can be set using the controls and num_controls members. |
| 107 | |
| 108 | e.g. Mixer widget (the kcontrols are declared first) |
| 109 | |
| 110 | /* Output Mixer */ |
| 111 | static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = { |
| 112 | SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), |
| 113 | SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), |
| 114 | SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), |
| 115 | }; |
| 116 | |
| 117 | SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls, |
| 118 | ARRAY_SIZE(wm8731_output_mixer_controls)), |
| 119 | |
Ian Molton | ca9c1aa | 2009-01-06 20:11:51 +0000 | [diff] [blame] | 120 | If you dont want the mixer elements prefixed with the name of the mixer widget, |
| 121 | you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same |
| 122 | as for SND_SOC_DAPM_MIXER. |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 123 | |
| 124 | 2.3 Platform/Machine domain Widgets |
| 125 | ----------------------------------- |
| 126 | |
| 127 | Machine widgets are different from codec widgets in that they don't have a |
| 128 | codec register bit associated with them. A machine widget is assigned to each |
| 129 | machine audio component (non codec) that can be independently powered. e.g. |
| 130 | |
| 131 | o Speaker Amp |
| 132 | o Microphone Bias |
| 133 | o Jack connectors |
| 134 | |
| 135 | A machine widget can have an optional call back. |
| 136 | |
| 137 | e.g. Jack connector widget for an external Mic that enables Mic Bias |
| 138 | when the Mic is inserted:- |
| 139 | |
| 140 | static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event) |
| 141 | { |
Eric Miao | fec12a6 | 2008-09-19 02:15:08 +0800 | [diff] [blame] | 142 | gpio_set_value(SPITZ_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event)); |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 143 | return 0; |
| 144 | } |
| 145 | |
| 146 | SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias), |
| 147 | |
| 148 | |
| 149 | 2.4 Codec Domain |
| 150 | ---------------- |
| 151 | |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 152 | The codec power domain has no widgets and is handled by the codecs DAPM event |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 153 | handler. This handler is called when the codec powerstate is changed wrt to any |
| 154 | stream event or by kernel PM events. |
| 155 | |
| 156 | |
| 157 | 2.5 Virtual Widgets |
| 158 | ------------------- |
| 159 | |
| 160 | Sometimes widgets exist in the codec or machine audio map that don't have any |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 161 | corresponding soft power control. In this case it is necessary to create |
| 162 | a virtual widget - a widget with no control bits e.g. |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 163 | |
| 164 | SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0), |
| 165 | |
| 166 | This can be used to merge to signal paths together in software. |
| 167 | |
| 168 | After all the widgets have been defined, they can then be added to the DAPM |
| 169 | subsystem individually with a call to snd_soc_dapm_new_control(). |
| 170 | |
| 171 | |
| 172 | 3. Codec Widget Interconnections |
| 173 | ================================ |
| 174 | |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 175 | Widgets are connected to each other within the codec and machine by audio paths |
| 176 | (called interconnections). Each interconnection must be defined in order to |
| 177 | create a map of all audio paths between widgets. |
| 178 | |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 179 | This is easiest with a diagram of the codec (and schematic of the machine audio |
| 180 | system), as it requires joining widgets together via their audio signal paths. |
| 181 | |
Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 182 | e.g., from the WM8731 output mixer (wm8731.c) |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 183 | |
| 184 | The WM8731 output mixer has 3 inputs (sources) |
| 185 | |
| 186 | 1. Line Bypass Input |
| 187 | 2. DAC (HiFi playback) |
| 188 | 3. Mic Sidetone Input |
| 189 | |
| 190 | Each input in this example has a kcontrol associated with it (defined in example |
Francis Galiegue | a33f322 | 2010-04-23 00:08:02 +0200 | [diff] [blame] | 191 | above) and is connected to the output mixer via its kcontrol name. We can now |
| 192 | connect the destination widget (wrt audio signal) with its source widgets. |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 193 | |
| 194 | /* output mixer */ |
| 195 | {"Output Mixer", "Line Bypass Switch", "Line Input"}, |
| 196 | {"Output Mixer", "HiFi Playback Switch", "DAC"}, |
| 197 | {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, |
| 198 | |
| 199 | So we have :- |
| 200 | |
| 201 | Destination Widget <=== Path Name <=== Source Widget |
| 202 | |
| 203 | Or:- |
| 204 | |
| 205 | Sink, Path, Source |
| 206 | |
| 207 | Or :- |
| 208 | |
| 209 | "Output Mixer" is connected to the "DAC" via the "HiFi Playback Switch". |
| 210 | |
| 211 | When there is no path name connecting widgets (e.g. a direct connection) we |
| 212 | pass NULL for the path name. |
| 213 | |
| 214 | Interconnections are created with a call to:- |
| 215 | |
| 216 | snd_soc_dapm_connect_input(codec, sink, path, source); |
| 217 | |
| 218 | Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and |
| 219 | interconnections have been registered with the core. This causes the core to |
| 220 | scan the codec and machine so that the internal DAPM state matches the |
| 221 | physical state of the machine. |
| 222 | |
| 223 | |
| 224 | 3.1 Machine Widget Interconnections |
| 225 | ----------------------------------- |
| 226 | Machine widget interconnections are created in the same way as codec ones and |
| 227 | directly connect the codec pins to machine level widgets. |
| 228 | |
| 229 | e.g. connects the speaker out codec pins to the internal speaker. |
| 230 | |
| 231 | /* ext speaker connected to codec pins LOUT2, ROUT2 */ |
| 232 | {"Ext Spk", NULL , "ROUT2"}, |
| 233 | {"Ext Spk", NULL , "LOUT2"}, |
| 234 | |
| 235 | This allows the DAPM to power on and off pins that are connected (and in use) |
| 236 | and pins that are NC respectively. |
| 237 | |
| 238 | |
| 239 | 4 Endpoint Widgets |
| 240 | =================== |
| 241 | An endpoint is a start or end point (widget) of an audio signal within the |
| 242 | machine and includes the codec. e.g. |
| 243 | |
| 244 | o Headphone Jack |
| 245 | o Internal Speaker |
| 246 | o Internal Mic |
| 247 | o Mic Jack |
| 248 | o Codec Pins |
| 249 | |
| 250 | When a codec pin is NC it can be marked as not used with a call to |
| 251 | |
| 252 | snd_soc_dapm_set_endpoint(codec, "Widget Name", 0); |
| 253 | |
| 254 | The last argument is 0 for inactive and 1 for active. This way the pin and its |
| 255 | input widget will never be powered up and consume power. |
| 256 | |
| 257 | This also applies to machine widgets. e.g. if a headphone is connected to a |
| 258 | jack then the jack can be marked active. If the headphone is removed, then |
| 259 | the headphone jack can be marked inactive. |
| 260 | |
| 261 | |
| 262 | 5 DAPM Widget Events |
| 263 | ==================== |
| 264 | |
| 265 | Some widgets can register their interest with the DAPM core in PM events. |
| 266 | e.g. A Speaker with an amplifier registers a widget so the amplifier can be |
| 267 | powered only when the spk is in use. |
| 268 | |
| 269 | /* turn speaker amplifier on/off depending on use */ |
| 270 | static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) |
| 271 | { |
Eric Miao | fec12a6 | 2008-09-19 02:15:08 +0800 | [diff] [blame] | 272 | gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event)); |
Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 273 | return 0; |
| 274 | } |
| 275 | |
| 276 | /* corgi machine dapm widgets */ |
| 277 | static const struct snd_soc_dapm_widget wm8731_dapm_widgets = |
| 278 | SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event); |
| 279 | |
| 280 | Please see soc-dapm.h for all other widgets that support events. |
| 281 | |
| 282 | |
| 283 | 5.1 Event types |
| 284 | --------------- |
| 285 | |
| 286 | The following event types are supported by event widgets. |
| 287 | |
| 288 | /* dapm event types */ |
| 289 | #define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */ |
| 290 | #define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */ |
| 291 | #define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */ |
| 292 | #define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */ |
| 293 | #define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */ |
| 294 | #define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */ |