ASoC: Move name_prefix from CODEC to component
[deliverable/linux.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 16 * o Platform power domain - can support external components i.e. amps and
612a3fec 17 * mic/headphone insertion events.
2b97eabc
RP
18 * o Automatic Mic Bias support
19 * o Jack insertion power event initiation - e.g. hp insertion will enable
20 * sinks, dacs, etc
612a3fec 21 * o Delayed power down of audio subsystem to reduce pops between a quick
2b97eabc
RP
22 * device reopen.
23 *
2b97eabc
RP
24 */
25
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
9d0624a7 29#include <linux/async.h>
2b97eabc
RP
30#include <linux/delay.h>
31#include <linux/pm.h>
32#include <linux/bitops.h>
33#include <linux/platform_device.h>
34#include <linux/jiffies.h>
20496ff3 35#include <linux/debugfs.h>
f1aac484 36#include <linux/pm_runtime.h>
62ea874a 37#include <linux/regulator/consumer.h>
d7e7eb91 38#include <linux/clk.h>
5a0e3ad6 39#include <linux/slab.h>
2b97eabc
RP
40#include <sound/core.h>
41#include <sound/pcm.h>
42#include <sound/pcm_params.h>
ce6120cc 43#include <sound/soc.h>
2b97eabc
RP
44#include <sound/initval.h>
45
84e90930
MB
46#include <trace/events/asoc.h>
47
de02d078
MB
48#define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++;
49
57295073
LPC
50static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
51 struct snd_soc_dapm_widget *wsource, struct snd_soc_dapm_widget *wsink,
52 const char *control,
53 int (*connected)(struct snd_soc_dapm_widget *source,
54 struct snd_soc_dapm_widget *sink));
55static struct snd_soc_dapm_widget *
56snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
57 const struct snd_soc_dapm_widget *widget);
58
2b97eabc
RP
59/* dapm power sequences - make this per codec in the future */
60static int dapm_up_seq[] = {
38357ab2 61 [snd_soc_dapm_pre] = 0,
62ea874a 62 [snd_soc_dapm_regulator_supply] = 1,
d7e7eb91 63 [snd_soc_dapm_clock_supply] = 1,
1dd275b6
MB
64 [snd_soc_dapm_supply] = 2,
65 [snd_soc_dapm_micbias] = 3,
c74184ed 66 [snd_soc_dapm_dai_link] = 2,
1dd275b6
MB
67 [snd_soc_dapm_dai_in] = 4,
68 [snd_soc_dapm_dai_out] = 4,
69 [snd_soc_dapm_aif_in] = 4,
70 [snd_soc_dapm_aif_out] = 4,
71 [snd_soc_dapm_mic] = 5,
72 [snd_soc_dapm_mux] = 6,
1dd275b6
MB
73 [snd_soc_dapm_dac] = 7,
74 [snd_soc_dapm_switch] = 8,
75 [snd_soc_dapm_mixer] = 8,
76 [snd_soc_dapm_mixer_named_ctl] = 8,
77 [snd_soc_dapm_pga] = 9,
78 [snd_soc_dapm_adc] = 10,
79 [snd_soc_dapm_out_drv] = 11,
80 [snd_soc_dapm_hp] = 11,
81 [snd_soc_dapm_spk] = 11,
82 [snd_soc_dapm_line] = 11,
83 [snd_soc_dapm_kcontrol] = 12,
84 [snd_soc_dapm_post] = 13,
2b97eabc 85};
ca9c1aae 86
2b97eabc 87static int dapm_down_seq[] = {
38357ab2 88 [snd_soc_dapm_pre] = 0,
57295073
LPC
89 [snd_soc_dapm_kcontrol] = 1,
90 [snd_soc_dapm_adc] = 2,
91 [snd_soc_dapm_hp] = 3,
92 [snd_soc_dapm_spk] = 3,
93 [snd_soc_dapm_line] = 3,
94 [snd_soc_dapm_out_drv] = 3,
38357ab2 95 [snd_soc_dapm_pga] = 4,
efc77e36 96 [snd_soc_dapm_switch] = 5,
38357ab2 97 [snd_soc_dapm_mixer_named_ctl] = 5,
e3d4dabd
MB
98 [snd_soc_dapm_mixer] = 5,
99 [snd_soc_dapm_dac] = 6,
100 [snd_soc_dapm_mic] = 7,
101 [snd_soc_dapm_micbias] = 8,
102 [snd_soc_dapm_mux] = 9,
010ff262
MB
103 [snd_soc_dapm_aif_in] = 10,
104 [snd_soc_dapm_aif_out] = 10,
4616274d
MB
105 [snd_soc_dapm_dai_in] = 10,
106 [snd_soc_dapm_dai_out] = 10,
c74184ed 107 [snd_soc_dapm_dai_link] = 11,
c74184ed 108 [snd_soc_dapm_supply] = 12,
1dd275b6
MB
109 [snd_soc_dapm_clock_supply] = 13,
110 [snd_soc_dapm_regulator_supply] = 13,
111 [snd_soc_dapm_post] = 14,
2b97eabc
RP
112};
113
f9fa2b18
MB
114static void dapm_assert_locked(struct snd_soc_dapm_context *dapm)
115{
116 if (dapm->card && dapm->card->instantiated)
117 lockdep_assert_held(&dapm->card->dapm_mutex);
118}
119
12ef193d 120static void pop_wait(u32 pop_time)
15e4c72f
MB
121{
122 if (pop_time)
123 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
124}
125
fd8d3bc0 126static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...)
15e4c72f
MB
127{
128 va_list args;
fd8d3bc0 129 char *buf;
15e4c72f 130
fd8d3bc0
JN
131 if (!pop_time)
132 return;
15e4c72f 133
fd8d3bc0
JN
134 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
135 if (buf == NULL)
136 return;
15e4c72f 137
fd8d3bc0
JN
138 va_start(args, fmt);
139 vsnprintf(buf, PAGE_SIZE, fmt, args);
9d01df06 140 dev_info(dev, "%s", buf);
15e4c72f 141 va_end(args);
fd8d3bc0
JN
142
143 kfree(buf);
15e4c72f
MB
144}
145
db432b41
MB
146static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w)
147{
148 return !list_empty(&w->dirty);
149}
150
492c0a18 151static void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason)
db432b41 152{
f9fa2b18
MB
153 dapm_assert_locked(w->dapm);
154
75c1f891
MB
155 if (!dapm_dirty_widget(w)) {
156 dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n",
157 w->name, reason);
db432b41 158 list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty);
75c1f891 159 }
db432b41
MB
160}
161
e2d32ff6
MB
162void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm)
163{
164 struct snd_soc_card *card = dapm->card;
165 struct snd_soc_dapm_widget *w;
166
167 mutex_lock(&card->dapm_mutex);
168
169 list_for_each_entry(w, &card->widgets, list) {
170 switch (w->id) {
171 case snd_soc_dapm_input:
172 case snd_soc_dapm_output:
173 dapm_mark_dirty(w, "Rechecking inputs and outputs");
174 break;
175 default:
176 break;
177 }
178 }
179
180 mutex_unlock(&card->dapm_mutex);
181}
182EXPORT_SYMBOL_GPL(dapm_mark_io_dirty);
183
2b97eabc 184/* create a new dapm widget */
88cb4290 185static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
2b97eabc
RP
186 const struct snd_soc_dapm_widget *_widget)
187{
88cb4290 188 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
2b97eabc
RP
189}
190
e84357f7 191struct dapm_kcontrol_data {
cf7c1de2 192 unsigned int value;
57295073 193 struct snd_soc_dapm_widget *widget;
5106b92f 194 struct list_head paths;
2c75bdf3 195 struct snd_soc_dapm_widget_list *wlist;
e84357f7
LPC
196};
197
198static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
199 struct snd_kcontrol *kcontrol)
200{
201 struct dapm_kcontrol_data *data;
57295073 202 struct soc_mixer_control *mc;
e84357f7 203
2c75bdf3 204 data = kzalloc(sizeof(*data), GFP_KERNEL);
e84357f7
LPC
205 if (!data) {
206 dev_err(widget->dapm->dev,
207 "ASoC: can't allocate kcontrol data for %s\n",
208 widget->name);
209 return -ENOMEM;
210 }
211
5106b92f 212 INIT_LIST_HEAD(&data->paths);
e84357f7 213
57295073
LPC
214 switch (widget->id) {
215 case snd_soc_dapm_switch:
216 case snd_soc_dapm_mixer:
217 case snd_soc_dapm_mixer_named_ctl:
218 mc = (struct soc_mixer_control *)kcontrol->private_value;
219
220 if (mc->autodisable) {
221 struct snd_soc_dapm_widget template;
222
223 memset(&template, 0, sizeof(template));
224 template.reg = mc->reg;
225 template.mask = (1 << fls(mc->max)) - 1;
226 template.shift = mc->shift;
227 if (mc->invert)
228 template.off_val = mc->max;
229 else
230 template.off_val = 0;
231 template.on_val = template.off_val;
232 template.id = snd_soc_dapm_kcontrol;
233 template.name = kcontrol->id.name;
234
2daabd78
LPC
235 data->value = template.on_val;
236
57295073
LPC
237 data->widget = snd_soc_dapm_new_control(widget->dapm,
238 &template);
239 if (!data->widget) {
240 kfree(data);
241 return -ENOMEM;
242 }
243 }
244 break;
245 default:
246 break;
247 }
248
e84357f7
LPC
249 kcontrol->private_data = data;
250
251 return 0;
252}
253
254static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
255{
256 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl);
2c75bdf3 257 kfree(data->wlist);
e84357f7
LPC
258 kfree(data);
259}
260
261static struct snd_soc_dapm_widget_list *dapm_kcontrol_get_wlist(
262 const struct snd_kcontrol *kcontrol)
263{
264 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
265
2c75bdf3 266 return data->wlist;
e84357f7
LPC
267}
268
269static int dapm_kcontrol_add_widget(struct snd_kcontrol *kcontrol,
270 struct snd_soc_dapm_widget *widget)
271{
272 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
2c75bdf3
LPC
273 struct snd_soc_dapm_widget_list *new_wlist;
274 unsigned int n;
e84357f7 275
2c75bdf3
LPC
276 if (data->wlist)
277 n = data->wlist->num_widgets + 1;
278 else
279 n = 1;
280
281 new_wlist = krealloc(data->wlist,
282 sizeof(*new_wlist) + sizeof(widget) * n, GFP_KERNEL);
283 if (!new_wlist)
e84357f7
LPC
284 return -ENOMEM;
285
2c75bdf3
LPC
286 new_wlist->widgets[n - 1] = widget;
287 new_wlist->num_widgets = n;
e84357f7 288
2c75bdf3 289 data->wlist = new_wlist;
e84357f7
LPC
290
291 return 0;
292}
293
5106b92f
LPC
294static void dapm_kcontrol_add_path(const struct snd_kcontrol *kcontrol,
295 struct snd_soc_dapm_path *path)
296{
297 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
298
299 list_add_tail(&path->list_kcontrol, &data->paths);
57295073
LPC
300
301 if (data->widget) {
302 snd_soc_dapm_add_path(data->widget->dapm, data->widget,
303 path->source, NULL, NULL);
304 }
305}
306
307static bool dapm_kcontrol_is_powered(const struct snd_kcontrol *kcontrol)
308{
309 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
310
311 if (!data->widget)
312 return true;
313
314 return data->widget->power;
5106b92f
LPC
315}
316
317static struct list_head *dapm_kcontrol_get_path_list(
318 const struct snd_kcontrol *kcontrol)
319{
320 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
321
322 return &data->paths;
323}
324
325#define dapm_kcontrol_for_each_path(path, kcontrol) \
326 list_for_each_entry(path, dapm_kcontrol_get_path_list(kcontrol), \
327 list_kcontrol)
328
cf7c1de2
LPC
329static unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol)
330{
331 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
332
333 return data->value;
334}
335
336static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
337 unsigned int value)
338{
339 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
340
341 if (data->value == value)
342 return false;
343
57295073
LPC
344 if (data->widget)
345 data->widget->on_val = value;
346
cf7c1de2
LPC
347 data->value = value;
348
349 return true;
350}
351
eee5d7f9
LPC
352/**
353 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
354 * @kcontrol: The kcontrol
355 */
356struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol)
357{
e84357f7 358 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->codec;
eee5d7f9
LPC
359}
360EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_codec);
361
6c120e19
LG
362static void dapm_reset(struct snd_soc_card *card)
363{
364 struct snd_soc_dapm_widget *w;
365
f9fa2b18
MB
366 lockdep_assert_held(&card->dapm_mutex);
367
6c120e19
LG
368 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
369
370 list_for_each_entry(w, &card->widgets, list) {
39eb5fd1 371 w->new_power = w->power;
6c120e19
LG
372 w->power_checked = false;
373 w->inputs = -1;
374 w->outputs = -1;
375 }
376}
377
94f99c87
LPC
378static const char *soc_dapm_prefix(struct snd_soc_dapm_context *dapm)
379{
380 if (!dapm->component)
381 return NULL;
382 return dapm->component->name_prefix;
383}
384
f7d3c170
ASL
385static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg,
386 unsigned int *value)
0445bdf4 387{
e2c330b9
LPC
388 if (!w->dapm->component)
389 return -EIO;
390 return snd_soc_component_read(w->dapm->component, reg, value);
49575fb5
LG
391}
392
23d5442b 393static int soc_widget_update_bits(struct snd_soc_dapm_widget *w,
e2c330b9 394 int reg, unsigned int mask, unsigned int value)
49575fb5 395{
e2c330b9
LPC
396 if (!w->dapm->component)
397 return -EIO;
398 return snd_soc_component_update_bits_async(w->dapm->component, reg,
399 mask, value);
49575fb5
LG
400}
401
eb270e98
MB
402static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm)
403{
e2c330b9
LPC
404 if (dapm->component)
405 snd_soc_component_async_complete(dapm->component);
0445bdf4
LG
406}
407
452c5eaa
MB
408/**
409 * snd_soc_dapm_set_bias_level - set the bias level for the system
ed5a4c47 410 * @dapm: DAPM context
452c5eaa
MB
411 * @level: level to configure
412 *
413 * Configure the bias (power) levels for the SoC audio device.
414 *
415 * Returns 0 for success else error.
416 */
ed5a4c47 417static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
ce6120cc 418 enum snd_soc_bias_level level)
452c5eaa 419{
ed5a4c47 420 struct snd_soc_card *card = dapm->card;
452c5eaa
MB
421 int ret = 0;
422
84e90930
MB
423 trace_snd_soc_bias_level_start(card, level);
424
f0fba2ad 425 if (card && card->set_bias_level)
d4c6005f 426 ret = card->set_bias_level(card, dapm, level);
171ec6b0
MB
427 if (ret != 0)
428 goto out;
429
cc4c670a
MB
430 if (dapm->codec) {
431 if (dapm->codec->driver->set_bias_level)
432 ret = dapm->codec->driver->set_bias_level(dapm->codec,
433 level);
d8c3bb91
MB
434 else
435 dapm->bias_level = level;
4e872a46 436 } else if (!card || dapm != &card->dapm) {
4123128e 437 dapm->bias_level = level;
4e872a46 438 }
4123128e 439
171ec6b0
MB
440 if (ret != 0)
441 goto out;
442
443 if (card && card->set_bias_level_post)
d4c6005f 444 ret = card->set_bias_level_post(card, dapm, level);
171ec6b0 445out:
84e90930
MB
446 trace_snd_soc_bias_level_done(card, level);
447
452c5eaa
MB
448 return ret;
449}
450
74b8f955 451/* connect mux widget to its interconnecting audio paths */
ce6120cc 452static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
2b97eabc
RP
453 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
454 struct snd_soc_dapm_path *path, const char *control_name,
455 const struct snd_kcontrol_new *kcontrol)
2b97eabc 456{
2b97eabc 457 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
234c0b8f 458 unsigned int val, item;
2b97eabc 459 int i;
24ff33ac 460
234c0b8f
LPC
461 if (e->reg != SND_SOC_NOPM) {
462 soc_widget_read(dest, e->reg, &val);
463 val = (val >> e->shift_l) & e->mask;
464 item = snd_soc_enum_val_to_item(e, val);
465 } else {
24ff33ac
DP
466 /* since a virtual mux has no backing registers to
467 * decide which path to connect, it will try to match
468 * with the first enumeration. This is to ensure
469 * that the default mux choice (the first) will be
470 * correctly powered up during initialization.
471 */
234c0b8f 472 item = 0;
24ff33ac 473 }
2e72f8e3 474
9a8d38db 475 for (i = 0; i < e->items; i++) {
2b97eabc 476 if (!(strcmp(control_name, e->texts[i]))) {
8ddab3f5 477 list_add(&path->list, &dapm->card->paths);
2b97eabc
RP
478 list_add(&path->list_sink, &dest->sources);
479 list_add(&path->list_source, &src->sinks);
480 path->name = (char*)e->texts[i];
234c0b8f
LPC
481 if (i == item)
482 path->connect = 1;
483 else
484 path->connect = 0;
2b97eabc
RP
485 return 0;
486 }
487 }
488
489 return -ENODEV;
490}
491
234c0b8f
LPC
492/* set up initial codec paths */
493static void dapm_set_mixer_path_status(struct snd_soc_dapm_widget *w,
494 struct snd_soc_dapm_path *p, int i)
495{
496 struct soc_mixer_control *mc = (struct soc_mixer_control *)
497 w->kcontrol_news[i].private_value;
498 unsigned int reg = mc->reg;
499 unsigned int shift = mc->shift;
500 unsigned int max = mc->max;
501 unsigned int mask = (1 << fls(max)) - 1;
502 unsigned int invert = mc->invert;
503 unsigned int val;
504
505 if (reg != SND_SOC_NOPM) {
506 soc_widget_read(w, reg, &val);
507 val = (val >> shift) & mask;
508 if (invert)
509 val = max - val;
510 p->connect = !!val;
511 } else {
512 p->connect = 0;
513 }
514}
515
74b8f955 516/* connect mixer widget to its interconnecting audio paths */
ce6120cc 517static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
2b97eabc
RP
518 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
519 struct snd_soc_dapm_path *path, const char *control_name)
520{
521 int i;
522
523 /* search for mixer kcontrol */
524 for (i = 0; i < dest->num_kcontrols; i++) {
82cfecdc 525 if (!strcmp(control_name, dest->kcontrol_news[i].name)) {
8ddab3f5 526 list_add(&path->list, &dapm->card->paths);
2b97eabc
RP
527 list_add(&path->list_sink, &dest->sources);
528 list_add(&path->list_source, &src->sinks);
82cfecdc 529 path->name = dest->kcontrol_news[i].name;
234c0b8f 530 dapm_set_mixer_path_status(dest, path, i);
2b97eabc
RP
531 return 0;
532 }
533 }
534 return -ENODEV;
535}
536
af46800b 537static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
1007da06 538 struct snd_soc_dapm_widget *kcontrolw,
af46800b
SW
539 const struct snd_kcontrol_new *kcontrol_new,
540 struct snd_kcontrol **kcontrol)
541{
542 struct snd_soc_dapm_widget *w;
543 int i;
544
545 *kcontrol = NULL;
546
547 list_for_each_entry(w, &dapm->card->widgets, list) {
1007da06
SW
548 if (w == kcontrolw || w->dapm != kcontrolw->dapm)
549 continue;
af46800b
SW
550 for (i = 0; i < w->num_kcontrols; i++) {
551 if (&w->kcontrol_news[i] == kcontrol_new) {
552 if (w->kcontrols)
553 *kcontrol = w->kcontrols[i];
554 return 1;
555 }
556 }
557 }
558
559 return 0;
560}
561
85762e71
SW
562/*
563 * Determine if a kcontrol is shared. If it is, look it up. If it isn't,
564 * create it. Either way, add the widget into the control's widget list
565 */
566static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
946d92a1 567 int kci)
2b97eabc 568{
4b80b8c2 569 struct snd_soc_dapm_context *dapm = w->dapm;
12ea2c78 570 struct snd_card *card = dapm->card->snd_card;
efb7ac3f 571 const char *prefix;
85762e71
SW
572 size_t prefix_len;
573 int shared;
574 struct snd_kcontrol *kcontrol;
85762e71 575 bool wname_in_long_name, kcname_in_long_name;
85762e71
SW
576 char *long_name;
577 const char *name;
578 int ret;
efb7ac3f 579
94f99c87 580 prefix = soc_dapm_prefix(dapm);
3e5ff4df
MB
581 if (prefix)
582 prefix_len = strlen(prefix) + 1;
583 else
584 prefix_len = 0;
585
85762e71
SW
586 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci],
587 &kcontrol);
2b97eabc 588
85762e71
SW
589 if (!kcontrol) {
590 if (shared) {
591 wname_in_long_name = false;
592 kcname_in_long_name = true;
593 } else {
594 switch (w->id) {
595 case snd_soc_dapm_switch:
596 case snd_soc_dapm_mixer:
597 wname_in_long_name = true;
598 kcname_in_long_name = true;
599 break;
600 case snd_soc_dapm_mixer_named_ctl:
601 wname_in_long_name = false;
602 kcname_in_long_name = true;
603 break;
604 case snd_soc_dapm_mux:
85762e71
SW
605 wname_in_long_name = true;
606 kcname_in_long_name = false;
607 break;
608 default:
85762e71 609 return -EINVAL;
82cd8764 610 }
85762e71
SW
611 }
612
613 if (wname_in_long_name && kcname_in_long_name) {
85762e71
SW
614 /*
615 * The control will get a prefix from the control
616 * creation process but we're also using the same
617 * prefix for widgets so cut the prefix off the
618 * front of the widget name.
ca9c1aae 619 */
2b581074 620 long_name = kasprintf(GFP_KERNEL, "%s %s",
85762e71
SW
621 w->name + prefix_len,
622 w->kcontrol_news[kci].name);
e84357f7 623 if (long_name == NULL)
2b581074 624 return -ENOMEM;
85762e71
SW
625
626 name = long_name;
627 } else if (wname_in_long_name) {
628 long_name = NULL;
629 name = w->name + prefix_len;
630 } else {
631 long_name = NULL;
632 name = w->kcontrol_news[kci].name;
633 }
ca9c1aae 634
e84357f7 635 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], NULL, name,
85762e71 636 prefix);
656ca9d3 637 kfree(long_name);
9356e9d5
LPC
638 if (!kcontrol)
639 return -ENOMEM;
640 kcontrol->private_free = dapm_kcontrol_free;
e84357f7
LPC
641
642 ret = dapm_kcontrol_data_alloc(w, kcontrol);
643 if (ret) {
644 snd_ctl_free_one(kcontrol);
645 return ret;
646 }
647
85762e71
SW
648 ret = snd_ctl_add(card, kcontrol);
649 if (ret < 0) {
650 dev_err(dapm->dev,
651 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n",
652 w->name, name, ret);
85762e71
SW
653 return ret;
654 }
85762e71 655 }
2b97eabc 656
2c75bdf3
LPC
657 ret = dapm_kcontrol_add_widget(kcontrol, w);
658 if (ret)
659 return ret;
660
85762e71 661 w->kcontrols[kci] = kcontrol;
ca9c1aae 662
85762e71
SW
663 return 0;
664}
219b93f5 665
85762e71
SW
666/* create new dapm mixer control */
667static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
668{
669 int i, ret;
670 struct snd_soc_dapm_path *path;
671
672 /* add kcontrol */
673 for (i = 0; i < w->num_kcontrols; i++) {
674 /* match name */
675 list_for_each_entry(path, &w->sources, list_sink) {
676 /* mixer/mux paths name must match control name */
677 if (path->name != (char *)w->kcontrol_news[i].name)
678 continue;
679
680 if (w->kcontrols[i]) {
5106b92f 681 dapm_kcontrol_add_path(w->kcontrols[i], path);
85762e71 682 continue;
2b97eabc 683 }
85762e71 684
946d92a1 685 ret = dapm_create_or_share_mixmux_kcontrol(w, i);
85762e71
SW
686 if (ret < 0)
687 return ret;
946d92a1
MB
688
689 dapm_kcontrol_add_path(w->kcontrols[i], path);
2b97eabc
RP
690 }
691 }
85762e71
SW
692
693 return 0;
2b97eabc
RP
694}
695
696/* create new dapm mux control */
4b80b8c2 697static int dapm_new_mux(struct snd_soc_dapm_widget *w)
2b97eabc 698{
4b80b8c2 699 struct snd_soc_dapm_context *dapm = w->dapm;
85762e71 700 struct snd_soc_dapm_path *path;
af46800b 701 int ret;
2b97eabc 702
af46800b
SW
703 if (w->num_kcontrols != 1) {
704 dev_err(dapm->dev,
30a6a1a4 705 "ASoC: mux %s has incorrect number of controls\n",
af46800b 706 w->name);
2b97eabc
RP
707 return -EINVAL;
708 }
709
fe581391 710 if (list_empty(&w->sources)) {
85762e71
SW
711 dev_err(dapm->dev, "ASoC: mux %s has no paths\n", w->name);
712 return -EINVAL;
af46800b 713 }
ce6120cc 714
946d92a1 715 ret = dapm_create_or_share_mixmux_kcontrol(w, 0);
85762e71
SW
716 if (ret < 0)
717 return ret;
fad59888 718
2b97eabc 719 list_for_each_entry(path, &w->sources, list_sink)
5106b92f 720 dapm_kcontrol_add_path(w->kcontrols[0], path);
2b97eabc 721
af46800b 722 return 0;
2b97eabc
RP
723}
724
725/* create new dapm volume control */
4b80b8c2 726static int dapm_new_pga(struct snd_soc_dapm_widget *w)
2b97eabc 727{
a6c65736 728 if (w->num_kcontrols)
f7d41ae8 729 dev_err(w->dapm->dev,
30a6a1a4 730 "ASoC: PGA controls not supported: '%s'\n", w->name);
2b97eabc 731
a6c65736 732 return 0;
2b97eabc
RP
733}
734
735/* reset 'walked' bit for each dapm path */
1059ecfa
RT
736static void dapm_clear_walk_output(struct snd_soc_dapm_context *dapm,
737 struct list_head *sink)
2b97eabc
RP
738{
739 struct snd_soc_dapm_path *p;
740
1059ecfa
RT
741 list_for_each_entry(p, sink, list_source) {
742 if (p->walked) {
743 p->walked = 0;
744 dapm_clear_walk_output(dapm, &p->sink->sinks);
745 }
746 }
2b97eabc
RP
747}
748
1059ecfa
RT
749static void dapm_clear_walk_input(struct snd_soc_dapm_context *dapm,
750 struct list_head *source)
2b97eabc
RP
751{
752 struct snd_soc_dapm_path *p;
753
1059ecfa
RT
754 list_for_each_entry(p, source, list_sink) {
755 if (p->walked) {
756 p->walked = 0;
757 dapm_clear_walk_input(dapm, &p->source->sources);
758 }
759 }
2b97eabc
RP
760}
761
1059ecfa 762
9949788b
MB
763/* We implement power down on suspend by checking the power state of
764 * the ALSA card - when we are suspending the ALSA state for the card
765 * is set to D3.
766 */
767static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
768{
12ea2c78 769 int level = snd_power_get_state(widget->dapm->card->snd_card);
9949788b 770
f0fba2ad 771 switch (level) {
9949788b
MB
772 case SNDRV_CTL_POWER_D3hot:
773 case SNDRV_CTL_POWER_D3cold:
1547aba9 774 if (widget->ignore_suspend)
30a6a1a4 775 dev_dbg(widget->dapm->dev, "ASoC: %s ignoring suspend\n",
f7d41ae8 776 widget->name);
1547aba9 777 return widget->ignore_suspend;
9949788b
MB
778 default:
779 return 1;
780 }
781}
782
ec2e3031
LG
783/* add widget to list if it's not already in the list */
784static int dapm_list_add_widget(struct snd_soc_dapm_widget_list **list,
785 struct snd_soc_dapm_widget *w)
786{
787 struct snd_soc_dapm_widget_list *wlist;
788 int wlistsize, wlistentries, i;
789
790 if (*list == NULL)
791 return -EINVAL;
792
793 wlist = *list;
794
795 /* is this widget already in the list */
796 for (i = 0; i < wlist->num_widgets; i++) {
797 if (wlist->widgets[i] == w)
798 return 0;
799 }
800
801 /* allocate some new space */
802 wlistentries = wlist->num_widgets + 1;
803 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
804 wlistentries * sizeof(struct snd_soc_dapm_widget *);
805 *list = krealloc(wlist, wlistsize, GFP_KERNEL);
806 if (*list == NULL) {
30a6a1a4 807 dev_err(w->dapm->dev, "ASoC: can't allocate widget list for %s\n",
ec2e3031
LG
808 w->name);
809 return -ENOMEM;
810 }
811 wlist = *list;
812
813 /* insert the widget */
30a6a1a4 814 dev_dbg(w->dapm->dev, "ASoC: added %s in widget list pos %d\n",
ec2e3031
LG
815 w->name, wlist->num_widgets);
816
817 wlist->widgets[wlist->num_widgets] = w;
818 wlist->num_widgets++;
819 return 1;
820}
821
2b97eabc
RP
822/*
823 * Recursively check for a completed path to an active or physically connected
824 * output widget. Returns number of complete paths.
825 */
ec2e3031
LG
826static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
827 struct snd_soc_dapm_widget_list **list)
2b97eabc
RP
828{
829 struct snd_soc_dapm_path *path;
830 int con = 0;
831
024dc078
MB
832 if (widget->outputs >= 0)
833 return widget->outputs;
834
de02d078
MB
835 DAPM_UPDATE_STAT(widget, path_checks);
836
62ea874a
MB
837 switch (widget->id) {
838 case snd_soc_dapm_supply:
839 case snd_soc_dapm_regulator_supply:
d7e7eb91 840 case snd_soc_dapm_clock_supply:
57295073 841 case snd_soc_dapm_kcontrol:
246d0a17 842 return 0;
62ea874a
MB
843 default:
844 break;
845 }
246d0a17 846
010ff262
MB
847 switch (widget->id) {
848 case snd_soc_dapm_adc:
849 case snd_soc_dapm_aif_out:
4616274d 850 case snd_soc_dapm_dai_out:
024dc078
MB
851 if (widget->active) {
852 widget->outputs = snd_soc_dapm_suspend_check(widget);
853 return widget->outputs;
854 }
010ff262
MB
855 default:
856 break;
857 }
2b97eabc
RP
858
859 if (widget->connected) {
860 /* connected pin ? */
024dc078
MB
861 if (widget->id == snd_soc_dapm_output && !widget->ext) {
862 widget->outputs = snd_soc_dapm_suspend_check(widget);
863 return widget->outputs;
864 }
2b97eabc
RP
865
866 /* connected jack or spk ? */
024dc078
MB
867 if (widget->id == snd_soc_dapm_hp ||
868 widget->id == snd_soc_dapm_spk ||
869 (widget->id == snd_soc_dapm_line &&
870 !list_empty(&widget->sources))) {
871 widget->outputs = snd_soc_dapm_suspend_check(widget);
872 return widget->outputs;
873 }
2b97eabc
RP
874 }
875
876 list_for_each_entry(path, &widget->sinks, list_source) {
e56235e0
MB
877 DAPM_UPDATE_STAT(widget, neighbour_checks);
878
bf3a9e13
MB
879 if (path->weak)
880 continue;
881
8af294b4
MB
882 if (path->walking)
883 return 1;
884
2b97eabc
RP
885 if (path->walked)
886 continue;
887
ec2e3031
LG
888 trace_snd_soc_dapm_output_path(widget, path);
889
2b97eabc
RP
890 if (path->sink && path->connect) {
891 path->walked = 1;
8af294b4 892 path->walking = 1;
ec2e3031
LG
893
894 /* do we need to add this widget to the list ? */
895 if (list) {
896 int err;
897 err = dapm_list_add_widget(list, path->sink);
898 if (err < 0) {
30a6a1a4
LG
899 dev_err(widget->dapm->dev,
900 "ASoC: could not add widget %s\n",
ec2e3031 901 widget->name);
8af294b4 902 path->walking = 0;
ec2e3031
LG
903 return con;
904 }
905 }
906
907 con += is_connected_output_ep(path->sink, list);
8af294b4
MB
908
909 path->walking = 0;
2b97eabc
RP
910 }
911 }
912
024dc078
MB
913 widget->outputs = con;
914
2b97eabc
RP
915 return con;
916}
917
918/*
919 * Recursively check for a completed path to an active or physically connected
920 * input widget. Returns number of complete paths.
921 */
ec2e3031
LG
922static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
923 struct snd_soc_dapm_widget_list **list)
2b97eabc
RP
924{
925 struct snd_soc_dapm_path *path;
926 int con = 0;
927
024dc078
MB
928 if (widget->inputs >= 0)
929 return widget->inputs;
930
de02d078
MB
931 DAPM_UPDATE_STAT(widget, path_checks);
932
62ea874a
MB
933 switch (widget->id) {
934 case snd_soc_dapm_supply:
935 case snd_soc_dapm_regulator_supply:
d7e7eb91 936 case snd_soc_dapm_clock_supply:
57295073 937 case snd_soc_dapm_kcontrol:
246d0a17 938 return 0;
62ea874a
MB
939 default:
940 break;
941 }
246d0a17 942
2b97eabc 943 /* active stream ? */
010ff262
MB
944 switch (widget->id) {
945 case snd_soc_dapm_dac:
946 case snd_soc_dapm_aif_in:
4616274d 947 case snd_soc_dapm_dai_in:
024dc078
MB
948 if (widget->active) {
949 widget->inputs = snd_soc_dapm_suspend_check(widget);
950 return widget->inputs;
951 }
010ff262
MB
952 default:
953 break;
954 }
2b97eabc
RP
955
956 if (widget->connected) {
957 /* connected pin ? */
024dc078
MB
958 if (widget->id == snd_soc_dapm_input && !widget->ext) {
959 widget->inputs = snd_soc_dapm_suspend_check(widget);
960 return widget->inputs;
961 }
2b97eabc
RP
962
963 /* connected VMID/Bias for lower pops */
024dc078
MB
964 if (widget->id == snd_soc_dapm_vmid) {
965 widget->inputs = snd_soc_dapm_suspend_check(widget);
966 return widget->inputs;
967 }
2b97eabc
RP
968
969 /* connected jack ? */
eaeae5d9 970 if (widget->id == snd_soc_dapm_mic ||
024dc078
MB
971 (widget->id == snd_soc_dapm_line &&
972 !list_empty(&widget->sinks))) {
973 widget->inputs = snd_soc_dapm_suspend_check(widget);
974 return widget->inputs;
975 }
976
1ab97c8c
MB
977 /* signal generator */
978 if (widget->id == snd_soc_dapm_siggen) {
979 widget->inputs = snd_soc_dapm_suspend_check(widget);
980 return widget->inputs;
981 }
2b97eabc
RP
982 }
983
984 list_for_each_entry(path, &widget->sources, list_sink) {
e56235e0
MB
985 DAPM_UPDATE_STAT(widget, neighbour_checks);
986
bf3a9e13
MB
987 if (path->weak)
988 continue;
989
8af294b4
MB
990 if (path->walking)
991 return 1;
992
2b97eabc
RP
993 if (path->walked)
994 continue;
995
ec2e3031
LG
996 trace_snd_soc_dapm_input_path(widget, path);
997
2b97eabc
RP
998 if (path->source && path->connect) {
999 path->walked = 1;
8af294b4 1000 path->walking = 1;
ec2e3031
LG
1001
1002 /* do we need to add this widget to the list ? */
1003 if (list) {
1004 int err;
90c6ce0d 1005 err = dapm_list_add_widget(list, path->source);
ec2e3031 1006 if (err < 0) {
30a6a1a4
LG
1007 dev_err(widget->dapm->dev,
1008 "ASoC: could not add widget %s\n",
ec2e3031 1009 widget->name);
8af294b4 1010 path->walking = 0;
ec2e3031
LG
1011 return con;
1012 }
1013 }
1014
1015 con += is_connected_input_ep(path->source, list);
8af294b4
MB
1016
1017 path->walking = 0;
2b97eabc
RP
1018 }
1019 }
1020
024dc078
MB
1021 widget->inputs = con;
1022
2b97eabc
RP
1023 return con;
1024}
1025
ec2e3031
LG
1026/**
1027 * snd_soc_dapm_get_connected_widgets - query audio path and it's widgets.
1028 * @dai: the soc DAI.
1029 * @stream: stream direction.
1030 * @list: list of active widgets for this stream.
1031 *
1032 * Queries DAPM graph as to whether an valid audio stream path exists for
1033 * the initial stream specified by name. This takes into account
1034 * current mixer and mux kcontrol settings. Creates list of valid widgets.
1035 *
1036 * Returns the number of valid paths or negative error.
1037 */
1038int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
1039 struct snd_soc_dapm_widget_list **list)
1040{
1041 struct snd_soc_card *card = dai->card;
1042 int paths;
1043
1044 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1045 dapm_reset(card);
1046
1059ecfa 1047 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
ec2e3031 1048 paths = is_connected_output_ep(dai->playback_widget, list);
1059ecfa
RT
1049 dapm_clear_walk_output(&card->dapm,
1050 &dai->playback_widget->sinks);
1051 } else {
d298caae 1052 paths = is_connected_input_ep(dai->capture_widget, list);
1059ecfa
RT
1053 dapm_clear_walk_input(&card->dapm,
1054 &dai->capture_widget->sources);
1055 }
ec2e3031
LG
1056
1057 trace_snd_soc_dapm_connected(paths, stream);
ec2e3031
LG
1058 mutex_unlock(&card->dapm_mutex);
1059
1060 return paths;
1061}
1062
62ea874a
MB
1063/*
1064 * Handler for regulator supply widget.
1065 */
1066int dapm_regulator_event(struct snd_soc_dapm_widget *w,
1067 struct snd_kcontrol *kcontrol, int event)
1068{
c05b84d1
MB
1069 int ret;
1070
eb270e98
MB
1071 soc_dapm_async_complete(w->dapm);
1072
c05b84d1 1073 if (SND_SOC_DAPM_EVENT_ON(event)) {
de9ba98b 1074 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
8784c77a 1075 ret = regulator_allow_bypass(w->regulator, false);
c05b84d1
MB
1076 if (ret != 0)
1077 dev_warn(w->dapm->dev,
30686c35 1078 "ASoC: Failed to unbypass %s: %d\n",
c05b84d1
MB
1079 w->name, ret);
1080 }
1081
a3cc056b 1082 return regulator_enable(w->regulator);
c05b84d1 1083 } else {
de9ba98b 1084 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
8784c77a 1085 ret = regulator_allow_bypass(w->regulator, true);
c05b84d1
MB
1086 if (ret != 0)
1087 dev_warn(w->dapm->dev,
30686c35 1088 "ASoC: Failed to bypass %s: %d\n",
c05b84d1
MB
1089 w->name, ret);
1090 }
1091
a3cc056b 1092 return regulator_disable_deferred(w->regulator, w->shift);
c05b84d1 1093 }
62ea874a
MB
1094}
1095EXPORT_SYMBOL_GPL(dapm_regulator_event);
1096
d7e7eb91
OL
1097/*
1098 * Handler for clock supply widget.
1099 */
1100int dapm_clock_event(struct snd_soc_dapm_widget *w,
1101 struct snd_kcontrol *kcontrol, int event)
1102{
1103 if (!w->clk)
1104 return -EIO;
1105
eb270e98
MB
1106 soc_dapm_async_complete(w->dapm);
1107
ec02995a 1108#ifdef CONFIG_HAVE_CLK
d7e7eb91 1109 if (SND_SOC_DAPM_EVENT_ON(event)) {
37c1b927 1110 return clk_prepare_enable(w->clk);
d7e7eb91 1111 } else {
37c1b927 1112 clk_disable_unprepare(w->clk);
d7e7eb91
OL
1113 return 0;
1114 }
ec02995a 1115#endif
98b3cf12 1116 return 0;
d7e7eb91
OL
1117}
1118EXPORT_SYMBOL_GPL(dapm_clock_event);
1119
d805002b
MB
1120static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
1121{
9b8a83b2
MB
1122 if (w->power_checked)
1123 return w->new_power;
1124
d805002b 1125 if (w->force)
9b8a83b2 1126 w->new_power = 1;
d805002b 1127 else
9b8a83b2
MB
1128 w->new_power = w->power_check(w);
1129
1130 w->power_checked = true;
1131
1132 return w->new_power;
d805002b
MB
1133}
1134
cd0f2d47
MB
1135/* Generic check to see if a widget should be powered.
1136 */
1137static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
1138{
1139 int in, out;
1140
de02d078
MB
1141 DAPM_UPDATE_STAT(w, power_checks);
1142
ec2e3031 1143 in = is_connected_input_ep(w, NULL);
1059ecfa 1144 dapm_clear_walk_input(w->dapm, &w->sources);
ec2e3031 1145 out = is_connected_output_ep(w, NULL);
1059ecfa 1146 dapm_clear_walk_output(w->dapm, &w->sinks);
cd0f2d47
MB
1147 return out != 0 && in != 0;
1148}
1149
6ea31b9f
MB
1150/* Check to see if an ADC has power */
1151static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
1152{
1153 int in;
1154
de02d078
MB
1155 DAPM_UPDATE_STAT(w, power_checks);
1156
6ea31b9f 1157 if (w->active) {
ec2e3031 1158 in = is_connected_input_ep(w, NULL);
1059ecfa 1159 dapm_clear_walk_input(w->dapm, &w->sources);
6ea31b9f
MB
1160 return in != 0;
1161 } else {
1162 return dapm_generic_check_power(w);
1163 }
1164}
1165
1166/* Check to see if a DAC has power */
1167static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
1168{
1169 int out;
1170
de02d078
MB
1171 DAPM_UPDATE_STAT(w, power_checks);
1172
6ea31b9f 1173 if (w->active) {
ec2e3031 1174 out = is_connected_output_ep(w, NULL);
1059ecfa 1175 dapm_clear_walk_output(w->dapm, &w->sinks);
6ea31b9f
MB
1176 return out != 0;
1177 } else {
1178 return dapm_generic_check_power(w);
1179 }
1180}
1181
246d0a17
MB
1182/* Check to see if a power supply is needed */
1183static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
1184{
1185 struct snd_soc_dapm_path *path;
246d0a17 1186
de02d078
MB
1187 DAPM_UPDATE_STAT(w, power_checks);
1188
246d0a17
MB
1189 /* Check if one of our outputs is connected */
1190 list_for_each_entry(path, &w->sinks, list_source) {
a8fdac83
MB
1191 DAPM_UPDATE_STAT(w, neighbour_checks);
1192
bf3a9e13
MB
1193 if (path->weak)
1194 continue;
1195
215edda3
MB
1196 if (path->connected &&
1197 !path->connected(path->source, path->sink))
1198 continue;
1199
3017358a
MB
1200 if (!path->sink)
1201 continue;
1202
f68d7e16
MB
1203 if (dapm_widget_power_check(path->sink))
1204 return 1;
246d0a17
MB
1205 }
1206
f68d7e16 1207 return 0;
246d0a17
MB
1208}
1209
35c64bca
MB
1210static int dapm_always_on_check_power(struct snd_soc_dapm_widget *w)
1211{
1212 return 1;
1213}
1214
38357ab2
MB
1215static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
1216 struct snd_soc_dapm_widget *b,
828a842f 1217 bool power_up)
42aa3418 1218{
828a842f
MB
1219 int *sort;
1220
1221 if (power_up)
1222 sort = dapm_up_seq;
1223 else
1224 sort = dapm_down_seq;
1225
38357ab2
MB
1226 if (sort[a->id] != sort[b->id])
1227 return sort[a->id] - sort[b->id];
20e4859d
MB
1228 if (a->subseq != b->subseq) {
1229 if (power_up)
1230 return a->subseq - b->subseq;
1231 else
1232 return b->subseq - a->subseq;
1233 }
b22ead2a
MB
1234 if (a->reg != b->reg)
1235 return a->reg - b->reg;
84dab567
MB
1236 if (a->dapm != b->dapm)
1237 return (unsigned long)a->dapm - (unsigned long)b->dapm;
42aa3418 1238
38357ab2
MB
1239 return 0;
1240}
42aa3418 1241
38357ab2
MB
1242/* Insert a widget in order into a DAPM power sequence. */
1243static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
1244 struct list_head *list,
828a842f 1245 bool power_up)
38357ab2
MB
1246{
1247 struct snd_soc_dapm_widget *w;
1248
1249 list_for_each_entry(w, list, power_list)
828a842f 1250 if (dapm_seq_compare(new_widget, w, power_up) < 0) {
38357ab2
MB
1251 list_add_tail(&new_widget->power_list, &w->power_list);
1252 return;
1253 }
1254
1255 list_add_tail(&new_widget->power_list, list);
1256}
1257
95dd5cd6 1258static void dapm_seq_check_event(struct snd_soc_card *card,
68f89ad8
MB
1259 struct snd_soc_dapm_widget *w, int event)
1260{
68f89ad8
MB
1261 const char *ev_name;
1262 int power, ret;
1263
1264 switch (event) {
1265 case SND_SOC_DAPM_PRE_PMU:
1266 ev_name = "PRE_PMU";
1267 power = 1;
1268 break;
1269 case SND_SOC_DAPM_POST_PMU:
1270 ev_name = "POST_PMU";
1271 power = 1;
1272 break;
1273 case SND_SOC_DAPM_PRE_PMD:
1274 ev_name = "PRE_PMD";
1275 power = 0;
1276 break;
1277 case SND_SOC_DAPM_POST_PMD:
1278 ev_name = "POST_PMD";
1279 power = 0;
1280 break;
80114129
MB
1281 case SND_SOC_DAPM_WILL_PMU:
1282 ev_name = "WILL_PMU";
1283 power = 1;
1284 break;
1285 case SND_SOC_DAPM_WILL_PMD:
1286 ev_name = "WILL_PMD";
1287 power = 0;
1288 break;
68f89ad8 1289 default:
a6ed0608 1290 WARN(1, "Unknown event %d\n", event);
68f89ad8
MB
1291 return;
1292 }
1293
39eb5fd1 1294 if (w->new_power != power)
68f89ad8
MB
1295 return;
1296
1297 if (w->event && (w->event_flags & event)) {
95dd5cd6 1298 pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n",
68f89ad8 1299 w->name, ev_name);
eb270e98 1300 soc_dapm_async_complete(w->dapm);
84e90930 1301 trace_snd_soc_dapm_widget_event_start(w, event);
68f89ad8 1302 ret = w->event(w, NULL, event);
84e90930 1303 trace_snd_soc_dapm_widget_event_done(w, event);
68f89ad8 1304 if (ret < 0)
95dd5cd6 1305 dev_err(w->dapm->dev, "ASoC: %s: %s event failed: %d\n",
68f89ad8
MB
1306 ev_name, w->name, ret);
1307 }
1308}
1309
b22ead2a 1310/* Apply the coalesced changes from a DAPM sequence */
95dd5cd6 1311static void dapm_seq_run_coalesced(struct snd_soc_card *card,
b22ead2a 1312 struct list_head *pending)
163cac06 1313{
68f89ad8 1314 struct snd_soc_dapm_widget *w;
de9ba98b 1315 int reg;
b22ead2a
MB
1316 unsigned int value = 0;
1317 unsigned int mask = 0;
b22ead2a
MB
1318
1319 reg = list_first_entry(pending, struct snd_soc_dapm_widget,
1320 power_list)->reg;
1321
1322 list_for_each_entry(w, pending, power_list) {
bf4edea8 1323 WARN_ON(reg != w->reg);
39eb5fd1 1324 w->power = w->new_power;
b22ead2a 1325
de9ba98b
LPC
1326 mask |= w->mask << w->shift;
1327 if (w->power)
1328 value |= w->on_val << w->shift;
b22ead2a 1329 else
de9ba98b 1330 value |= w->off_val << w->shift;
b22ead2a 1331
95dd5cd6 1332 pop_dbg(w->dapm->dev, card->pop_time,
b22ead2a
MB
1333 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
1334 w->name, reg, value, mask);
81628103 1335
68f89ad8 1336 /* Check for events */
95dd5cd6
LPC
1337 dapm_seq_check_event(card, w, SND_SOC_DAPM_PRE_PMU);
1338 dapm_seq_check_event(card, w, SND_SOC_DAPM_PRE_PMD);
81628103
MB
1339 }
1340
1341 if (reg >= 0) {
29376bc7
MB
1342 /* Any widget will do, they should all be updating the
1343 * same register.
1344 */
1345 w = list_first_entry(pending, struct snd_soc_dapm_widget,
1346 power_list);
1347
95dd5cd6 1348 pop_dbg(w->dapm->dev, card->pop_time,
81628103 1349 "pop test : Applying 0x%x/0x%x to %x in %dms\n",
3a45b867
JN
1350 value, mask, reg, card->pop_time);
1351 pop_wait(card->pop_time);
23d5442b 1352 soc_widget_update_bits(w, reg, mask, value);
b22ead2a
MB
1353 }
1354
81628103 1355 list_for_each_entry(w, pending, power_list) {
95dd5cd6
LPC
1356 dapm_seq_check_event(card, w, SND_SOC_DAPM_POST_PMU);
1357 dapm_seq_check_event(card, w, SND_SOC_DAPM_POST_PMD);
81628103 1358 }
b22ead2a 1359}
42aa3418 1360
b22ead2a
MB
1361/* Apply a DAPM power sequence.
1362 *
1363 * We walk over a pre-sorted list of widgets to apply power to. In
1364 * order to minimise the number of writes to the device required
1365 * multiple widgets will be updated in a single write where possible.
1366 * Currently anything that requires more than a single write is not
1367 * handled.
1368 */
95dd5cd6
LPC
1369static void dapm_seq_run(struct snd_soc_card *card,
1370 struct list_head *list, int event, bool power_up)
b22ead2a
MB
1371{
1372 struct snd_soc_dapm_widget *w, *n;
eb270e98 1373 struct snd_soc_dapm_context *d;
b22ead2a
MB
1374 LIST_HEAD(pending);
1375 int cur_sort = -1;
20e4859d 1376 int cur_subseq = -1;
b22ead2a 1377 int cur_reg = SND_SOC_NOPM;
7be31be8 1378 struct snd_soc_dapm_context *cur_dapm = NULL;
474b62d6 1379 int ret, i;
828a842f
MB
1380 int *sort;
1381
1382 if (power_up)
1383 sort = dapm_up_seq;
1384 else
1385 sort = dapm_down_seq;
163cac06 1386
b22ead2a
MB
1387 list_for_each_entry_safe(w, n, list, power_list) {
1388 ret = 0;
1389
1390 /* Do we need to apply any queued changes? */
7be31be8 1391 if (sort[w->id] != cur_sort || w->reg != cur_reg ||
20e4859d 1392 w->dapm != cur_dapm || w->subseq != cur_subseq) {
b22ead2a 1393 if (!list_empty(&pending))
95dd5cd6 1394 dapm_seq_run_coalesced(card, &pending);
b22ead2a 1395
474b62d6
MB
1396 if (cur_dapm && cur_dapm->seq_notifier) {
1397 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
1398 if (sort[i] == cur_sort)
1399 cur_dapm->seq_notifier(cur_dapm,
f85a9e0d
MB
1400 i,
1401 cur_subseq);
474b62d6
MB
1402 }
1403
eb270e98
MB
1404 if (cur_dapm && w->dapm != cur_dapm)
1405 soc_dapm_async_complete(cur_dapm);
1406
b22ead2a
MB
1407 INIT_LIST_HEAD(&pending);
1408 cur_sort = -1;
b0b3e6f8 1409 cur_subseq = INT_MIN;
b22ead2a 1410 cur_reg = SND_SOC_NOPM;
7be31be8 1411 cur_dapm = NULL;
b22ead2a
MB
1412 }
1413
163cac06
MB
1414 switch (w->id) {
1415 case snd_soc_dapm_pre:
1416 if (!w->event)
b22ead2a
MB
1417 list_for_each_entry_safe_continue(w, n, list,
1418 power_list);
163cac06 1419
b22ead2a 1420 if (event == SND_SOC_DAPM_STREAM_START)
163cac06
MB
1421 ret = w->event(w,
1422 NULL, SND_SOC_DAPM_PRE_PMU);
b22ead2a 1423 else if (event == SND_SOC_DAPM_STREAM_STOP)
163cac06
MB
1424 ret = w->event(w,
1425 NULL, SND_SOC_DAPM_PRE_PMD);
163cac06
MB
1426 break;
1427
1428 case snd_soc_dapm_post:
1429 if (!w->event)
b22ead2a
MB
1430 list_for_each_entry_safe_continue(w, n, list,
1431 power_list);
163cac06 1432
b22ead2a 1433 if (event == SND_SOC_DAPM_STREAM_START)
163cac06
MB
1434 ret = w->event(w,
1435 NULL, SND_SOC_DAPM_POST_PMU);
b22ead2a 1436 else if (event == SND_SOC_DAPM_STREAM_STOP)
163cac06
MB
1437 ret = w->event(w,
1438 NULL, SND_SOC_DAPM_POST_PMD);
163cac06
MB
1439 break;
1440
b22ead2a 1441 default:
81628103
MB
1442 /* Queue it up for application */
1443 cur_sort = sort[w->id];
20e4859d 1444 cur_subseq = w->subseq;
81628103 1445 cur_reg = w->reg;
7be31be8 1446 cur_dapm = w->dapm;
81628103
MB
1447 list_move(&w->power_list, &pending);
1448 break;
163cac06 1449 }
b22ead2a
MB
1450
1451 if (ret < 0)
f7d41ae8 1452 dev_err(w->dapm->dev,
30a6a1a4 1453 "ASoC: Failed to apply widget power: %d\n", ret);
6ea31b9f 1454 }
b22ead2a
MB
1455
1456 if (!list_empty(&pending))
95dd5cd6 1457 dapm_seq_run_coalesced(card, &pending);
474b62d6
MB
1458
1459 if (cur_dapm && cur_dapm->seq_notifier) {
1460 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
1461 if (sort[i] == cur_sort)
1462 cur_dapm->seq_notifier(cur_dapm,
f85a9e0d 1463 i, cur_subseq);
474b62d6 1464 }
eb270e98
MB
1465
1466 list_for_each_entry(d, &card->dapm_list, list) {
1467 soc_dapm_async_complete(d);
1468 }
42aa3418
MB
1469}
1470
95dd5cd6 1471static void dapm_widget_update(struct snd_soc_card *card)
97404f2e 1472{
95dd5cd6 1473 struct snd_soc_dapm_update *update = card->update;
ce6cfaf1
LPC
1474 struct snd_soc_dapm_widget_list *wlist;
1475 struct snd_soc_dapm_widget *w = NULL;
1476 unsigned int wi;
97404f2e
MB
1477 int ret;
1478
57295073 1479 if (!update || !dapm_kcontrol_is_powered(update->kcontrol))
97404f2e
MB
1480 return;
1481
e84357f7 1482 wlist = dapm_kcontrol_get_wlist(update->kcontrol);
97404f2e 1483
ce6cfaf1
LPC
1484 for (wi = 0; wi < wlist->num_widgets; wi++) {
1485 w = wlist->widgets[wi];
1486
1487 if (w->event && (w->event_flags & SND_SOC_DAPM_PRE_REG)) {
1488 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG);
1489 if (ret != 0)
95dd5cd6 1490 dev_err(w->dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n",
ce6cfaf1
LPC
1491 w->name, ret);
1492 }
97404f2e
MB
1493 }
1494
ce6cfaf1
LPC
1495 if (!w)
1496 return;
1497
23d5442b 1498 ret = soc_widget_update_bits(w, update->reg, update->mask, update->val);
97404f2e 1499 if (ret < 0)
95dd5cd6 1500 dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n",
30a6a1a4 1501 w->name, ret);
97404f2e 1502
ce6cfaf1
LPC
1503 for (wi = 0; wi < wlist->num_widgets; wi++) {
1504 w = wlist->widgets[wi];
1505
1506 if (w->event && (w->event_flags & SND_SOC_DAPM_POST_REG)) {
1507 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
1508 if (ret != 0)
95dd5cd6 1509 dev_err(w->dapm->dev, "ASoC: %s DAPM post-event failed: %d\n",
ce6cfaf1
LPC
1510 w->name, ret);
1511 }
97404f2e
MB
1512 }
1513}
1514
9d0624a7
MB
1515/* Async callback run prior to DAPM sequences - brings to _PREPARE if
1516 * they're changing state.
1517 */
1518static void dapm_pre_sequence_async(void *data, async_cookie_t cookie)
1519{
1520 struct snd_soc_dapm_context *d = data;
1521 int ret;
1522
56fba41f
MB
1523 /* If we're off and we're not supposed to be go into STANDBY */
1524 if (d->bias_level == SND_SOC_BIAS_OFF &&
1525 d->target_bias_level != SND_SOC_BIAS_OFF) {
f1aac484
MB
1526 if (d->dev)
1527 pm_runtime_get_sync(d->dev);
1528
9d0624a7
MB
1529 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1530 if (ret != 0)
1531 dev_err(d->dev,
30a6a1a4 1532 "ASoC: Failed to turn on bias: %d\n", ret);
9d0624a7
MB
1533 }
1534
ce85a4d7
LPC
1535 /* Prepare for a transition to ON or away from ON */
1536 if ((d->target_bias_level == SND_SOC_BIAS_ON &&
1537 d->bias_level != SND_SOC_BIAS_ON) ||
1538 (d->target_bias_level != SND_SOC_BIAS_ON &&
1539 d->bias_level == SND_SOC_BIAS_ON)) {
9d0624a7
MB
1540 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
1541 if (ret != 0)
1542 dev_err(d->dev,
30a6a1a4 1543 "ASoC: Failed to prepare bias: %d\n", ret);
9d0624a7
MB
1544 }
1545}
1546
1547/* Async callback run prior to DAPM sequences - brings to their final
1548 * state.
1549 */
1550static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1551{
1552 struct snd_soc_dapm_context *d = data;
1553 int ret;
1554
1555 /* If we just powered the last thing off drop to standby bias */
56fba41f
MB
1556 if (d->bias_level == SND_SOC_BIAS_PREPARE &&
1557 (d->target_bias_level == SND_SOC_BIAS_STANDBY ||
1558 d->target_bias_level == SND_SOC_BIAS_OFF)) {
9d0624a7
MB
1559 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1560 if (ret != 0)
30a6a1a4 1561 dev_err(d->dev, "ASoC: Failed to apply standby bias: %d\n",
9d0624a7
MB
1562 ret);
1563 }
97404f2e 1564
9d0624a7 1565 /* If we're in standby and can support bias off then do that */
56fba41f
MB
1566 if (d->bias_level == SND_SOC_BIAS_STANDBY &&
1567 d->target_bias_level == SND_SOC_BIAS_OFF) {
9d0624a7
MB
1568 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
1569 if (ret != 0)
30a6a1a4
LG
1570 dev_err(d->dev, "ASoC: Failed to turn off bias: %d\n",
1571 ret);
f1aac484
MB
1572
1573 if (d->dev)
fb644e9c 1574 pm_runtime_put(d->dev);
9d0624a7
MB
1575 }
1576
1577 /* If we just powered up then move to active bias */
56fba41f
MB
1578 if (d->bias_level == SND_SOC_BIAS_PREPARE &&
1579 d->target_bias_level == SND_SOC_BIAS_ON) {
9d0624a7
MB
1580 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
1581 if (ret != 0)
30a6a1a4 1582 dev_err(d->dev, "ASoC: Failed to apply active bias: %d\n",
9d0624a7
MB
1583 ret);
1584 }
1585}
97404f2e 1586
fe4fda5d
MB
1587static void dapm_widget_set_peer_power(struct snd_soc_dapm_widget *peer,
1588 bool power, bool connect)
1589{
1590 /* If a connection is being made or broken then that update
1591 * will have marked the peer dirty, otherwise the widgets are
1592 * not connected and this update has no impact. */
1593 if (!connect)
1594 return;
1595
1596 /* If the peer is already in the state we're moving to then we
1597 * won't have an impact on it. */
1598 if (power != peer->power)
75c1f891 1599 dapm_mark_dirty(peer, "peer state change");
fe4fda5d
MB
1600}
1601
05623c43
MB
1602static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
1603 struct list_head *up_list,
1604 struct list_head *down_list)
1605{
db432b41
MB
1606 struct snd_soc_dapm_path *path;
1607
05623c43
MB
1608 if (w->power == power)
1609 return;
1610
1611 trace_snd_soc_dapm_widget_power(w, power);
1612
db432b41 1613 /* If we changed our power state perhaps our neigbours changed
fe4fda5d 1614 * also.
db432b41
MB
1615 */
1616 list_for_each_entry(path, &w->sources, list_sink) {
1617 if (path->source) {
fe4fda5d
MB
1618 dapm_widget_set_peer_power(path->source, power,
1619 path->connect);
db432b41
MB
1620 }
1621 }
f3bf3e45
MB
1622 switch (w->id) {
1623 case snd_soc_dapm_supply:
62ea874a 1624 case snd_soc_dapm_regulator_supply:
d7e7eb91 1625 case snd_soc_dapm_clock_supply:
57295073 1626 case snd_soc_dapm_kcontrol:
f3bf3e45
MB
1627 /* Supplies can't affect their outputs, only their inputs */
1628 break;
1629 default:
1630 list_for_each_entry(path, &w->sinks, list_source) {
1631 if (path->sink) {
1632 dapm_widget_set_peer_power(path->sink, power,
1633 path->connect);
1634 }
db432b41 1635 }
f3bf3e45 1636 break;
db432b41
MB
1637 }
1638
05623c43
MB
1639 if (power)
1640 dapm_seq_insert(w, up_list, true);
1641 else
1642 dapm_seq_insert(w, down_list, false);
05623c43
MB
1643}
1644
7c81beb0
MB
1645static void dapm_power_one_widget(struct snd_soc_dapm_widget *w,
1646 struct list_head *up_list,
1647 struct list_head *down_list)
1648{
7c81beb0
MB
1649 int power;
1650
1651 switch (w->id) {
1652 case snd_soc_dapm_pre:
1653 dapm_seq_insert(w, down_list, false);
1654 break;
1655 case snd_soc_dapm_post:
1656 dapm_seq_insert(w, up_list, true);
1657 break;
1658
1659 default:
d805002b 1660 power = dapm_widget_power_check(w);
7c81beb0 1661
05623c43 1662 dapm_widget_set_power(w, power, up_list, down_list);
7c81beb0
MB
1663 break;
1664 }
1665}
1666
2b97eabc
RP
1667/*
1668 * Scan each dapm widget for complete audio path.
1669 * A complete path is a route that has valid endpoints i.e.:-
1670 *
1671 * o DAC to output pin.
1672 * o Input Pin to ADC.
1673 * o Input pin to Output pin (bypass, sidetone)
1674 * o DAC to ADC (loopback).
1675 */
95dd5cd6 1676static int dapm_power_widgets(struct snd_soc_card *card, int event)
2b97eabc
RP
1677{
1678 struct snd_soc_dapm_widget *w;
7be31be8 1679 struct snd_soc_dapm_context *d;
291f3bbc
MB
1680 LIST_HEAD(up_list);
1681 LIST_HEAD(down_list);
2955b47d 1682 ASYNC_DOMAIN_EXCLUSIVE(async_domain);
56fba41f 1683 enum snd_soc_bias_level bias;
6d3ddc81 1684
f9fa2b18
MB
1685 lockdep_assert_held(&card->dapm_mutex);
1686
84e90930
MB
1687 trace_snd_soc_dapm_start(card);
1688
56fba41f 1689 list_for_each_entry(d, &card->dapm_list, list) {
497098be
MB
1690 if (d->idle_bias_off)
1691 d->target_bias_level = SND_SOC_BIAS_OFF;
1692 else
1693 d->target_bias_level = SND_SOC_BIAS_STANDBY;
56fba41f 1694 }
7be31be8 1695
6c120e19 1696 dapm_reset(card);
9b8a83b2 1697
6d3ddc81 1698 /* Check which widgets we need to power and store them in
db432b41
MB
1699 * lists indicating if they should be powered up or down. We
1700 * only check widgets that have been flagged as dirty but note
1701 * that new widgets may be added to the dirty list while we
1702 * iterate.
6d3ddc81 1703 */
db432b41 1704 list_for_each_entry(w, &card->dapm_dirty, dirty) {
7c81beb0 1705 dapm_power_one_widget(w, &up_list, &down_list);
2b97eabc
RP
1706 }
1707
f9de6d74 1708 list_for_each_entry(w, &card->widgets, list) {
0ff97ebf
MB
1709 switch (w->id) {
1710 case snd_soc_dapm_pre:
1711 case snd_soc_dapm_post:
1712 /* These widgets always need to be powered */
1713 break;
1714 default:
1715 list_del_init(&w->dirty);
1716 break;
1717 }
db432b41 1718
39eb5fd1 1719 if (w->new_power) {
f9de6d74
MB
1720 d = w->dapm;
1721
1722 /* Supplies and micbiases only bring the
1723 * context up to STANDBY as unless something
1724 * else is active and passing audio they
afe62367
MB
1725 * generally don't require full power. Signal
1726 * generators are virtual pins and have no
1727 * power impact themselves.
f9de6d74
MB
1728 */
1729 switch (w->id) {
afe62367 1730 case snd_soc_dapm_siggen:
da83fea6 1731 case snd_soc_dapm_vmid:
afe62367 1732 break;
f9de6d74 1733 case snd_soc_dapm_supply:
62ea874a 1734 case snd_soc_dapm_regulator_supply:
d7e7eb91 1735 case snd_soc_dapm_clock_supply:
f9de6d74
MB
1736 case snd_soc_dapm_micbias:
1737 if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
1738 d->target_bias_level = SND_SOC_BIAS_STANDBY;
1739 break;
1740 default:
1741 d->target_bias_level = SND_SOC_BIAS_ON;
1742 break;
1743 }
1744 }
1745
1746 }
1747
85a843c5
MB
1748 /* Force all contexts in the card to the same bias state if
1749 * they're not ground referenced.
1750 */
56fba41f 1751 bias = SND_SOC_BIAS_OFF;
52ba67bf 1752 list_for_each_entry(d, &card->dapm_list, list)
56fba41f
MB
1753 if (d->target_bias_level > bias)
1754 bias = d->target_bias_level;
52ba67bf 1755 list_for_each_entry(d, &card->dapm_list, list)
85a843c5
MB
1756 if (!d->idle_bias_off)
1757 d->target_bias_level = bias;
52ba67bf 1758
de02d078 1759 trace_snd_soc_dapm_walk_done(card);
52ba67bf 1760
17282ba4
XX
1761 /* Run card bias changes at first */
1762 dapm_pre_sequence_async(&card->dapm, 0);
1763 /* Run other bias changes in parallel */
1764 list_for_each_entry(d, &card->dapm_list, list) {
1765 if (d != &card->dapm)
1766 async_schedule_domain(dapm_pre_sequence_async, d,
1767 &async_domain);
1768 }
9d0624a7 1769 async_synchronize_full_domain(&async_domain);
452c5eaa 1770
cf1f7c6e 1771 list_for_each_entry(w, &down_list, power_list) {
95dd5cd6 1772 dapm_seq_check_event(card, w, SND_SOC_DAPM_WILL_PMD);
80114129
MB
1773 }
1774
cf1f7c6e 1775 list_for_each_entry(w, &up_list, power_list) {
95dd5cd6 1776 dapm_seq_check_event(card, w, SND_SOC_DAPM_WILL_PMU);
80114129
MB
1777 }
1778
6d3ddc81 1779 /* Power down widgets first; try to avoid amplifying pops. */
95dd5cd6 1780 dapm_seq_run(card, &down_list, event, false);
2b97eabc 1781
95dd5cd6 1782 dapm_widget_update(card);
97404f2e 1783
6d3ddc81 1784 /* Now power up. */
95dd5cd6 1785 dapm_seq_run(card, &up_list, event, true);
2b97eabc 1786
9d0624a7 1787 /* Run all the bias changes in parallel */
17282ba4
XX
1788 list_for_each_entry(d, &card->dapm_list, list) {
1789 if (d != &card->dapm)
1790 async_schedule_domain(dapm_post_sequence_async, d,
1791 &async_domain);
1792 }
9d0624a7 1793 async_synchronize_full_domain(&async_domain);
17282ba4
XX
1794 /* Run card bias changes at last */
1795 dapm_post_sequence_async(&card->dapm, 0);
452c5eaa 1796
8078d87f
LG
1797 /* do we need to notify any clients that DAPM event is complete */
1798 list_for_each_entry(d, &card->dapm_list, list) {
1799 if (d->stream_event)
1800 d->stream_event(d, event);
1801 }
1802
95dd5cd6 1803 pop_dbg(card->dev, card->pop_time,
fd8d3bc0 1804 "DAPM sequencing finished, waiting %dms\n", card->pop_time);
3a45b867 1805 pop_wait(card->pop_time);
cb507e7e 1806
84e90930
MB
1807 trace_snd_soc_dapm_done(card);
1808
42aa3418 1809 return 0;
2b97eabc
RP
1810}
1811
79fb9387 1812#ifdef CONFIG_DEBUG_FS
79fb9387
MB
1813static ssize_t dapm_widget_power_read_file(struct file *file,
1814 char __user *user_buf,
1815 size_t count, loff_t *ppos)
1816{
1817 struct snd_soc_dapm_widget *w = file->private_data;
1818 char *buf;
1819 int in, out;
1820 ssize_t ret;
1821 struct snd_soc_dapm_path *p = NULL;
1822
1823 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1824 if (!buf)
1825 return -ENOMEM;
1826
ec2e3031 1827 in = is_connected_input_ep(w, NULL);
1059ecfa 1828 dapm_clear_walk_input(w->dapm, &w->sources);
ec2e3031 1829 out = is_connected_output_ep(w, NULL);
1059ecfa 1830 dapm_clear_walk_output(w->dapm, &w->sinks);
79fb9387 1831
f13ebada
MB
1832 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
1833 w->name, w->power ? "On" : "Off",
1834 w->force ? " (forced)" : "", in, out);
79fb9387 1835
d033c36a
MB
1836 if (w->reg >= 0)
1837 ret += snprintf(buf + ret, PAGE_SIZE - ret,
de9ba98b
LPC
1838 " - R%d(0x%x) mask 0x%x",
1839 w->reg, w->reg, w->mask << w->shift);
d033c36a
MB
1840
1841 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
1842
3eef08ba
MB
1843 if (w->sname)
1844 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
1845 w->sname,
1846 w->active ? "active" : "inactive");
79fb9387
MB
1847
1848 list_for_each_entry(p, &w->sources, list_sink) {
ff18620c 1849 if (p->connected && !p->connected(w, p->source))
215edda3
MB
1850 continue;
1851
79fb9387
MB
1852 if (p->connect)
1853 ret += snprintf(buf + ret, PAGE_SIZE - ret,
67f5ed6e 1854 " in \"%s\" \"%s\"\n",
79fb9387
MB
1855 p->name ? p->name : "static",
1856 p->source->name);
1857 }
1858 list_for_each_entry(p, &w->sinks, list_source) {
215edda3
MB
1859 if (p->connected && !p->connected(w, p->sink))
1860 continue;
1861
79fb9387
MB
1862 if (p->connect)
1863 ret += snprintf(buf + ret, PAGE_SIZE - ret,
67f5ed6e 1864 " out \"%s\" \"%s\"\n",
79fb9387
MB
1865 p->name ? p->name : "static",
1866 p->sink->name);
1867 }
1868
1869 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1870
1871 kfree(buf);
1872 return ret;
1873}
1874
1875static const struct file_operations dapm_widget_power_fops = {
234e3405 1876 .open = simple_open,
79fb9387 1877 .read = dapm_widget_power_read_file,
6038f373 1878 .llseek = default_llseek,
79fb9387
MB
1879};
1880
ef49e4fa
MB
1881static ssize_t dapm_bias_read_file(struct file *file, char __user *user_buf,
1882 size_t count, loff_t *ppos)
1883{
1884 struct snd_soc_dapm_context *dapm = file->private_data;
1885 char *level;
1886
1887 switch (dapm->bias_level) {
1888 case SND_SOC_BIAS_ON:
1889 level = "On\n";
1890 break;
1891 case SND_SOC_BIAS_PREPARE:
1892 level = "Prepare\n";
1893 break;
1894 case SND_SOC_BIAS_STANDBY:
1895 level = "Standby\n";
1896 break;
1897 case SND_SOC_BIAS_OFF:
1898 level = "Off\n";
1899 break;
1900 default:
a6ed0608 1901 WARN(1, "Unknown bias_level %d\n", dapm->bias_level);
ef49e4fa
MB
1902 level = "Unknown\n";
1903 break;
1904 }
1905
1906 return simple_read_from_buffer(user_buf, count, ppos, level,
1907 strlen(level));
1908}
1909
1910static const struct file_operations dapm_bias_fops = {
234e3405 1911 .open = simple_open,
ef49e4fa
MB
1912 .read = dapm_bias_read_file,
1913 .llseek = default_llseek,
1914};
1915
8eecaf62
LPC
1916void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1917 struct dentry *parent)
79fb9387 1918{
79fb9387
MB
1919 struct dentry *d;
1920
8eecaf62
LPC
1921 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
1922
1923 if (!dapm->debugfs_dapm) {
f1e90af2 1924 dev_warn(dapm->dev,
30a6a1a4 1925 "ASoC: Failed to create DAPM debugfs directory\n");
79fb9387 1926 return;
8eecaf62 1927 }
79fb9387 1928
ef49e4fa
MB
1929 d = debugfs_create_file("bias_level", 0444,
1930 dapm->debugfs_dapm, dapm,
1931 &dapm_bias_fops);
1932 if (!d)
1933 dev_warn(dapm->dev,
1934 "ASoC: Failed to create bias level debugfs file\n");
d5d1e0be 1935}
ef49e4fa 1936
d5d1e0be
LPC
1937static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
1938{
1939 struct snd_soc_dapm_context *dapm = w->dapm;
1940 struct dentry *d;
79fb9387 1941
d5d1e0be
LPC
1942 if (!dapm->debugfs_dapm || !w->name)
1943 return;
1944
1945 d = debugfs_create_file(w->name, 0444,
1946 dapm->debugfs_dapm, w,
1947 &dapm_widget_power_fops);
1948 if (!d)
1949 dev_warn(w->dapm->dev,
1950 "ASoC: Failed to create %s debugfs file\n",
1951 w->name);
79fb9387 1952}
d5d1e0be 1953
6c45e126
LPC
1954static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1955{
1956 debugfs_remove_recursive(dapm->debugfs_dapm);
1957}
1958
79fb9387 1959#else
8eecaf62
LPC
1960void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1961 struct dentry *parent)
79fb9387
MB
1962{
1963}
d5d1e0be
LPC
1964
1965static inline void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
1966{
1967}
1968
6c45e126
LPC
1969static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1970{
1971}
1972
79fb9387
MB
1973#endif
1974
2b97eabc 1975/* test and update the power status of a mux widget */
95dd5cd6 1976static int soc_dapm_mux_update_power(struct snd_soc_card *card,
40f02cd9 1977 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
2b97eabc
RP
1978{
1979 struct snd_soc_dapm_path *path;
1980 int found = 0;
1981
f9fa2b18
MB
1982 lockdep_assert_held(&card->dapm_mutex);
1983
2b97eabc 1984 /* find dapm widget path assoc with kcontrol */
5106b92f 1985 dapm_kcontrol_for_each_path(path, kcontrol) {
cb01e2b9 1986 if (!path->name || !e->texts[mux])
2b97eabc
RP
1987 continue;
1988
1989 found = 1;
1990 /* we now need to match the string in the enum to the path */
db432b41 1991 if (!(strcmp(path->name, e->texts[mux]))) {
2b97eabc 1992 path->connect = 1; /* new connection */
75c1f891 1993 dapm_mark_dirty(path->source, "mux connection");
db432b41
MB
1994 } else {
1995 if (path->connect)
75c1f891
MB
1996 dapm_mark_dirty(path->source,
1997 "mux disconnection");
2b97eabc 1998 path->connect = 0; /* old connection must be powered down */
db432b41 1999 }
ce6cfaf1 2000 dapm_mark_dirty(path->sink, "mux change");
2b97eabc
RP
2001 }
2002
ce6cfaf1 2003 if (found)
95dd5cd6 2004 dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP);
2b97eabc 2005
618dae11 2006 return found;
2b97eabc 2007}
4edbb345 2008
ce6cfaf1 2009int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
6b3fc03b
LPC
2010 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e,
2011 struct snd_soc_dapm_update *update)
4edbb345 2012{
ce6cfaf1 2013 struct snd_soc_card *card = dapm->card;
4edbb345
LG
2014 int ret;
2015
3cd04343 2016 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
564c6504 2017 card->update = update;
95dd5cd6 2018 ret = soc_dapm_mux_update_power(card, kcontrol, mux, e);
564c6504 2019 card->update = NULL;
4edbb345 2020 mutex_unlock(&card->dapm_mutex);
618dae11 2021 if (ret > 0)
c3f48ae6 2022 soc_dpcm_runtime_update(card);
4edbb345
LG
2023 return ret;
2024}
40f02cd9 2025EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
2b97eabc 2026
1b075e3f 2027/* test and update the power status of a mixer or switch widget */
95dd5cd6 2028static int soc_dapm_mixer_update_power(struct snd_soc_card *card,
283375ce 2029 struct snd_kcontrol *kcontrol, int connect)
2b97eabc
RP
2030{
2031 struct snd_soc_dapm_path *path;
2032 int found = 0;
2033
f9fa2b18
MB
2034 lockdep_assert_held(&card->dapm_mutex);
2035
2b97eabc 2036 /* find dapm widget path assoc with kcontrol */
5106b92f 2037 dapm_kcontrol_for_each_path(path, kcontrol) {
2b97eabc 2038 found = 1;
283375ce 2039 path->connect = connect;
75c1f891 2040 dapm_mark_dirty(path->source, "mixer connection");
ce6cfaf1 2041 dapm_mark_dirty(path->sink, "mixer update");
2b97eabc
RP
2042 }
2043
ce6cfaf1 2044 if (found)
95dd5cd6 2045 dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP);
2b97eabc 2046
618dae11 2047 return found;
2b97eabc 2048}
4edbb345 2049
ce6cfaf1 2050int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
6b3fc03b
LPC
2051 struct snd_kcontrol *kcontrol, int connect,
2052 struct snd_soc_dapm_update *update)
4edbb345 2053{
ce6cfaf1 2054 struct snd_soc_card *card = dapm->card;
4edbb345
LG
2055 int ret;
2056
3cd04343 2057 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
564c6504 2058 card->update = update;
95dd5cd6 2059 ret = soc_dapm_mixer_update_power(card, kcontrol, connect);
564c6504 2060 card->update = NULL;
4edbb345 2061 mutex_unlock(&card->dapm_mutex);
618dae11 2062 if (ret > 0)
c3f48ae6 2063 soc_dpcm_runtime_update(card);
4edbb345
LG
2064 return ret;
2065}
40f02cd9 2066EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power);
2b97eabc
RP
2067
2068/* show dapm widget status in sys fs */
2069static ssize_t dapm_widget_show(struct device *dev,
2070 struct device_attribute *attr, char *buf)
2071{
36ae1a96 2072 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
f0fba2ad 2073 struct snd_soc_codec *codec =rtd->codec;
2b97eabc
RP
2074 struct snd_soc_dapm_widget *w;
2075 int count = 0;
2076 char *state = "not set";
2077
97c866de
JN
2078 list_for_each_entry(w, &codec->card->widgets, list) {
2079 if (w->dapm != &codec->dapm)
2080 continue;
2b97eabc
RP
2081
2082 /* only display widgets that burnm power */
2083 switch (w->id) {
2084 case snd_soc_dapm_hp:
2085 case snd_soc_dapm_mic:
2086 case snd_soc_dapm_spk:
2087 case snd_soc_dapm_line:
2088 case snd_soc_dapm_micbias:
2089 case snd_soc_dapm_dac:
2090 case snd_soc_dapm_adc:
2091 case snd_soc_dapm_pga:
d88429a6 2092 case snd_soc_dapm_out_drv:
2b97eabc 2093 case snd_soc_dapm_mixer:
ca9c1aae 2094 case snd_soc_dapm_mixer_named_ctl:
246d0a17 2095 case snd_soc_dapm_supply:
62ea874a 2096 case snd_soc_dapm_regulator_supply:
d7e7eb91 2097 case snd_soc_dapm_clock_supply:
2b97eabc
RP
2098 if (w->name)
2099 count += sprintf(buf + count, "%s: %s\n",
2100 w->name, w->power ? "On":"Off");
2101 break;
2102 default:
2103 break;
2104 }
2105 }
2106
ce6120cc 2107 switch (codec->dapm.bias_level) {
0be9898a
MB
2108 case SND_SOC_BIAS_ON:
2109 state = "On";
2b97eabc 2110 break;
0be9898a
MB
2111 case SND_SOC_BIAS_PREPARE:
2112 state = "Prepare";
2b97eabc 2113 break;
0be9898a
MB
2114 case SND_SOC_BIAS_STANDBY:
2115 state = "Standby";
2b97eabc 2116 break;
0be9898a
MB
2117 case SND_SOC_BIAS_OFF:
2118 state = "Off";
2b97eabc
RP
2119 break;
2120 }
2121 count += sprintf(buf + count, "PM State: %s\n", state);
2122
2123 return count;
2124}
2125
2126static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
2127
2128int snd_soc_dapm_sys_add(struct device *dev)
2129{
12ef193d 2130 return device_create_file(dev, &dev_attr_dapm_widget);
2b97eabc
RP
2131}
2132
2133static void snd_soc_dapm_sys_remove(struct device *dev)
2134{
aef90843 2135 device_remove_file(dev, &dev_attr_dapm_widget);
2b97eabc
RP
2136}
2137
8872293f
LPC
2138static void dapm_free_path(struct snd_soc_dapm_path *path)
2139{
2140 list_del(&path->list_sink);
2141 list_del(&path->list_source);
5106b92f 2142 list_del(&path->list_kcontrol);
8872293f 2143 list_del(&path->list);
8872293f
LPC
2144 kfree(path);
2145}
2146
2b97eabc 2147/* free all dapm widgets and resources */
ce6120cc 2148static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
2b97eabc
RP
2149{
2150 struct snd_soc_dapm_widget *w, *next_w;
2151 struct snd_soc_dapm_path *p, *next_p;
2152
97c866de
JN
2153 list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) {
2154 if (w->dapm != dapm)
2155 continue;
2b97eabc 2156 list_del(&w->list);
8ddab3f5
JN
2157 /*
2158 * remove source and sink paths associated to this widget.
2159 * While removing the path, remove reference to it from both
2160 * source and sink widgets so that path is removed only once.
2161 */
8872293f
LPC
2162 list_for_each_entry_safe(p, next_p, &w->sources, list_sink)
2163 dapm_free_path(p);
2164
2165 list_for_each_entry_safe(p, next_p, &w->sinks, list_source)
2166 dapm_free_path(p);
2167
fad59888 2168 kfree(w->kcontrols);
ead9b919 2169 kfree(w->name);
2b97eabc
RP
2170 kfree(w);
2171 }
2b97eabc
RP
2172}
2173
91a5fca4
LPC
2174static struct snd_soc_dapm_widget *dapm_find_widget(
2175 struct snd_soc_dapm_context *dapm, const char *pin,
2176 bool search_other_contexts)
a5302181
LG
2177{
2178 struct snd_soc_dapm_widget *w;
91a5fca4 2179 struct snd_soc_dapm_widget *fallback = NULL;
a5302181 2180
97c866de 2181 list_for_each_entry(w, &dapm->card->widgets, list) {
a5302181 2182 if (!strcmp(w->name, pin)) {
91a5fca4
LPC
2183 if (w->dapm == dapm)
2184 return w;
2185 else
2186 fallback = w;
a5302181
LG
2187 }
2188 }
2189
91a5fca4
LPC
2190 if (search_other_contexts)
2191 return fallback;
2192
2193 return NULL;
2194}
2195
2196static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
2197 const char *pin, int status)
2198{
2199 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
2200
f9fa2b18
MB
2201 dapm_assert_locked(dapm);
2202
91a5fca4 2203 if (!w) {
30a6a1a4 2204 dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin);
91a5fca4 2205 return -EINVAL;
0d86733c
MB
2206 }
2207
1a8b2d9d
MB
2208 if (w->connected != status)
2209 dapm_mark_dirty(w, "pin configuration");
2210
91a5fca4
LPC
2211 w->connected = status;
2212 if (status == 0)
2213 w->force = 0;
2214
2215 return 0;
a5302181
LG
2216}
2217
2b97eabc 2218/**
3eb29dfb 2219 * snd_soc_dapm_sync_unlocked - scan and power dapm paths
ce6120cc 2220 * @dapm: DAPM context
2b97eabc
RP
2221 *
2222 * Walks all dapm audio paths and powers widgets according to their
2223 * stream or path usage.
2224 *
3eb29dfb
CK
2225 * Requires external locking.
2226 *
2b97eabc
RP
2227 * Returns 0 for success.
2228 */
3eb29dfb 2229int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm)
2b97eabc 2230{
4f4c0072
MB
2231 /*
2232 * Suppress early reports (eg, jacks syncing their state) to avoid
2233 * silly DAPM runs during card startup.
2234 */
2235 if (!dapm->card || !dapm->card->instantiated)
2236 return 0;
2237
3eb29dfb
CK
2238 return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP);
2239}
2240EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_unlocked);
2241
2242/**
2243 * snd_soc_dapm_sync - scan and power dapm paths
2244 * @dapm: DAPM context
2245 *
2246 * Walks all dapm audio paths and powers widgets according to their
2247 * stream or path usage.
2248 *
2249 * Returns 0 for success.
2250 */
2251int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
2252{
2253 int ret;
2254
3cd04343 2255 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3eb29dfb 2256 ret = snd_soc_dapm_sync_unlocked(dapm);
a73fb2df
LG
2257 mutex_unlock(&dapm->card->dapm_mutex);
2258 return ret;
2b97eabc 2259}
a5302181 2260EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
2b97eabc 2261
2553628e
LPC
2262static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
2263 struct snd_soc_dapm_widget *wsource, struct snd_soc_dapm_widget *wsink,
2264 const char *control,
2265 int (*connected)(struct snd_soc_dapm_widget *source,
2266 struct snd_soc_dapm_widget *sink))
2b97eabc
RP
2267{
2268 struct snd_soc_dapm_path *path;
2553628e 2269 int ret;
2b97eabc
RP
2270
2271 path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL);
2272 if (!path)
2273 return -ENOMEM;
2274
2275 path->source = wsource;
2276 path->sink = wsink;
2553628e 2277 path->connected = connected;
2b97eabc 2278 INIT_LIST_HEAD(&path->list);
69c2d346 2279 INIT_LIST_HEAD(&path->list_kcontrol);
2b97eabc
RP
2280 INIT_LIST_HEAD(&path->list_source);
2281 INIT_LIST_HEAD(&path->list_sink);
2282
2283 /* check for external widgets */
2284 if (wsink->id == snd_soc_dapm_input) {
2285 if (wsource->id == snd_soc_dapm_micbias ||
2286 wsource->id == snd_soc_dapm_mic ||
087d53ab
RC
2287 wsource->id == snd_soc_dapm_line ||
2288 wsource->id == snd_soc_dapm_output)
2b97eabc
RP
2289 wsink->ext = 1;
2290 }
2291 if (wsource->id == snd_soc_dapm_output) {
2292 if (wsink->id == snd_soc_dapm_spk ||
2293 wsink->id == snd_soc_dapm_hp ||
1e39221e
SF
2294 wsink->id == snd_soc_dapm_line ||
2295 wsink->id == snd_soc_dapm_input)
2b97eabc
RP
2296 wsource->ext = 1;
2297 }
2298
34742cb0
LPC
2299 dapm_mark_dirty(wsource, "Route added");
2300 dapm_mark_dirty(wsink, "Route added");
2301
2b97eabc
RP
2302 /* connect static paths */
2303 if (control == NULL) {
8ddab3f5 2304 list_add(&path->list, &dapm->card->paths);
2b97eabc
RP
2305 list_add(&path->list_sink, &wsink->sources);
2306 list_add(&path->list_source, &wsource->sinks);
2307 path->connect = 1;
2308 return 0;
2309 }
2310
2311 /* connect dynamic paths */
dc2bea61 2312 switch (wsink->id) {
2b97eabc
RP
2313 case snd_soc_dapm_adc:
2314 case snd_soc_dapm_dac:
2315 case snd_soc_dapm_pga:
d88429a6 2316 case snd_soc_dapm_out_drv:
2b97eabc
RP
2317 case snd_soc_dapm_input:
2318 case snd_soc_dapm_output:
1ab97c8c 2319 case snd_soc_dapm_siggen:
2b97eabc
RP
2320 case snd_soc_dapm_micbias:
2321 case snd_soc_dapm_vmid:
2322 case snd_soc_dapm_pre:
2323 case snd_soc_dapm_post:
246d0a17 2324 case snd_soc_dapm_supply:
62ea874a 2325 case snd_soc_dapm_regulator_supply:
d7e7eb91 2326 case snd_soc_dapm_clock_supply:
010ff262
MB
2327 case snd_soc_dapm_aif_in:
2328 case snd_soc_dapm_aif_out:
4616274d
MB
2329 case snd_soc_dapm_dai_in:
2330 case snd_soc_dapm_dai_out:
c74184ed 2331 case snd_soc_dapm_dai_link:
57295073 2332 case snd_soc_dapm_kcontrol:
8ddab3f5 2333 list_add(&path->list, &dapm->card->paths);
2b97eabc
RP
2334 list_add(&path->list_sink, &wsink->sources);
2335 list_add(&path->list_source, &wsource->sinks);
2336 path->connect = 1;
2337 return 0;
2338 case snd_soc_dapm_mux:
ce6120cc 2339 ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
82cfecdc 2340 &wsink->kcontrol_news[0]);
2b97eabc
RP
2341 if (ret != 0)
2342 goto err;
2343 break;
2344 case snd_soc_dapm_switch:
2345 case snd_soc_dapm_mixer:
ca9c1aae 2346 case snd_soc_dapm_mixer_named_ctl:
ce6120cc 2347 ret = dapm_connect_mixer(dapm, wsource, wsink, path, control);
2b97eabc
RP
2348 if (ret != 0)
2349 goto err;
2350 break;
2351 case snd_soc_dapm_hp:
2352 case snd_soc_dapm_mic:
2353 case snd_soc_dapm_line:
2354 case snd_soc_dapm_spk:
8ddab3f5 2355 list_add(&path->list, &dapm->card->paths);
2b97eabc
RP
2356 list_add(&path->list_sink, &wsink->sources);
2357 list_add(&path->list_source, &wsource->sinks);
2358 path->connect = 0;
2359 return 0;
2360 }
fabd0384 2361
2b97eabc 2362 return 0;
2553628e
LPC
2363err:
2364 kfree(path);
2365 return ret;
2366}
2b97eabc 2367
2553628e 2368static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
a4e9154c 2369 const struct snd_soc_dapm_route *route)
2553628e
LPC
2370{
2371 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
2372 struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;
2373 const char *sink;
2374 const char *source;
2375 char prefixed_sink[80];
2376 char prefixed_source[80];
94f99c87 2377 const char *prefix;
2553628e
LPC
2378 int ret;
2379
94f99c87
LPC
2380 prefix = soc_dapm_prefix(dapm);
2381 if (prefix) {
2553628e 2382 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
94f99c87 2383 prefix, route->sink);
2553628e
LPC
2384 sink = prefixed_sink;
2385 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
94f99c87 2386 prefix, route->source);
2553628e
LPC
2387 source = prefixed_source;
2388 } else {
2389 sink = route->sink;
2390 source = route->source;
2391 }
2392
2393 /*
2394 * find src and dest widgets over all widgets but favor a widget from
2395 * current DAPM context
2396 */
2397 list_for_each_entry(w, &dapm->card->widgets, list) {
2398 if (!wsink && !(strcmp(w->name, sink))) {
2399 wtsink = w;
2400 if (w->dapm == dapm)
2401 wsink = w;
2402 continue;
2403 }
2404 if (!wsource && !(strcmp(w->name, source))) {
2405 wtsource = w;
2406 if (w->dapm == dapm)
2407 wsource = w;
2408 }
2409 }
2410 /* use widget from another DAPM context if not found from this */
2411 if (!wsink)
2412 wsink = wtsink;
2413 if (!wsource)
2414 wsource = wtsource;
2415
2416 if (wsource == NULL) {
2417 dev_err(dapm->dev, "ASoC: no source widget found for %s\n",
2418 route->source);
2419 return -ENODEV;
2420 }
2421 if (wsink == NULL) {
2422 dev_err(dapm->dev, "ASoC: no sink widget found for %s\n",
2423 route->sink);
2424 return -ENODEV;
2425 }
2426
2427 ret = snd_soc_dapm_add_path(dapm, wsource, wsink, route->control,
2428 route->connected);
2429 if (ret)
2430 goto err;
2431
2432 return 0;
2b97eabc 2433err:
30a6a1a4 2434 dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n",
2553628e 2435 source, route->control, sink);
2b97eabc
RP
2436 return ret;
2437}
105f1c28 2438
efcc3c61
MB
2439static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
2440 const struct snd_soc_dapm_route *route)
2441{
2442 struct snd_soc_dapm_path *path, *p;
2443 const char *sink;
2444 const char *source;
2445 char prefixed_sink[80];
2446 char prefixed_source[80];
94f99c87 2447 const char *prefix;
efcc3c61
MB
2448
2449 if (route->control) {
2450 dev_err(dapm->dev,
30a6a1a4 2451 "ASoC: Removal of routes with controls not supported\n");
efcc3c61
MB
2452 return -EINVAL;
2453 }
2454
94f99c87
LPC
2455 prefix = soc_dapm_prefix(dapm);
2456 if (prefix) {
efcc3c61 2457 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
94f99c87 2458 prefix, route->sink);
efcc3c61
MB
2459 sink = prefixed_sink;
2460 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
94f99c87 2461 prefix, route->source);
efcc3c61
MB
2462 source = prefixed_source;
2463 } else {
2464 sink = route->sink;
2465 source = route->source;
2466 }
2467
2468 path = NULL;
2469 list_for_each_entry(p, &dapm->card->paths, list) {
2470 if (strcmp(p->source->name, source) != 0)
2471 continue;
2472 if (strcmp(p->sink->name, sink) != 0)
2473 continue;
2474 path = p;
2475 break;
2476 }
2477
2478 if (path) {
2479 dapm_mark_dirty(path->source, "Route removed");
2480 dapm_mark_dirty(path->sink, "Route removed");
2481
8872293f 2482 dapm_free_path(path);
efcc3c61 2483 } else {
30a6a1a4 2484 dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n",
efcc3c61
MB
2485 source, sink);
2486 }
2487
2488 return 0;
2489}
2490
105f1c28
MB
2491/**
2492 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
ce6120cc 2493 * @dapm: DAPM context
105f1c28
MB
2494 * @route: audio routes
2495 * @num: number of routes
2496 *
2497 * Connects 2 dapm widgets together via a named audio path. The sink is
2498 * the widget receiving the audio signal, whilst the source is the sender
2499 * of the audio signal.
2500 *
2501 * Returns 0 for success else error. On error all resources can be freed
2502 * with a call to snd_soc_card_free().
2503 */
ce6120cc 2504int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
105f1c28
MB
2505 const struct snd_soc_dapm_route *route, int num)
2506{
62d4a4b9 2507 int i, r, ret = 0;
105f1c28 2508
a73fb2df 2509 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
105f1c28 2510 for (i = 0; i < num; i++) {
a4e9154c 2511 r = snd_soc_dapm_add_route(dapm, route);
62d4a4b9 2512 if (r < 0) {
30a6a1a4
LG
2513 dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n",
2514 route->source,
2515 route->control ? route->control : "direct",
2516 route->sink);
62d4a4b9 2517 ret = r;
105f1c28
MB
2518 }
2519 route++;
2520 }
a73fb2df 2521 mutex_unlock(&dapm->card->dapm_mutex);
105f1c28 2522
60884c27 2523 return ret;
105f1c28
MB
2524}
2525EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
2526
efcc3c61
MB
2527/**
2528 * snd_soc_dapm_del_routes - Remove routes between DAPM widgets
2529 * @dapm: DAPM context
2530 * @route: audio routes
2531 * @num: number of routes
2532 *
2533 * Removes routes from the DAPM context.
2534 */
2535int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
2536 const struct snd_soc_dapm_route *route, int num)
2537{
2538 int i, ret = 0;
2539
2540 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2541 for (i = 0; i < num; i++) {
2542 snd_soc_dapm_del_route(dapm, route);
2543 route++;
2544 }
2545 mutex_unlock(&dapm->card->dapm_mutex);
2546
2547 return ret;
2548}
2549EXPORT_SYMBOL_GPL(snd_soc_dapm_del_routes);
2550
bf3a9e13
MB
2551static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm,
2552 const struct snd_soc_dapm_route *route)
2553{
2554 struct snd_soc_dapm_widget *source = dapm_find_widget(dapm,
2555 route->source,
2556 true);
2557 struct snd_soc_dapm_widget *sink = dapm_find_widget(dapm,
2558 route->sink,
2559 true);
2560 struct snd_soc_dapm_path *path;
2561 int count = 0;
2562
2563 if (!source) {
30a6a1a4 2564 dev_err(dapm->dev, "ASoC: Unable to find source %s for weak route\n",
bf3a9e13
MB
2565 route->source);
2566 return -ENODEV;
2567 }
2568
2569 if (!sink) {
30a6a1a4 2570 dev_err(dapm->dev, "ASoC: Unable to find sink %s for weak route\n",
bf3a9e13
MB
2571 route->sink);
2572 return -ENODEV;
2573 }
2574
2575 if (route->control || route->connected)
30a6a1a4 2576 dev_warn(dapm->dev, "ASoC: Ignoring control for weak route %s->%s\n",
bf3a9e13
MB
2577 route->source, route->sink);
2578
2579 list_for_each_entry(path, &source->sinks, list_source) {
2580 if (path->sink == sink) {
2581 path->weak = 1;
2582 count++;
2583 }
2584 }
2585
2586 if (count == 0)
30a6a1a4 2587 dev_err(dapm->dev, "ASoC: No path found for weak route %s->%s\n",
bf3a9e13
MB
2588 route->source, route->sink);
2589 if (count > 1)
30a6a1a4 2590 dev_warn(dapm->dev, "ASoC: %d paths found for weak route %s->%s\n",
bf3a9e13
MB
2591 count, route->source, route->sink);
2592
2593 return 0;
2594}
2595
2596/**
2597 * snd_soc_dapm_weak_routes - Mark routes between DAPM widgets as weak
2598 * @dapm: DAPM context
2599 * @route: audio routes
2600 * @num: number of routes
2601 *
2602 * Mark existing routes matching those specified in the passed array
2603 * as being weak, meaning that they are ignored for the purpose of
2604 * power decisions. The main intended use case is for sidetone paths
2605 * which couple audio between other independent paths if they are both
2606 * active in order to make the combination work better at the user
2607 * level but which aren't intended to be "used".
2608 *
2609 * Note that CODEC drivers should not use this as sidetone type paths
2610 * can frequently also be used as bypass paths.
2611 */
2612int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
2613 const struct snd_soc_dapm_route *route, int num)
2614{
2615 int i, err;
2616 int ret = 0;
2617
a73fb2df 2618 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
bf3a9e13
MB
2619 for (i = 0; i < num; i++) {
2620 err = snd_soc_dapm_weak_route(dapm, route);
2621 if (err)
2622 ret = err;
2623 route++;
2624 }
a73fb2df 2625 mutex_unlock(&dapm->card->dapm_mutex);
bf3a9e13
MB
2626
2627 return ret;
2628}
2629EXPORT_SYMBOL_GPL(snd_soc_dapm_weak_routes);
2630
2b97eabc
RP
2631/**
2632 * snd_soc_dapm_new_widgets - add new dapm widgets
ce6120cc 2633 * @dapm: DAPM context
2b97eabc
RP
2634 *
2635 * Checks the codec for any new dapm widgets and creates them if found.
2636 *
2637 * Returns 0 for success.
2638 */
824ef826 2639int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
2b97eabc
RP
2640{
2641 struct snd_soc_dapm_widget *w;
b66a70d5 2642 unsigned int val;
2b97eabc 2643
95dd5cd6 2644 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
a73fb2df 2645
95dd5cd6 2646 list_for_each_entry(w, &card->widgets, list)
2b97eabc
RP
2647 {
2648 if (w->new)
2649 continue;
2650
fad59888
SW
2651 if (w->num_kcontrols) {
2652 w->kcontrols = kzalloc(w->num_kcontrols *
2653 sizeof(struct snd_kcontrol *),
2654 GFP_KERNEL);
a73fb2df 2655 if (!w->kcontrols) {
95dd5cd6 2656 mutex_unlock(&card->dapm_mutex);
fad59888 2657 return -ENOMEM;
a73fb2df 2658 }
fad59888
SW
2659 }
2660
2b97eabc
RP
2661 switch(w->id) {
2662 case snd_soc_dapm_switch:
2663 case snd_soc_dapm_mixer:
ca9c1aae 2664 case snd_soc_dapm_mixer_named_ctl:
4b80b8c2 2665 dapm_new_mixer(w);
2b97eabc
RP
2666 break;
2667 case snd_soc_dapm_mux:
4b80b8c2 2668 dapm_new_mux(w);
2b97eabc 2669 break;
2b97eabc 2670 case snd_soc_dapm_pga:
d88429a6 2671 case snd_soc_dapm_out_drv:
4b80b8c2 2672 dapm_new_pga(w);
2b97eabc 2673 break;
7ca3a18b 2674 default:
2b97eabc
RP
2675 break;
2676 }
b66a70d5
MB
2677
2678 /* Read the initial power state from the device */
2679 if (w->reg >= 0) {
f7d3c170
ASL
2680 soc_widget_read(w, w->reg, &val);
2681 val = val >> w->shift;
de9ba98b
LPC
2682 val &= w->mask;
2683 if (val == w->on_val)
b66a70d5
MB
2684 w->power = 1;
2685 }
2686
2b97eabc 2687 w->new = 1;
d5d1e0be 2688
7508b12a 2689 dapm_mark_dirty(w, "new widget");
d5d1e0be 2690 dapm_debugfs_add_widget(w);
2b97eabc
RP
2691 }
2692
95dd5cd6
LPC
2693 dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP);
2694 mutex_unlock(&card->dapm_mutex);
2b97eabc
RP
2695 return 0;
2696}
2697EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
2698
2699/**
2700 * snd_soc_dapm_get_volsw - dapm mixer get callback
2701 * @kcontrol: mixer control
ac11a2b3 2702 * @ucontrol: control element information
2b97eabc
RP
2703 *
2704 * Callback to get the value of a dapm mixer control.
2705 *
2706 * Returns 0 for success.
2707 */
2708int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
2709 struct snd_ctl_elem_value *ucontrol)
2710{
eee5d7f9 2711 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
57295073 2712 struct snd_soc_card *card = codec->card;
4eaa9819
JS
2713 struct soc_mixer_control *mc =
2714 (struct soc_mixer_control *)kcontrol->private_value;
249ce138 2715 int reg = mc->reg;
815ecf8d 2716 unsigned int shift = mc->shift;
4eaa9819 2717 int max = mc->max;
815ecf8d 2718 unsigned int mask = (1 << fls(max)) - 1;
da602ab8 2719 unsigned int invert = mc->invert;
57295073 2720 unsigned int val;
da602ab8
BT
2721
2722 if (snd_soc_volsw_is_stereo(mc))
eee5d7f9 2723 dev_warn(codec->dapm.dev,
30a6a1a4 2724 "ASoC: Control '%s' is stereo, which is not supported\n",
da602ab8 2725 kcontrol->id.name);
2b97eabc 2726
57295073 2727 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
249ce138 2728 if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM)
57295073
LPC
2729 val = (snd_soc_read(codec, reg) >> shift) & mask;
2730 else
2731 val = dapm_kcontrol_get_value(kcontrol);
2732 mutex_unlock(&card->dapm_mutex);
2733
da602ab8 2734 if (invert)
57295073
LPC
2735 ucontrol->value.integer.value[0] = max - val;
2736 else
2737 ucontrol->value.integer.value[0] = val;
2b97eabc
RP
2738
2739 return 0;
2740}
2741EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
2742
2743/**
2744 * snd_soc_dapm_put_volsw - dapm mixer set callback
2745 * @kcontrol: mixer control
ac11a2b3 2746 * @ucontrol: control element information
2b97eabc
RP
2747 *
2748 * Callback to set the value of a dapm mixer control.
2749 *
2750 * Returns 0 for success.
2751 */
2752int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2753 struct snd_ctl_elem_value *ucontrol)
2754{
eee5d7f9 2755 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
a73fb2df 2756 struct snd_soc_card *card = codec->card;
4eaa9819
JS
2757 struct soc_mixer_control *mc =
2758 (struct soc_mixer_control *)kcontrol->private_value;
249ce138 2759 int reg = mc->reg;
815ecf8d 2760 unsigned int shift = mc->shift;
4eaa9819 2761 int max = mc->max;
815ecf8d
JS
2762 unsigned int mask = (1 << fls(max)) - 1;
2763 unsigned int invert = mc->invert;
e9cf7049 2764 unsigned int val;
97404f2e
MB
2765 int connect, change;
2766 struct snd_soc_dapm_update update;
52765976 2767 int ret = 0;
2b97eabc 2768
da602ab8 2769 if (snd_soc_volsw_is_stereo(mc))
eee5d7f9 2770 dev_warn(codec->dapm.dev,
30a6a1a4 2771 "ASoC: Control '%s' is stereo, which is not supported\n",
da602ab8
BT
2772 kcontrol->id.name);
2773
2b97eabc 2774 val = (ucontrol->value.integer.value[0] & mask);
8a720718 2775 connect = !!val;
2b97eabc
RP
2776
2777 if (invert)
a7a4ac86 2778 val = max - val;
2b97eabc 2779
3cd04343 2780 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2b97eabc 2781
249ce138 2782 change = dapm_kcontrol_set_value(kcontrol, val);
97404f2e 2783 if (change) {
249ce138 2784 if (reg != SND_SOC_NOPM) {
c9e065c2
LPC
2785 mask = mask << shift;
2786 val = val << shift;
2787
2788 if (snd_soc_test_bits(codec, reg, mask, val)) {
2789 update.kcontrol = kcontrol;
2790 update.reg = reg;
2791 update.mask = mask;
2792 update.val = val;
2793 card->update = &update;
2794 }
97404f2e 2795
249ce138 2796 }
97404f2e 2797
52765976 2798 ret = soc_dapm_mixer_update_power(card, kcontrol, connect);
fafd2176 2799
564c6504 2800 card->update = NULL;
283375ce
MB
2801 }
2802
a73fb2df 2803 mutex_unlock(&card->dapm_mutex);
52765976
NC
2804
2805 if (ret > 0)
2806 soc_dpcm_runtime_update(card);
2807
56a67834 2808 return change;
2b97eabc
RP
2809}
2810EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
2811
2812/**
2813 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
2814 * @kcontrol: mixer control
ac11a2b3 2815 * @ucontrol: control element information
2b97eabc
RP
2816 *
2817 * Callback to get the value of a dapm enumerated double mixer control.
2818 *
2819 * Returns 0 for success.
2820 */
2821int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
2822 struct snd_ctl_elem_value *ucontrol)
2823{
eee5d7f9 2824 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2b97eabc 2825 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3727b496 2826 unsigned int reg_val, val;
52765976 2827
236aaa68
LPC
2828 if (e->reg != SND_SOC_NOPM)
2829 reg_val = snd_soc_read(codec, e->reg);
2830 else
2831 reg_val = dapm_kcontrol_get_value(kcontrol);
2e72f8e3 2832
2e72f8e3 2833 val = (reg_val >> e->shift_l) & e->mask;
3727b496 2834 ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val);
2e72f8e3
PU
2835 if (e->shift_l != e->shift_r) {
2836 val = (reg_val >> e->shift_r) & e->mask;
3727b496
LPC
2837 val = snd_soc_enum_val_to_item(e, val);
2838 ucontrol->value.enumerated.item[1] = val;
2e72f8e3
PU
2839 }
2840
2841 return 0;
2842}
2b97eabc 2843EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
2e72f8e3
PU
2844
2845/**
2b97eabc 2846 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
2e72f8e3
PU
2847 * @kcontrol: mixer control
2848 * @ucontrol: control element information
2849 *
2b97eabc 2850 * Callback to set the value of a dapm enumerated double mixer control.
2e72f8e3
PU
2851 *
2852 * Returns 0 for success.
2853 */
2b97eabc 2854int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2e72f8e3
PU
2855 struct snd_ctl_elem_value *ucontrol)
2856{
cf7c1de2 2857 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
a73fb2df 2858 struct snd_soc_card *card = codec->card;
74155556 2859 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
3727b496
LPC
2860 unsigned int *item = ucontrol->value.enumerated.item;
2861 unsigned int val, change;
46f5822f 2862 unsigned int mask;
97404f2e 2863 struct snd_soc_dapm_update update;
52765976 2864 int ret = 0;
2e72f8e3 2865
3727b496 2866 if (item[0] >= e->items)
2e72f8e3 2867 return -EINVAL;
3727b496
LPC
2868
2869 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
2e72f8e3
PU
2870 mask = e->mask << e->shift_l;
2871 if (e->shift_l != e->shift_r) {
3727b496 2872 if (item[1] > e->items)
2e72f8e3 2873 return -EINVAL;
3727b496 2874 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l;
2e72f8e3
PU
2875 mask |= e->mask << e->shift_r;
2876 }
2877
3cd04343 2878 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
fafd2176 2879
236aaa68
LPC
2880 if (e->reg != SND_SOC_NOPM)
2881 change = snd_soc_test_bits(codec, e->reg, mask, val);
2882 else
2883 change = dapm_kcontrol_set_value(kcontrol, val);
2884
fafd2176 2885 if (change) {
236aaa68
LPC
2886 if (e->reg != SND_SOC_NOPM) {
2887 update.kcontrol = kcontrol;
2888 update.reg = e->reg;
2889 update.mask = mask;
2890 update.val = val;
2891 card->update = &update;
2892 }
1642e3d4 2893
3727b496 2894 ret = soc_dapm_mux_update_power(card, kcontrol, item[0], e);
fafd2176 2895
564c6504 2896 card->update = NULL;
fafd2176 2897 }
2e72f8e3 2898
a73fb2df 2899 mutex_unlock(&card->dapm_mutex);
52765976
NC
2900
2901 if (ret > 0)
2902 soc_dpcm_runtime_update(card);
2903
97404f2e 2904 return change;
2e72f8e3 2905}
2b97eabc 2906EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
2e72f8e3 2907
8b37dbd2
MB
2908/**
2909 * snd_soc_dapm_info_pin_switch - Info for a pin switch
2910 *
2911 * @kcontrol: mixer control
2912 * @uinfo: control element information
2913 *
2914 * Callback to provide information about a pin switch control.
2915 */
2916int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
2917 struct snd_ctl_elem_info *uinfo)
2918{
2919 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2920 uinfo->count = 1;
2921 uinfo->value.integer.min = 0;
2922 uinfo->value.integer.max = 1;
2923
2924 return 0;
2925}
2926EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch);
2927
2928/**
2929 * snd_soc_dapm_get_pin_switch - Get information for a pin switch
2930 *
2931 * @kcontrol: mixer control
2932 * @ucontrol: Value
2933 */
2934int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
2935 struct snd_ctl_elem_value *ucontrol)
2936{
48a8c394 2937 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
8b37dbd2
MB
2938 const char *pin = (const char *)kcontrol->private_value;
2939
3cd04343 2940 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
8b37dbd2
MB
2941
2942 ucontrol->value.integer.value[0] =
48a8c394 2943 snd_soc_dapm_get_pin_status(&card->dapm, pin);
8b37dbd2 2944
a73fb2df 2945 mutex_unlock(&card->dapm_mutex);
8b37dbd2
MB
2946
2947 return 0;
2948}
2949EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch);
2950
2951/**
2952 * snd_soc_dapm_put_pin_switch - Set information for a pin switch
2953 *
2954 * @kcontrol: mixer control
2955 * @ucontrol: Value
2956 */
2957int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
2958 struct snd_ctl_elem_value *ucontrol)
2959{
48a8c394 2960 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
8b37dbd2
MB
2961 const char *pin = (const char *)kcontrol->private_value;
2962
8b37dbd2 2963 if (ucontrol->value.integer.value[0])
48a8c394 2964 snd_soc_dapm_enable_pin(&card->dapm, pin);
8b37dbd2 2965 else
48a8c394 2966 snd_soc_dapm_disable_pin(&card->dapm, pin);
8b37dbd2 2967
a73fb2df 2968 snd_soc_dapm_sync(&card->dapm);
8b37dbd2
MB
2969 return 0;
2970}
2971EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
2972
5ba06fc9
MB
2973static struct snd_soc_dapm_widget *
2974snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2975 const struct snd_soc_dapm_widget *widget)
2b97eabc
RP
2976{
2977 struct snd_soc_dapm_widget *w;
94f99c87 2978 const char *prefix;
62ea874a 2979 int ret;
2b97eabc
RP
2980
2981 if ((w = dapm_cnew_widget(widget)) == NULL)
5ba06fc9 2982 return NULL;
2b97eabc 2983
62ea874a
MB
2984 switch (w->id) {
2985 case snd_soc_dapm_regulator_supply:
a3cc056b
LG
2986 w->regulator = devm_regulator_get(dapm->dev, w->name);
2987 if (IS_ERR(w->regulator)) {
2988 ret = PTR_ERR(w->regulator);
30a6a1a4 2989 dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
62ea874a 2990 w->name, ret);
5ba06fc9 2991 return NULL;
62ea874a 2992 }
8784c77a 2993
de9ba98b 2994 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
8784c77a
MB
2995 ret = regulator_allow_bypass(w->regulator, true);
2996 if (ret != 0)
2997 dev_warn(w->dapm->dev,
30686c35 2998 "ASoC: Failed to bypass %s: %d\n",
8784c77a
MB
2999 w->name, ret);
3000 }
62ea874a 3001 break;
d7e7eb91 3002 case snd_soc_dapm_clock_supply:
165961ef 3003#ifdef CONFIG_CLKDEV_LOOKUP
695594f1 3004 w->clk = devm_clk_get(dapm->dev, w->name);
d7e7eb91
OL
3005 if (IS_ERR(w->clk)) {
3006 ret = PTR_ERR(w->clk);
30a6a1a4 3007 dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
d7e7eb91
OL
3008 w->name, ret);
3009 return NULL;
3010 }
ec02995a
MB
3011#else
3012 return NULL;
3013#endif
d7e7eb91 3014 break;
62ea874a
MB
3015 default:
3016 break;
3017 }
2b97eabc 3018
94f99c87
LPC
3019 prefix = soc_dapm_prefix(dapm);
3020 if (prefix)
3021 w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, widget->name);
2b581074
LPC
3022 else
3023 w->name = kasprintf(GFP_KERNEL, "%s", widget->name);
3024
ead9b919
JN
3025 if (w->name == NULL) {
3026 kfree(w);
5ba06fc9 3027 return NULL;
ead9b919 3028 }
ead9b919 3029
7ca3a18b
MB
3030 switch (w->id) {
3031 case snd_soc_dapm_switch:
3032 case snd_soc_dapm_mixer:
3033 case snd_soc_dapm_mixer_named_ctl:
3034 w->power_check = dapm_generic_check_power;
3035 break;
3036 case snd_soc_dapm_mux:
7ca3a18b
MB
3037 w->power_check = dapm_generic_check_power;
3038 break;
4616274d 3039 case snd_soc_dapm_dai_out:
7ca3a18b
MB
3040 w->power_check = dapm_adc_check_power;
3041 break;
4616274d 3042 case snd_soc_dapm_dai_in:
7ca3a18b
MB
3043 w->power_check = dapm_dac_check_power;
3044 break;
63c69a6e
MB
3045 case snd_soc_dapm_adc:
3046 case snd_soc_dapm_aif_out:
3047 case snd_soc_dapm_dac:
3048 case snd_soc_dapm_aif_in:
7ca3a18b
MB
3049 case snd_soc_dapm_pga:
3050 case snd_soc_dapm_out_drv:
3051 case snd_soc_dapm_input:
3052 case snd_soc_dapm_output:
3053 case snd_soc_dapm_micbias:
3054 case snd_soc_dapm_spk:
3055 case snd_soc_dapm_hp:
3056 case snd_soc_dapm_mic:
3057 case snd_soc_dapm_line:
c74184ed 3058 case snd_soc_dapm_dai_link:
7ca3a18b
MB
3059 w->power_check = dapm_generic_check_power;
3060 break;
3061 case snd_soc_dapm_supply:
62ea874a 3062 case snd_soc_dapm_regulator_supply:
d7e7eb91 3063 case snd_soc_dapm_clock_supply:
57295073 3064 case snd_soc_dapm_kcontrol:
7ca3a18b
MB
3065 w->power_check = dapm_supply_check_power;
3066 break;
3067 default:
3068 w->power_check = dapm_always_on_check_power;
3069 break;
3070 }
3071
ce6120cc
LG
3072 w->dapm = dapm;
3073 w->codec = dapm->codec;
b7950641 3074 w->platform = dapm->platform;
2b97eabc
RP
3075 INIT_LIST_HEAD(&w->sources);
3076 INIT_LIST_HEAD(&w->sinks);
3077 INIT_LIST_HEAD(&w->list);
db432b41 3078 INIT_LIST_HEAD(&w->dirty);
97c866de 3079 list_add(&w->list, &dapm->card->widgets);
2b97eabc
RP
3080
3081 /* machine layer set ups unconnected pins and insertions */
3082 w->connected = 1;
5ba06fc9 3083 return w;
2b97eabc 3084}
2b97eabc 3085
4ba1327a
MB
3086/**
3087 * snd_soc_dapm_new_controls - create new dapm controls
ce6120cc 3088 * @dapm: DAPM context
4ba1327a
MB
3089 * @widget: widget array
3090 * @num: number of widgets
3091 *
3092 * Creates new DAPM controls based upon the templates.
3093 *
3094 * Returns 0 for success else error.
3095 */
ce6120cc 3096int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
4ba1327a
MB
3097 const struct snd_soc_dapm_widget *widget,
3098 int num)
3099{
5ba06fc9
MB
3100 struct snd_soc_dapm_widget *w;
3101 int i;
60884c27 3102 int ret = 0;
4ba1327a 3103
a73fb2df 3104 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
4ba1327a 3105 for (i = 0; i < num; i++) {
5ba06fc9
MB
3106 w = snd_soc_dapm_new_control(dapm, widget);
3107 if (!w) {
f7d41ae8 3108 dev_err(dapm->dev,
5ba06fc9
MB
3109 "ASoC: Failed to create DAPM control %s\n",
3110 widget->name);
60884c27
DC
3111 ret = -ENOMEM;
3112 break;
b8b33cb5 3113 }
4ba1327a
MB
3114 widget++;
3115 }
a73fb2df 3116 mutex_unlock(&dapm->card->dapm_mutex);
60884c27 3117 return ret;
4ba1327a
MB
3118}
3119EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
3120
c74184ed
MB
3121static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3122 struct snd_kcontrol *kcontrol, int event)
3123{
3124 struct snd_soc_dapm_path *source_p, *sink_p;
3125 struct snd_soc_dai *source, *sink;
3126 const struct snd_soc_pcm_stream *config = w->params;
3127 struct snd_pcm_substream substream;
9747cec2 3128 struct snd_pcm_hw_params *params = NULL;
c74184ed
MB
3129 u64 fmt;
3130 int ret;
3131
bf4edea8
TI
3132 if (WARN_ON(!config) ||
3133 WARN_ON(list_empty(&w->sources) || list_empty(&w->sinks)))
3134 return -EINVAL;
c74184ed
MB
3135
3136 /* We only support a single source and sink, pick the first */
3137 source_p = list_first_entry(&w->sources, struct snd_soc_dapm_path,
3138 list_sink);
3139 sink_p = list_first_entry(&w->sinks, struct snd_soc_dapm_path,
3140 list_source);
3141
bf4edea8
TI
3142 if (WARN_ON(!source_p || !sink_p) ||
3143 WARN_ON(!sink_p->source || !source_p->sink) ||
3144 WARN_ON(!source_p->source || !sink_p->sink))
3145 return -EINVAL;
c74184ed
MB
3146
3147 source = source_p->source->priv;
3148 sink = sink_p->sink->priv;
3149
3150 /* Be a little careful as we don't want to overflow the mask array */
3151 if (config->formats) {
3152 fmt = ffs(config->formats) - 1;
3153 } else {
30a6a1a4 3154 dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n",
c74184ed
MB
3155 config->formats);
3156 fmt = 0;
3157 }
3158
3159 /* Currently very limited parameter selection */
9747cec2
MB
3160 params = kzalloc(sizeof(*params), GFP_KERNEL);
3161 if (!params) {
3162 ret = -ENOMEM;
3163 goto out;
3164 }
3165 snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
c74184ed 3166
9747cec2 3167 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min =
c74184ed 3168 config->rate_min;
9747cec2 3169 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max =
c74184ed
MB
3170 config->rate_max;
3171
9747cec2 3172 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min
c74184ed 3173 = config->channels_min;
9747cec2 3174 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max
c74184ed
MB
3175 = config->channels_max;
3176
3177 memset(&substream, 0, sizeof(substream));
3178
3179 switch (event) {
3180 case SND_SOC_DAPM_PRE_PMU:
3181 if (source->driver->ops && source->driver->ops->hw_params) {
3182 substream.stream = SNDRV_PCM_STREAM_CAPTURE;
3183 ret = source->driver->ops->hw_params(&substream,
9747cec2 3184 params, source);
c74184ed
MB
3185 if (ret != 0) {
3186 dev_err(source->dev,
30a6a1a4 3187 "ASoC: hw_params() failed: %d\n", ret);
9747cec2 3188 goto out;
c74184ed
MB
3189 }
3190 }
3191
3192 if (sink->driver->ops && sink->driver->ops->hw_params) {
3193 substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
9747cec2 3194 ret = sink->driver->ops->hw_params(&substream, params,
c74184ed
MB
3195 sink);
3196 if (ret != 0) {
3197 dev_err(sink->dev,
30a6a1a4 3198 "ASoC: hw_params() failed: %d\n", ret);
9747cec2 3199 goto out;
c74184ed
MB
3200 }
3201 }
3202 break;
3203
3204 case SND_SOC_DAPM_POST_PMU:
da18396f
MB
3205 ret = snd_soc_dai_digital_mute(sink, 0,
3206 SNDRV_PCM_STREAM_PLAYBACK);
c74184ed 3207 if (ret != 0 && ret != -ENOTSUPP)
30a6a1a4 3208 dev_warn(sink->dev, "ASoC: Failed to unmute: %d\n", ret);
9747cec2 3209 ret = 0;
c74184ed
MB
3210 break;
3211
3212 case SND_SOC_DAPM_PRE_PMD:
da18396f
MB
3213 ret = snd_soc_dai_digital_mute(sink, 1,
3214 SNDRV_PCM_STREAM_PLAYBACK);
c74184ed 3215 if (ret != 0 && ret != -ENOTSUPP)
30a6a1a4 3216 dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret);
9747cec2 3217 ret = 0;
c74184ed
MB
3218 break;
3219
3220 default:
a6ed0608 3221 WARN(1, "Unknown event %d\n", event);
c74184ed
MB
3222 return -EINVAL;
3223 }
3224
9747cec2
MB
3225out:
3226 kfree(params);
3227 return ret;
c74184ed
MB
3228}
3229
3230int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
3231 const struct snd_soc_pcm_stream *params,
3232 struct snd_soc_dapm_widget *source,
3233 struct snd_soc_dapm_widget *sink)
3234{
c74184ed
MB
3235 struct snd_soc_dapm_widget template;
3236 struct snd_soc_dapm_widget *w;
3237 size_t len;
3238 char *link_name;
fe83897f 3239 int ret;
c74184ed
MB
3240
3241 len = strlen(source->name) + strlen(sink->name) + 2;
3242 link_name = devm_kzalloc(card->dev, len, GFP_KERNEL);
3243 if (!link_name)
3244 return -ENOMEM;
3245 snprintf(link_name, len, "%s-%s", source->name, sink->name);
3246
3247 memset(&template, 0, sizeof(template));
3248 template.reg = SND_SOC_NOPM;
3249 template.id = snd_soc_dapm_dai_link;
3250 template.name = link_name;
3251 template.event = snd_soc_dai_link_event;
3252 template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3253 SND_SOC_DAPM_PRE_PMD;
3254
30a6a1a4 3255 dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name);
c74184ed
MB
3256
3257 w = snd_soc_dapm_new_control(&card->dapm, &template);
3258 if (!w) {
30a6a1a4 3259 dev_err(card->dev, "ASoC: Failed to create %s widget\n",
c74184ed
MB
3260 link_name);
3261 return -ENOMEM;
3262 }
3263
3264 w->params = params;
3265
fe83897f
LPC
3266 ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL);
3267 if (ret)
3268 return ret;
3269 return snd_soc_dapm_add_path(&card->dapm, w, sink, NULL, NULL);
c74184ed
MB
3270}
3271
888df395
MB
3272int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
3273 struct snd_soc_dai *dai)
2b97eabc 3274{
888df395 3275 struct snd_soc_dapm_widget template;
2b97eabc
RP
3276 struct snd_soc_dapm_widget *w;
3277
888df395
MB
3278 WARN_ON(dapm->dev != dai->dev);
3279
3280 memset(&template, 0, sizeof(template));
3281 template.reg = SND_SOC_NOPM;
3282
3283 if (dai->driver->playback.stream_name) {
4616274d 3284 template.id = snd_soc_dapm_dai_in;
888df395
MB
3285 template.name = dai->driver->playback.stream_name;
3286 template.sname = dai->driver->playback.stream_name;
3287
30a6a1a4 3288 dev_dbg(dai->dev, "ASoC: adding %s widget\n",
888df395
MB
3289 template.name);
3290
3291 w = snd_soc_dapm_new_control(dapm, &template);
3292 if (!w) {
30a6a1a4 3293 dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
888df395 3294 dai->driver->playback.stream_name);
298402a3 3295 return -ENOMEM;
888df395
MB
3296 }
3297
3298 w->priv = dai;
3299 dai->playback_widget = w;
3300 }
3301
3302 if (dai->driver->capture.stream_name) {
4616274d 3303 template.id = snd_soc_dapm_dai_out;
888df395
MB
3304 template.name = dai->driver->capture.stream_name;
3305 template.sname = dai->driver->capture.stream_name;
3306
30a6a1a4 3307 dev_dbg(dai->dev, "ASoC: adding %s widget\n",
888df395
MB
3308 template.name);
3309
3310 w = snd_soc_dapm_new_control(dapm, &template);
3311 if (!w) {
30a6a1a4 3312 dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
888df395 3313 dai->driver->capture.stream_name);
298402a3 3314 return -ENOMEM;
888df395
MB
3315 }
3316
3317 w->priv = dai;
3318 dai->capture_widget = w;
3319 }
3320
3321 return 0;
3322}
3323
3324int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
3325{
3326 struct snd_soc_dapm_widget *dai_w, *w;
0f9bd7b1 3327 struct snd_soc_dapm_widget *src, *sink;
888df395 3328 struct snd_soc_dai *dai;
888df395
MB
3329
3330 /* For each DAI widget... */
3331 list_for_each_entry(dai_w, &card->widgets, list) {
4616274d
MB
3332 switch (dai_w->id) {
3333 case snd_soc_dapm_dai_in:
3334 case snd_soc_dapm_dai_out:
3335 break;
3336 default:
2b97eabc 3337 continue;
4616274d 3338 }
888df395
MB
3339
3340 dai = dai_w->priv;
3341
3342 /* ...find all widgets with the same stream and link them */
3343 list_for_each_entry(w, &card->widgets, list) {
3344 if (w->dapm != dai_w->dapm)
3345 continue;
3346
4616274d
MB
3347 switch (w->id) {
3348 case snd_soc_dapm_dai_in:
3349 case snd_soc_dapm_dai_out:
888df395 3350 continue;
4616274d
MB
3351 default:
3352 break;
3353 }
888df395 3354
19c2c5f5 3355 if (!w->sname || !strstr(w->sname, dai_w->name))
888df395
MB
3356 continue;
3357
0f9bd7b1
LPC
3358 if (dai_w->id == snd_soc_dapm_dai_in) {
3359 src = dai_w;
3360 sink = w;
3361 } else {
3362 src = w;
3363 sink = dai_w;
2b97eabc 3364 }
0f9bd7b1
LPC
3365 dev_dbg(dai->dev, "%s -> %s\n", src->name, sink->name);
3366 snd_soc_dapm_add_path(w->dapm, src, sink, NULL, NULL);
2b97eabc
RP
3367 }
3368 }
2b97eabc 3369
888df395
MB
3370 return 0;
3371}
64a648c2 3372
b893ea5f
LG
3373void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
3374{
3375 struct snd_soc_pcm_runtime *rtd = card->rtd;
9887c20b 3376 struct snd_soc_dapm_widget *sink, *source;
b893ea5f 3377 struct snd_soc_dai *cpu_dai, *codec_dai;
b893ea5f
LG
3378 int i;
3379
b893ea5f
LG
3380 /* for each BE DAI link... */
3381 for (i = 0; i < card->num_rtd; i++) {
3382 rtd = &card->rtd[i];
3383 cpu_dai = rtd->cpu_dai;
3384 codec_dai = rtd->codec_dai;
3385
ca5106ae
LPC
3386 /*
3387 * dynamic FE links have no fixed DAI mapping.
3388 * CODEC<->CODEC links have no direct connection.
3389 */
3390 if (rtd->dai_link->dynamic || rtd->dai_link->params)
b893ea5f
LG
3391 continue;
3392
3393 /* there is no point in connecting BE DAI links with dummies */
3394 if (snd_soc_dai_is_dummy(codec_dai) ||
3395 snd_soc_dai_is_dummy(cpu_dai))
3396 continue;
3397
3398 /* connect BE DAI playback if widgets are valid */
3399 if (codec_dai->playback_widget && cpu_dai->playback_widget) {
9887c20b
LPC
3400 source = cpu_dai->playback_widget;
3401 sink = codec_dai->playback_widget;
b893ea5f 3402 dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
9887c20b
LPC
3403 cpu_dai->codec->name, source->name,
3404 codec_dai->platform->name, sink->name);
b893ea5f 3405
9887c20b
LPC
3406 snd_soc_dapm_add_path(&card->dapm, source, sink,
3407 NULL, NULL);
b893ea5f
LG
3408 }
3409
3410 /* connect BE DAI capture if widgets are valid */
3411 if (codec_dai->capture_widget && cpu_dai->capture_widget) {
9887c20b
LPC
3412 source = codec_dai->capture_widget;
3413 sink = cpu_dai->capture_widget;
b893ea5f 3414 dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
9887c20b
LPC
3415 codec_dai->codec->name, source->name,
3416 cpu_dai->platform->name, sink->name);
b893ea5f 3417
9887c20b
LPC
3418 snd_soc_dapm_add_path(&card->dapm, source, sink,
3419 NULL, NULL);
b893ea5f 3420 }
b893ea5f
LG
3421 }
3422}
3423
c471fdd1 3424static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
d9b0951b 3425 int event)
2b97eabc 3426{
c471fdd1 3427 struct snd_soc_dapm_widget *w;
7bd3a6f3 3428
c471fdd1
LPC
3429 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
3430 w = dai->playback_widget;
3431 else
3432 w = dai->capture_widget;
fe360685 3433
c471fdd1
LPC
3434 if (w) {
3435 dapm_mark_dirty(w, "stream event");
d9b0951b
LG
3436
3437 switch (event) {
3438 case SND_SOC_DAPM_STREAM_START:
c471fdd1 3439 w->active = 1;
d9b0951b
LG
3440 break;
3441 case SND_SOC_DAPM_STREAM_STOP:
c471fdd1 3442 w->active = 0;
d9b0951b
LG
3443 break;
3444 case SND_SOC_DAPM_STREAM_SUSPEND:
3445 case SND_SOC_DAPM_STREAM_RESUME:
3446 case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
3447 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
3448 break;
3449 }
3450 }
c471fdd1 3451}
d9b0951b 3452
c471fdd1
LPC
3453static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
3454 int event)
3455{
3456 soc_dapm_dai_stream_event(rtd->cpu_dai, stream, event);
3457 soc_dapm_dai_stream_event(rtd->codec_dai, stream, event);
2b97eabc 3458
95dd5cd6 3459 dapm_power_widgets(rtd->card, event);
ce6120cc
LG
3460}
3461
3462/**
3463 * snd_soc_dapm_stream_event - send a stream event to the dapm core
3464 * @rtd: PCM runtime data
3465 * @stream: stream name
3466 * @event: stream event
3467 *
3468 * Sends a stream event to the dapm core. The core then makes any
3469 * necessary widget power changes.
3470 *
3471 * Returns 0 for success else error.
3472 */
d9b0951b
LG
3473void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
3474 int event)
ce6120cc 3475{
a73fb2df 3476 struct snd_soc_card *card = rtd->card;
ce6120cc 3477
3cd04343 3478 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
d9b0951b 3479 soc_dapm_stream_event(rtd, stream, event);
a73fb2df 3480 mutex_unlock(&card->dapm_mutex);
2b97eabc 3481}
2b97eabc 3482
11391100
CK
3483/**
3484 * snd_soc_dapm_enable_pin_unlocked - enable pin.
3485 * @dapm: DAPM context
3486 * @pin: pin name
3487 *
3488 * Enables input/output pin and its parents or children widgets iff there is
3489 * a valid audio route and active audio stream.
3490 *
3491 * Requires external locking.
3492 *
3493 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3494 * do any widget power switching.
3495 */
3496int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
3497 const char *pin)
3498{
3499 return snd_soc_dapm_set_pin(dapm, pin, 1);
3500}
3501EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin_unlocked);
3502
2b97eabc 3503/**
a5302181 3504 * snd_soc_dapm_enable_pin - enable pin.
ce6120cc 3505 * @dapm: DAPM context
a5302181 3506 * @pin: pin name
2b97eabc 3507 *
74b8f955 3508 * Enables input/output pin and its parents or children widgets iff there is
a5302181 3509 * a valid audio route and active audio stream.
11391100 3510 *
a5302181
LG
3511 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3512 * do any widget power switching.
2b97eabc 3513 */
ce6120cc 3514int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin)
2b97eabc 3515{
11391100
CK
3516 int ret;
3517
3518 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3519
3520 ret = snd_soc_dapm_set_pin(dapm, pin, 1);
3521
3522 mutex_unlock(&dapm->card->dapm_mutex);
3523
3524 return ret;
a5302181
LG
3525}
3526EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
2b97eabc 3527
da34183e 3528/**
11391100 3529 * snd_soc_dapm_force_enable_pin_unlocked - force a pin to be enabled
ce6120cc 3530 * @dapm: DAPM context
da34183e
MB
3531 * @pin: pin name
3532 *
3533 * Enables input/output pin regardless of any other state. This is
3534 * intended for use with microphone bias supplies used in microphone
3535 * jack detection.
3536 *
11391100
CK
3537 * Requires external locking.
3538 *
da34183e
MB
3539 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3540 * do any widget power switching.
3541 */
11391100
CK
3542int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
3543 const char *pin)
da34183e 3544{
91a5fca4 3545 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
da34183e 3546
91a5fca4 3547 if (!w) {
30a6a1a4 3548 dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin);
91a5fca4 3549 return -EINVAL;
0d86733c
MB
3550 }
3551
30a6a1a4 3552 dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin);
91a5fca4
LPC
3553 w->connected = 1;
3554 w->force = 1;
75c1f891 3555 dapm_mark_dirty(w, "force enable");
da34183e 3556
91a5fca4 3557 return 0;
da34183e 3558}
11391100
CK
3559EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin_unlocked);
3560
3561/**
3562 * snd_soc_dapm_force_enable_pin - force a pin to be enabled
3563 * @dapm: DAPM context
3564 * @pin: pin name
3565 *
3566 * Enables input/output pin regardless of any other state. This is
3567 * intended for use with microphone bias supplies used in microphone
3568 * jack detection.
3569 *
3570 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3571 * do any widget power switching.
3572 */
3573int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
3574 const char *pin)
3575{
3576 int ret;
3577
3578 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3579
3580 ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
3581
3582 mutex_unlock(&dapm->card->dapm_mutex);
3583
3584 return ret;
3585}
da34183e
MB
3586EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
3587
11391100
CK
3588/**
3589 * snd_soc_dapm_disable_pin_unlocked - disable pin.
3590 * @dapm: DAPM context
3591 * @pin: pin name
3592 *
3593 * Disables input/output pin and its parents or children widgets.
3594 *
3595 * Requires external locking.
3596 *
3597 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3598 * do any widget power switching.
3599 */
3600int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm,
3601 const char *pin)
3602{
3603 return snd_soc_dapm_set_pin(dapm, pin, 0);
3604}
3605EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin_unlocked);
3606
a5302181
LG
3607/**
3608 * snd_soc_dapm_disable_pin - disable pin.
ce6120cc 3609 * @dapm: DAPM context
a5302181
LG
3610 * @pin: pin name
3611 *
74b8f955 3612 * Disables input/output pin and its parents or children widgets.
11391100 3613 *
a5302181
LG
3614 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3615 * do any widget power switching.
3616 */
ce6120cc
LG
3617int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
3618 const char *pin)
a5302181 3619{
11391100
CK
3620 int ret;
3621
3622 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3623
3624 ret = snd_soc_dapm_set_pin(dapm, pin, 0);
3625
3626 mutex_unlock(&dapm->card->dapm_mutex);
3627
3628 return ret;
2b97eabc 3629}
a5302181 3630EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
2b97eabc 3631
11391100
CK
3632/**
3633 * snd_soc_dapm_nc_pin_unlocked - permanently disable pin.
3634 * @dapm: DAPM context
3635 * @pin: pin name
3636 *
3637 * Marks the specified pin as being not connected, disabling it along
3638 * any parent or child widgets. At present this is identical to
3639 * snd_soc_dapm_disable_pin() but in future it will be extended to do
3640 * additional things such as disabling controls which only affect
3641 * paths through the pin.
3642 *
3643 * Requires external locking.
3644 *
3645 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3646 * do any widget power switching.
3647 */
3648int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm,
3649 const char *pin)
3650{
3651 return snd_soc_dapm_set_pin(dapm, pin, 0);
3652}
3653EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin_unlocked);
3654
5817b52a
MB
3655/**
3656 * snd_soc_dapm_nc_pin - permanently disable pin.
ce6120cc 3657 * @dapm: DAPM context
5817b52a
MB
3658 * @pin: pin name
3659 *
3660 * Marks the specified pin as being not connected, disabling it along
3661 * any parent or child widgets. At present this is identical to
3662 * snd_soc_dapm_disable_pin() but in future it will be extended to do
3663 * additional things such as disabling controls which only affect
3664 * paths through the pin.
3665 *
3666 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
3667 * do any widget power switching.
3668 */
ce6120cc 3669int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin)
5817b52a 3670{
11391100
CK
3671 int ret;
3672
3673 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
3674
3675 ret = snd_soc_dapm_set_pin(dapm, pin, 0);
3676
3677 mutex_unlock(&dapm->card->dapm_mutex);
3678
3679 return ret;
5817b52a
MB
3680}
3681EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
3682
eeec12bf 3683/**
a5302181 3684 * snd_soc_dapm_get_pin_status - get audio pin status
ce6120cc 3685 * @dapm: DAPM context
a5302181 3686 * @pin: audio signal pin endpoint (or start point)
eeec12bf 3687 *
a5302181 3688 * Get audio pin status - connected or disconnected.
eeec12bf 3689 *
a5302181 3690 * Returns 1 for connected otherwise 0.
eeec12bf 3691 */
ce6120cc
LG
3692int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
3693 const char *pin)
eeec12bf 3694{
91a5fca4 3695 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
eeec12bf 3696
91a5fca4
LPC
3697 if (w)
3698 return w->connected;
a68b38ad 3699
eeec12bf
GG
3700 return 0;
3701}
a5302181 3702EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
eeec12bf 3703
1547aba9
MB
3704/**
3705 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
ce6120cc 3706 * @dapm: DAPM context
1547aba9
MB
3707 * @pin: audio signal pin endpoint (or start point)
3708 *
3709 * Mark the given endpoint or pin as ignoring suspend. When the
3710 * system is disabled a path between two endpoints flagged as ignoring
3711 * suspend will not be disabled. The path must already be enabled via
3712 * normal means at suspend time, it will not be turned on if it was not
3713 * already enabled.
3714 */
ce6120cc
LG
3715int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
3716 const char *pin)
1547aba9 3717{
91a5fca4 3718 struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false);
1547aba9 3719
91a5fca4 3720 if (!w) {
30a6a1a4 3721 dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin);
91a5fca4 3722 return -EINVAL;
1547aba9
MB
3723 }
3724
91a5fca4
LPC
3725 w->ignore_suspend = 1;
3726
3727 return 0;
1547aba9
MB
3728}
3729EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
3730
1633281b
SW
3731static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card,
3732 struct snd_soc_dapm_widget *w)
3733{
3734 struct snd_soc_dapm_path *p;
3735
3736 list_for_each_entry(p, &card->paths, list) {
3737 if ((p->source == w) || (p->sink == w)) {
3738 dev_dbg(card->dev,
3739 "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n",
3740 p->source->name, p->source->id, p->source->dapm,
3741 p->sink->name, p->sink->id, p->sink->dapm);
3742
3743 /* Connected to something other than the codec */
3744 if (p->source->dapm != p->sink->dapm)
3745 return true;
3746 /*
3747 * Loopback connection from codec external pin to
3748 * codec external pin
3749 */
3750 if (p->sink->id == snd_soc_dapm_input) {
3751 switch (p->source->id) {
3752 case snd_soc_dapm_output:
3753 case snd_soc_dapm_micbias:
3754 return true;
3755 default:
3756 break;
3757 }
3758 }
3759 }
3760 }
3761
3762 return false;
3763}
3764
3765/**
3766 * snd_soc_dapm_auto_nc_codec_pins - call snd_soc_dapm_nc_pin for unused pins
3767 * @codec: The codec whose pins should be processed
3768 *
3769 * Automatically call snd_soc_dapm_nc_pin() for any external pins in the codec
3770 * which are unused. Pins are used if they are connected externally to the
3771 * codec, whether that be to some other device, or a loop-back connection to
3772 * the codec itself.
3773 */
3774void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec)
3775{
3776 struct snd_soc_card *card = codec->card;
3777 struct snd_soc_dapm_context *dapm = &codec->dapm;
3778 struct snd_soc_dapm_widget *w;
3779
30a6a1a4 3780 dev_dbg(codec->dev, "ASoC: Auto NC: DAPMs: card:%p codec:%p\n",
1633281b
SW
3781 &card->dapm, &codec->dapm);
3782
3783 list_for_each_entry(w, &card->widgets, list) {
3784 if (w->dapm != dapm)
3785 continue;
3786 switch (w->id) {
3787 case snd_soc_dapm_input:
3788 case snd_soc_dapm_output:
3789 case snd_soc_dapm_micbias:
30a6a1a4 3790 dev_dbg(codec->dev, "ASoC: Auto NC: Checking widget %s\n",
1633281b
SW
3791 w->name);
3792 if (!snd_soc_dapm_widget_in_card_paths(card, w)) {
a094b80b 3793 dev_dbg(codec->dev,
1633281b
SW
3794 "... Not in map; disabling\n");
3795 snd_soc_dapm_nc_pin(dapm, w->name);
3796 }
3797 break;
3798 default:
3799 break;
3800 }
3801 }
3802}
3803
2b97eabc
RP
3804/**
3805 * snd_soc_dapm_free - free dapm resources
728a5222 3806 * @dapm: DAPM context
2b97eabc
RP
3807 *
3808 * Free all dapm widgets and resources.
3809 */
ce6120cc 3810void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
2b97eabc 3811{
ce6120cc 3812 snd_soc_dapm_sys_remove(dapm->dev);
6c45e126 3813 dapm_debugfs_cleanup(dapm);
ce6120cc 3814 dapm_free_widgets(dapm);
7be31be8 3815 list_del(&dapm->list);
2b97eabc
RP
3816}
3817EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
3818
57996358 3819static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm)
51737470 3820{
01005a72 3821 struct snd_soc_card *card = dapm->card;
51737470
MB
3822 struct snd_soc_dapm_widget *w;
3823 LIST_HEAD(down_list);
3824 int powerdown = 0;
3825
01005a72
LG
3826 mutex_lock(&card->dapm_mutex);
3827
97c866de
JN
3828 list_for_each_entry(w, &dapm->card->widgets, list) {
3829 if (w->dapm != dapm)
3830 continue;
51737470 3831 if (w->power) {
828a842f 3832 dapm_seq_insert(w, &down_list, false);
c2caa4da 3833 w->power = 0;
51737470
MB
3834 powerdown = 1;
3835 }
3836 }
3837
3838 /* If there were no widgets to power down we're already in
3839 * standby.
3840 */
3841 if (powerdown) {
7679e42e
MB
3842 if (dapm->bias_level == SND_SOC_BIAS_ON)
3843 snd_soc_dapm_set_bias_level(dapm,
3844 SND_SOC_BIAS_PREPARE);
95dd5cd6 3845 dapm_seq_run(card, &down_list, 0, false);
7679e42e
MB
3846 if (dapm->bias_level == SND_SOC_BIAS_PREPARE)
3847 snd_soc_dapm_set_bias_level(dapm,
3848 SND_SOC_BIAS_STANDBY);
51737470 3849 }
01005a72
LG
3850
3851 mutex_unlock(&card->dapm_mutex);
f0fba2ad
LG
3852}
3853
3854/*
3855 * snd_soc_dapm_shutdown - callback for system shutdown
3856 */
3857void snd_soc_dapm_shutdown(struct snd_soc_card *card)
3858{
57996358 3859 struct snd_soc_dapm_context *dapm;
f0fba2ad 3860
57996358 3861 list_for_each_entry(dapm, &card->dapm_list, list) {
17282ba4
XX
3862 if (dapm != &card->dapm) {
3863 soc_dapm_shutdown_dapm(dapm);
3864 if (dapm->bias_level == SND_SOC_BIAS_STANDBY)
3865 snd_soc_dapm_set_bias_level(dapm,
3866 SND_SOC_BIAS_OFF);
3867 }
ce6120cc 3868 }
17282ba4
XX
3869
3870 soc_dapm_shutdown_dapm(&card->dapm);
3871 if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY)
3872 snd_soc_dapm_set_bias_level(&card->dapm,
3873 SND_SOC_BIAS_OFF);
51737470
MB
3874}
3875
2b97eabc 3876/* Module information */
d331124d 3877MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
2b97eabc
RP
3878MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");
3879MODULE_LICENSE("GPL");
This page took 0.843682 seconds and 5 git commands to generate.