| 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 | 
 | 65 |  o Pre        - Special PRE widget (exec before all others) | 
 | 66 |  o Post       - Special POST widget (exec after all others) | 
 | 67 |  | 
 | 68 | (Widgets are defined in include/sound/soc-dapm.h) | 
 | 69 |  | 
 | 70 | 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] | 71 | 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] | 72 | list of widgets of the codecs and machines DAPM widgets. | 
 | 73 |  | 
 | 74 | Most widgets have a name, register, shift and invert. Some widgets have extra | 
 | 75 | parameters for stream name and kcontrols. | 
 | 76 |  | 
 | 77 |  | 
 | 78 | 2.1 Stream Domain Widgets | 
 | 79 | ------------------------- | 
 | 80 |  | 
| Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 81 | Stream Widgets relate to the stream power domain and only consist of ADCs | 
 | 82 | (analog to digital converters) and DACs (digital to analog converters). | 
| Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 83 |  | 
 | 84 | Stream widgets have the following format:- | 
 | 85 |  | 
 | 86 | SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert), | 
 | 87 |  | 
| Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 88 | 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] | 89 | snd_soc_codec_dai. | 
 | 90 |  | 
 | 91 | e.g. stream widgets for HiFi playback and capture | 
 | 92 |  | 
 | 93 | SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1), | 
 | 94 | SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1), | 
 | 95 |  | 
 | 96 |  | 
 | 97 | 2.2 Path Domain Widgets | 
 | 98 | ----------------------- | 
 | 99 |  | 
| Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 100 | 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] | 101 | audio paths within the audio subsystem. They have the following form:- | 
 | 102 |  | 
 | 103 | SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls) | 
 | 104 |  | 
 | 105 | Any widget kcontrols can be set using the controls and num_controls members. | 
 | 106 |  | 
 | 107 | e.g. Mixer widget (the kcontrols are declared first) | 
 | 108 |  | 
 | 109 | /* Output Mixer */ | 
 | 110 | static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = { | 
 | 111 | SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), | 
 | 112 | SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), | 
 | 113 | SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), | 
 | 114 | }; | 
 | 115 |  | 
 | 116 | SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls, | 
 | 117 | 	ARRAY_SIZE(wm8731_output_mixer_controls)), | 
 | 118 |  | 
 | 119 |  | 
 | 120 | 2.3 Platform/Machine domain Widgets | 
 | 121 | ----------------------------------- | 
 | 122 |  | 
 | 123 | Machine widgets are different from codec widgets in that they don't have a | 
 | 124 | codec register bit associated with them. A machine widget is assigned to each | 
 | 125 | machine audio component (non codec) that can be independently powered. e.g. | 
 | 126 |  | 
 | 127 |  o Speaker Amp | 
 | 128 |  o Microphone Bias | 
 | 129 |  o Jack connectors | 
 | 130 |  | 
 | 131 | A machine widget can have an optional call back. | 
 | 132 |  | 
 | 133 | e.g. Jack connector widget for an external Mic that enables Mic Bias | 
 | 134 | when the Mic is inserted:- | 
 | 135 |  | 
 | 136 | static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event) | 
 | 137 | { | 
| Eric Miao | fec12a6 | 2008-09-19 02:15:08 +0800 | [diff] [blame] | 138 | 	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] | 139 | 	return 0; | 
 | 140 | } | 
 | 141 |  | 
 | 142 | SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias), | 
 | 143 |  | 
 | 144 |  | 
 | 145 | 2.4 Codec Domain | 
 | 146 | ---------------- | 
 | 147 |  | 
| Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 148 | 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] | 149 | handler. This handler is called when the codec powerstate is changed wrt to any | 
 | 150 | stream event or by kernel PM events. | 
 | 151 |  | 
 | 152 |  | 
 | 153 | 2.5 Virtual Widgets | 
 | 154 | ------------------- | 
 | 155 |  | 
 | 156 | 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] | 157 | corresponding soft power control. In this case it is necessary to create | 
 | 158 | a virtual widget - a widget with no control bits e.g. | 
| Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 159 |  | 
 | 160 | SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0), | 
 | 161 |  | 
 | 162 | This can be used to merge to signal paths together in software. | 
 | 163 |  | 
 | 164 | After all the widgets have been defined, they can then be added to the DAPM | 
 | 165 | subsystem individually with a call to snd_soc_dapm_new_control(). | 
 | 166 |  | 
 | 167 |  | 
 | 168 | 3. Codec Widget Interconnections | 
 | 169 | ================================ | 
 | 170 |  | 
| Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 171 | Widgets are connected to each other within the codec and machine by audio paths | 
 | 172 | (called interconnections). Each interconnection must be defined in order to | 
 | 173 | create a map of all audio paths between widgets. | 
 | 174 |  | 
| Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 175 | This is easiest with a diagram of the codec (and schematic of the machine audio | 
 | 176 | system), as it requires joining widgets together via their audio signal paths. | 
 | 177 |  | 
