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