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