| Mark Brown | 7c4dbbd | 2008-01-23 08:41:46 +0100 | [diff] [blame] | 178 | e.g., from the WM8731 output mixer (wm8731.c) | 
| Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame] | 179 |  | 
 | 180 | The WM8731 output mixer has 3 inputs (sources) | 
 | 181 |  | 
 | 182 |  1. Line Bypass Input | 
 | 183 |  2. DAC (HiFi playback) | 
 | 184 |  3. Mic Sidetone Input | 
 | 185 |  | 
 | 186 | Each input in this example has a kcontrol associated with it (defined in example | 
 | 187 | above) and is connected to the output mixer via it's kcontrol name. We can now | 
 | 188 | connect the destination widget (wrt audio signal) with it's source widgets. | 
 | 189 |  | 
 | 190 | 	/* output mixer */ | 
 | 191 | 	{"Output Mixer", "Line Bypass Switch", "Line Input"}, | 
 | 192 | 	{"Output Mixer", "HiFi Playback Switch", "DAC"}, | 
 | 193 | 	{"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, | 
 | 194 |  | 
 | 195 | So we have :- | 
 | 196 |  | 
 | 197 | 	Destination Widget  <=== Path Name <=== Source Widget | 
 | 198 |  | 
 | 199 | Or:- | 
 | 200 |  | 
 | 201 | 	Sink, Path, Source | 
 | 202 |  | 
 | 203 | Or :- | 
 | 204 |  | 
 | 205 | 	"Output Mixer" is connected to the "DAC" via the "HiFi Playback Switch". | 
 | 206 |  | 
 | 207 | When there is no path name connecting widgets (e.g. a direct connection) we | 
 | 208 | pass NULL for the path name. | 
 | 209 |  | 
 | 210 | Interconnections are created with a call to:- | 
 | 211 |  | 
 | 212 | snd_soc_dapm_connect_input(codec, sink, path, source); | 
 | 213 |  | 
 | 214 | Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and | 
 | 215 | interconnections have been registered with the core. This causes the core to | 
 | 216 | scan the codec and machine so that the internal DAPM state matches the | 
 | 217 | physical state of the machine. | 
 | 218 |  | 
 | 219 |  | 
 | 220 | 3.1 Machine Widget Interconnections | 
 | 221 | ----------------------------------- | 
 | 222 | Machine widget interconnections are created in the same way as codec ones and | 
 | 223 | directly connect the codec pins to machine level widgets. | 
 | 224 |  | 
 | 225 | e.g. connects the speaker out codec pins to the internal speaker. | 
 | 226 |  | 
 | 227 | 	/* ext speaker connected to codec pins LOUT2, ROUT2  */ | 
 | 228 | 	{"Ext Spk", NULL , "ROUT2"}, | 
 | 229 | 	{"Ext Spk", NULL , "LOUT2"}, | 
 | 230 |  | 
 | 231 | This allows the DAPM to power on and off pins that are connected (and in use) | 
 | 232 | and pins that are NC respectively. | 
 | 233 |  | 
 | 234 |  | 
 | 235 | 4 Endpoint Widgets | 
 | 236 | =================== | 
 | 237 | An endpoint is a start or end point (widget) of an audio signal within the | 
 | 238 | machine and includes the codec. e.g. | 
 | 239 |  | 
 | 240 |  o Headphone Jack | 
 | 241 |  o Internal Speaker | 
 | 242 |  o Internal Mic | 
 | 243 |  o Mic Jack | 
 | 244 |  o Codec Pins | 
 | 245 |  | 
 | 246 | When a codec pin is NC it can be marked as not used with a call to | 
 | 247 |  | 
 | 248 | snd_soc_dapm_set_endpoint(codec, "Widget Name", 0); | 
 | 249 |  | 
 | 250 | The last argument is 0 for inactive and 1 for active. This way the pin and its | 
 | 251 | input widget will never be powered up and consume power. | 
 | 252 |  | 
 | 253 | This also applies to machine widgets. e.g. if a headphone is connected to a | 
 | 254 | jack then the jack can be marked active. If the headphone is removed, then | 
 | 255 | the headphone jack can be marked inactive. | 
 | 256 |  | 
 | 257 |  | 
 | 258 | 5 DAPM Widget Events | 
 | 259 | ==================== | 
 | 260 |  | 
 | 261 | Some widgets can register their interest with the DAPM core in PM events. | 
 | 262 | e.g. A Speaker with an amplifier registers a widget so the amplifier can be | 
 | 263 | powered only when the spk is in use. | 
 | 264 |  | 
 | 265 | /* turn speaker amplifier on/off depending on use */ | 
 | 266 | static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) | 
 | 267 | { | 
| Eric Miao | fec12a6 | 2008-09-19 02:15:08 +0800 | [diff] [blame] | 268 | 	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] | 269 | 	return 0; | 
 | 270 | } | 
 | 271 |  | 
 | 272 | /* corgi machine dapm widgets */ | 
 | 273 | static const struct snd_soc_dapm_widget wm8731_dapm_widgets = | 
 | 274 | 	SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event); | 
 | 275 |  | 
 | 276 | Please see soc-dapm.h for all other widgets that support events. | 
 | 277 |  | 
 | 278 |  | 
 | 279 | 5.1 Event types | 
 | 280 | --------------- | 
 | 281 |  | 
 | 282 | The following event types are supported by event widgets. | 
 | 283 |  | 
 | 284 | /* dapm event types */ | 
 | 285 | #define SND_SOC_DAPM_PRE_PMU	0x1 	/* before widget power up */ | 
 | 286 | #define SND_SOC_DAPM_POST_PMU	0x2		/* after widget power up */ | 
 | 287 | #define SND_SOC_DAPM_PRE_PMD	0x4 	/* before widget power down */ | 
 | 288 | #define SND_SOC_DAPM_POST_PMD	0x8		/* after widget power down */ | 
 | 289 | #define SND_SOC_DAPM_PRE_REG	0x10	/* before audio path setup */ | 
 | 290 | #define SND_SOC_DAPM_POST_REG	0x20	/* after audio path setup */ |