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