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