xref: /openbmc/linux/include/sound/soc-dapm.h (revision 14f6863328164a9e66024bce5f2fa27de7dc00f0)
1c01f3af4SKuninori Morimoto /* SPDX-License-Identifier: GPL-2.0
2c01f3af4SKuninori Morimoto  *
3808db4a4SRichard Purdie  * linux/sound/soc-dapm.h -- ALSA SoC Dynamic Audio Power Management
4808db4a4SRichard Purdie  *
5808db4a4SRichard Purdie  * Author:	Liam Girdwood
6808db4a4SRichard Purdie  * Created:	Aug 11th 2005
7808db4a4SRichard Purdie  * Copyright:	Wolfson Microelectronics. PLC.
8808db4a4SRichard Purdie  */
9808db4a4SRichard Purdie 
10808db4a4SRichard Purdie #ifndef __LINUX_SND_SOC_DAPM_H
11808db4a4SRichard Purdie #define __LINUX_SND_SOC_DAPM_H
12808db4a4SRichard Purdie 
13808db4a4SRichard Purdie #include <linux/types.h>
14808db4a4SRichard Purdie #include <sound/control.h>
158a978234SLiam Girdwood #include <sound/soc-topology.h>
16c147c0e1SLiam Girdwood #include <sound/asoc.h>
17808db4a4SRichard Purdie 
18313162d0SPaul Gortmaker struct device;
19fdff966bSLucas Tanure struct snd_pcm_substream;
203d62ef42STzung-Bi Shih struct snd_soc_pcm_runtime;
213d62ef42STzung-Bi Shih struct soc_enum;
22313162d0SPaul Gortmaker 
23808db4a4SRichard Purdie /* widget has no PM register bit */
24808db4a4SRichard Purdie #define SND_SOC_NOPM	-1
25808db4a4SRichard Purdie 
26808db4a4SRichard Purdie /*
27b7d2a803SJoe Perches  * SoC dynamic audio power management
28808db4a4SRichard Purdie  *
29808db4a4SRichard Purdie  * We can have up to 4 power domains
30808db4a4SRichard Purdie  *  1. Codec domain - VREF, VMID
31808db4a4SRichard Purdie  *     Usually controlled at codec probe/remove, although can be set
32808db4a4SRichard Purdie  *     at stream time if power is not needed for sidetone, etc.
33808db4a4SRichard Purdie  *  2. Platform/Machine domain - physically connected inputs and outputs
34808db4a4SRichard Purdie  *     Is platform/machine and user action specific, is set in the machine
35808db4a4SRichard Purdie  *     driver and by userspace e.g when HP are inserted
36808db4a4SRichard Purdie  *  3. Path domain - Internal codec path mixers
37808db4a4SRichard Purdie  *     Are automatically set when mixer and mux settings are
38808db4a4SRichard Purdie  *     changed by the user.
39808db4a4SRichard Purdie  *  4. Stream domain - DAC's and ADC's.
40808db4a4SRichard Purdie  *     Enabled when stream playback/capture is started.
41808db4a4SRichard Purdie  */
42808db4a4SRichard Purdie 
43808db4a4SRichard Purdie /* codec domain */
44808db4a4SRichard Purdie #define SND_SOC_DAPM_VMID(wname) \
4512e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
4612e58fecSHerve Codina 	.id = snd_soc_dapm_vmid, .name = wname, .kcontrol_news = NULL, \
47808db4a4SRichard Purdie 	.num_kcontrols = 0}
48808db4a4SRichard Purdie 
49808db4a4SRichard Purdie /* platform domain */
501ab97c8cSMark Brown #define SND_SOC_DAPM_SIGGEN(wname) \
5112e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
5212e58fecSHerve Codina 	.id = snd_soc_dapm_siggen, .name = wname, .kcontrol_news = NULL, \
531ab97c8cSMark Brown 	.num_kcontrols = 0, .reg = SND_SOC_NOPM }
5456b4437fSVinod Koul #define SND_SOC_DAPM_SINK(wname) \
5512e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
5612e58fecSHerve Codina 	.id = snd_soc_dapm_sink, .name = wname, .kcontrol_news = NULL, \
5756b4437fSVinod Koul 	.num_kcontrols = 0, .reg = SND_SOC_NOPM }
58808db4a4SRichard Purdie #define SND_SOC_DAPM_INPUT(wname) \
5912e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
6012e58fecSHerve Codina 	.id = snd_soc_dapm_input, .name = wname, .kcontrol_news = NULL, \
610ca03cd7SMark Brown 	.num_kcontrols = 0, .reg = SND_SOC_NOPM }
62808db4a4SRichard Purdie #define SND_SOC_DAPM_OUTPUT(wname) \
6312e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
6412e58fecSHerve Codina 	.id = snd_soc_dapm_output, .name = wname, .kcontrol_news = NULL, \
650ca03cd7SMark Brown 	.num_kcontrols = 0, .reg = SND_SOC_NOPM }
66808db4a4SRichard Purdie #define SND_SOC_DAPM_MIC(wname, wevent) \
6712e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
6812e58fecSHerve Codina 	.id = snd_soc_dapm_mic, .name = wname, .kcontrol_news = NULL, \
690ca03cd7SMark Brown 	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
70808db4a4SRichard Purdie 	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
71808db4a4SRichard Purdie #define SND_SOC_DAPM_HP(wname, wevent) \
7212e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
7312e58fecSHerve Codina 	.id = snd_soc_dapm_hp, .name = wname, .kcontrol_news = NULL, \
740ca03cd7SMark Brown 	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
75808db4a4SRichard Purdie 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
76808db4a4SRichard Purdie #define SND_SOC_DAPM_SPK(wname, wevent) \
7712e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
7812e58fecSHerve Codina 	.id = snd_soc_dapm_spk, .name = wname, .kcontrol_news = NULL, \
790ca03cd7SMark Brown 	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
80808db4a4SRichard Purdie 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
81808db4a4SRichard Purdie #define SND_SOC_DAPM_LINE(wname, wevent) \
8212e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
8312e58fecSHerve Codina 	.id = snd_soc_dapm_line, .name = wname, .kcontrol_news = NULL, \
840ca03cd7SMark Brown 	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
85808db4a4SRichard Purdie 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
86808db4a4SRichard Purdie 
87de9ba98bSLars-Peter Clausen #define SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert) \
88de9ba98bSLars-Peter Clausen 	.reg = wreg, .mask = 1, .shift = wshift, \
89de9ba98bSLars-Peter Clausen 	.on_val = winvert ? 0 : 1, .off_val = winvert ? 1 : 0
90de9ba98bSLars-Peter Clausen 
91808db4a4SRichard Purdie /* path domain */
92808db4a4SRichard Purdie #define SND_SOC_DAPM_PGA(wname, wreg, wshift, winvert,\
93808db4a4SRichard Purdie 	 wcontrols, wncontrols) \
9412e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
9512e58fecSHerve Codina 	.id = snd_soc_dapm_pga, .name = wname, \
96de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
97de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
98d88429a6SOlaya, Margarita #define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\
99d88429a6SOlaya, Margarita 	 wcontrols, wncontrols) \
10012e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
10112e58fecSHerve Codina 	.id = snd_soc_dapm_out_drv, .name = wname, \
102de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
103de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
104808db4a4SRichard Purdie #define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \
105808db4a4SRichard Purdie 	 wcontrols, wncontrols)\
10612e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
10712e58fecSHerve Codina 	.id = snd_soc_dapm_mixer, .name = wname, \
108de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
109de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
110ca9c1aaeSIan Molton #define SND_SOC_DAPM_MIXER_NAMED_CTL(wname, wreg, wshift, winvert, \
111ca9c1aaeSIan Molton 	 wcontrols, wncontrols)\
11212e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
11312e58fecSHerve Codina 	.id = snd_soc_dapm_mixer_named_ctl, .name = wname, \
114de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
115de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
11632902177SJohn Keeping /* DEPRECATED: use SND_SOC_DAPM_SUPPLY */
117808db4a4SRichard Purdie #define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert) \
11812e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
11912e58fecSHerve Codina 	.id = snd_soc_dapm_micbias, .name = wname, \
120de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
121de9ba98bSLars-Peter Clausen 	.kcontrol_news = NULL, .num_kcontrols = 0}
122808db4a4SRichard Purdie #define SND_SOC_DAPM_SWITCH(wname, wreg, wshift, winvert, wcontrols) \
12312e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
12412e58fecSHerve Codina 	.id = snd_soc_dapm_switch, .name = wname, \
125de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
126de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = 1}
127808db4a4SRichard Purdie #define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
12812e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
12912e58fecSHerve Codina 	.id = snd_soc_dapm_mux, .name = wname, \
130faf6615bSStephen Warren 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
131de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = 1}
132d714f97cSLars-Peter Clausen #define SND_SOC_DAPM_DEMUX(wname, wreg, wshift, winvert, wcontrols) \
13312e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
13412e58fecSHerve Codina 	.id = snd_soc_dapm_demux, .name = wname, \
135d714f97cSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
136d714f97cSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = 1}
137808db4a4SRichard Purdie 
1388484c63fSGuennadi Liakhovetski /* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
1398484c63fSGuennadi Liakhovetski #define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
1408484c63fSGuennadi Liakhovetski 	 wcontrols) \
14112e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
14212e58fecSHerve Codina 	.id = snd_soc_dapm_pga, .name = wname, \
143de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
144de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
1458484c63fSGuennadi Liakhovetski #define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, \
1468484c63fSGuennadi Liakhovetski 	 wcontrols)\
14712e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
14812e58fecSHerve Codina 	.id = snd_soc_dapm_mixer, .name = wname, \
149de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
150de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
1518484c63fSGuennadi Liakhovetski #define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, \
1528484c63fSGuennadi Liakhovetski 	 wcontrols)\
15312e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
15412e58fecSHerve Codina 	.id = snd_soc_dapm_mixer_named_ctl, .name = wname, \
155de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
156de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
1578484c63fSGuennadi Liakhovetski 
158808db4a4SRichard Purdie /* path domain with event - event handler must return 0 for success */
159808db4a4SRichard Purdie #define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \
160808db4a4SRichard Purdie 	wncontrols, wevent, wflags) \
16112e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
16212e58fecSHerve Codina 	.id = snd_soc_dapm_pga, .name = wname, \
163de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
164de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
165808db4a4SRichard Purdie 	.event = wevent, .event_flags = wflags}
166d88429a6SOlaya, Margarita #define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \
167d88429a6SOlaya, Margarita 	wncontrols, wevent, wflags) \
16812e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
16912e58fecSHerve Codina 	.id = snd_soc_dapm_out_drv, .name = wname, \
170de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
171de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
172d88429a6SOlaya, Margarita 	.event = wevent, .event_flags = wflags}
173808db4a4SRichard Purdie #define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \
174808db4a4SRichard Purdie 	wncontrols, wevent, wflags) \
17512e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
17612e58fecSHerve Codina 	.id = snd_soc_dapm_mixer, .name = wname, \
177de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
178de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
179808db4a4SRichard Purdie 	.event = wevent, .event_flags = wflags}
180ca9c1aaeSIan Molton #define SND_SOC_DAPM_MIXER_NAMED_CTL_E(wname, wreg, wshift, winvert, \
181ca9c1aaeSIan Molton 	wcontrols, wncontrols, wevent, wflags) \
18212e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
18312e58fecSHerve Codina 	.id = snd_soc_dapm_mixer, .name = wname, \
184de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
185de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, \
186ca9c1aaeSIan Molton 	.num_kcontrols = wncontrols, .event = wevent, .event_flags = wflags}
187808db4a4SRichard Purdie #define SND_SOC_DAPM_SWITCH_E(wname, wreg, wshift, winvert, wcontrols, \
188808db4a4SRichard Purdie 	wevent, wflags) \
18912e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
19012e58fecSHerve Codina 	.id = snd_soc_dapm_switch, .name = wname, \
191de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
192de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = 1, \
193808db4a4SRichard Purdie 	.event = wevent, .event_flags = wflags}
194808db4a4SRichard Purdie #define SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, \
195808db4a4SRichard Purdie 	wevent, wflags) \
19612e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
19712e58fecSHerve Codina 	.id = snd_soc_dapm_mux, .name = wname, \
198de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
199de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = 1, \
200808db4a4SRichard Purdie 	.event = wevent, .event_flags = wflags}
201808db4a4SRichard Purdie 
20220e4859dSMark Brown /* additional sequencing control within an event type */
2033d23c73fSMark Brown #define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, \
2043d23c73fSMark Brown 	wevent, wflags) \
20512e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
20612e58fecSHerve Codina 	.id = snd_soc_dapm_pga, .name = wname, \
207de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
208de9ba98bSLars-Peter Clausen 	.event = wevent, .event_flags = wflags, \
2093d23c73fSMark Brown 	.subseq = wsubseq}
21020e4859dSMark Brown #define SND_SOC_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, winvert, wevent, \
21120e4859dSMark Brown 	wflags)	\
21212e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
21312e58fecSHerve Codina 	.id = snd_soc_dapm_supply, .name = wname, \
214de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
215de9ba98bSLars-Peter Clausen 	.event = wevent, .event_flags = wflags, .subseq = wsubseq}
21620e4859dSMark Brown 
2178484c63fSGuennadi Liakhovetski /* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
2188484c63fSGuennadi Liakhovetski #define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
2198484c63fSGuennadi Liakhovetski 	wevent, wflags) \
22012e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
22112e58fecSHerve Codina 	.id = snd_soc_dapm_pga, .name = wname, \
222de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
223de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
2248484c63fSGuennadi Liakhovetski 	.event = wevent, .event_flags = wflags}
2258484c63fSGuennadi Liakhovetski #define SOC_MIXER_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
2268484c63fSGuennadi Liakhovetski 	wevent, wflags) \
22712e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
22812e58fecSHerve Codina 	.id = snd_soc_dapm_mixer, .name = wname, \
229de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
230de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
2318484c63fSGuennadi Liakhovetski 	.event = wevent, .event_flags = wflags}
2328484c63fSGuennadi Liakhovetski #define SOC_MIXER_NAMED_CTL_E_ARRAY(wname, wreg, wshift, winvert, \
2338484c63fSGuennadi Liakhovetski 	wcontrols, wevent, wflags) \
23412e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
23512e58fecSHerve Codina 	.id = snd_soc_dapm_mixer, .name = wname, \
236de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
237de9ba98bSLars-Peter Clausen 	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
238de9ba98bSLars-Peter Clausen 	.event = wevent, .event_flags = wflags}
2398484c63fSGuennadi Liakhovetski 
240808db4a4SRichard Purdie /* events that are pre and post DAPM */
241808db4a4SRichard Purdie #define SND_SOC_DAPM_PRE(wname, wevent) \
24212e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
24312e58fecSHerve Codina 	.id = snd_soc_dapm_pre, .name = wname, .kcontrol_news = NULL, \
2440ca03cd7SMark Brown 	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
245808db4a4SRichard Purdie 	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD}
246808db4a4SRichard Purdie #define SND_SOC_DAPM_POST(wname, wevent) \
24712e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
24812e58fecSHerve Codina 	.id = snd_soc_dapm_post, .name = wname, .kcontrol_news = NULL, \
2490ca03cd7SMark Brown 	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
250808db4a4SRichard Purdie 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD}
251808db4a4SRichard Purdie 
252808db4a4SRichard Purdie /* stream domain */
253078a85f2SCharles Keepax #define SND_SOC_DAPM_AIF_IN(wname, stname, wchan, wreg, wshift, winvert) \
25412e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
25512e58fecSHerve Codina 	.id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
256078a85f2SCharles Keepax 	.channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
257078a85f2SCharles Keepax #define SND_SOC_DAPM_AIF_IN_E(wname, stname, wchan, wreg, wshift, winvert, \
258ea0d09deSMark Brown 			      wevent, wflags)				\
25912e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
26012e58fecSHerve Codina 	.id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
261078a85f2SCharles Keepax 	.channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
262ea0d09deSMark Brown 	.event = wevent, .event_flags = wflags }
263078a85f2SCharles Keepax #define SND_SOC_DAPM_AIF_OUT(wname, stname, wchan, wreg, wshift, winvert) \
26412e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
26512e58fecSHerve Codina 	.id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
266078a85f2SCharles Keepax 	.channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
267078a85f2SCharles Keepax #define SND_SOC_DAPM_AIF_OUT_E(wname, stname, wchan, wreg, wshift, winvert, \
268ea0d09deSMark Brown 			     wevent, wflags)				\
26912e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
27012e58fecSHerve Codina 	.id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
271078a85f2SCharles Keepax 	.channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
272ea0d09deSMark Brown 	.event = wevent, .event_flags = wflags }
273808db4a4SRichard Purdie #define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
27412e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
27512e58fecSHerve Codina 	.id = snd_soc_dapm_dac, .name = wname, .sname = stname, \
276de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert) }
277f6d655a6SMark Brown #define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \
278f6d655a6SMark Brown 			   wevent, wflags)				\
27912e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
28012e58fecSHerve Codina 	.id = snd_soc_dapm_dac, .name = wname, .sname = stname, \
281de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
282f6d655a6SMark Brown 	.event = wevent, .event_flags = wflags}
283de9ba98bSLars-Peter Clausen 
284808db4a4SRichard Purdie #define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \
28512e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
28612e58fecSHerve Codina 	.id = snd_soc_dapm_adc, .name = wname, .sname = stname, \
287de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
288f6d655a6SMark Brown #define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \
289f6d655a6SMark Brown 			   wevent, wflags)				\
29012e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
29112e58fecSHerve Codina 	.id = snd_soc_dapm_adc, .name = wname, .sname = stname, \
292de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
293f6d655a6SMark Brown 	.event = wevent, .event_flags = wflags}
294d7e7eb91SOla Lilja #define SND_SOC_DAPM_CLOCK_SUPPLY(wname) \
29512e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
29612e58fecSHerve Codina 	.id = snd_soc_dapm_clock_supply, .name = wname, \
297d7e7eb91SOla Lilja 	.reg = SND_SOC_NOPM, .event = dapm_clock_event, \
298d7e7eb91SOla Lilja 	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
299808db4a4SRichard Purdie 
300246d0a17SMark Brown /* generic widgets */
301e2be2ccfSJarkko Nikula #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
30212e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
30312e58fecSHerve Codina 	.id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \
30494986198SLars-Peter Clausen 	.reg = wreg, .shift = wshift, .mask = wmask, \
30594986198SLars-Peter Clausen 	.on_val = won_val, .off_val = woff_val, }
306246d0a17SMark Brown #define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
30712e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
30812e58fecSHerve Codina 	.id = snd_soc_dapm_supply, .name = wname, \
309de9ba98bSLars-Peter Clausen 	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
310de9ba98bSLars-Peter Clausen 	.event = wevent, .event_flags = wflags}
311822b4b8dSMark Brown #define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay, wflags)	    \
31212e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
31312e58fecSHerve Codina 	.id = snd_soc_dapm_regulator_supply, .name = wname, \
31462ea874aSMark Brown 	.reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
315822b4b8dSMark Brown 	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
316de9ba98bSLars-Peter Clausen 	.on_val = wflags}
3175b2d15bbSSrinivas Kandagatla #define SND_SOC_DAPM_PINCTRL(wname, active, sleep) \
31812e58fecSHerve Codina (struct snd_soc_dapm_widget) { \
31912e58fecSHerve Codina 	.id = snd_soc_dapm_pinctrl, .name = wname, \
3205b2d15bbSSrinivas Kandagatla 	.priv = (&(struct snd_soc_dapm_pinctrl_priv) \
3215b2d15bbSSrinivas Kandagatla 		{ .active_state = active, .sleep_state = sleep,}), \
3225b2d15bbSSrinivas Kandagatla 	.reg = SND_SOC_NOPM, .event = dapm_pinctrl_event, \
3235b2d15bbSSrinivas Kandagatla 	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
3245b2d15bbSSrinivas Kandagatla 
325e2be2ccfSJarkko Nikula 
326d7e7eb91SOla Lilja 
327808db4a4SRichard Purdie /* dapm kcontrol types */
3289ee7ef31SChen-Yu Tsai #define SOC_DAPM_DOUBLE(xname, reg, lshift, rshift, max, invert) \
3299ee7ef31SChen-Yu Tsai {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
3309ee7ef31SChen-Yu Tsai 	.info = snd_soc_info_volsw, \
3319ee7ef31SChen-Yu Tsai 	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
3329ee7ef31SChen-Yu Tsai 	.private_value = SOC_DOUBLE_VALUE(reg, lshift, rshift, max, invert, 0) }
33302866eabSChen-Yu Tsai #define SOC_DAPM_DOUBLE_R(xname, lreg, rreg, shift, max, invert) \
33402866eabSChen-Yu Tsai {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
33502866eabSChen-Yu Tsai 	.info = snd_soc_info_volsw, \
33602866eabSChen-Yu Tsai 	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
33702866eabSChen-Yu Tsai 	.private_value = SOC_DOUBLE_R_VALUE(lreg, rreg, shift, max, invert) }
338a7a4ac86SPhilipp Zabel #define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
339808db4a4SRichard Purdie {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
340808db4a4SRichard Purdie 	.info = snd_soc_info_volsw, \
341808db4a4SRichard Purdie 	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
34257295073SLars-Peter Clausen 	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
34357295073SLars-Peter Clausen #define SOC_DAPM_SINGLE_AUTODISABLE(xname, reg, shift, max, invert) \
34457295073SLars-Peter Clausen {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
34557295073SLars-Peter Clausen 	.info = snd_soc_info_volsw, \
34657295073SLars-Peter Clausen 	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
34757295073SLars-Peter Clausen 	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) }
348249ce138SLars-Peter Clausen #define SOC_DAPM_SINGLE_VIRT(xname, max) \
349249ce138SLars-Peter Clausen 	SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0)
350a7a4ac86SPhilipp Zabel #define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
351a7a4ac86SPhilipp Zabel {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
352a7a4ac86SPhilipp Zabel 	.info = snd_soc_info_volsw, \
353a7a4ac86SPhilipp Zabel 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\
354a7a4ac86SPhilipp Zabel 	.tlv.p = (tlv_array), \
355a7a4ac86SPhilipp Zabel 	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
35657295073SLars-Peter Clausen 	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
35757295073SLars-Peter Clausen #define SOC_DAPM_SINGLE_TLV_AUTODISABLE(xname, reg, shift, max, invert, tlv_array) \
35857295073SLars-Peter Clausen {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
35957295073SLars-Peter Clausen 	.info = snd_soc_info_volsw, \
36057295073SLars-Peter Clausen 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\
36157295073SLars-Peter Clausen 	.tlv.p = (tlv_array), \
36257295073SLars-Peter Clausen 	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
363a2d97723SCharles Keepax 	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) }
364249ce138SLars-Peter Clausen #define SOC_DAPM_SINGLE_TLV_VIRT(xname, max, tlv_array) \
365249ce138SLars-Peter Clausen 	SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0, tlv_array)
366808db4a4SRichard Purdie #define SOC_DAPM_ENUM(xname, xenum) \
367808db4a4SRichard Purdie {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
368808db4a4SRichard Purdie 	.info = snd_soc_info_enum_double, \
369808db4a4SRichard Purdie  	.get = snd_soc_dapm_get_enum_double, \
370808db4a4SRichard Purdie  	.put = snd_soc_dapm_put_enum_double, \
371808db4a4SRichard Purdie   	.private_value = (unsigned long)&xenum }
372c219c809SLiam Girdwood #define SOC_DAPM_ENUM_EXT(xname, xenum, xget, xput) \
373c219c809SLiam Girdwood {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
374c219c809SLiam Girdwood 	.info = snd_soc_info_enum_double, \
375c219c809SLiam Girdwood 	.get = xget, \
376c219c809SLiam Girdwood 	.put = xput, \
377c219c809SLiam Girdwood 	.private_value = (unsigned long)&xenum }
3788b37dbd2SMark Brown #define SOC_DAPM_PIN_SWITCH(xname) \
3798b37dbd2SMark Brown {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname " Switch", \
3808b37dbd2SMark Brown 	.info = snd_soc_dapm_info_pin_switch, \
3818b37dbd2SMark Brown 	.get = snd_soc_dapm_get_pin_switch, \
3828b37dbd2SMark Brown 	.put = snd_soc_dapm_put_pin_switch, \
3838b37dbd2SMark Brown 	.private_value = (unsigned long)xname }
384808db4a4SRichard Purdie 
385808db4a4SRichard Purdie /* dapm stream operations */
386808db4a4SRichard Purdie #define SND_SOC_DAPM_STREAM_NOP			0x0
387808db4a4SRichard Purdie #define SND_SOC_DAPM_STREAM_START		0x1
388808db4a4SRichard Purdie #define SND_SOC_DAPM_STREAM_STOP		0x2
389808db4a4SRichard Purdie #define SND_SOC_DAPM_STREAM_SUSPEND		0x4
390808db4a4SRichard Purdie #define SND_SOC_DAPM_STREAM_RESUME		0x8
391808db4a4SRichard Purdie #define SND_SOC_DAPM_STREAM_PAUSE_PUSH		0x10
392808db4a4SRichard Purdie #define SND_SOC_DAPM_STREAM_PAUSE_RELEASE	0x20
393808db4a4SRichard Purdie 
394808db4a4SRichard Purdie /* dapm event types */
395808db4a4SRichard Purdie #define SND_SOC_DAPM_PRE_PMU		0x1	/* before widget power up */
396808db4a4SRichard Purdie #define SND_SOC_DAPM_POST_PMU		0x2	/* after  widget power up */
397808db4a4SRichard Purdie #define SND_SOC_DAPM_PRE_PMD		0x4	/* before widget power down */
398808db4a4SRichard Purdie #define SND_SOC_DAPM_POST_PMD		0x8	/* after  widget power down */
399808db4a4SRichard Purdie #define SND_SOC_DAPM_PRE_REG		0x10	/* before audio path setup */
400808db4a4SRichard Purdie #define SND_SOC_DAPM_POST_REG		0x20	/* after  audio path setup */
40180114129SMark Brown #define SND_SOC_DAPM_WILL_PMU		0x40	/* called at start of sequence */
40280114129SMark Brown #define SND_SOC_DAPM_WILL_PMD		0x80	/* called at start of sequence */
403f3779b16SKuninori Morimoto #define SND_SOC_DAPM_PRE_POST_PMD	(SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD)
404f3779b16SKuninori Morimoto #define SND_SOC_DAPM_PRE_POST_PMU	(SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU)
405808db4a4SRichard Purdie 
406808db4a4SRichard Purdie /* convenience event type detection */
407f3779b16SKuninori Morimoto #define SND_SOC_DAPM_EVENT_ON(e)	(e & (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU))
408f3779b16SKuninori Morimoto #define SND_SOC_DAPM_EVENT_OFF(e)	(e & (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD))
409808db4a4SRichard Purdie 
410c05b84d1SMark Brown /* regulator widget flags */
411c05b84d1SMark Brown #define SND_SOC_DAPM_REGULATOR_BYPASS	0x1	/* bypass when disabled */
412c05b84d1SMark Brown 
413808db4a4SRichard Purdie struct snd_soc_dapm_widget;
414808db4a4SRichard Purdie enum snd_soc_dapm_type;
415808db4a4SRichard Purdie struct snd_soc_dapm_path;
416808db4a4SRichard Purdie struct snd_soc_dapm_pin;
417105f1c28SMark Brown struct snd_soc_dapm_route;
418ce6120ccSLiam Girdwood struct snd_soc_dapm_context;
419a3cc056bSLiam Girdwood struct regulator;
420ec2e3031SLiam Girdwood struct snd_soc_dapm_widget_list;
4216b3fc03bSLars-Peter Clausen struct snd_soc_dapm_update;
4226742064aSPiotr Stankiewicz enum snd_soc_dapm_direction;
423808db4a4SRichard Purdie 
42410e83409STzung-Bi Shih /*
42510e83409STzung-Bi Shih  * Bias levels
42610e83409STzung-Bi Shih  *
42710e83409STzung-Bi Shih  * @ON:      Bias is fully on for audio playback and capture operations.
42810e83409STzung-Bi Shih  * @PREPARE: Prepare for audio operations. Called before DAPM switching for
42910e83409STzung-Bi Shih  *           stream start and stop operations.
43010e83409STzung-Bi Shih  * @STANDBY: Low power standby state when no playback/capture operations are
43110e83409STzung-Bi Shih  *           in progress. NOTE: The transition time between STANDBY and ON
43210e83409STzung-Bi Shih  *           should be as fast as possible and no longer than 10ms.
43310e83409STzung-Bi Shih  * @OFF:     Power Off. No restrictions on transition times.
43410e83409STzung-Bi Shih  */
43510e83409STzung-Bi Shih enum snd_soc_bias_level {
43610e83409STzung-Bi Shih 	SND_SOC_BIAS_OFF = 0,
43710e83409STzung-Bi Shih 	SND_SOC_BIAS_STANDBY = 1,
43810e83409STzung-Bi Shih 	SND_SOC_BIAS_PREPARE = 2,
43910e83409STzung-Bi Shih 	SND_SOC_BIAS_ON = 3,
44010e83409STzung-Bi Shih };
44110e83409STzung-Bi Shih 
442f3779b16SKuninori Morimoto int dapm_regulator_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
443f3779b16SKuninori Morimoto int dapm_clock_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
444f3779b16SKuninori Morimoto int dapm_pinctrl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
44511589418SMark Brown 
446808db4a4SRichard Purdie /* dapm controls */
447f3779b16SKuninori Morimoto int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
448f3779b16SKuninori Morimoto int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
449808db4a4SRichard Purdie int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
450808db4a4SRichard Purdie 	struct snd_ctl_elem_value *ucontrol);
451808db4a4SRichard Purdie int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
452808db4a4SRichard Purdie 	struct snd_ctl_elem_value *ucontrol);
4538b37dbd2SMark Brown int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
4548b37dbd2SMark Brown 	struct snd_ctl_elem_info *uinfo);
4558b37dbd2SMark Brown int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
4568b37dbd2SMark Brown 	struct snd_ctl_elem_value *uncontrol);
4578b37dbd2SMark Brown int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
4588b37dbd2SMark Brown 	struct snd_ctl_elem_value *uncontrol);
459ce6120ccSLiam Girdwood int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
460f3779b16SKuninori Morimoto 	const struct snd_soc_dapm_widget *widget, int num);
461f3779b16SKuninori Morimoto struct snd_soc_dapm_widget *snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
462a5d5639fSSubhransu S. Prusty 		const struct snd_soc_dapm_widget *widget);
463f3779b16SKuninori Morimoto struct snd_soc_dapm_widget *snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
464db33f00dSAmadeusz Sławiński 		const struct snd_soc_dapm_widget *widget);
465f3779b16SKuninori Morimoto int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, struct snd_soc_dai *dai);
466da039809SCezary Rojewski void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
467888df395SMark Brown int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
468b893ea5fSLiam Girdwood void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);
469808db4a4SRichard Purdie 
470078a85f2SCharles Keepax int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream,
471f3779b16SKuninori Morimoto 			    struct snd_pcm_hw_params *params, struct snd_soc_dai *dai);
472*76aca10cSKrzysztof Kozlowski int snd_soc_dapm_widget_name_cmp(struct snd_soc_dapm_widget *widget, const char *s);
473078a85f2SCharles Keepax 
474808db4a4SRichard Purdie /* dapm path setup */
475824ef826SLars-Peter Clausen int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
476ce6120ccSLiam Girdwood void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
47795c267ddSKuninori Morimoto void snd_soc_dapm_init(struct snd_soc_dapm_context *dapm,
478f3779b16SKuninori Morimoto 		       struct snd_soc_card *card, struct snd_soc_component *component);
479ce6120ccSLiam Girdwood int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
480105f1c28SMark Brown 			    const struct snd_soc_dapm_route *route, int num);
481efcc3c61SMark Brown int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
482efcc3c61SMark Brown 			    const struct snd_soc_dapm_route *route, int num);
483bf3a9e13SMark Brown int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
484bf3a9e13SMark Brown 			     const struct snd_soc_dapm_route *route, int num);
485b97e2698SLars-Peter Clausen void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
486808db4a4SRichard Purdie 
487808db4a4SRichard Purdie /* dapm events */
488f3779b16SKuninori Morimoto void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, int event);
4893f4cf797SKuninori Morimoto void snd_soc_dapm_stream_stop(struct snd_soc_pcm_runtime *rtd, int stream);
490f0fba2adSLiam Girdwood void snd_soc_dapm_shutdown(struct snd_soc_card *card);
491808db4a4SRichard Purdie 
49240f02cd9SLiam Girdwood /* external DAPM widget events */
493ce6cfaf1SLars-Peter Clausen int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
494f3779b16SKuninori Morimoto 		struct snd_kcontrol *kcontrol, int connect, struct snd_soc_dapm_update *update);
495ce6cfaf1SLars-Peter Clausen int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
4966b3fc03bSLars-Peter Clausen 		struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e,
4976b3fc03bSLars-Peter Clausen 		struct snd_soc_dapm_update *update);
49840f02cd9SLiam Girdwood 
499808db4a4SRichard Purdie /* dapm sys fs - used by the core */
500d29697dcSTakashi Iwai extern struct attribute *soc_dapm_dev_attrs[];
501f3779b16SKuninori Morimoto void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, struct dentry *parent);
502808db4a4SRichard Purdie 
503a5302181SLiam Girdwood /* dapm audio pin control and status */
504f3779b16SKuninori Morimoto int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
505f3779b16SKuninori Morimoto int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
506f3779b16SKuninori Morimoto int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
507f3779b16SKuninori Morimoto int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
508ce6120ccSLiam Girdwood int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin);
509f3779b16SKuninori Morimoto int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
510f3779b16SKuninori Morimoto int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, const char *pin);
511ce6120ccSLiam Girdwood int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm);
5123eb29dfbSCharles Keepax int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm);
513f3779b16SKuninori Morimoto int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
514f3779b16SKuninori Morimoto int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
515f3779b16SKuninori Morimoto int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, const char *pin);
5165dc0158aSSubhransu S. Prusty unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol);
517808db4a4SRichard Purdie 
51825c77c5fSMark Brown /* Mostly internal - should not normally be used */
5198be4da29SLars-Peter Clausen void dapm_mark_endpoints_dirty(struct snd_soc_card *card);
52025c77c5fSMark Brown 
521ec2e3031SLiam Girdwood /* dapm path query */
522ec2e3031SLiam Girdwood int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
5236742064aSPiotr Stankiewicz 	struct snd_soc_dapm_widget_list **list,
524f3779b16SKuninori Morimoto 	bool (*custom_stop_condition)(struct snd_soc_dapm_widget *, enum snd_soc_dapm_direction));
52552645e33SKuninori Morimoto void snd_soc_dapm_dai_free_widgets(struct snd_soc_dapm_widget_list **list);
526ec2e3031SLiam Girdwood 
527f3779b16SKuninori Morimoto struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(struct snd_kcontrol *kcontrol);
528f3779b16SKuninori Morimoto struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget(struct snd_kcontrol *kcontrol);
529eee5d7f9SLars-Peter Clausen 
530f3779b16SKuninori Morimoto int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level);
531fa880775SLars-Peter Clausen 
532808db4a4SRichard Purdie /* dapm widget types */
533808db4a4SRichard Purdie enum snd_soc_dapm_type {
534808db4a4SRichard Purdie 	snd_soc_dapm_input = 0,		/* input pin */
535808db4a4SRichard Purdie 	snd_soc_dapm_output,		/* output pin */
536808db4a4SRichard Purdie 	snd_soc_dapm_mux,		/* selects 1 analog signal from many inputs */
537d714f97cSLars-Peter Clausen 	snd_soc_dapm_demux,		/* connects the input to one of multiple outputs */
538808db4a4SRichard Purdie 	snd_soc_dapm_mixer,		/* mixes several analog signals together */
539ca9c1aaeSIan Molton 	snd_soc_dapm_mixer_named_ctl,	/* mixer with named controls */
540808db4a4SRichard Purdie 	snd_soc_dapm_pga,		/* programmable gain/attenuation (volume) */
541d88429a6SOlaya, Margarita 	snd_soc_dapm_out_drv,		/* output driver */
542808db4a4SRichard Purdie 	snd_soc_dapm_adc,		/* analog to digital converter */
543808db4a4SRichard Purdie 	snd_soc_dapm_dac,		/* digital to analog converter */
54432902177SJohn Keeping 	snd_soc_dapm_micbias,		/* microphone bias (power) - DEPRECATED: use snd_soc_dapm_supply */
545808db4a4SRichard Purdie 	snd_soc_dapm_mic,		/* microphone */
546808db4a4SRichard Purdie 	snd_soc_dapm_hp,		/* headphones */
547808db4a4SRichard Purdie 	snd_soc_dapm_spk,		/* speaker */
548808db4a4SRichard Purdie 	snd_soc_dapm_line,		/* line input/output */
549808db4a4SRichard Purdie 	snd_soc_dapm_switch,		/* analog switch */
550808db4a4SRichard Purdie 	snd_soc_dapm_vmid,		/* codec bias/vmid - to minimise pops */
551808db4a4SRichard Purdie 	snd_soc_dapm_pre,		/* machine specific pre widget - exec first */
552808db4a4SRichard Purdie 	snd_soc_dapm_post,		/* machine specific post widget - exec last */
553246d0a17SMark Brown 	snd_soc_dapm_supply,		/* power/clock supply */
5545b2d15bbSSrinivas Kandagatla 	snd_soc_dapm_pinctrl,		/* pinctrl */
55562ea874aSMark Brown 	snd_soc_dapm_regulator_supply,	/* external regulator */
556d7e7eb91SOla Lilja 	snd_soc_dapm_clock_supply,	/* external clock */
557010ff262SMark Brown 	snd_soc_dapm_aif_in,		/* audio interface input */
558010ff262SMark Brown 	snd_soc_dapm_aif_out,		/* audio interface output */
5591ab97c8cSMark Brown 	snd_soc_dapm_siggen,		/* signal generator */
56056b4437fSVinod Koul 	snd_soc_dapm_sink,
5614616274dSMark Brown 	snd_soc_dapm_dai_in,		/* link to DAI structure */
5624616274dSMark Brown 	snd_soc_dapm_dai_out,
563c74184edSMark Brown 	snd_soc_dapm_dai_link,		/* link between two DAI structures */
56457295073SLars-Peter Clausen 	snd_soc_dapm_kcontrol,		/* Auto-disabled kcontrol */
5658a70b454SLiam Girdwood 	snd_soc_dapm_buffer,		/* DSP/CODEC internal buffer */
5668a70b454SLiam Girdwood 	snd_soc_dapm_scheduler,		/* DSP/CODEC internal scheduler */
5678a70b454SLiam Girdwood 	snd_soc_dapm_effect,		/* DSP/CODEC effect component */
5688a70b454SLiam Girdwood 	snd_soc_dapm_src,		/* DSP/CODEC SRC component */
5698a70b454SLiam Girdwood 	snd_soc_dapm_asrc,		/* DSP/CODEC ASRC component */
5708a70b454SLiam Girdwood 	snd_soc_dapm_encoder,		/* FW/SW audio encoder component */
5718a70b454SLiam Girdwood 	snd_soc_dapm_decoder,		/* FW/SW audio decoder component */
572f13d4b5fSPierre-Louis Bossart 
573f13d4b5fSPierre-Louis Bossart 	/* Don't edit below this line */
574f13d4b5fSPierre-Louis Bossart 	SND_SOC_DAPM_TYPE_COUNT
575808db4a4SRichard Purdie };
576808db4a4SRichard Purdie 
577105f1c28SMark Brown /*
578105f1c28SMark Brown  * DAPM audio route definition.
579105f1c28SMark Brown  *
580105f1c28SMark Brown  * Defines an audio route originating at source via control and finishing
581105f1c28SMark Brown  * at sink.
582105f1c28SMark Brown  */
583105f1c28SMark Brown struct snd_soc_dapm_route {
584105f1c28SMark Brown 	const char *sink;
585105f1c28SMark Brown 	const char *control;
586105f1c28SMark Brown 	const char *source;
587215edda3SMark Brown 
588215edda3SMark Brown 	/* Note: currently only supported for links where source is a supply */
589215edda3SMark Brown 	int (*connected)(struct snd_soc_dapm_widget *source,
590215edda3SMark Brown 			 struct snd_soc_dapm_widget *sink);
5915c30f43fSRanjani Sridharan 
5925c30f43fSRanjani Sridharan 	struct snd_soc_dobj dobj;
593105f1c28SMark Brown };
594105f1c28SMark Brown 
595808db4a4SRichard Purdie /* dapm audio path between two widgets */
596808db4a4SRichard Purdie struct snd_soc_dapm_path {
5973056557fSMark Brown 	const char *name;
598808db4a4SRichard Purdie 
599a3423b02SLars-Peter Clausen 	/*
600a3423b02SLars-Peter Clausen 	 * source (input) and sink (output) widgets
601a3423b02SLars-Peter Clausen 	 * The union is for convience, since it is a lot nicer to type
602a3423b02SLars-Peter Clausen 	 * p->source, rather than p->node[SND_SOC_DAPM_DIR_IN]
603a3423b02SLars-Peter Clausen 	 */
604a3423b02SLars-Peter Clausen 	union {
605a3423b02SLars-Peter Clausen 		struct {
606808db4a4SRichard Purdie 			struct snd_soc_dapm_widget *source;
607808db4a4SRichard Purdie 			struct snd_soc_dapm_widget *sink;
608a3423b02SLars-Peter Clausen 		};
609a3423b02SLars-Peter Clausen 		struct snd_soc_dapm_widget *node[2];
610a3423b02SLars-Peter Clausen 	};
611808db4a4SRichard Purdie 
612808db4a4SRichard Purdie 	/* status */
613808db4a4SRichard Purdie 	u32 connect:1;		/* source and sink widgets are connected */
6148af294b4SMark Brown 	u32 walking:1;		/* path is in the process of being walked */
615169d5a83SMark Brown 	u32 weak:1;		/* path ignored for power management */
616c1862c8bSLars-Peter Clausen 	u32 is_supply:1;	/* At least one of the connected widgets is a supply */
617808db4a4SRichard Purdie 
618215edda3SMark Brown 	int (*connected)(struct snd_soc_dapm_widget *source,
619215edda3SMark Brown 			 struct snd_soc_dapm_widget *sink);
620215edda3SMark Brown 
621a3423b02SLars-Peter Clausen 	struct list_head list_node[2];
6225106b92fSLars-Peter Clausen 	struct list_head list_kcontrol;
623808db4a4SRichard Purdie 	struct list_head list;
624808db4a4SRichard Purdie };
625808db4a4SRichard Purdie 
626808db4a4SRichard Purdie /* dapm widget */
627808db4a4SRichard Purdie struct snd_soc_dapm_widget {
628808db4a4SRichard Purdie 	enum snd_soc_dapm_type id;
6293056557fSMark Brown 	const char *name;			/* widget name */
6303056557fSMark Brown 	const char *sname;			/* stream name */
631808db4a4SRichard Purdie 	struct list_head list;
632ce6120ccSLiam Girdwood 	struct snd_soc_dapm_context *dapm;
633808db4a4SRichard Purdie 
63462ea874aSMark Brown 	void *priv;				/* widget specific data */
635a3cc056bSLiam Girdwood 	struct regulator *regulator;		/* attached regulator */
6365b2d15bbSSrinivas Kandagatla 	struct pinctrl *pinctrl;		/* attached pinctrl */
63762ea874aSMark Brown 
638808db4a4SRichard Purdie 	/* dapm control */
63941b5b3bdSMark Brown 	int reg;				/* negative reg = no direct dapm */
640808db4a4SRichard Purdie 	unsigned char shift;			/* bits to shift */
641e2be2ccfSJarkko Nikula 	unsigned int mask;			/* non-shifted mask */
642e2be2ccfSJarkko Nikula 	unsigned int on_val;			/* on state value */
643e2be2ccfSJarkko Nikula 	unsigned int off_val;			/* off state value */
644808db4a4SRichard Purdie 	unsigned char power:1;			/* block power status */
645808db4a4SRichard Purdie 	unsigned char active:1;			/* active stream on DAC, ADC's */
646808db4a4SRichard Purdie 	unsigned char connected:1;		/* connected codec pin */
647808db4a4SRichard Purdie 	unsigned char new:1;			/* cnew complete */
648da34183eSMark Brown 	unsigned char force:1;			/* force state */
6491547aba9SMark Brown 	unsigned char ignore_suspend:1;		/* kept enabled over suspend */
6509b8a83b2SMark Brown 	unsigned char new_power:1;		/* power from this run */
6519b8a83b2SMark Brown 	unsigned char power_checked:1;		/* power checked this run */
6526dd98b0aSLars-Peter Clausen 	unsigned char is_supply:1;		/* Widget is a supply type widget */
653a3423b02SLars-Peter Clausen 	unsigned char is_ep:2;			/* Widget is a endpoint type widget */
654f7f4a5adSJyri Sarha 	unsigned char no_wname_in_kcontrol_name:1; /* No widget name prefix in kcontrol name */
65520e4859dSMark Brown 	int subseq;				/* sort within widget type */
656808db4a4SRichard Purdie 
657b75576d7SMark Brown 	int (*power_check)(struct snd_soc_dapm_widget *w);
658b75576d7SMark Brown 
659808db4a4SRichard Purdie 	/* external events */
660808db4a4SRichard Purdie 	unsigned short event_flags;		/* flags to specify event types */
6619af6d956SLaim Girdwood 	int (*event)(struct snd_soc_dapm_widget*, struct snd_kcontrol *, int);
662808db4a4SRichard Purdie 
663808db4a4SRichard Purdie 	/* kcontrols that relate to this widget */
664808db4a4SRichard Purdie 	int num_kcontrols;
66582cfecdcSStephen Warren 	const struct snd_kcontrol_new *kcontrol_news;
666fad59888SStephen Warren 	struct snd_kcontrol **kcontrols;
6678a978234SLiam Girdwood 	struct snd_soc_dobj dobj;
668808db4a4SRichard Purdie 
669a3423b02SLars-Peter Clausen 	/* widget input and output edges */
670a3423b02SLars-Peter Clausen 	struct list_head edges[2];
6716d3ddc81SMark Brown 
6726d3ddc81SMark Brown 	/* used during DAPM updates */
67392a99ea4SLars-Peter Clausen 	struct list_head work_list;
6746d3ddc81SMark Brown 	struct list_head power_list;
675db432b41SMark Brown 	struct list_head dirty;
676a3423b02SLars-Peter Clausen 	int endpoints[2];
677d7e7eb91SOla Lilja 
678d7e7eb91SOla Lilja 	struct clk *clk;
679078a85f2SCharles Keepax 
680078a85f2SCharles Keepax 	int channel;
681808db4a4SRichard Purdie };
682808db4a4SRichard Purdie 
68397404f2eSMark Brown struct snd_soc_dapm_update {
68497404f2eSMark Brown 	struct snd_kcontrol *kcontrol;
68597404f2eSMark Brown 	int reg;
68697404f2eSMark Brown 	int mask;
68797404f2eSMark Brown 	int val;
688e411b0b5SChen-Yu Tsai 	int reg2;
689e411b0b5SChen-Yu Tsai 	int mask2;
690e411b0b5SChen-Yu Tsai 	int val2;
691e411b0b5SChen-Yu Tsai 	bool has_second_set;
69297404f2eSMark Brown };
69397404f2eSMark Brown 
694ce6120ccSLiam Girdwood /* DAPM context */
695ce6120ccSLiam Girdwood struct snd_soc_dapm_context {
696ce6120ccSLiam Girdwood 	enum snd_soc_bias_level bias_level;
697f3779b16SKuninori Morimoto 
698f3779b16SKuninori Morimoto 	/* bit field */
699ce6120ccSLiam Girdwood 	unsigned int idle_bias_off:1;		/* Use BIAS_OFF instead of STANDBY */
700f3779b16SKuninori Morimoto 	unsigned int suspend_bias_off:1;	/* Use BIAS_OFF in suspend if the DAPM is idle */
701474b62d6SMark Brown 
702ce6120ccSLiam Girdwood 	struct device *dev;			/* from parent - for debug */
703e2c330b9SLars-Peter Clausen 	struct snd_soc_component *component;	/* parent component */
7043a45b867SJarkko Nikula 	struct snd_soc_card *card;		/* parent card */
7057be31be8SJarkko Nikula 
7067be31be8SJarkko Nikula 	/* used during DAPM updates */
70756fba41fSMark Brown 	enum snd_soc_bias_level target_bias_level;
7087be31be8SJarkko Nikula 	struct list_head list;
7097be31be8SJarkko Nikula 
71086b94c39SKuninori Morimoto 	struct snd_soc_dapm_widget *wcache_sink;
71186b94c39SKuninori Morimoto 	struct snd_soc_dapm_widget *wcache_source;
71245a110a1SCharles Keepax 
713ce6120ccSLiam Girdwood #ifdef CONFIG_DEBUG_FS
714ce6120ccSLiam Girdwood 	struct dentry *debugfs_dapm;
715ce6120ccSLiam Girdwood #endif
716ce6120ccSLiam Girdwood };
717ce6120ccSLiam Girdwood 
718fafd2176SStephen Warren /* A list of widgets associated with an object, typically a snd_kcontrol */
719fafd2176SStephen Warren struct snd_soc_dapm_widget_list {
720fafd2176SStephen Warren 	int num_widgets;
7212d6201eeSGustavo A. R. Silva 	struct snd_soc_dapm_widget *widgets[];
722fafd2176SStephen Warren };
723fafd2176SStephen Warren 
72409e88f8aSKuninori Morimoto #define for_each_dapm_widgets(list, i, widget)				\
72509e88f8aSKuninori Morimoto 	for ((i) = 0;							\
72609e88f8aSKuninori Morimoto 	     (i) < list->num_widgets && (widget = list->widgets[i]);	\
72709e88f8aSKuninori Morimoto 	     (i)++)
72809e88f8aSKuninori Morimoto 
729de02d078SMark Brown struct snd_soc_dapm_stats {
730de02d078SMark Brown 	int power_checks;
731de02d078SMark Brown 	int path_checks;
732e56235e0SMark Brown 	int neighbour_checks;
733de02d078SMark Brown };
734de02d078SMark Brown 
7355b2d15bbSSrinivas Kandagatla struct snd_soc_dapm_pinctrl_priv {
7365b2d15bbSSrinivas Kandagatla 	const char *active_state;
7375b2d15bbSSrinivas Kandagatla 	const char *sleep_state;
7385b2d15bbSSrinivas Kandagatla };
7395b2d15bbSSrinivas Kandagatla 
740fa880775SLars-Peter Clausen /**
741fa880775SLars-Peter Clausen  * snd_soc_dapm_init_bias_level() - Initialize DAPM bias level
742fa880775SLars-Peter Clausen  * @dapm: The DAPM context to initialize
743fa880775SLars-Peter Clausen  * @level: The DAPM level to initialize to
744fa880775SLars-Peter Clausen  *
745fa880775SLars-Peter Clausen  * This function only sets the driver internal state of the DAPM level and will
746fa880775SLars-Peter Clausen  * not modify the state of the device. Hence it should not be used during normal
747fa880775SLars-Peter Clausen  * operation, but only to synchronize the internal state to the device state.
748fa880775SLars-Peter Clausen  * E.g. during driver probe to set the DAPM level to the one corresponding with
749fa880775SLars-Peter Clausen  * the power-on reset state of the device.
750fa880775SLars-Peter Clausen  *
751fa880775SLars-Peter Clausen  * To change the DAPM state of the device use snd_soc_dapm_set_bias_level().
752fa880775SLars-Peter Clausen  */
snd_soc_dapm_init_bias_level(struct snd_soc_dapm_context * dapm,enum snd_soc_bias_level level)753fa880775SLars-Peter Clausen static inline void snd_soc_dapm_init_bias_level(
754fa880775SLars-Peter Clausen 	struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
755fa880775SLars-Peter Clausen {
756fa880775SLars-Peter Clausen 	dapm->bias_level = level;
757fa880775SLars-Peter Clausen }
758fa880775SLars-Peter Clausen 
759fa880775SLars-Peter Clausen /**
760fa880775SLars-Peter Clausen  * snd_soc_dapm_get_bias_level() - Get current DAPM bias level
761fa880775SLars-Peter Clausen  * @dapm: The context for which to get the bias level
762fa880775SLars-Peter Clausen  *
763fa880775SLars-Peter Clausen  * Returns: The current bias level of the passed DAPM context.
764fa880775SLars-Peter Clausen  */
snd_soc_dapm_get_bias_level(struct snd_soc_dapm_context * dapm)765fa880775SLars-Peter Clausen static inline enum snd_soc_bias_level snd_soc_dapm_get_bias_level(
766fa880775SLars-Peter Clausen 	struct snd_soc_dapm_context *dapm)
767fa880775SLars-Peter Clausen {
768fa880775SLars-Peter Clausen 	return dapm->bias_level;
769fa880775SLars-Peter Clausen }
770fa880775SLars-Peter Clausen 
771a3423b02SLars-Peter Clausen enum snd_soc_dapm_direction {
772a3423b02SLars-Peter Clausen 	SND_SOC_DAPM_DIR_IN,
773a3423b02SLars-Peter Clausen 	SND_SOC_DAPM_DIR_OUT
774a3423b02SLars-Peter Clausen };
775a3423b02SLars-Peter Clausen 
776a3423b02SLars-Peter Clausen #define SND_SOC_DAPM_DIR_TO_EP(x) BIT(x)
777a3423b02SLars-Peter Clausen 
778a3423b02SLars-Peter Clausen #define SND_SOC_DAPM_EP_SOURCE	SND_SOC_DAPM_DIR_TO_EP(SND_SOC_DAPM_DIR_IN)
779a3423b02SLars-Peter Clausen #define SND_SOC_DAPM_EP_SINK	SND_SOC_DAPM_DIR_TO_EP(SND_SOC_DAPM_DIR_OUT)
780a3423b02SLars-Peter Clausen 
781a3423b02SLars-Peter Clausen /**
782c670a224SKuninori Morimoto  * snd_soc_dapm_widget_for_each_path - Iterates over all paths in the
783a3423b02SLars-Peter Clausen  *   specified direction of a widget
784a3423b02SLars-Peter Clausen  * @w: The widget
785a3423b02SLars-Peter Clausen  * @dir: Whether to iterate over the paths where the specified widget is the
786a3423b02SLars-Peter Clausen  *       incoming or outgoing widgets
787a3423b02SLars-Peter Clausen  * @p: The path iterator variable
788a3423b02SLars-Peter Clausen  */
789a3423b02SLars-Peter Clausen #define snd_soc_dapm_widget_for_each_path(w, dir, p) \
790a3423b02SLars-Peter Clausen 	list_for_each_entry(p, &w->edges[dir], list_node[dir])
791a3423b02SLars-Peter Clausen 
792a3423b02SLars-Peter Clausen /**
793c670a224SKuninori Morimoto  * snd_soc_dapm_widget_for_each_path_safe - Iterates over all paths in the
794a3423b02SLars-Peter Clausen  *   specified direction of a widget
795a3423b02SLars-Peter Clausen  * @w: The widget
796a3423b02SLars-Peter Clausen  * @dir: Whether to iterate over the paths where the specified widget is the
797a3423b02SLars-Peter Clausen  *       incoming or outgoing widgets
798a3423b02SLars-Peter Clausen  * @p: The path iterator variable
799a3423b02SLars-Peter Clausen  * @next_p: Temporary storage for the next path
800a3423b02SLars-Peter Clausen  *
801c670a224SKuninori Morimoto  *  This function works like snd_soc_dapm_widget_for_each_path, expect that
802a3423b02SLars-Peter Clausen  *  it is safe to remove the current path from the list while iterating
803a3423b02SLars-Peter Clausen  */
804a3423b02SLars-Peter Clausen #define snd_soc_dapm_widget_for_each_path_safe(w, dir, p, next_p) \
805a3423b02SLars-Peter Clausen 	list_for_each_entry_safe(p, next_p, &w->edges[dir], list_node[dir])
806a3423b02SLars-Peter Clausen 
807e63bfd45SLars-Peter Clausen /**
808e63bfd45SLars-Peter Clausen  * snd_soc_dapm_widget_for_each_sink_path - Iterates over all paths leaving a
809e63bfd45SLars-Peter Clausen  *  widget
810e63bfd45SLars-Peter Clausen  * @w: The widget
811e63bfd45SLars-Peter Clausen  * @p: The path iterator variable
812e63bfd45SLars-Peter Clausen  */
813e63bfd45SLars-Peter Clausen #define snd_soc_dapm_widget_for_each_sink_path(w, p) \
814a3423b02SLars-Peter Clausen 	snd_soc_dapm_widget_for_each_path(w, SND_SOC_DAPM_DIR_IN, p)
815e63bfd45SLars-Peter Clausen 
816e63bfd45SLars-Peter Clausen /**
817e63bfd45SLars-Peter Clausen  * snd_soc_dapm_widget_for_each_source_path - Iterates over all paths leading to
818e63bfd45SLars-Peter Clausen  *  a widget
819e63bfd45SLars-Peter Clausen  * @w: The widget
820e63bfd45SLars-Peter Clausen  * @p: The path iterator variable
821e63bfd45SLars-Peter Clausen  */
822e63bfd45SLars-Peter Clausen #define snd_soc_dapm_widget_for_each_source_path(w, p) \
823a3423b02SLars-Peter Clausen 	snd_soc_dapm_widget_for_each_path(w, SND_SOC_DAPM_DIR_OUT, p)
824e63bfd45SLars-Peter Clausen 
825808db4a4SRichard Purdie #endif
826