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