]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/soc/soc-dapm.c
ASoC: Simplify WM9081 speaker startup by using widgets for spaker output
[mirror_ubuntu-bionic-kernel.git] / sound / soc / soc-dapm.c
CommitLineData
2b97eabc
RP
1/*
2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management
3 *
4 * Copyright 2005 Wolfson Microelectronics PLC.
d331124d 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
2b97eabc
RP
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
2b97eabc
RP
12 * Features:
13 * o Changes power status of internal codec blocks depending on the
14 * dynamic configuration of codec internal audio paths and active
74b8f955 15 * DACs/ADCs.
2b97eabc
RP
16 * o Platform power domain - can support external components i.e. amps and
17 * mic/meadphone insertion events.
18 * o Automatic Mic Bias support
19 * o Jack insertion power event initiation - e.g. hp insertion will enable
20 * sinks, dacs, etc
3a4fa0a2 21 * o Delayed powerdown of audio susbsystem to reduce pops between a quick
2b97eabc
RP
22 * device reopen.
23 *
24 * Todo:
25 * o DAPM power change sequencing - allow for configurable per
26 * codec sequences.
27 * o Support for analogue bias optimisation.
28 * o Support for reduced codec oversampling rates.
29 * o Support for reduced codec bias currents.
30 */
31
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/init.h>
9d0624a7 35#include <linux/async.h>
2b97eabc
RP
36#include <linux/delay.h>
37#include <linux/pm.h>
38#include <linux/bitops.h>
39#include <linux/platform_device.h>
40#include <linux/jiffies.h>
20496ff3 41#include <linux/debugfs.h>
5a0e3ad6 42#include <linux/slab.h>
2b97eabc
RP
43#include <sound/core.h>
44#include <sound/pcm.h>
45#include <sound/pcm_params.h>
ce6120cc 46#include <sound/soc.h>
2b97eabc
RP
47#include <sound/initval.h>
48
84e90930
MB
49#include <trace/events/asoc.h>
50
2b97eabc
RP
51/* dapm power sequences - make this per codec in the future */
52static int dapm_up_seq[] = {
38357ab2
MB
53 [snd_soc_dapm_pre] = 0,
54 [snd_soc_dapm_supply] = 1,
55 [snd_soc_dapm_micbias] = 2,
010ff262
MB
56 [snd_soc_dapm_aif_in] = 3,
57 [snd_soc_dapm_aif_out] = 3,
58 [snd_soc_dapm_mic] = 4,
59 [snd_soc_dapm_mux] = 5,
24ff33ac 60 [snd_soc_dapm_virt_mux] = 5,
010ff262
MB
61 [snd_soc_dapm_value_mux] = 5,
62 [snd_soc_dapm_dac] = 6,
63 [snd_soc_dapm_mixer] = 7,
64 [snd_soc_dapm_mixer_named_ctl] = 7,
65 [snd_soc_dapm_pga] = 8,
66 [snd_soc_dapm_adc] = 9,
d88429a6 67 [snd_soc_dapm_out_drv] = 10,
010ff262
MB
68 [snd_soc_dapm_hp] = 10,
69 [snd_soc_dapm_spk] = 10,
70 [snd_soc_dapm_post] = 11,
2b97eabc 71};
ca9c1aae 72
2b97eabc 73static int dapm_down_seq[] = {
38357ab2
MB
74 [snd_soc_dapm_pre] = 0,
75 [snd_soc_dapm_adc] = 1,
76 [snd_soc_dapm_hp] = 2,
1ca04065 77 [snd_soc_dapm_spk] = 2,
d88429a6 78 [snd_soc_dapm_out_drv] = 2,
38357ab2
MB
79 [snd_soc_dapm_pga] = 4,
80 [snd_soc_dapm_mixer_named_ctl] = 5,
e3d4dabd
MB
81 [snd_soc_dapm_mixer] = 5,
82 [snd_soc_dapm_dac] = 6,
83 [snd_soc_dapm_mic] = 7,
84 [snd_soc_dapm_micbias] = 8,
85 [snd_soc_dapm_mux] = 9,
24ff33ac 86 [snd_soc_dapm_virt_mux] = 9,
e3d4dabd 87 [snd_soc_dapm_value_mux] = 9,
010ff262
MB
88 [snd_soc_dapm_aif_in] = 10,
89 [snd_soc_dapm_aif_out] = 10,
90 [snd_soc_dapm_supply] = 11,
91 [snd_soc_dapm_post] = 12,
2b97eabc
RP
92};
93
12ef193d 94static void pop_wait(u32 pop_time)
15e4c72f
MB
95{
96 if (pop_time)
97 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
98}
99
fd8d3bc0 100static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...)
15e4c72f
MB
101{
102 va_list args;
fd8d3bc0 103 char *buf;
15e4c72f 104
fd8d3bc0
JN
105 if (!pop_time)
106 return;
15e4c72f 107
fd8d3bc0
JN
108 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
109 if (buf == NULL)
110 return;
15e4c72f 111
fd8d3bc0
JN
112 va_start(args, fmt);
113 vsnprintf(buf, PAGE_SIZE, fmt, args);
9d01df06 114 dev_info(dev, "%s", buf);
15e4c72f 115 va_end(args);
fd8d3bc0
JN
116
117 kfree(buf);
15e4c72f
MB
118}
119
2b97eabc 120/* create a new dapm widget */
88cb4290 121static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
2b97eabc
RP
122 const struct snd_soc_dapm_widget *_widget)
123{
88cb4290 124 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
2b97eabc
RP
125}
126
452c5eaa
MB
127/**
128 * snd_soc_dapm_set_bias_level - set the bias level for the system
ed5a4c47 129 * @dapm: DAPM context
452c5eaa
MB
130 * @level: level to configure
131 *
132 * Configure the bias (power) levels for the SoC audio device.
133 *
134 * Returns 0 for success else error.
135 */
ed5a4c47 136static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
ce6120cc 137 enum snd_soc_bias_level level)
452c5eaa 138{
ed5a4c47 139 struct snd_soc_card *card = dapm->card;
452c5eaa
MB
140 int ret = 0;
141
f83fba8b
MB
142 switch (level) {
143 case SND_SOC_BIAS_ON:
ce6120cc 144 dev_dbg(dapm->dev, "Setting full bias\n");
f83fba8b
MB
145 break;
146 case SND_SOC_BIAS_PREPARE:
ce6120cc 147 dev_dbg(dapm->dev, "Setting bias prepare\n");
f83fba8b
MB
148 break;
149 case SND_SOC_BIAS_STANDBY:
ce6120cc 150 dev_dbg(dapm->dev, "Setting standby bias\n");
f83fba8b
MB
151 break;
152 case SND_SOC_BIAS_OFF:
ce6120cc 153 dev_dbg(dapm->dev, "Setting bias off\n");
f83fba8b
MB
154 break;
155 default:
ce6120cc 156 dev_err(dapm->dev, "Setting invalid bias %d\n", level);
f83fba8b
MB
157 return -EINVAL;
158 }
159
84e90930
MB
160 trace_snd_soc_bias_level_start(card, level);
161
f0fba2ad 162 if (card && card->set_bias_level)
452c5eaa 163 ret = card->set_bias_level(card, level);
474e09ca 164 if (ret == 0) {
ce6120cc
LG
165 if (dapm->codec && dapm->codec->driver->set_bias_level)
166 ret = dapm->codec->driver->set_bias_level(dapm->codec, level);
474e09ca 167 else
ce6120cc 168 dapm->bias_level = level;
474e09ca 169 }
1badabd9
MB
170 if (ret == 0) {
171 if (card && card->set_bias_level_post)
172 ret = card->set_bias_level_post(card, level);
173 }
452c5eaa 174
84e90930
MB
175 trace_snd_soc_bias_level_done(card, level);
176
452c5eaa
MB
177 return ret;
178}
179
2b97eabc
RP
180/* set up initial codec paths */
181static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
182 struct snd_soc_dapm_path *p, int i)
183{
184 switch (w->id) {
185 case snd_soc_dapm_switch:
ca9c1aae
IM
186 case snd_soc_dapm_mixer:
187 case snd_soc_dapm_mixer_named_ctl: {
2b97eabc 188 int val;
4eaa9819
JS
189 struct soc_mixer_control *mc = (struct soc_mixer_control *)
190 w->kcontrols[i].private_value;
815ecf8d
JS
191 unsigned int reg = mc->reg;
192 unsigned int shift = mc->shift;
4eaa9819 193 int max = mc->max;
815ecf8d
JS
194 unsigned int mask = (1 << fls(max)) - 1;
195 unsigned int invert = mc->invert;
2b97eabc
RP
196
197 val = snd_soc_read(w->codec, reg);
198 val = (val >> shift) & mask;
199
200 if ((invert && !val) || (!invert && val))
201 p->connect = 1;
202 else
203 p->connect = 0;
204 }
205 break;
206 case snd_soc_dapm_mux: {
207 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value;
208 int val, item, bitmask;
209
f8ba0b7b 210 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
2b97eabc
RP
211 ;
212 val = snd_soc_read(w->codec, e->reg);
213 item = (val >> e->shift_l) & (bitmask - 1);
214
215 p->connect = 0;
f8ba0b7b 216 for (i = 0; i < e->max; i++) {
2b97eabc
RP
217 if (!(strcmp(p->name, e->texts[i])) && item == i)
218 p->connect = 1;
219 }
220 }
221 break;
24ff33ac
DP
222 case snd_soc_dapm_virt_mux: {
223 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value;
224
225 p->connect = 0;
226 /* since a virtual mux has no backing registers to
227 * decide which path to connect, it will try to match
228 * with the first enumeration. This is to ensure
229 * that the default mux choice (the first) will be
230 * correctly powered up during initialization.
231 */
232 if (!strcmp(p->name, e->texts[0]))
233 p->connect = 1;
234 }
235 break;
2e72f8e3 236 case snd_soc_dapm_value_mux: {
74155556 237 struct soc_enum *e = (struct soc_enum *)
2e72f8e3
PU
238 w->kcontrols[i].private_value;
239 int val, item;
240
241 val = snd_soc_read(w->codec, e->reg);
242 val = (val >> e->shift_l) & e->mask;
243 for (item = 0; item < e->max; item++) {
244 if (val == e->values[item])
245 break;
246 }
247
248 p->connect = 0;
249 for (i = 0; i < e->max; i++) {
250 if (!(strcmp(p->name, e->texts[i])) && item == i)
251 p->connect = 1;
252 }
253 }
254 break;
2b97eabc
RP
255 /* does not effect routing - always connected */
256 case snd_soc_dapm_pga:
d88429a6 257 case snd_soc_dapm_out_drv:
2b97eabc
RP
258 case snd_soc_dapm_output:
259 case snd_soc_dapm_adc:
260 case snd_soc_dapm_input:
261 case snd_soc_dapm_dac:
262 case snd_soc_dapm_micbias:
263 case snd_soc_dapm_vmid:
246d0a17 264 case snd_soc_dapm_supply:
010ff262
MB
265 case snd_soc_dapm_aif_in:
266 case snd_soc_dapm_aif_out:
2b97eabc
RP
267 p->connect = 1;
268 break;
269 /* does effect routing - dynamically connected */
270 case snd_soc_dapm_hp:
271 case snd_soc_dapm_mic:
272 case snd_soc_dapm_spk:
273 case snd_soc_dapm_line:
274 case snd_soc_dapm_pre:
275 case snd_soc_dapm_post:
276 p->connect = 0;
277 break;
278 }
279}
280
74b8f955 281/* connect mux widget to its interconnecting audio paths */
ce6120cc 282static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
2b97eabc
RP
283 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
284 struct snd_soc_dapm_path *path, const char *control_name,
285 const struct snd_kcontrol_new *kcontrol)
286{
287 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
288 int i;
289
f8ba0b7b 290 for (i = 0; i < e->max; i++) {
2b97eabc 291 if (!(strcmp(control_name, e->texts[i]))) {
8ddab3f5 292 list_add(&path->list, &dapm->card->paths);
2b97eabc
RP
293 list_add(&path->list_sink, &dest->sources);
294 list_add(&path->list_source, &src->sinks);
295 path->name = (char*)e->texts[i];
296 dapm_set_path_status(dest, path, 0);
297 return 0;
298 }
299 }
300
301 return -ENODEV;
302}
303
74b8f955 304/* connect mixer widget to its interconnecting audio paths */
ce6120cc 305static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
2b97eabc
RP
306 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
307 struct snd_soc_dapm_path *path, const char *control_name)
308{
309 int i;
310
311 /* search for mixer kcontrol */
312 for (i = 0; i < dest->num_kcontrols; i++) {
313 if (!strcmp(control_name, dest->kcontrols[i].name)) {
8ddab3f5 314 list_add(&path->list, &dapm->card->paths);
2b97eabc
RP
315 list_add(&path->list_sink, &dest->sources);
316 list_add(&path->list_source, &src->sinks);
317 path->name = dest->kcontrols[i].name;
318 dapm_set_path_status(dest, path, i);
319 return 0;
320 }
321 }
322 return -ENODEV;
323}
324
325/* update dapm codec register bits */
326static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
327{
328 int change, power;
46f5822f 329 unsigned int old, new;
2b97eabc 330 struct snd_soc_codec *codec = widget->codec;
ce6120cc 331 struct snd_soc_dapm_context *dapm = widget->dapm;
3a45b867 332 struct snd_soc_card *card = dapm->card;
2b97eabc
RP
333
334 /* check for valid widgets */
335 if (widget->reg < 0 || widget->id == snd_soc_dapm_input ||
336 widget->id == snd_soc_dapm_output ||
337 widget->id == snd_soc_dapm_hp ||
338 widget->id == snd_soc_dapm_mic ||
339 widget->id == snd_soc_dapm_line ||
340 widget->id == snd_soc_dapm_spk)
341 return 0;
342
343 power = widget->power;
344 if (widget->invert)
345 power = (power ? 0:1);
346
347 old = snd_soc_read(codec, widget->reg);
348 new = (old & ~(0x1 << widget->shift)) | (power << widget->shift);
349
350 change = old != new;
351 if (change) {
fd8d3bc0
JN
352 pop_dbg(dapm->dev, card->pop_time,
353 "pop test %s : %s in %d ms\n",
12ef193d 354 widget->name, widget->power ? "on" : "off",
3a45b867
JN
355 card->pop_time);
356 pop_wait(card->pop_time);
69224719 357 snd_soc_write(codec, widget->reg, new);
2b97eabc 358 }
f7d41ae8
JN
359 dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg,
360 old, new, change);
2b97eabc
RP
361 return change;
362}
363
2b97eabc 364/* create new dapm mixer control */
ce6120cc 365static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
2b97eabc
RP
366 struct snd_soc_dapm_widget *w)
367{
368 int i, ret = 0;
219b93f5 369 size_t name_len;
2b97eabc 370 struct snd_soc_dapm_path *path;
12ea2c78 371 struct snd_card *card = dapm->card->snd_card;
efb7ac3f
MB
372 const char *prefix;
373
374 if (dapm->codec)
375 prefix = dapm->codec->name_prefix;
376 else
377 prefix = NULL;
2b97eabc
RP
378
379 /* add kcontrol */
380 for (i = 0; i < w->num_kcontrols; i++) {
381
382 /* match name */
383 list_for_each_entry(path, &w->sources, list_sink) {
384
385 /* mixer/mux paths name must match control name */
386 if (path->name != (char*)w->kcontrols[i].name)
387 continue;
388
ca9c1aae
IM
389 /* add dapm control with long name.
390 * for dapm_mixer this is the concatenation of the
391 * mixer and kcontrol name.
392 * for dapm_mixer_named_ctl this is simply the
393 * kcontrol name.
394 */
395 name_len = strlen(w->kcontrols[i].name) + 1;
07495f3e 396 if (w->id != snd_soc_dapm_mixer_named_ctl)
ca9c1aae
IM
397 name_len += 1 + strlen(w->name);
398
219b93f5 399 path->long_name = kmalloc(name_len, GFP_KERNEL);
ca9c1aae 400
2b97eabc
RP
401 if (path->long_name == NULL)
402 return -ENOMEM;
403
ca9c1aae 404 switch (w->id) {
ca9c1aae
IM
405 default:
406 snprintf(path->long_name, name_len, "%s %s",
407 w->name, w->kcontrols[i].name);
07495f3e 408 break;
ca9c1aae
IM
409 case snd_soc_dapm_mixer_named_ctl:
410 snprintf(path->long_name, name_len, "%s",
411 w->kcontrols[i].name);
07495f3e 412 break;
ca9c1aae
IM
413 }
414
219b93f5
MB
415 path->long_name[name_len - 1] = '\0';
416
2b97eabc 417 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
efb7ac3f 418 path->long_name, prefix);
ce6120cc 419 ret = snd_ctl_add(card, path->kcontrol);
2b97eabc 420 if (ret < 0) {
f7d41ae8
JN
421 dev_err(dapm->dev,
422 "asoc: failed to add dapm kcontrol %s: %d\n",
423 path->long_name, ret);
2b97eabc
RP
424 kfree(path->long_name);
425 path->long_name = NULL;
426 return ret;
427 }
428 }
429 }
430 return ret;
431}
432
433/* create new dapm mux control */
ce6120cc 434static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
2b97eabc
RP
435 struct snd_soc_dapm_widget *w)
436{
437 struct snd_soc_dapm_path *path = NULL;
438 struct snd_kcontrol *kcontrol;
12ea2c78 439 struct snd_card *card = dapm->card->snd_card;
efb7ac3f 440 const char *prefix;
2b97eabc
RP
441 int ret = 0;
442
443 if (!w->num_kcontrols) {
f7d41ae8 444 dev_err(dapm->dev, "asoc: mux %s has no controls\n", w->name);
2b97eabc
RP
445 return -EINVAL;
446 }
447
efb7ac3f
MB
448 if (dapm->codec)
449 prefix = dapm->codec->name_prefix;
450 else
451 prefix = NULL;
452
453 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name, prefix);
ce6120cc
LG
454 ret = snd_ctl_add(card, kcontrol);
455
2b97eabc
RP
456 if (ret < 0)
457 goto err;
458
459 list_for_each_entry(path, &w->sources, list_sink)
460 path->kcontrol = kcontrol;
461
462 return ret;
463
464err:
f7d41ae8 465 dev_err(dapm->dev, "asoc: failed to add kcontrol %s\n", w->name);
2b97eabc
RP
466 return ret;
467}
468
469/* create new dapm volume control */
ce6120cc 470static int dapm_new_pga(struct snd_soc_dapm_context *dapm,
2b97eabc
RP
471 struct snd_soc_dapm_widget *w)
472{
a6c65736 473 if (w->num_kcontrols)
f7d41ae8
JN
474 dev_err(w->dapm->dev,
475 "asoc: PGA controls not supported: '%s'\n", w->name);
2b97eabc 476
a6c65736 477 return 0;
2b97eabc
RP
478}
479
480/* reset 'walked' bit for each dapm path */
ce6120cc 481static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm)
2b97eabc
RP
482{
483 struct snd_soc_dapm_path *p;
484
8ddab3f5 485 list_for_each_entry(p, &dapm->card->paths, list)
2b97eabc
RP
486 p->walked = 0;
487}
488
9949788b
MB
489/* We implement power down on suspend by checking the power state of
490 * the ALSA card - when we are suspending the ALSA state for the card
491 * is set to D3.
492 */
493static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
494{
12ea2c78 495 int level = snd_power_get_state(widget->dapm->card->snd_card);
9949788b 496
f0fba2ad 497 switch (level) {
9949788b
MB
498 case SNDRV_CTL_POWER_D3hot:
499 case SNDRV_CTL_POWER_D3cold:
1547aba9 500 if (widget->ignore_suspend)
f7d41ae8
JN
501 dev_dbg(widget->dapm->dev, "%s ignoring suspend\n",
502 widget->name);
1547aba9 503 return widget->ignore_suspend;
9949788b
MB
504 default:
505 return 1;
506 }
507}
508
2b97eabc
RP
509/*
510 * Recursively check for a completed path to an active or physically connected
511 * output widget. Returns number of complete paths.
512 */
513static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
514{
515 struct snd_soc_dapm_path *path;
516 int con = 0;
517
246d0a17
MB
518 if (widget->id == snd_soc_dapm_supply)
519 return 0;
520
010ff262
MB
521 switch (widget->id) {
522 case snd_soc_dapm_adc:
523 case snd_soc_dapm_aif_out:
524 if (widget->active)
9949788b 525 return snd_soc_dapm_suspend_check(widget);
010ff262
MB
526 default:
527 break;
528 }
2b97eabc
RP
529
530 if (widget->connected) {
531 /* connected pin ? */
532 if (widget->id == snd_soc_dapm_output && !widget->ext)
9949788b 533 return snd_soc_dapm_suspend_check(widget);
2b97eabc
RP
534
535 /* connected jack or spk ? */
536 if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk ||
eaeae5d9 537 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources)))
9949788b 538 return snd_soc_dapm_suspend_check(widget);
2b97eabc
RP
539 }
540
541 list_for_each_entry(path, &widget->sinks, list_source) {
542 if (path->walked)
543 continue;
544
545 if (path->sink && path->connect) {
546 path->walked = 1;
547 con += is_connected_output_ep(path->sink);
548 }
549 }
550
551 return con;
552}
553
554/*
555 * Recursively check for a completed path to an active or physically connected
556 * input widget. Returns number of complete paths.
557 */
558static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
559{
560 struct snd_soc_dapm_path *path;
561 int con = 0;
562
246d0a17
MB
563 if (widget->id == snd_soc_dapm_supply)
564 return 0;
565
2b97eabc 566 /* active stream ? */
010ff262
MB
567 switch (widget->id) {
568 case snd_soc_dapm_dac:
569 case snd_soc_dapm_aif_in:
570 if (widget->active)
9949788b 571 return snd_soc_dapm_suspend_check(widget);
010ff262
MB
572 default:
573 break;
574 }
2b97eabc
RP
575
576 if (widget->connected) {
577 /* connected pin ? */
578 if (widget->id == snd_soc_dapm_input && !widget->ext)
9949788b 579 return snd_soc_dapm_suspend_check(widget);
2b97eabc
RP
580
581 /* connected VMID/Bias for lower pops */
582 if (widget->id == snd_soc_dapm_vmid)
9949788b 583 return snd_soc_dapm_suspend_check(widget);
2b97eabc
RP
584
585 /* connected jack ? */
eaeae5d9
PU
586 if (widget->id == snd_soc_dapm_mic ||
587 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks)))
9949788b 588 return snd_soc_dapm_suspend_check(widget);
2b97eabc
RP
589 }
590
591 list_for_each_entry(path, &widget->sources, list_sink) {
592 if (path->walked)
593 continue;
594
595 if (path->source && path->connect) {
596 path->walked = 1;
597 con += is_connected_input_ep(path->source);
598 }
599 }
600
601 return con;
602}
603
e2be2ccf
JN
604/*
605 * Handler for generic register modifier widget.
606 */
607int dapm_reg_event(struct snd_soc_dapm_widget *w,
608 struct snd_kcontrol *kcontrol, int event)
609{
610 unsigned int val;
611
612 if (SND_SOC_DAPM_EVENT_ON(event))
613 val = w->on_val;
614 else
615 val = w->off_val;
616
617 snd_soc_update_bits(w->codec, -(w->reg + 1),
618 w->mask << w->shift, val << w->shift);
619
620 return 0;
621}
11589418 622EXPORT_SYMBOL_GPL(dapm_reg_event);
e2be2ccf 623
025756ec
MB
624/* Standard power change method, used to apply power changes to most
625 * widgets.
626 */
627static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
628{
629 int ret;
630
631 /* call any power change event handlers */
632 if (w->event)
f7d41ae8 633 dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n",
025756ec
MB
634 w->power ? "on" : "off",
635 w->name, w->event_flags);
636
637 /* power up pre event */
638 if (w->power && w->event &&
639 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
640 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
641 if (ret < 0)
642 return ret;
643 }
644
645 /* power down pre event */
646 if (!w->power && w->event &&
647 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
648 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
649 if (ret < 0)
650 return ret;
651 }
652
025756ec
MB
653 dapm_update_bits(w);
654
025756ec
MB
655 /* power up post event */
656 if (w->power && w->event &&
657 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
658 ret = w->event(w,
659 NULL, SND_SOC_DAPM_POST_PMU);
660 if (ret < 0)
661 return ret;
662 }
663
664 /* power down post event */
665 if (!w->power && w->event &&
666 (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
667 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
668 if (ret < 0)
669 return ret;
670 }
671
672 return 0;
673}
674
cd0f2d47
MB
675/* Generic check to see if a widget should be powered.
676 */
677static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
678{
679 int in, out;
680
681 in = is_connected_input_ep(w);
ce6120cc 682 dapm_clear_walk(w->dapm);
cd0f2d47 683 out = is_connected_output_ep(w);
ce6120cc 684 dapm_clear_walk(w->dapm);
cd0f2d47
MB
685 return out != 0 && in != 0;
686}
687
6ea31b9f
MB
688/* Check to see if an ADC has power */
689static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
690{
691 int in;
692
693 if (w->active) {
694 in = is_connected_input_ep(w);
ce6120cc 695 dapm_clear_walk(w->dapm);
6ea31b9f
MB
696 return in != 0;
697 } else {
698 return dapm_generic_check_power(w);
699 }
700}
701
702/* Check to see if a DAC has power */
703static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
704{
705 int out;
706
707 if (w->active) {
708 out = is_connected_output_ep(w);
ce6120cc 709 dapm_clear_walk(w->dapm);
6ea31b9f
MB
710 return out != 0;
711 } else {
712 return dapm_generic_check_power(w);
713 }
714}
715
246d0a17
MB
716/* Check to see if a power supply is needed */
717static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
718{
719 struct snd_soc_dapm_path *path;
720 int power = 0;
721
722 /* Check if one of our outputs is connected */
723 list_for_each_entry(path, &w->sinks, list_source) {
215edda3
MB
724 if (path->connected &&
725 !path->connected(path->source, path->sink))
726 continue;
727
3017358a
MB
728 if (!path->sink)
729 continue;
730
731 if (path->sink->force) {
732 power = 1;
733 break;
734 }
735
736 if (path->sink->power_check &&
246d0a17
MB
737 path->sink->power_check(path->sink)) {
738 power = 1;
739 break;
740 }
741 }
742
ce6120cc 743 dapm_clear_walk(w->dapm);
246d0a17
MB
744
745 return power;
746}
747
38357ab2
MB
748static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
749 struct snd_soc_dapm_widget *b,
828a842f 750 bool power_up)
42aa3418 751{
828a842f
MB
752 int *sort;
753
754 if (power_up)
755 sort = dapm_up_seq;
756 else
757 sort = dapm_down_seq;
758
38357ab2
MB
759 if (sort[a->id] != sort[b->id])
760 return sort[a->id] - sort[b->id];
20e4859d
MB
761 if (a->subseq != b->subseq) {
762 if (power_up)
763 return a->subseq - b->subseq;
764 else
765 return b->subseq - a->subseq;
766 }
b22ead2a
MB
767 if (a->reg != b->reg)
768 return a->reg - b->reg;
84dab567
MB
769 if (a->dapm != b->dapm)
770 return (unsigned long)a->dapm - (unsigned long)b->dapm;
42aa3418 771
38357ab2
MB
772 return 0;
773}
42aa3418 774
38357ab2
MB
775/* Insert a widget in order into a DAPM power sequence. */
776static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
777 struct list_head *list,
828a842f 778 bool power_up)
38357ab2
MB
779{
780 struct snd_soc_dapm_widget *w;
781
782 list_for_each_entry(w, list, power_list)
828a842f 783 if (dapm_seq_compare(new_widget, w, power_up) < 0) {
38357ab2
MB
784 list_add_tail(&new_widget->power_list, &w->power_list);
785 return;
786 }
787
788 list_add_tail(&new_widget->power_list, list);
789}
790
68f89ad8
MB
791static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm,
792 struct snd_soc_dapm_widget *w, int event)
793{
794 struct snd_soc_card *card = dapm->card;
795 const char *ev_name;
796 int power, ret;
797
798 switch (event) {
799 case SND_SOC_DAPM_PRE_PMU:
800 ev_name = "PRE_PMU";
801 power = 1;
802 break;
803 case SND_SOC_DAPM_POST_PMU:
804 ev_name = "POST_PMU";
805 power = 1;
806 break;
807 case SND_SOC_DAPM_PRE_PMD:
808 ev_name = "PRE_PMD";
809 power = 0;
810 break;
811 case SND_SOC_DAPM_POST_PMD:
812 ev_name = "POST_PMD";
813 power = 0;
814 break;
815 default:
816 BUG();
817 return;
818 }
819
820 if (w->power != power)
821 return;
822
823 if (w->event && (w->event_flags & event)) {
824 pop_dbg(dapm->dev, card->pop_time, "pop test : %s %s\n",
825 w->name, ev_name);
84e90930 826 trace_snd_soc_dapm_widget_event_start(w, event);
68f89ad8 827 ret = w->event(w, NULL, event);
84e90930 828 trace_snd_soc_dapm_widget_event_done(w, event);
68f89ad8
MB
829 if (ret < 0)
830 pr_err("%s: %s event failed: %d\n",
831 ev_name, w->name, ret);
832 }
833}
834
b22ead2a 835/* Apply the coalesced changes from a DAPM sequence */
ce6120cc 836static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
b22ead2a 837 struct list_head *pending)
163cac06 838{
3a45b867 839 struct snd_soc_card *card = dapm->card;
68f89ad8
MB
840 struct snd_soc_dapm_widget *w;
841 int reg, power;
b22ead2a
MB
842 unsigned int value = 0;
843 unsigned int mask = 0;
844 unsigned int cur_mask;
845
846 reg = list_first_entry(pending, struct snd_soc_dapm_widget,
847 power_list)->reg;
848
849 list_for_each_entry(w, pending, power_list) {
850 cur_mask = 1 << w->shift;
851 BUG_ON(reg != w->reg);
852
853 if (w->invert)
854 power = !w->power;
855 else
856 power = w->power;
857
858 mask |= cur_mask;
859 if (power)
860 value |= cur_mask;
861
fd8d3bc0 862 pop_dbg(dapm->dev, card->pop_time,
b22ead2a
MB
863 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
864 w->name, reg, value, mask);
81628103 865
68f89ad8
MB
866 /* Check for events */
867 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMU);
868 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMD);
81628103
MB
869 }
870
871 if (reg >= 0) {
fd8d3bc0 872 pop_dbg(dapm->dev, card->pop_time,
81628103 873 "pop test : Applying 0x%x/0x%x to %x in %dms\n",
3a45b867
JN
874 value, mask, reg, card->pop_time);
875 pop_wait(card->pop_time);
ce6120cc 876 snd_soc_update_bits(dapm->codec, reg, mask, value);
b22ead2a
MB
877 }
878
81628103 879 list_for_each_entry(w, pending, power_list) {
68f89ad8
MB
880 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMU);
881 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMD);
81628103 882 }
b22ead2a 883}
42aa3418 884
b22ead2a
MB
885/* Apply a DAPM power sequence.
886 *
887 * We walk over a pre-sorted list of widgets to apply power to. In
888 * order to minimise the number of writes to the device required
889 * multiple widgets will be updated in a single write where possible.
890 * Currently anything that requires more than a single write is not
891 * handled.
892 */
ce6120cc 893static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
828a842f 894 struct list_head *list, int event, bool power_up)
b22ead2a
MB
895{
896 struct snd_soc_dapm_widget *w, *n;
897 LIST_HEAD(pending);
898 int cur_sort = -1;
20e4859d 899 int cur_subseq = -1;
b22ead2a 900 int cur_reg = SND_SOC_NOPM;
7be31be8 901 struct snd_soc_dapm_context *cur_dapm = NULL;
474b62d6 902 int ret, i;
828a842f
MB
903 int *sort;
904
905 if (power_up)
906 sort = dapm_up_seq;
907 else
908 sort = dapm_down_seq;
163cac06 909
b22ead2a
MB
910 list_for_each_entry_safe(w, n, list, power_list) {
911 ret = 0;
912
913 /* Do we need to apply any queued changes? */
7be31be8 914 if (sort[w->id] != cur_sort || w->reg != cur_reg ||
20e4859d 915 w->dapm != cur_dapm || w->subseq != cur_subseq) {
b22ead2a 916 if (!list_empty(&pending))
7be31be8 917 dapm_seq_run_coalesced(cur_dapm, &pending);
b22ead2a 918
474b62d6
MB
919 if (cur_dapm && cur_dapm->seq_notifier) {
920 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
921 if (sort[i] == cur_sort)
922 cur_dapm->seq_notifier(cur_dapm,
f85a9e0d
MB
923 i,
924 cur_subseq);
474b62d6
MB
925 }
926
b22ead2a
MB
927 INIT_LIST_HEAD(&pending);
928 cur_sort = -1;
20e4859d 929 cur_subseq = -1;
b22ead2a 930 cur_reg = SND_SOC_NOPM;
7be31be8 931 cur_dapm = NULL;
b22ead2a
MB
932 }
933
163cac06
MB
934 switch (w->id) {
935 case snd_soc_dapm_pre:
936 if (!w->event)
b22ead2a
MB
937 list_for_each_entry_safe_continue(w, n, list,
938 power_list);
163cac06 939
b22ead2a 940 if (event == SND_SOC_DAPM_STREAM_START)
163cac06
MB
941 ret = w->event(w,
942 NULL, SND_SOC_DAPM_PRE_PMU);
b22ead2a 943 else if (event == SND_SOC_DAPM_STREAM_STOP)
163cac06
MB
944 ret = w->event(w,
945 NULL, SND_SOC_DAPM_PRE_PMD);
163cac06
MB
946 break;
947
948 case snd_soc_dapm_post:
949 if (!w->event)
b22ead2a
MB
950 list_for_each_entry_safe_continue(w, n, list,
951 power_list);
163cac06 952
b22ead2a 953 if (event == SND_SOC_DAPM_STREAM_START)
163cac06
MB
954 ret = w->event(w,
955 NULL, SND_SOC_DAPM_POST_PMU);
b22ead2a 956 else if (event == SND_SOC_DAPM_STREAM_STOP)
163cac06
MB
957 ret = w->event(w,
958 NULL, SND_SOC_DAPM_POST_PMD);
163cac06
MB
959 break;
960
b22ead2a
MB
961 case snd_soc_dapm_input:
962 case snd_soc_dapm_output:
963 case snd_soc_dapm_hp:
964 case snd_soc_dapm_mic:
965 case snd_soc_dapm_line:
966 case snd_soc_dapm_spk:
967 /* No register support currently */
163cac06 968 ret = dapm_generic_apply_power(w);
163cac06 969 break;
b22ead2a
MB
970
971 default:
81628103
MB
972 /* Queue it up for application */
973 cur_sort = sort[w->id];
20e4859d 974 cur_subseq = w->subseq;
81628103 975 cur_reg = w->reg;
7be31be8 976 cur_dapm = w->dapm;
81628103
MB
977 list_move(&w->power_list, &pending);
978 break;
163cac06 979 }
b22ead2a
MB
980
981 if (ret < 0)
f7d41ae8
JN
982 dev_err(w->dapm->dev,
983 "Failed to apply widget power: %d\n", ret);
6ea31b9f 984 }
b22ead2a
MB
985
986 if (!list_empty(&pending))
ce6120cc 987 dapm_seq_run_coalesced(dapm, &pending);
474b62d6
MB
988
989 if (cur_dapm && cur_dapm->seq_notifier) {
990 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
991 if (sort[i] == cur_sort)
992 cur_dapm->seq_notifier(cur_dapm,
f85a9e0d 993 i, cur_subseq);
474b62d6 994 }
42aa3418
MB
995}
996
97404f2e
MB
997static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
998{
999 struct snd_soc_dapm_update *update = dapm->update;
1000 struct snd_soc_dapm_widget *w;
1001 int ret;
1002
1003 if (!update)
1004 return;
1005
1006 w = update->widget;
1007
1008 if (w->event &&
1009 (w->event_flags & SND_SOC_DAPM_PRE_REG)) {
1010 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG);
1011 if (ret != 0)
1012 pr_err("%s DAPM pre-event failed: %d\n",
1013 w->name, ret);
1014 }
1015
1016 ret = snd_soc_update_bits(w->codec, update->reg, update->mask,
1017 update->val);
1018 if (ret < 0)
1019 pr_err("%s DAPM update failed: %d\n", w->name, ret);
1020
1021 if (w->event &&
1022 (w->event_flags & SND_SOC_DAPM_POST_REG)) {
1023 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
1024 if (ret != 0)
1025 pr_err("%s DAPM post-event failed: %d\n",
1026 w->name, ret);
1027 }
1028}
1029
9d0624a7
MB
1030/* Async callback run prior to DAPM sequences - brings to _PREPARE if
1031 * they're changing state.
1032 */
1033static void dapm_pre_sequence_async(void *data, async_cookie_t cookie)
1034{
1035 struct snd_soc_dapm_context *d = data;
1036 int ret;
1037
1038 if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) {
1039 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1040 if (ret != 0)
1041 dev_err(d->dev,
1042 "Failed to turn on bias: %d\n", ret);
1043 }
1044
1045 /* If we're changing to all on or all off then prepare */
1046 if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
1047 (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
1048 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
1049 if (ret != 0)
1050 dev_err(d->dev,
1051 "Failed to prepare bias: %d\n", ret);
1052 }
1053}
1054
1055/* Async callback run prior to DAPM sequences - brings to their final
1056 * state.
1057 */
1058static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1059{
1060 struct snd_soc_dapm_context *d = data;
1061 int ret;
1062
1063 /* If we just powered the last thing off drop to standby bias */
1064 if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
1065 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1066 if (ret != 0)
1067 dev_err(d->dev, "Failed to apply standby bias: %d\n",
1068 ret);
1069 }
97404f2e 1070
9d0624a7
MB
1071 /* If we're in standby and can support bias off then do that */
1072 if (d->bias_level == SND_SOC_BIAS_STANDBY && d->idle_bias_off) {
1073 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
1074 if (ret != 0)
1075 dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
1076 }
1077
1078 /* If we just powered up then move to active bias */
1079 if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
1080 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
1081 if (ret != 0)
1082 dev_err(d->dev, "Failed to apply active bias: %d\n",
1083 ret);
1084 }
1085}
97404f2e 1086
2b97eabc
RP
1087/*
1088 * Scan each dapm widget for complete audio path.
1089 * A complete path is a route that has valid endpoints i.e.:-
1090 *
1091 * o DAC to output pin.
1092 * o Input Pin to ADC.
1093 * o Input pin to Output pin (bypass, sidetone)
1094 * o DAC to ADC (loopback).
1095 */
ce6120cc 1096static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
2b97eabc 1097{
12ea2c78 1098 struct snd_soc_card *card = dapm->card;
2b97eabc 1099 struct snd_soc_dapm_widget *w;
7be31be8 1100 struct snd_soc_dapm_context *d;
291f3bbc
MB
1101 LIST_HEAD(up_list);
1102 LIST_HEAD(down_list);
9d0624a7 1103 LIST_HEAD(async_domain);
38357ab2 1104 int power;
6d3ddc81 1105
84e90930
MB
1106 trace_snd_soc_dapm_start(card);
1107
7be31be8
JN
1108 list_for_each_entry(d, &card->dapm_list, list)
1109 if (d->n_widgets)
1110 d->dev_power = 0;
1111
6d3ddc81
MB
1112 /* Check which widgets we need to power and store them in
1113 * lists indicating if they should be powered up or down.
1114 */
97c866de 1115 list_for_each_entry(w, &card->widgets, list) {
6d3ddc81
MB
1116 switch (w->id) {
1117 case snd_soc_dapm_pre:
828a842f 1118 dapm_seq_insert(w, &down_list, false);
6d3ddc81
MB
1119 break;
1120 case snd_soc_dapm_post:
828a842f 1121 dapm_seq_insert(w, &up_list, true);
6d3ddc81
MB
1122 break;
1123
1124 default:
1125 if (!w->power_check)
1126 continue;
1127
9949788b 1128 if (!w->force)
50b6bce5 1129 power = w->power_check(w);
9949788b
MB
1130 else
1131 power = 1;
1132 if (power)
7be31be8 1133 w->dapm->dev_power = 1;
452c5eaa 1134
6d3ddc81
MB
1135 if (w->power == power)
1136 continue;
1137
84e90930
MB
1138 trace_snd_soc_dapm_widget_power(w, power);
1139
6d3ddc81 1140 if (power)
828a842f 1141 dapm_seq_insert(w, &up_list, true);
6d3ddc81 1142 else
828a842f 1143 dapm_seq_insert(w, &down_list, false);
6d3ddc81
MB
1144
1145 w->power = power;
1146 break;
1147 }
2b97eabc
RP
1148 }
1149
b14b76a5
MB
1150 /* If there are no DAPM widgets then try to figure out power from the
1151 * event type.
1152 */
97c866de 1153 if (!dapm->n_widgets) {
b14b76a5
MB
1154 switch (event) {
1155 case SND_SOC_DAPM_STREAM_START:
1156 case SND_SOC_DAPM_STREAM_RESUME:
7be31be8 1157 dapm->dev_power = 1;
b14b76a5 1158 break;
862af8ad 1159 case SND_SOC_DAPM_STREAM_STOP:
7be31be8 1160 dapm->dev_power = !!dapm->codec->active;
862af8ad 1161 break;
50b6bce5 1162 case SND_SOC_DAPM_STREAM_SUSPEND:
7be31be8 1163 dapm->dev_power = 0;
50b6bce5 1164 break;
b14b76a5 1165 case SND_SOC_DAPM_STREAM_NOP:
ce6120cc 1166 switch (dapm->bias_level) {
a96ca338
MB
1167 case SND_SOC_BIAS_STANDBY:
1168 case SND_SOC_BIAS_OFF:
7be31be8 1169 dapm->dev_power = 0;
a96ca338
MB
1170 break;
1171 default:
7be31be8 1172 dapm->dev_power = 1;
a96ca338
MB
1173 break;
1174 }
50b6bce5 1175 break;
b14b76a5
MB
1176 default:
1177 break;
1178 }
1179 }
1180
9d0624a7
MB
1181 /* Run all the bias changes in parallel */
1182 list_for_each_entry(d, &dapm->card->dapm_list, list)
1183 async_schedule_domain(dapm_pre_sequence_async, d,
1184 &async_domain);
1185 async_synchronize_full_domain(&async_domain);
452c5eaa 1186
6d3ddc81 1187 /* Power down widgets first; try to avoid amplifying pops. */
828a842f 1188 dapm_seq_run(dapm, &down_list, event, false);
2b97eabc 1189
97404f2e
MB
1190 dapm_widget_update(dapm);
1191
6d3ddc81 1192 /* Now power up. */
828a842f 1193 dapm_seq_run(dapm, &up_list, event, true);
2b97eabc 1194
9d0624a7
MB
1195 /* Run all the bias changes in parallel */
1196 list_for_each_entry(d, &dapm->card->dapm_list, list)
1197 async_schedule_domain(dapm_post_sequence_async, d,
1198 &async_domain);
1199 async_synchronize_full_domain(&async_domain);
452c5eaa 1200
fd8d3bc0
JN
1201 pop_dbg(dapm->dev, card->pop_time,
1202 "DAPM sequencing finished, waiting %dms\n", card->pop_time);
3a45b867 1203 pop_wait(card->pop_time);
cb507e7e 1204
84e90930
MB
1205 trace_snd_soc_dapm_done(card);
1206
42aa3418 1207 return 0;
2b97eabc
RP
1208}
1209
79fb9387
MB
1210#ifdef CONFIG_DEBUG_FS
1211static int dapm_widget_power_open_file(struct inode *inode, struct file *file)
1212{
1213 file->private_data = inode->i_private;
1214 return 0;
1215}
1216
1217static ssize_t dapm_widget_power_read_file(struct file *file,
1218 char __user *user_buf,
1219 size_t count, loff_t *ppos)
1220{
1221 struct snd_soc_dapm_widget *w = file->private_data;
1222 char *buf;
1223 int in, out;
1224 ssize_t ret;
1225 struct snd_soc_dapm_path *p = NULL;
1226
1227 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1228 if (!buf)
1229 return -ENOMEM;
1230
1231 in = is_connected_input_ep(w);
ce6120cc 1232 dapm_clear_walk(w->dapm);
79fb9387 1233 out = is_connected_output_ep(w);
ce6120cc 1234 dapm_clear_walk(w->dapm);
79fb9387 1235
d033c36a 1236 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d",
79fb9387
MB
1237 w->name, w->power ? "On" : "Off", in, out);
1238
d033c36a
MB
1239 if (w->reg >= 0)
1240 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1241 " - R%d(0x%x) bit %d",
1242 w->reg, w->reg, w->shift);
1243
1244 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
1245
3eef08ba
MB
1246 if (w->sname)
1247 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
1248 w->sname,
1249 w->active ? "active" : "inactive");
79fb9387
MB
1250
1251 list_for_each_entry(p, &w->sources, list_sink) {
215edda3
MB
1252 if (p->connected && !p->connected(w, p->sink))
1253 continue;
1254
79fb9387
MB
1255 if (p->connect)
1256 ret += snprintf(buf + ret, PAGE_SIZE - ret,
67f5ed6e 1257 " in \"%s\" \"%s\"\n",
79fb9387
MB
1258 p->name ? p->name : "static",
1259 p->source->name);
1260 }
1261 list_for_each_entry(p, &w->sinks, list_source) {
215edda3
MB
1262 if (p->connected && !p->connected(w, p->sink))
1263 continue;
1264
79fb9387
MB
1265 if (p->connect)
1266 ret += snprintf(buf + ret, PAGE_SIZE - ret,
67f5ed6e 1267 " out \"%s\" \"%s\"\n",
79fb9387
MB
1268 p->name ? p->name : "static",
1269 p->sink->name);
1270 }
1271
1272 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1273
1274 kfree(buf);
1275 return ret;
1276}
1277
1278static const struct file_operations dapm_widget_power_fops = {
1279 .open = dapm_widget_power_open_file,
1280 .read = dapm_widget_power_read_file,
6038f373 1281 .llseek = default_llseek,
79fb9387
MB
1282};
1283
ce6120cc 1284void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
79fb9387
MB
1285{
1286 struct snd_soc_dapm_widget *w;
1287 struct dentry *d;
1288
ce6120cc 1289 if (!dapm->debugfs_dapm)
79fb9387
MB
1290 return;
1291
97c866de
JN
1292 list_for_each_entry(w, &dapm->card->widgets, list) {
1293 if (!w->name || w->dapm != dapm)
79fb9387
MB
1294 continue;
1295
1296 d = debugfs_create_file(w->name, 0444,
ce6120cc 1297 dapm->debugfs_dapm, w,
79fb9387
MB
1298 &dapm_widget_power_fops);
1299 if (!d)
f7d41ae8
JN
1300 dev_warn(w->dapm->dev,
1301 "ASoC: Failed to create %s debugfs file\n",
1302 w->name);
79fb9387
MB
1303 }
1304}
1305#else
ce6120cc 1306void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
79fb9387
MB
1307{
1308}
1309#endif
1310
2b97eabc 1311/* test and update the power status of a mux widget */
d9c96cf3 1312static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
3a65577d
MB
1313 struct snd_kcontrol *kcontrol, int change,
1314 int mux, struct soc_enum *e)
2b97eabc
RP
1315{
1316 struct snd_soc_dapm_path *path;
1317 int found = 0;
1318
eff317d0 1319 if (widget->id != snd_soc_dapm_mux &&
24ff33ac 1320 widget->id != snd_soc_dapm_virt_mux &&
eff317d0 1321 widget->id != snd_soc_dapm_value_mux)
2b97eabc
RP
1322 return -ENODEV;
1323
3a65577d 1324 if (!change)
2b97eabc
RP
1325 return 0;
1326
1327 /* find dapm widget path assoc with kcontrol */
8ddab3f5 1328 list_for_each_entry(path, &widget->dapm->card->paths, list) {
2b97eabc
RP
1329 if (path->kcontrol != kcontrol)
1330 continue;
1331
cb01e2b9 1332 if (!path->name || !e->texts[mux])
2b97eabc
RP
1333 continue;
1334
1335 found = 1;
1336 /* we now need to match the string in the enum to the path */
cb01e2b9 1337 if (!(strcmp(path->name, e->texts[mux])))
2b97eabc
RP
1338 path->connect = 1; /* new connection */
1339 else
1340 path->connect = 0; /* old connection must be powered down */
1341 }
1342
b91b8fa0 1343 if (found)
ce6120cc 1344 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
2b97eabc
RP
1345
1346 return 0;
1347}
2b97eabc 1348
1b075e3f 1349/* test and update the power status of a mixer or switch widget */
d9c96cf3 1350static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
283375ce 1351 struct snd_kcontrol *kcontrol, int connect)
2b97eabc
RP
1352{
1353 struct snd_soc_dapm_path *path;
1354 int found = 0;
1355
1b075e3f 1356 if (widget->id != snd_soc_dapm_mixer &&
ca9c1aae 1357 widget->id != snd_soc_dapm_mixer_named_ctl &&
1b075e3f 1358 widget->id != snd_soc_dapm_switch)
2b97eabc
RP
1359 return -ENODEV;
1360
2b97eabc 1361 /* find dapm widget path assoc with kcontrol */
8ddab3f5 1362 list_for_each_entry(path, &widget->dapm->card->paths, list) {
2b97eabc
RP
1363 if (path->kcontrol != kcontrol)
1364 continue;
1365
1366 /* found, now check type */
1367 found = 1;
283375ce 1368 path->connect = connect;
2b97eabc
RP
1369 break;
1370 }
1371
b91b8fa0 1372 if (found)
ce6120cc 1373 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
2b97eabc
RP
1374
1375 return 0;
1376}
2b97eabc
RP
1377
1378/* show dapm widget status in sys fs */
1379static ssize_t dapm_widget_show(struct device *dev,
1380 struct device_attribute *attr, char *buf)
1381{
f0fba2ad
LG
1382 struct snd_soc_pcm_runtime *rtd =
1383 container_of(dev, struct snd_soc_pcm_runtime, dev);
1384 struct snd_soc_codec *codec =rtd->codec;
2b97eabc
RP
1385 struct snd_soc_dapm_widget *w;
1386 int count = 0;
1387 char *state = "not set";
1388
97c866de
JN
1389 list_for_each_entry(w, &codec->card->widgets, list) {
1390 if (w->dapm != &codec->dapm)
1391 continue;
2b97eabc
RP
1392
1393 /* only display widgets that burnm power */
1394 switch (w->id) {
1395 case snd_soc_dapm_hp:
1396 case snd_soc_dapm_mic:
1397 case snd_soc_dapm_spk:
1398 case snd_soc_dapm_line:
1399 case snd_soc_dapm_micbias:
1400 case snd_soc_dapm_dac:
1401 case snd_soc_dapm_adc:
1402 case snd_soc_dapm_pga:
d88429a6 1403 case snd_soc_dapm_out_drv:
2b97eabc 1404 case snd_soc_dapm_mixer:
ca9c1aae 1405 case snd_soc_dapm_mixer_named_ctl:
246d0a17 1406 case snd_soc_dapm_supply:
2b97eabc
RP
1407 if (w->name)
1408 count += sprintf(buf + count, "%s: %s\n",
1409 w->name, w->power ? "On":"Off");
1410 break;
1411 default:
1412 break;
1413 }
1414 }
1415
ce6120cc 1416 switch (codec->dapm.bias_level) {
0be9898a
MB
1417 case SND_SOC_BIAS_ON:
1418 state = "On";
2b97eabc 1419 break;
0be9898a
MB
1420 case SND_SOC_BIAS_PREPARE:
1421 state = "Prepare";
2b97eabc 1422 break;
0be9898a
MB
1423 case SND_SOC_BIAS_STANDBY:
1424 state = "Standby";
2b97eabc 1425 break;
0be9898a
MB
1426 case SND_SOC_BIAS_OFF:
1427 state = "Off";
2b97eabc
RP
1428 break;
1429 }
1430 count += sprintf(buf + count, "PM State: %s\n", state);
1431
1432 return count;
1433}
1434
1435static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
1436
1437int snd_soc_dapm_sys_add(struct device *dev)
1438{
12ef193d 1439 return device_create_file(dev, &dev_attr_dapm_widget);
2b97eabc
RP
1440}
1441
1442static void snd_soc_dapm_sys_remove(struct device *dev)
1443{
aef90843 1444 device_remove_file(dev, &dev_attr_dapm_widget);
2b97eabc
RP
1445}
1446
1447/* free all dapm widgets and resources */
ce6120cc 1448static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
2b97eabc
RP
1449{
1450 struct snd_soc_dapm_widget *w, *next_w;
1451 struct snd_soc_dapm_path *p, *next_p;
1452
97c866de
JN
1453 list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) {
1454 if (w->dapm != dapm)
1455 continue;
2b97eabc 1456 list_del(&w->list);
8ddab3f5
JN
1457 /*
1458 * remove source and sink paths associated to this widget.
1459 * While removing the path, remove reference to it from both
1460 * source and sink widgets so that path is removed only once.
1461 */
1462 list_for_each_entry_safe(p, next_p, &w->sources, list_sink) {
1463 list_del(&p->list_sink);
1464 list_del(&p->list_source);
1465 list_del(&p->list);
1466 kfree(p->long_name);
1467 kfree(p);
1468 }
1469 list_for_each_entry_safe(p, next_p, &w->sinks, list_source) {
1470 list_del(&p->list_sink);
1471 list_del(&p->list_source);
1472 list_del(&p->list);
1473 kfree(p->long_name);
1474 kfree(p);
1475 }
ead9b919 1476 kfree(w->name);
2b97eabc
RP
1477 kfree(w);
1478 }
2b97eabc
RP
1479}
1480
ce6120cc 1481static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1649923d 1482 const char *pin, int status)
a5302181
LG
1483{
1484 struct snd_soc_dapm_widget *w;
1485
97c866de
JN
1486 list_for_each_entry(w, &dapm->card->widgets, list) {
1487 if (w->dapm != dapm)
1488 continue;
a5302181 1489 if (!strcmp(w->name, pin)) {
f7d41ae8
JN
1490 dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n",
1491 pin, status);
a5302181 1492 w->connected = status;
5b9e87cc
MB
1493 /* Allow disabling of forced pins */
1494 if (status == 0)
1495 w->force = 0;
a5302181
LG
1496 return 0;
1497 }
1498 }
1499
f7d41ae8 1500 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
a5302181
LG
1501 return -EINVAL;
1502}
1503
2b97eabc 1504/**
a5302181 1505 * snd_soc_dapm_sync - scan and power dapm paths
ce6120cc 1506 * @dapm: DAPM context
2b97eabc
RP
1507 *
1508 * Walks all dapm audio paths and powers widgets according to their
1509 * stream or path usage.
1510 *
1511 * Returns 0 for success.
1512 */
ce6120cc 1513int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
2b97eabc 1514{
ce6120cc 1515 return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
2b97eabc 1516}
a5302181 1517EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
2b97eabc 1518
ce6120cc 1519static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
215edda3 1520 const struct snd_soc_dapm_route *route)
2b97eabc
RP
1521{
1522 struct snd_soc_dapm_path *path;
1523 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
97c866de 1524 struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;
ead9b919 1525 const char *sink;
215edda3 1526 const char *control = route->control;
ead9b919
JN
1527 const char *source;
1528 char prefixed_sink[80];
1529 char prefixed_source[80];
2b97eabc
RP
1530 int ret = 0;
1531
88e8b9a8 1532 if (dapm->codec && dapm->codec->name_prefix) {
ead9b919
JN
1533 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
1534 dapm->codec->name_prefix, route->sink);
1535 sink = prefixed_sink;
1536 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
1537 dapm->codec->name_prefix, route->source);
1538 source = prefixed_source;
1539 } else {
1540 sink = route->sink;
1541 source = route->source;
1542 }
1543
97c866de
JN
1544 /*
1545 * find src and dest widgets over all widgets but favor a widget from
1546 * current DAPM context
1547 */
1548 list_for_each_entry(w, &dapm->card->widgets, list) {
2b97eabc 1549 if (!wsink && !(strcmp(w->name, sink))) {
97c866de
JN
1550 wtsink = w;
1551 if (w->dapm == dapm)
1552 wsink = w;
2b97eabc
RP
1553 continue;
1554 }
1555 if (!wsource && !(strcmp(w->name, source))) {
97c866de
JN
1556 wtsource = w;
1557 if (w->dapm == dapm)
1558 wsource = w;
2b97eabc
RP
1559 }
1560 }
97c866de
JN
1561 /* use widget from another DAPM context if not found from this */
1562 if (!wsink)
1563 wsink = wtsink;
1564 if (!wsource)
1565 wsource = wtsource;
2b97eabc
RP
1566
1567 if (wsource == NULL || wsink == NULL)
1568 return -ENODEV;
1569
1570 path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL);
1571 if (!path)
1572 return -ENOMEM;
1573
1574 path->source = wsource;
1575 path->sink = wsink;
215edda3 1576 path->connected = route->connected;
2b97eabc
RP
1577 INIT_LIST_HEAD(&path->list);
1578 INIT_LIST_HEAD(&path->list_source);
1579 INIT_LIST_HEAD(&path->list_sink);
1580
1581 /* check for external widgets */
1582 if (wsink->id == snd_soc_dapm_input) {
1583 if (wsource->id == snd_soc_dapm_micbias ||
1584 wsource->id == snd_soc_dapm_mic ||
087d53ab
RC
1585 wsource->id == snd_soc_dapm_line ||
1586 wsource->id == snd_soc_dapm_output)
2b97eabc
RP
1587 wsink->ext = 1;
1588 }
1589 if (wsource->id == snd_soc_dapm_output) {
1590 if (wsink->id == snd_soc_dapm_spk ||
1591 wsink->id == snd_soc_dapm_hp ||
1e39221e
SF
1592 wsink->id == snd_soc_dapm_line ||
1593 wsink->id == snd_soc_dapm_input)
2b97eabc
RP
1594 wsource->ext = 1;
1595 }
1596
1597 /* connect static paths */
1598 if (control == NULL) {
8ddab3f5 1599 list_add(&path->list, &dapm->card->paths);
2b97eabc
RP
1600 list_add(&path->list_sink, &wsink->sources);
1601 list_add(&path->list_source, &wsource->sinks);
1602 path->connect = 1;
1603 return 0;
1604 }
1605
1606 /* connect dynamic paths */
1607 switch(wsink->id) {
1608 case snd_soc_dapm_adc:
1609 case snd_soc_dapm_dac:
1610 case snd_soc_dapm_pga:
d88429a6 1611 case snd_soc_dapm_out_drv:
2b97eabc
RP
1612 case snd_soc_dapm_input:
1613 case snd_soc_dapm_output:
1614 case snd_soc_dapm_micbias:
1615 case snd_soc_dapm_vmid:
1616 case snd_soc_dapm_pre:
1617 case snd_soc_dapm_post:
246d0a17 1618 case snd_soc_dapm_supply:
010ff262
MB
1619 case snd_soc_dapm_aif_in:
1620 case snd_soc_dapm_aif_out:
8ddab3f5 1621 list_add(&path->list, &dapm->card->paths);
2b97eabc
RP
1622 list_add(&path->list_sink, &wsink->sources);
1623 list_add(&path->list_source, &wsource->sinks);
1624 path->connect = 1;
1625 return 0;
1626 case snd_soc_dapm_mux:
24ff33ac 1627 case snd_soc_dapm_virt_mux:
74155556 1628 case snd_soc_dapm_value_mux:
ce6120cc 1629 ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
2b97eabc
RP
1630 &wsink->kcontrols[0]);
1631 if (ret != 0)
1632 goto err;
1633 break;
1634 case snd_soc_dapm_switch:
1635 case snd_soc_dapm_mixer:
ca9c1aae 1636 case snd_soc_dapm_mixer_named_ctl:
ce6120cc 1637 ret = dapm_connect_mixer(dapm, wsource, wsink, path, control);
2b97eabc
RP
1638 if (ret != 0)
1639 goto err;
1640 break;
1641 case snd_soc_dapm_hp:
1642 case snd_soc_dapm_mic:
1643 case snd_soc_dapm_line:
1644 case snd_soc_dapm_spk:
8ddab3f5 1645 list_add(&path->list, &dapm->card->paths);
2b97eabc
RP
1646 list_add(&path->list_sink, &wsink->sources);
1647 list_add(&path->list_source, &wsource->sinks);
1648 path->connect = 0;
1649 return 0;
1650 }
1651 return 0;
1652
1653err:
f7d41ae8
JN
1654 dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n",
1655 source, control, sink);
2b97eabc
RP
1656 kfree(path);
1657 return ret;
1658}
105f1c28 1659
105f1c28
MB
1660/**
1661 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
ce6120cc 1662 * @dapm: DAPM context
105f1c28
MB
1663 * @route: audio routes
1664 * @num: number of routes
1665 *
1666 * Connects 2 dapm widgets together via a named audio path. The sink is
1667 * the widget receiving the audio signal, whilst the source is the sender
1668 * of the audio signal.
1669 *
1670 * Returns 0 for success else error. On error all resources can be freed
1671 * with a call to snd_soc_card_free().
1672 */
ce6120cc 1673int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
105f1c28
MB
1674 const struct snd_soc_dapm_route *route, int num)
1675{
1676 int i, ret;
1677
1678 for (i = 0; i < num; i++) {
ce6120cc 1679 ret = snd_soc_dapm_add_route(dapm, route);
105f1c28 1680 if (ret < 0) {
f7d41ae8
JN
1681 dev_err(dapm->dev, "Failed to add route %s->%s\n",
1682 route->source, route->sink);
105f1c28
MB
1683 return ret;
1684 }
1685 route++;
1686 }
1687
1688 return 0;
1689}
1690EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
1691
2b97eabc
RP
1692/**
1693 * snd_soc_dapm_new_widgets - add new dapm widgets
ce6120cc 1694 * @dapm: DAPM context
2b97eabc
RP
1695 *
1696 * Checks the codec for any new dapm widgets and creates them if found.
1697 *
1698 * Returns 0 for success.
1699 */
ce6120cc 1700int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2b97eabc
RP
1701{
1702 struct snd_soc_dapm_widget *w;
b66a70d5 1703 unsigned int val;
2b97eabc 1704
97c866de 1705 list_for_each_entry(w, &dapm->card->widgets, list)
2b97eabc
RP
1706 {
1707 if (w->new)
1708 continue;
1709
1710 switch(w->id) {
1711 case snd_soc_dapm_switch:
1712 case snd_soc_dapm_mixer:
ca9c1aae 1713 case snd_soc_dapm_mixer_named_ctl:
b75576d7 1714 w->power_check = dapm_generic_check_power;
ce6120cc 1715 dapm_new_mixer(dapm, w);
2b97eabc
RP
1716 break;
1717 case snd_soc_dapm_mux:
24ff33ac 1718 case snd_soc_dapm_virt_mux:
2e72f8e3 1719 case snd_soc_dapm_value_mux:
b75576d7 1720 w->power_check = dapm_generic_check_power;
ce6120cc 1721 dapm_new_mux(dapm, w);
2b97eabc
RP
1722 break;
1723 case snd_soc_dapm_adc:
010ff262 1724 case snd_soc_dapm_aif_out:
b75576d7
MB
1725 w->power_check = dapm_adc_check_power;
1726 break;
2b97eabc 1727 case snd_soc_dapm_dac:
010ff262 1728 case snd_soc_dapm_aif_in:
b75576d7
MB
1729 w->power_check = dapm_dac_check_power;
1730 break;
2b97eabc 1731 case snd_soc_dapm_pga:
d88429a6 1732 case snd_soc_dapm_out_drv:
b75576d7 1733 w->power_check = dapm_generic_check_power;
ce6120cc 1734 dapm_new_pga(dapm, w);
2b97eabc
RP
1735 break;
1736 case snd_soc_dapm_input:
1737 case snd_soc_dapm_output:
1738 case snd_soc_dapm_micbias:
1739 case snd_soc_dapm_spk:
1740 case snd_soc_dapm_hp:
1741 case snd_soc_dapm_mic:
1742 case snd_soc_dapm_line:
b75576d7
MB
1743 w->power_check = dapm_generic_check_power;
1744 break;
246d0a17
MB
1745 case snd_soc_dapm_supply:
1746 w->power_check = dapm_supply_check_power;
2b97eabc
RP
1747 case snd_soc_dapm_vmid:
1748 case snd_soc_dapm_pre:
1749 case snd_soc_dapm_post:
1750 break;
1751 }
b66a70d5
MB
1752
1753 /* Read the initial power state from the device */
1754 if (w->reg >= 0) {
1755 val = snd_soc_read(w->codec, w->reg);
1756 val &= 1 << w->shift;
1757 if (w->invert)
1758 val = !val;
1759
1760 if (val)
1761 w->power = 1;
1762 }
1763
2b97eabc
RP
1764 w->new = 1;
1765 }
1766
ce6120cc 1767 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
2b97eabc
RP
1768 return 0;
1769}
1770EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
1771
1772/**
1773 * snd_soc_dapm_get_volsw - dapm mixer get callback
1774 * @kcontrol: mixer control
ac11a2b3 1775 * @ucontrol: control element information
2b97eabc
RP
1776 *
1777 * Callback to get the value of a dapm mixer control.
1778 *
1779 * Returns 0 for success.
1780 */
1781int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
1782 struct snd_ctl_elem_value *ucontrol)
1783{
1784 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
4eaa9819
JS
1785 struct soc_mixer_control *mc =
1786 (struct soc_mixer_control *)kcontrol->private_value;
815ecf8d
JS
1787 unsigned int reg = mc->reg;
1788 unsigned int shift = mc->shift;
1789 unsigned int rshift = mc->rshift;
4eaa9819 1790 int max = mc->max;
815ecf8d
JS
1791 unsigned int invert = mc->invert;
1792 unsigned int mask = (1 << fls(max)) - 1;
2b97eabc 1793
2b97eabc
RP
1794 ucontrol->value.integer.value[0] =
1795 (snd_soc_read(widget->codec, reg) >> shift) & mask;
1796 if (shift != rshift)
1797 ucontrol->value.integer.value[1] =
1798 (snd_soc_read(widget->codec, reg) >> rshift) & mask;
1799 if (invert) {
1800 ucontrol->value.integer.value[0] =
a7a4ac86 1801 max - ucontrol->value.integer.value[0];
2b97eabc
RP
1802 if (shift != rshift)
1803 ucontrol->value.integer.value[1] =
a7a4ac86 1804 max - ucontrol->value.integer.value[1];
2b97eabc
RP
1805 }
1806
1807 return 0;
1808}
1809EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
1810
1811/**
1812 * snd_soc_dapm_put_volsw - dapm mixer set callback
1813 * @kcontrol: mixer control
ac11a2b3 1814 * @ucontrol: control element information
2b97eabc
RP
1815 *
1816 * Callback to set the value of a dapm mixer control.
1817 *
1818 * Returns 0 for success.
1819 */
1820int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1821 struct snd_ctl_elem_value *ucontrol)
1822{
1823 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
4eaa9819
JS
1824 struct soc_mixer_control *mc =
1825 (struct soc_mixer_control *)kcontrol->private_value;
815ecf8d
JS
1826 unsigned int reg = mc->reg;
1827 unsigned int shift = mc->shift;
4eaa9819 1828 int max = mc->max;
815ecf8d
JS
1829 unsigned int mask = (1 << fls(max)) - 1;
1830 unsigned int invert = mc->invert;
e9cf7049 1831 unsigned int val;
97404f2e
MB
1832 int connect, change;
1833 struct snd_soc_dapm_update update;
2b97eabc
RP
1834
1835 val = (ucontrol->value.integer.value[0] & mask);
1836
1837 if (invert)
a7a4ac86 1838 val = max - val;
e9cf7049 1839 mask = mask << shift;
2b97eabc 1840 val = val << shift;
2b97eabc
RP
1841
1842 mutex_lock(&widget->codec->mutex);
1843 widget->value = val;
1844
e9cf7049 1845 change = snd_soc_test_bits(widget->codec, reg, mask, val);
97404f2e 1846 if (change) {
283375ce
MB
1847 if (val)
1848 /* new connection */
1849 connect = invert ? 0:1;
1850 else
1851 /* old connection must be powered down */
1852 connect = invert ? 1:0;
1853
97404f2e
MB
1854 update.kcontrol = kcontrol;
1855 update.widget = widget;
1856 update.reg = reg;
1857 update.mask = mask;
1858 update.val = val;
1859 widget->dapm->update = &update;
1860
283375ce 1861 dapm_mixer_update_power(widget, kcontrol, connect);
97404f2e
MB
1862
1863 widget->dapm->update = NULL;
283375ce
MB
1864 }
1865
2b97eabc 1866 mutex_unlock(&widget->codec->mutex);
97404f2e 1867 return 0;
2b97eabc
RP
1868}
1869EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
1870
1871/**
1872 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
1873 * @kcontrol: mixer control
ac11a2b3 1874 * @ucontrol: control element information
2b97eabc
RP
1875 *
1876 * Callback to get the value of a dapm enumerated double mixer control.
1877 *
1878 * Returns 0 for success.
1879 */
1880int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
1881 struct snd_ctl_elem_value *ucontrol)
1882{
1883 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1884 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
46f5822f 1885 unsigned int val, bitmask;
2b97eabc 1886
f8ba0b7b 1887 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
2b97eabc
RP
1888 ;
1889 val = snd_soc_read(widget->codec, e->reg);
1890 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
1891 if (e->shift_l != e->shift_r)
1892 ucontrol->value.enumerated.item[1] =
1893 (val >> e->shift_r) & (bitmask - 1);
1894
1895 return 0;
1896}
1897EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
1898
1899/**
1900 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
1901 * @kcontrol: mixer control
ac11a2b3 1902 * @ucontrol: control element information
2b97eabc
RP
1903 *
1904 * Callback to set the value of a dapm enumerated double mixer control.
1905 *
1906 * Returns 0 for success.
1907 */
1908int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1909 struct snd_ctl_elem_value *ucontrol)
1910{
1911 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1912 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3a65577d 1913 unsigned int val, mux, change;
46f5822f 1914 unsigned int mask, bitmask;
97404f2e 1915 struct snd_soc_dapm_update update;
2b97eabc 1916
f8ba0b7b 1917 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
2b97eabc 1918 ;
f8ba0b7b 1919 if (ucontrol->value.enumerated.item[0] > e->max - 1)
2b97eabc
RP
1920 return -EINVAL;
1921 mux = ucontrol->value.enumerated.item[0];
1922 val = mux << e->shift_l;
1923 mask = (bitmask - 1) << e->shift_l;
1924 if (e->shift_l != e->shift_r) {
f8ba0b7b 1925 if (ucontrol->value.enumerated.item[1] > e->max - 1)
2b97eabc
RP
1926 return -EINVAL;
1927 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1928 mask |= (bitmask - 1) << e->shift_r;
1929 }
1930
1931 mutex_lock(&widget->codec->mutex);
1932 widget->value = val;
3a65577d 1933 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1642e3d4 1934
97404f2e
MB
1935 update.kcontrol = kcontrol;
1936 update.widget = widget;
1937 update.reg = e->reg;
1938 update.mask = mask;
1939 update.val = val;
1940 widget->dapm->update = &update;
1642e3d4 1941
97404f2e 1942 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1642e3d4 1943
97404f2e 1944 widget->dapm->update = NULL;
2b97eabc 1945
2b97eabc 1946 mutex_unlock(&widget->codec->mutex);
97404f2e 1947 return change;
2b97eabc
RP
1948}
1949EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1950
d2b247a8
MB
1951/**
1952 * snd_soc_dapm_get_enum_virt - Get virtual DAPM mux
1953 * @kcontrol: mixer control
1954 * @ucontrol: control element information
1955 *
1956 * Returns 0 for success.
1957 */
1958int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
1959 struct snd_ctl_elem_value *ucontrol)
1960{
1961 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1962
1963 ucontrol->value.enumerated.item[0] = widget->value;
1964
1965 return 0;
1966}
1967EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
1968
1969/**
1970 * snd_soc_dapm_put_enum_virt - Set virtual DAPM mux
1971 * @kcontrol: mixer control
1972 * @ucontrol: control element information
1973 *
1974 * Returns 0 for success.
1975 */
1976int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
1977 struct snd_ctl_elem_value *ucontrol)
1978{
1979 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1980 struct soc_enum *e =
1981 (struct soc_enum *)kcontrol->private_value;
1982 int change;
1983 int ret = 0;
1984
1985 if (ucontrol->value.enumerated.item[0] >= e->max)
1986 return -EINVAL;
1987
1988 mutex_lock(&widget->codec->mutex);
1989
1990 change = widget->value != ucontrol->value.enumerated.item[0];
1991 widget->value = ucontrol->value.enumerated.item[0];
1992 dapm_mux_update_power(widget, kcontrol, change, widget->value, e);
1993
1994 mutex_unlock(&widget->codec->mutex);
1995 return ret;
1996}
1997EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
1998
2e72f8e3
PU
1999/**
2000 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
2001 * callback
2002 * @kcontrol: mixer control
2003 * @ucontrol: control element information
2004 *
2005 * Callback to get the value of a dapm semi enumerated double mixer control.
2006 *
2007 * Semi enumerated mixer: the enumerated items are referred as values. Can be
2008 * used for handling bitfield coded enumeration for example.
2009 *
2010 * Returns 0 for success.
2011 */
2012int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
2013 struct snd_ctl_elem_value *ucontrol)
2014{
2015 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
74155556 2016 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
46f5822f 2017 unsigned int reg_val, val, mux;
2e72f8e3
PU
2018
2019 reg_val = snd_soc_read(widget->codec, e->reg);
2020 val = (reg_val >> e->shift_l) & e->mask;
2021 for (mux = 0; mux < e->max; mux++) {
2022 if (val == e->values[mux])
2023 break;
2024 }
2025 ucontrol->value.enumerated.item[0] = mux;
2026 if (e->shift_l != e->shift_r) {
2027 val = (reg_val >> e->shift_r) & e->mask;
2028 for (mux = 0; mux < e->max; mux++) {
2029 if (val == e->values[mux])
2030 break;
2031 }
2032 ucontrol->value.enumerated.item[1] = mux;
2033 }
2034
2035 return 0;
2036}
2037EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double);
2038
2039/**
2040 * snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set
2041 * callback
2042 * @kcontrol: mixer control
2043 * @ucontrol: control element information
2044 *
2045 * Callback to set the value of a dapm semi enumerated double mixer control.
2046 *
2047 * Semi enumerated mixer: the enumerated items are referred as values. Can be
2048 * used for handling bitfield coded enumeration for example.
2049 *
2050 * Returns 0 for success.
2051 */
2052int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2053 struct snd_ctl_elem_value *ucontrol)
2054{
2055 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
74155556 2056 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3a65577d 2057 unsigned int val, mux, change;
46f5822f 2058 unsigned int mask;
97404f2e 2059 struct snd_soc_dapm_update update;
2e72f8e3
PU
2060
2061 if (ucontrol->value.enumerated.item[0] > e->max - 1)
2062 return -EINVAL;
2063 mux = ucontrol->value.enumerated.item[0];
2064 val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
2065 mask = e->mask << e->shift_l;
2066 if (e->shift_l != e->shift_r) {
2067 if (ucontrol->value.enumerated.item[1] > e->max - 1)
2068 return -EINVAL;
2069 val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
2070 mask |= e->mask << e->shift_r;
2071 }
2072
2073 mutex_lock(&widget->codec->mutex);
2074 widget->value = val;
3a65577d 2075 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1642e3d4 2076
97404f2e
MB
2077 update.kcontrol = kcontrol;
2078 update.widget = widget;
2079 update.reg = e->reg;
2080 update.mask = mask;
2081 update.val = val;
2082 widget->dapm->update = &update;
1642e3d4 2083
97404f2e 2084 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1642e3d4 2085
97404f2e 2086 widget->dapm->update = NULL;
2e72f8e3 2087
2e72f8e3 2088 mutex_unlock(&widget->codec->mutex);
97404f2e 2089 return change;
2e72f8e3
PU
2090}
2091EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
2092
8b37dbd2
MB
2093/**
2094 * snd_soc_dapm_info_pin_switch - Info for a pin switch
2095 *
2096 * @kcontrol: mixer control
2097 * @uinfo: control element information
2098 *
2099 * Callback to provide information about a pin switch control.
2100 */
2101int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
2102 struct snd_ctl_elem_info *uinfo)
2103{
2104 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2105 uinfo->count = 1;
2106 uinfo->value.integer.min = 0;
2107 uinfo->value.integer.max = 1;
2108
2109 return 0;
2110}
2111EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch);
2112
2113/**
2114 * snd_soc_dapm_get_pin_switch - Get information for a pin switch
2115 *
2116 * @kcontrol: mixer control
2117 * @ucontrol: Value
2118 */
2119int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
2120 struct snd_ctl_elem_value *ucontrol)
2121{
2122 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2123 const char *pin = (const char *)kcontrol->private_value;
2124
2125 mutex_lock(&codec->mutex);
2126
2127 ucontrol->value.integer.value[0] =
ce6120cc 2128 snd_soc_dapm_get_pin_status(&codec->dapm, pin);
8b37dbd2
MB
2129
2130 mutex_unlock(&codec->mutex);
2131
2132 return 0;
2133}
2134EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch);
2135
2136/**
2137 * snd_soc_dapm_put_pin_switch - Set information for a pin switch
2138 *
2139 * @kcontrol: mixer control
2140 * @ucontrol: Value
2141 */
2142int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
2143 struct snd_ctl_elem_value *ucontrol)
2144{
2145 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2146 const char *pin = (const char *)kcontrol->private_value;
2147
2148 mutex_lock(&codec->mutex);
2149
2150 if (ucontrol->value.integer.value[0])
ce6120cc 2151 snd_soc_dapm_enable_pin(&codec->dapm, pin);
8b37dbd2 2152 else
ce6120cc 2153 snd_soc_dapm_disable_pin(&codec->dapm, pin);
8b37dbd2 2154
ce6120cc 2155 snd_soc_dapm_sync(&codec->dapm);
8b37dbd2
MB
2156
2157 mutex_unlock(&codec->mutex);
2158
2159 return 0;
2160}
2161EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
2162
2b97eabc
RP
2163/**
2164 * snd_soc_dapm_new_control - create new dapm control
ce6120cc 2165 * @dapm: DAPM context
2b97eabc
RP
2166 * @widget: widget template
2167 *
2168 * Creates a new dapm control based upon the template.
2169 *
2170 * Returns 0 for success else error.
2171 */
ce6120cc 2172int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2b97eabc
RP
2173 const struct snd_soc_dapm_widget *widget)
2174{
2175 struct snd_soc_dapm_widget *w;
ead9b919 2176 size_t name_len;
2b97eabc
RP
2177
2178 if ((w = dapm_cnew_widget(widget)) == NULL)
2179 return -ENOMEM;
2180
ead9b919 2181 name_len = strlen(widget->name) + 1;
88e8b9a8 2182 if (dapm->codec && dapm->codec->name_prefix)
ead9b919
JN
2183 name_len += 1 + strlen(dapm->codec->name_prefix);
2184 w->name = kmalloc(name_len, GFP_KERNEL);
2185 if (w->name == NULL) {
2186 kfree(w);
2187 return -ENOMEM;
2188 }
88e8b9a8 2189 if (dapm->codec && dapm->codec->name_prefix)
ead9b919
JN
2190 snprintf(w->name, name_len, "%s %s",
2191 dapm->codec->name_prefix, widget->name);
2192 else
2193 snprintf(w->name, name_len, "%s", widget->name);
2194
97c866de 2195 dapm->n_widgets++;
ce6120cc
LG
2196 w->dapm = dapm;
2197 w->codec = dapm->codec;
2b97eabc
RP
2198 INIT_LIST_HEAD(&w->sources);
2199 INIT_LIST_HEAD(&w->sinks);
2200 INIT_LIST_HEAD(&w->list);
97c866de 2201 list_add(&w->list, &dapm->card->widgets);
2b97eabc
RP
2202
2203 /* machine layer set ups unconnected pins and insertions */
2204 w->connected = 1;
2205 return 0;
2206}
2207EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
2208
4ba1327a
MB
2209/**
2210 * snd_soc_dapm_new_controls - create new dapm controls
ce6120cc 2211 * @dapm: DAPM context
4ba1327a
MB
2212 * @widget: widget array
2213 * @num: number of widgets
2214 *
2215 * Creates new DAPM controls based upon the templates.
2216 *
2217 * Returns 0 for success else error.
2218 */
ce6120cc 2219int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
4ba1327a
MB
2220 const struct snd_soc_dapm_widget *widget,
2221 int num)
2222{
2223 int i, ret;
2224
2225 for (i = 0; i < num; i++) {
ce6120cc 2226 ret = snd_soc_dapm_new_control(dapm, widget);
b8b33cb5 2227 if (ret < 0) {
f7d41ae8
JN
2228 dev_err(dapm->dev,
2229 "ASoC: Failed to create DAPM control %s: %d\n",
2230 widget->name, ret);
4ba1327a 2231 return ret;
b8b33cb5 2232 }
4ba1327a
MB
2233 widget++;
2234 }
2235 return 0;
2236}
2237EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
2238
ce6120cc 2239static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
f0fba2ad 2240 const char *stream, int event)
2b97eabc
RP
2241{
2242 struct snd_soc_dapm_widget *w;
2243
97c866de 2244 list_for_each_entry(w, &dapm->card->widgets, list)
2b97eabc 2245 {
97c866de 2246 if (!w->sname || w->dapm != dapm)
2b97eabc 2247 continue;
f7d41ae8
JN
2248 dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
2249 w->name, w->sname, stream, event);
2b97eabc
RP
2250 if (strstr(w->sname, stream)) {
2251 switch(event) {
2252 case SND_SOC_DAPM_STREAM_START:
2253 w->active = 1;
2254 break;
2255 case SND_SOC_DAPM_STREAM_STOP:
2256 w->active = 0;
2257 break;
2258 case SND_SOC_DAPM_STREAM_SUSPEND:
2b97eabc 2259 case SND_SOC_DAPM_STREAM_RESUME:
2b97eabc 2260 case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
2b97eabc
RP
2261 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
2262 break;
2263 }
2264 }
2265 }
2b97eabc 2266
ce6120cc
LG
2267 dapm_power_widgets(dapm, event);
2268}
2269
2270/**
2271 * snd_soc_dapm_stream_event - send a stream event to the dapm core
2272 * @rtd: PCM runtime data
2273 * @stream: stream name
2274 * @event: stream event
2275 *
2276 * Sends a stream event to the dapm core. The core then makes any
2277 * necessary widget power changes.
2278 *
2279 * Returns 0 for success else error.
2280 */
2281int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
2282 const char *stream, int event)
2283{
2284 struct snd_soc_codec *codec = rtd->codec;
2285
2286 if (stream == NULL)
2287 return 0;
2288
2289 mutex_lock(&codec->mutex);
2290 soc_dapm_stream_event(&codec->dapm, stream, event);
8e8b2d67 2291 mutex_unlock(&codec->mutex);
2b97eabc
RP
2292 return 0;
2293}
2b97eabc
RP
2294
2295/**
a5302181 2296 * snd_soc_dapm_enable_pin - enable pin.
ce6120cc 2297 * @dapm: DAPM context
a5302181 2298 * @pin: pin name
2b97eabc 2299 *
74b8f955 2300 * Enables input/output pin and its parents or children widgets iff there is
a5302181
LG
2301 * a valid audio route and active audio stream.
2302 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2303 * do any widget power switching.
2b97eabc 2304 */
ce6120cc 2305int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin)
2b97eabc 2306{
ce6120cc 2307 return snd_soc_dapm_set_pin(dapm, pin, 1);
a5302181
LG
2308}
2309EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
2b97eabc 2310
da34183e
MB
2311/**
2312 * snd_soc_dapm_force_enable_pin - force a pin to be enabled
ce6120cc 2313 * @dapm: DAPM context
da34183e
MB
2314 * @pin: pin name
2315 *
2316 * Enables input/output pin regardless of any other state. This is
2317 * intended for use with microphone bias supplies used in microphone
2318 * jack detection.
2319 *
2320 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2321 * do any widget power switching.
2322 */
ce6120cc
LG
2323int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
2324 const char *pin)
da34183e
MB
2325{
2326 struct snd_soc_dapm_widget *w;
2327
97c866de
JN
2328 list_for_each_entry(w, &dapm->card->widgets, list) {
2329 if (w->dapm != dapm)
2330 continue;
da34183e 2331 if (!strcmp(w->name, pin)) {
f7d41ae8
JN
2332 dev_dbg(w->dapm->dev,
2333 "dapm: force enable pin %s\n", pin);
da34183e
MB
2334 w->connected = 1;
2335 w->force = 1;
2336 return 0;
2337 }
2338 }
2339
f7d41ae8 2340 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
da34183e
MB
2341 return -EINVAL;
2342}
2343EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
2344
a5302181
LG
2345/**
2346 * snd_soc_dapm_disable_pin - disable pin.
ce6120cc 2347 * @dapm: DAPM context
a5302181
LG
2348 * @pin: pin name
2349 *
74b8f955 2350 * Disables input/output pin and its parents or children widgets.
a5302181
LG
2351 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2352 * do any widget power switching.
2353 */
ce6120cc
LG
2354int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
2355 const char *pin)
a5302181 2356{
ce6120cc 2357 return snd_soc_dapm_set_pin(dapm, pin, 0);
2b97eabc 2358}
a5302181 2359EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
2b97eabc 2360
5817b52a
MB
2361/**
2362 * snd_soc_dapm_nc_pin - permanently disable pin.
ce6120cc 2363 * @dapm: DAPM context
5817b52a
MB
2364 * @pin: pin name
2365 *
2366 * Marks the specified pin as being not connected, disabling it along
2367 * any parent or child widgets. At present this is identical to
2368 * snd_soc_dapm_disable_pin() but in future it will be extended to do
2369 * additional things such as disabling controls which only affect
2370 * paths through the pin.
2371 *
2372 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2373 * do any widget power switching.
2374 */
ce6120cc 2375int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin)
5817b52a 2376{
ce6120cc 2377 return snd_soc_dapm_set_pin(dapm, pin, 0);
5817b52a
MB
2378}
2379EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
2380
eeec12bf 2381/**
a5302181 2382 * snd_soc_dapm_get_pin_status - get audio pin status
ce6120cc 2383 * @dapm: DAPM context
a5302181 2384 * @pin: audio signal pin endpoint (or start point)
eeec12bf 2385 *
a5302181 2386 * Get audio pin status - connected or disconnected.
eeec12bf 2387 *
a5302181 2388 * Returns 1 for connected otherwise 0.
eeec12bf 2389 */
ce6120cc
LG
2390int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
2391 const char *pin)
eeec12bf
GG
2392{
2393 struct snd_soc_dapm_widget *w;
2394
97c866de
JN
2395 list_for_each_entry(w, &dapm->card->widgets, list) {
2396 if (w->dapm != dapm)
2397 continue;
a5302181 2398 if (!strcmp(w->name, pin))
eeec12bf
GG
2399 return w->connected;
2400 }
2401
2402 return 0;
2403}
a5302181 2404EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
eeec12bf 2405
1547aba9
MB
2406/**
2407 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
ce6120cc 2408 * @dapm: DAPM context
1547aba9
MB
2409 * @pin: audio signal pin endpoint (or start point)
2410 *
2411 * Mark the given endpoint or pin as ignoring suspend. When the
2412 * system is disabled a path between two endpoints flagged as ignoring
2413 * suspend will not be disabled. The path must already be enabled via
2414 * normal means at suspend time, it will not be turned on if it was not
2415 * already enabled.
2416 */
ce6120cc
LG
2417int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
2418 const char *pin)
1547aba9
MB
2419{
2420 struct snd_soc_dapm_widget *w;
2421
97c866de
JN
2422 list_for_each_entry(w, &dapm->card->widgets, list) {
2423 if (w->dapm != dapm)
2424 continue;
1547aba9
MB
2425 if (!strcmp(w->name, pin)) {
2426 w->ignore_suspend = 1;
2427 return 0;
2428 }
2429 }
2430
f7d41ae8 2431 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
1547aba9
MB
2432 return -EINVAL;
2433}
2434EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
2435
2b97eabc
RP
2436/**
2437 * snd_soc_dapm_free - free dapm resources
f0fba2ad 2438 * @card: SoC device
2b97eabc
RP
2439 *
2440 * Free all dapm widgets and resources.
2441 */
ce6120cc 2442void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
2b97eabc 2443{
ce6120cc
LG
2444 snd_soc_dapm_sys_remove(dapm->dev);
2445 dapm_free_widgets(dapm);
7be31be8 2446 list_del(&dapm->list);
2b97eabc
RP
2447}
2448EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
2449
ce6120cc 2450static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
51737470 2451{
51737470
MB
2452 struct snd_soc_dapm_widget *w;
2453 LIST_HEAD(down_list);
2454 int powerdown = 0;
2455
97c866de
JN
2456 list_for_each_entry(w, &dapm->card->widgets, list) {
2457 if (w->dapm != dapm)
2458 continue;
51737470 2459 if (w->power) {
828a842f 2460 dapm_seq_insert(w, &down_list, false);
c2caa4da 2461 w->power = 0;
51737470
MB
2462 powerdown = 1;
2463 }
2464 }
2465
2466 /* If there were no widgets to power down we're already in
2467 * standby.
2468 */
2469 if (powerdown) {
ed5a4c47 2470 snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_PREPARE);
828a842f 2471 dapm_seq_run(dapm, &down_list, 0, false);
ed5a4c47 2472 snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_STANDBY);
51737470 2473 }
f0fba2ad
LG
2474}
2475
2476/*
2477 * snd_soc_dapm_shutdown - callback for system shutdown
2478 */
2479void snd_soc_dapm_shutdown(struct snd_soc_card *card)
2480{
2481 struct snd_soc_codec *codec;
2482
ce6120cc
LG
2483 list_for_each_entry(codec, &card->codec_dev_list, list) {
2484 soc_dapm_shutdown_codec(&codec->dapm);
ed5a4c47 2485 snd_soc_dapm_set_bias_level(&codec->dapm, SND_SOC_BIAS_OFF);
ce6120cc 2486 }
51737470
MB
2487}
2488
2b97eabc 2489/* Module information */
d331124d 2490MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
2b97eabc
RP
2491MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");
2492MODULE_LICENSE("GPL");