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