Commit | Line | Data |
---|---|---|
eb1a6af3 LG |
1 | Dynamic Audio Power Management for Portable Devices |
2 | =================================================== | |
3 | ||
4 | 1. Description | |
5 | ============== | |
6 | ||
7 | Dynamic Audio Power Management (DAPM) is designed to allow portable Linux devices | |
8 | to use the minimum amount of power within the audio subsystem at all times. It | |
9 | is independent of other kernel PM and as such, can easily co-exist with the | |
10 | other PM systems. | |
11 | ||
12 | DAPM is also completely transparent to all user space applications as all power | |
13 | switching is done within the ASoC core. No code changes or recompiling are | |
01dd2fbf | 14 | required for user space applications. DAPM makes power switching decisions based |
eb1a6af3 LG |
15 | upon any audio stream (capture/playback) activity and audio mixer settings |
16 | within the device. | |
17 | ||
18 | DAPM spans the whole machine. It covers power control within the entire audio | |
19 | subsystem, this includes internal codec power blocks and machine level power | |
20 | systems. | |
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 | ||
37 | 4. Stream domain - DAC's and ADC's. | |
38 | Enabled and disabled when stream playback/capture is started and | |
39 | stopped respectively. e.g. aplay, arecord. | |
40 | ||
01dd2fbf | 41 | All DAPM power switching decisions are made automatically by consulting an audio |
eb1a6af3 LG |
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. | |
54 | o Mux - An analog switch that outputs only 1 of it's inputs. | |
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 | |
71 | convience macros defined in soc-dapm.h that can be used to quickly build a | |
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 | ||
81 | Stream Widgets relate to the stream power domain and only consist of ADC's | |
82 | (analog to digital converters) and DAC's (digital to analog converters). | |
83 | ||
84 | Stream widgets have the following format:- | |
85 | ||
86 | SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert), | |
87 | ||
88 | NOTE: the stream name must match the corresponding stream name in your codecs | |
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 | ||
100 | Path domain widgets have a ability to control or effect the audio signal or | |
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 | { | |
138 | if(SND_SOC_DAPM_EVENT_ON(event)) | |
139 | set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_MIC_BIAS); | |
140 | else | |
141 | reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_MIC_BIAS); | |
142 | ||
143 | return 0; | |
144 | } | |
145 | ||
146 | SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias), | |
147 | ||
148 | ||
149 | 2.4 Codec Domain | |
150 | ---------------- | |
151 | ||
152 | The Codec power domain has no widgets and is handled by the codecs DAPM event | |
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 | |
161 | corresponding register bit for power control. In this case it's necessary to | |
162 | create a virtual widget - a widget with no control bits e.g. | |
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 | ||
175 | Widgets are connected to each other within the codec and machine by audio | |
176 | paths (called interconnections). Each interconnection must be defined in order | |
177 | to create a map of all audio paths between widgets. | |
178 | This is easiest with a diagram of the codec (and schematic of the machine audio | |
179 | system), as it requires joining widgets together via their audio signal paths. | |
180 | ||
181 | i.e. from the WM8731 codec's output mixer (wm8731.c) | |
182 | ||
183 | The WM8731 output mixer has 3 inputs (sources) | |
184 | ||
185 | 1. Line Bypass Input | |
186 | 2. DAC (HiFi playback) | |
187 | 3. Mic Sidetone Input | |
188 | ||
189 | Each input in this example has a kcontrol associated with it (defined in example | |
190 | above) and is connected to the output mixer via it's kcontrol name. We can now | |
191 | connect the destination widget (wrt audio signal) with it's source widgets. | |
192 | ||
193 | /* output mixer */ | |
194 | {"Output Mixer", "Line Bypass Switch", "Line Input"}, | |
195 | {"Output Mixer", "HiFi Playback Switch", "DAC"}, | |
196 | {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, | |
197 | ||
198 | So we have :- | |
199 | ||
200 | Destination Widget <=== Path Name <=== Source Widget | |
201 | ||
202 | Or:- | |
203 | ||
204 | Sink, Path, Source | |
205 | ||
206 | Or :- | |
207 | ||
208 | "Output Mixer" is connected to the "DAC" via the "HiFi Playback Switch". | |
209 | ||
210 | When there is no path name connecting widgets (e.g. a direct connection) we | |
211 | pass NULL for the path name. | |
212 | ||
213 | Interconnections are created with a call to:- | |
214 | ||
215 | snd_soc_dapm_connect_input(codec, sink, path, source); | |
216 | ||
217 | Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and | |
218 | interconnections have been registered with the core. This causes the core to | |
219 | scan the codec and machine so that the internal DAPM state matches the | |
220 | physical state of the machine. | |
221 | ||
222 | ||
223 | 3.1 Machine Widget Interconnections | |
224 | ----------------------------------- | |
225 | Machine widget interconnections are created in the same way as codec ones and | |
226 | directly connect the codec pins to machine level widgets. | |
227 | ||
228 | e.g. connects the speaker out codec pins to the internal speaker. | |
229 | ||
230 | /* ext speaker connected to codec pins LOUT2, ROUT2 */ | |
231 | {"Ext Spk", NULL , "ROUT2"}, | |
232 | {"Ext Spk", NULL , "LOUT2"}, | |
233 | ||
234 | This allows the DAPM to power on and off pins that are connected (and in use) | |
235 | and pins that are NC respectively. | |
236 | ||
237 | ||
238 | 4 Endpoint Widgets | |
239 | =================== | |
240 | An endpoint is a start or end point (widget) of an audio signal within the | |
241 | machine and includes the codec. e.g. | |
242 | ||
243 | o Headphone Jack | |
244 | o Internal Speaker | |
245 | o Internal Mic | |
246 | o Mic Jack | |
247 | o Codec Pins | |
248 | ||
249 | When a codec pin is NC it can be marked as not used with a call to | |
250 | ||
251 | snd_soc_dapm_set_endpoint(codec, "Widget Name", 0); | |
252 | ||
253 | The last argument is 0 for inactive and 1 for active. This way the pin and its | |
254 | input widget will never be powered up and consume power. | |
255 | ||
256 | This also applies to machine widgets. e.g. if a headphone is connected to a | |
257 | jack then the jack can be marked active. If the headphone is removed, then | |
258 | the headphone jack can be marked inactive. | |
259 | ||
260 | ||
261 | 5 DAPM Widget Events | |
262 | ==================== | |
263 | ||
264 | Some widgets can register their interest with the DAPM core in PM events. | |
265 | e.g. A Speaker with an amplifier registers a widget so the amplifier can be | |
266 | powered only when the spk is in use. | |
267 | ||
268 | /* turn speaker amplifier on/off depending on use */ | |
269 | static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) | |
270 | { | |
271 | if (SND_SOC_DAPM_EVENT_ON(event)) | |
272 | set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); | |
273 | else | |
274 | reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); | |
275 | ||
276 | return 0; | |
277 | } | |
278 | ||
279 | /* corgi machine dapm widgets */ | |
280 | static const struct snd_soc_dapm_widget wm8731_dapm_widgets = | |
281 | SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event); | |
282 | ||
283 | Please see soc-dapm.h for all other widgets that support events. | |
284 | ||
285 | ||
286 | 5.1 Event types | |
287 | --------------- | |
288 | ||
289 | The following event types are supported by event widgets. | |
290 | ||
291 | /* dapm event types */ | |
292 | #define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */ | |
293 | #define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */ | |
294 | #define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */ | |
295 | #define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */ | |
296 | #define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */ | |
297 | #define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */ |