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