xref: /openbmc/linux/sound/soc/soc-dapm.c (revision 367b8112)
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  *      DAC's/ADC's.
16  *    o Platform power domain - can support external components i.e. amps and
17  *      mic/meadphone 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 powerdown of audio susbsystem to reduce pops between a quick
22  *      device reopen.
23  *
24  *  Todo:
25  *    o DAPM power change sequencing - allow for configurable per
26  *      codec sequences.
27  *    o Support for analogue bias optimisation.
28  *    o Support for reduced codec oversampling rates.
29  *    o Support for reduced codec bias currents.
30  */
31 
32 #include <linux/module.h>
33 #include <linux/moduleparam.h>
34 #include <linux/init.h>
35 #include <linux/delay.h>
36 #include <linux/pm.h>
37 #include <linux/bitops.h>
38 #include <linux/platform_device.h>
39 #include <linux/jiffies.h>
40 #include <linux/debugfs.h>
41 #include <sound/core.h>
42 #include <sound/pcm.h>
43 #include <sound/pcm_params.h>
44 #include <sound/soc-dapm.h>
45 #include <sound/initval.h>
46 
47 /* debug */
48 #ifdef DEBUG
49 #define dump_dapm(codec, action) dbg_dump_dapm(codec, action)
50 #else
51 #define dump_dapm(codec, action)
52 #endif
53 
54 /* dapm power sequences - make this per codec in the future */
55 static int dapm_up_seq[] = {
56 	snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic,
57 	snd_soc_dapm_mux, snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_pga,
58 	snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post
59 };
60 static int dapm_down_seq[] = {
61 	snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
62 	snd_soc_dapm_pga, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic,
63 	snd_soc_dapm_micbias, snd_soc_dapm_mux, snd_soc_dapm_post
64 };
65 
66 static int dapm_status = 1;
67 module_param(dapm_status, int, 0);
68 MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
69 
70 static struct dentry *asoc_debugfs;
71 
72 static u32 pop_time;
73 
74 static void pop_wait(void)
75 {
76 	if (pop_time)
77 		schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
78 }
79 
80 static void pop_dbg(const char *fmt, ...)
81 {
82 	va_list args;
83 
84 	va_start(args, fmt);
85 
86 	if (pop_time) {
87 		vprintk(fmt, args);
88 		pop_wait();
89 	}
90 
91 	va_end(args);
92 }
93 
94 /* create a new dapm widget */
95 static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
96 	const struct snd_soc_dapm_widget *_widget)
97 {
98 	return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
99 }
100 
101 /* set up initial codec paths */
102 static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
103 	struct snd_soc_dapm_path *p, int i)
104 {
105 	switch (w->id) {
106 	case snd_soc_dapm_switch:
107 	case snd_soc_dapm_mixer: {
108 		int val;
109 		struct soc_mixer_control *mc = (struct soc_mixer_control *)
110 			w->kcontrols[i].private_value;
111 		unsigned int reg = mc->reg;
112 		unsigned int shift = mc->shift;
113 		int max = mc->max;
114 		unsigned int mask = (1 << fls(max)) - 1;
115 		unsigned int invert = mc->invert;
116 
117 		val = snd_soc_read(w->codec, reg);
118 		val = (val >> shift) & mask;
119 
120 		if ((invert && !val) || (!invert && val))
121 			p->connect = 1;
122 		else
123 			p->connect = 0;
124 	}
125 	break;
126 	case snd_soc_dapm_mux: {
127 		struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value;
128 		int val, item, bitmask;
129 
130 		for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
131 		;
132 		val = snd_soc_read(w->codec, e->reg);
133 		item = (val >> e->shift_l) & (bitmask - 1);
134 
135 		p->connect = 0;
136 		for (i = 0; i < e->max; i++) {
137 			if (!(strcmp(p->name, e->texts[i])) && item == i)
138 				p->connect = 1;
139 		}
140 	}
141 	break;
142 	/* does not effect routing - always connected */
143 	case snd_soc_dapm_pga:
144 	case snd_soc_dapm_output:
145 	case snd_soc_dapm_adc:
146 	case snd_soc_dapm_input:
147 	case snd_soc_dapm_dac:
148 	case snd_soc_dapm_micbias:
149 	case snd_soc_dapm_vmid:
150 		p->connect = 1;
151 	break;
152 	/* does effect routing - dynamically connected */
153 	case snd_soc_dapm_hp:
154 	case snd_soc_dapm_mic:
155 	case snd_soc_dapm_spk:
156 	case snd_soc_dapm_line:
157 	case snd_soc_dapm_pre:
158 	case snd_soc_dapm_post:
159 		p->connect = 0;
160 	break;
161 	}
162 }
163 
164 /* connect mux widget to it's interconnecting audio paths */
165 static int dapm_connect_mux(struct snd_soc_codec *codec,
166 	struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
167 	struct snd_soc_dapm_path *path, const char *control_name,
168 	const struct snd_kcontrol_new *kcontrol)
169 {
170 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
171 	int i;
172 
173 	for (i = 0; i < e->max; i++) {
174 		if (!(strcmp(control_name, e->texts[i]))) {
175 			list_add(&path->list, &codec->dapm_paths);
176 			list_add(&path->list_sink, &dest->sources);
177 			list_add(&path->list_source, &src->sinks);
178 			path->name = (char*)e->texts[i];
179 			dapm_set_path_status(dest, path, 0);
180 			return 0;
181 		}
182 	}
183 
184 	return -ENODEV;
185 }
186 
187 /* connect mixer widget to it's interconnecting audio paths */
188 static int dapm_connect_mixer(struct snd_soc_codec *codec,
189 	struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
190 	struct snd_soc_dapm_path *path, const char *control_name)
191 {
192 	int i;
193 
194 	/* search for mixer kcontrol */
195 	for (i = 0; i < dest->num_kcontrols; i++) {
196 		if (!strcmp(control_name, dest->kcontrols[i].name)) {
197 			list_add(&path->list, &codec->dapm_paths);
198 			list_add(&path->list_sink, &dest->sources);
199 			list_add(&path->list_source, &src->sinks);
200 			path->name = dest->kcontrols[i].name;
201 			dapm_set_path_status(dest, path, i);
202 			return 0;
203 		}
204 	}
205 	return -ENODEV;
206 }
207 
208 /* update dapm codec register bits */
209 static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
210 {
211 	int change, power;
212 	unsigned short old, new;
213 	struct snd_soc_codec *codec = widget->codec;
214 
215 	/* check for valid widgets */
216 	if (widget->reg < 0 || widget->id == snd_soc_dapm_input ||
217 		widget->id == snd_soc_dapm_output ||
218 		widget->id == snd_soc_dapm_hp ||
219 		widget->id == snd_soc_dapm_mic ||
220 		widget->id == snd_soc_dapm_line ||
221 		widget->id == snd_soc_dapm_spk)
222 		return 0;
223 
224 	power = widget->power;
225 	if (widget->invert)
226 		power = (power ? 0:1);
227 
228 	old = snd_soc_read(codec, widget->reg);
229 	new = (old & ~(0x1 << widget->shift)) | (power << widget->shift);
230 
231 	change = old != new;
232 	if (change) {
233 		pop_dbg("pop test %s : %s in %d ms\n", widget->name,
234 			widget->power ? "on" : "off", pop_time);
235 		snd_soc_write(codec, widget->reg, new);
236 		pop_wait();
237 	}
238 	pr_debug("reg %x old %x new %x change %d\n", widget->reg,
239 		 old, new, change);
240 	return change;
241 }
242 
243 /* ramps the volume up or down to minimise pops before or after a
244  * DAPM power event */
245 static int dapm_set_pga(struct snd_soc_dapm_widget *widget, int power)
246 {
247 	const struct snd_kcontrol_new *k = widget->kcontrols;
248 
249 	if (widget->muted && !power)
250 		return 0;
251 	if (!widget->muted && power)
252 		return 0;
253 
254 	if (widget->num_kcontrols && k) {
255 		struct soc_mixer_control *mc =
256 			(struct soc_mixer_control *)k->private_value;
257 		unsigned int reg = mc->reg;
258 		unsigned int shift = mc->shift;
259 		int max = mc->max;
260 		unsigned int mask = (1 << fls(max)) - 1;
261 		unsigned int invert = mc->invert;
262 
263 		if (power) {
264 			int i;
265 			/* power up has happended, increase volume to last level */
266 			if (invert) {
267 				for (i = max; i > widget->saved_value; i--)
268 					snd_soc_update_bits(widget->codec, reg, mask, i);
269 			} else {
270 				for (i = 0; i < widget->saved_value; i++)
271 					snd_soc_update_bits(widget->codec, reg, mask, i);
272 			}
273 			widget->muted = 0;
274 		} else {
275 			/* power down is about to occur, decrease volume to mute */
276 			int val = snd_soc_read(widget->codec, reg);
277 			int i = widget->saved_value = (val >> shift) & mask;
278 			if (invert) {
279 				for (; i < mask; i++)
280 					snd_soc_update_bits(widget->codec, reg, mask, i);
281 			} else {
282 				for (; i > 0; i--)
283 					snd_soc_update_bits(widget->codec, reg, mask, i);
284 			}
285 			widget->muted = 1;
286 		}
287 	}
288 	return 0;
289 }
290 
291 /* create new dapm mixer control */
292 static int dapm_new_mixer(struct snd_soc_codec *codec,
293 	struct snd_soc_dapm_widget *w)
294 {
295 	int i, ret = 0;
296 	char name[32];
297 	struct snd_soc_dapm_path *path;
298 
299 	/* add kcontrol */
300 	for (i = 0; i < w->num_kcontrols; i++) {
301 
302 		/* match name */
303 		list_for_each_entry(path, &w->sources, list_sink) {
304 
305 			/* mixer/mux paths name must match control name */
306 			if (path->name != (char*)w->kcontrols[i].name)
307 				continue;
308 
309 			/* add dapm control with long name */
310 			snprintf(name, 32, "%s %s", w->name, w->kcontrols[i].name);
311 			path->long_name = kstrdup (name, GFP_KERNEL);
312 			if (path->long_name == NULL)
313 				return -ENOMEM;
314 
315 			path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
316 				path->long_name);
317 			ret = snd_ctl_add(codec->card, path->kcontrol);
318 			if (ret < 0) {
319 				printk(KERN_ERR "asoc: failed to add dapm kcontrol %s\n",
320 						path->long_name);
321 				kfree(path->long_name);
322 				path->long_name = NULL;
323 				return ret;
324 			}
325 		}
326 	}
327 	return ret;
328 }
329 
330 /* create new dapm mux control */
331 static int dapm_new_mux(struct snd_soc_codec *codec,
332 	struct snd_soc_dapm_widget *w)
333 {
334 	struct snd_soc_dapm_path *path = NULL;
335 	struct snd_kcontrol *kcontrol;
336 	int ret = 0;
337 
338 	if (!w->num_kcontrols) {
339 		printk(KERN_ERR "asoc: mux %s has no controls\n", w->name);
340 		return -EINVAL;
341 	}
342 
343 	kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name);
344 	ret = snd_ctl_add(codec->card, kcontrol);
345 	if (ret < 0)
346 		goto err;
347 
348 	list_for_each_entry(path, &w->sources, list_sink)
349 		path->kcontrol = kcontrol;
350 
351 	return ret;
352 
353 err:
354 	printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name);
355 	return ret;
356 }
357 
358 /* create new dapm volume control */
359 static int dapm_new_pga(struct snd_soc_codec *codec,
360 	struct snd_soc_dapm_widget *w)
361 {
362 	struct snd_kcontrol *kcontrol;
363 	int ret = 0;
364 
365 	if (!w->num_kcontrols)
366 		return -EINVAL;
367 
368 	kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name);
369 	ret = snd_ctl_add(codec->card, kcontrol);
370 	if (ret < 0) {
371 		printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name);
372 		return ret;
373 	}
374 
375 	return ret;
376 }
377 
378 /* reset 'walked' bit for each dapm path */
379 static inline void dapm_clear_walk(struct snd_soc_codec *codec)
380 {
381 	struct snd_soc_dapm_path *p;
382 
383 	list_for_each_entry(p, &codec->dapm_paths, list)
384 		p->walked = 0;
385 }
386 
387 /*
388  * Recursively check for a completed path to an active or physically connected
389  * output widget. Returns number of complete paths.
390  */
391 static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
392 {
393 	struct snd_soc_dapm_path *path;
394 	int con = 0;
395 
396 	if (widget->id == snd_soc_dapm_adc && widget->active)
397 		return 1;
398 
399 	if (widget->connected) {
400 		/* connected pin ? */
401 		if (widget->id == snd_soc_dapm_output && !widget->ext)
402 			return 1;
403 
404 		/* connected jack or spk ? */
405 		if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk ||
406 			widget->id == snd_soc_dapm_line)
407 			return 1;
408 	}
409 
410 	list_for_each_entry(path, &widget->sinks, list_source) {
411 		if (path->walked)
412 			continue;
413 
414 		if (path->sink && path->connect) {
415 			path->walked = 1;
416 			con += is_connected_output_ep(path->sink);
417 		}
418 	}
419 
420 	return con;
421 }
422 
423 /*
424  * Recursively check for a completed path to an active or physically connected
425  * input widget. Returns number of complete paths.
426  */
427 static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
428 {
429 	struct snd_soc_dapm_path *path;
430 	int con = 0;
431 
432 	/* active stream ? */
433 	if (widget->id == snd_soc_dapm_dac && widget->active)
434 		return 1;
435 
436 	if (widget->connected) {
437 		/* connected pin ? */
438 		if (widget->id == snd_soc_dapm_input && !widget->ext)
439 			return 1;
440 
441 		/* connected VMID/Bias for lower pops */
442 		if (widget->id == snd_soc_dapm_vmid)
443 			return 1;
444 
445 		/* connected jack ? */
446 		if (widget->id == snd_soc_dapm_mic || widget->id == snd_soc_dapm_line)
447 			return 1;
448 	}
449 
450 	list_for_each_entry(path, &widget->sources, list_sink) {
451 		if (path->walked)
452 			continue;
453 
454 		if (path->source && path->connect) {
455 			path->walked = 1;
456 			con += is_connected_input_ep(path->source);
457 		}
458 	}
459 
460 	return con;
461 }
462 
463 /*
464  * Handler for generic register modifier widget.
465  */
466 int dapm_reg_event(struct snd_soc_dapm_widget *w,
467 		   struct snd_kcontrol *kcontrol, int event)
468 {
469 	unsigned int val;
470 
471 	if (SND_SOC_DAPM_EVENT_ON(event))
472 		val = w->on_val;
473 	else
474 		val = w->off_val;
475 
476 	snd_soc_update_bits(w->codec, -(w->reg + 1),
477 			    w->mask << w->shift, val << w->shift);
478 
479 	return 0;
480 }
481 EXPORT_SYMBOL_GPL(dapm_reg_event);
482 
483 /*
484  * Scan each dapm widget for complete audio path.
485  * A complete path is a route that has valid endpoints i.e.:-
486  *
487  *  o DAC to output pin.
488  *  o Input Pin to ADC.
489  *  o Input pin to Output pin (bypass, sidetone)
490  *  o DAC to ADC (loopback).
491  */
492 static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
493 {
494 	struct snd_soc_dapm_widget *w;
495 	int in, out, i, c = 1, *seq = NULL, ret = 0, power_change, power;
496 
497 	/* do we have a sequenced stream event */
498 	if (event == SND_SOC_DAPM_STREAM_START) {
499 		c = ARRAY_SIZE(dapm_up_seq);
500 		seq = dapm_up_seq;
501 	} else if (event == SND_SOC_DAPM_STREAM_STOP) {
502 		c = ARRAY_SIZE(dapm_down_seq);
503 		seq = dapm_down_seq;
504 	}
505 
506 	for(i = 0; i < c; i++) {
507 		list_for_each_entry(w, &codec->dapm_widgets, list) {
508 
509 			/* is widget in stream order */
510 			if (seq && seq[i] && w->id != seq[i])
511 				continue;
512 
513 			/* vmid - no action */
514 			if (w->id == snd_soc_dapm_vmid)
515 				continue;
516 
517 			/* active ADC */
518 			if (w->id == snd_soc_dapm_adc && w->active) {
519 				in = is_connected_input_ep(w);
520 				dapm_clear_walk(w->codec);
521 				w->power = (in != 0) ? 1 : 0;
522 				dapm_update_bits(w);
523 				continue;
524 			}
525 
526 			/* active DAC */
527 			if (w->id == snd_soc_dapm_dac && w->active) {
528 				out = is_connected_output_ep(w);
529 				dapm_clear_walk(w->codec);
530 				w->power = (out != 0) ? 1 : 0;
531 				dapm_update_bits(w);
532 				continue;
533 			}
534 
535 			/* pre and post event widgets */
536 			if (w->id == snd_soc_dapm_pre) {
537 				if (!w->event)
538 					continue;
539 
540 				if (event == SND_SOC_DAPM_STREAM_START) {
541 					ret = w->event(w,
542 						NULL, SND_SOC_DAPM_PRE_PMU);
543 					if (ret < 0)
544 						return ret;
545 				} else if (event == SND_SOC_DAPM_STREAM_STOP) {
546 					ret = w->event(w,
547 						NULL, SND_SOC_DAPM_PRE_PMD);
548 					if (ret < 0)
549 						return ret;
550 				}
551 				continue;
552 			}
553 			if (w->id == snd_soc_dapm_post) {
554 				if (!w->event)
555 					continue;
556 
557 				if (event == SND_SOC_DAPM_STREAM_START) {
558 					ret = w->event(w,
559 						NULL, SND_SOC_DAPM_POST_PMU);
560 					if (ret < 0)
561 						return ret;
562 				} else if (event == SND_SOC_DAPM_STREAM_STOP) {
563 					ret = w->event(w,
564 						NULL, SND_SOC_DAPM_POST_PMD);
565 					if (ret < 0)
566 						return ret;
567 				}
568 				continue;
569 			}
570 
571 			/* all other widgets */
572 			in = is_connected_input_ep(w);
573 			dapm_clear_walk(w->codec);
574 			out = is_connected_output_ep(w);
575 			dapm_clear_walk(w->codec);
576 			power = (out != 0 && in != 0) ? 1 : 0;
577 			power_change = (w->power == power) ? 0: 1;
578 			w->power = power;
579 
580 			if (!power_change)
581 				continue;
582 
583 			/* call any power change event handlers */
584 			if (w->event)
585 				pr_debug("power %s event for %s flags %x\n",
586 					 w->power ? "on" : "off",
587 					 w->name, w->event_flags);
588 
589 			/* power up pre event */
590 			if (power && w->event &&
591 			    (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
592 				ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
593 				if (ret < 0)
594 					return ret;
595 			}
596 
597 			/* power down pre event */
598 			if (!power && w->event &&
599 			    (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
600 				ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
601 				if (ret < 0)
602 					return ret;
603 			}
604 
605 			/* Lower PGA volume to reduce pops */
606 			if (w->id == snd_soc_dapm_pga && !power)
607 				dapm_set_pga(w, power);
608 
609 			dapm_update_bits(w);
610 
611 			/* Raise PGA volume to reduce pops */
612 			if (w->id == snd_soc_dapm_pga && power)
613 				dapm_set_pga(w, power);
614 
615 			/* power up post event */
616 			if (power && w->event &&
617 			    (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
618 				ret = w->event(w,
619 					       NULL, SND_SOC_DAPM_POST_PMU);
620 				if (ret < 0)
621 					return ret;
622 			}
623 
624 			/* power down post event */
625 			if (!power && w->event &&
626 			    (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
627 				ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
628 				if (ret < 0)
629 					return ret;
630 			}
631 		}
632 	}
633 
634 	return ret;
635 }
636 
637 #ifdef DEBUG
638 static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
639 {
640 	struct snd_soc_dapm_widget *w;
641 	struct snd_soc_dapm_path *p = NULL;
642 	int in, out;
643 
644 	printk("DAPM %s %s\n", codec->name, action);
645 
646 	list_for_each_entry(w, &codec->dapm_widgets, list) {
647 
648 		/* only display widgets that effect routing */
649 		switch (w->id) {
650 		case snd_soc_dapm_pre:
651 		case snd_soc_dapm_post:
652 		case snd_soc_dapm_vmid:
653 			continue;
654 		case snd_soc_dapm_mux:
655 		case snd_soc_dapm_output:
656 		case snd_soc_dapm_input:
657 		case snd_soc_dapm_switch:
658 		case snd_soc_dapm_hp:
659 		case snd_soc_dapm_mic:
660 		case snd_soc_dapm_spk:
661 		case snd_soc_dapm_line:
662 		case snd_soc_dapm_micbias:
663 		case snd_soc_dapm_dac:
664 		case snd_soc_dapm_adc:
665 		case snd_soc_dapm_pga:
666 		case snd_soc_dapm_mixer:
667 			if (w->name) {
668 				in = is_connected_input_ep(w);
669 				dapm_clear_walk(w->codec);
670 				out = is_connected_output_ep(w);
671 				dapm_clear_walk(w->codec);
672 				printk("%s: %s  in %d out %d\n", w->name,
673 					w->power ? "On":"Off",in, out);
674 
675 				list_for_each_entry(p, &w->sources, list_sink) {
676 					if (p->connect)
677 						printk(" in  %s %s\n", p->name ? p->name : "static",
678 							p->source->name);
679 				}
680 				list_for_each_entry(p, &w->sinks, list_source) {
681 					if (p->connect)
682 						printk(" out %s %s\n", p->name ? p->name : "static",
683 							p->sink->name);
684 				}
685 			}
686 		break;
687 		}
688 	}
689 }
690 #endif
691 
692 /* test and update the power status of a mux widget */
693 static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
694 				 struct snd_kcontrol *kcontrol, int mask,
695 				 int mux, int val, struct soc_enum *e)
696 {
697 	struct snd_soc_dapm_path *path;
698 	int found = 0;
699 
700 	if (widget->id != snd_soc_dapm_mux)
701 		return -ENODEV;
702 
703 	if (!snd_soc_test_bits(widget->codec, e->reg, mask, val))
704 		return 0;
705 
706 	/* find dapm widget path assoc with kcontrol */
707 	list_for_each_entry(path, &widget->codec->dapm_paths, list) {
708 		if (path->kcontrol != kcontrol)
709 			continue;
710 
711 		if (!path->name || !e->texts[mux])
712 			continue;
713 
714 		found = 1;
715 		/* we now need to match the string in the enum to the path */
716 		if (!(strcmp(path->name, e->texts[mux])))
717 			path->connect = 1; /* new connection */
718 		else
719 			path->connect = 0; /* old connection must be powered down */
720 	}
721 
722 	if (found) {
723 		dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
724 		dump_dapm(widget->codec, "mux power update");
725 	}
726 
727 	return 0;
728 }
729 
730 /* test and update the power status of a mixer or switch widget */
731 static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
732 				   struct snd_kcontrol *kcontrol, int reg,
733 				   int val_mask, int val, int invert)
734 {
735 	struct snd_soc_dapm_path *path;
736 	int found = 0;
737 
738 	if (widget->id != snd_soc_dapm_mixer &&
739 	    widget->id != snd_soc_dapm_switch)
740 		return -ENODEV;
741 
742 	if (!snd_soc_test_bits(widget->codec, reg, val_mask, val))
743 		return 0;
744 
745 	/* find dapm widget path assoc with kcontrol */
746 	list_for_each_entry(path, &widget->codec->dapm_paths, list) {
747 		if (path->kcontrol != kcontrol)
748 			continue;
749 
750 		/* found, now check type */
751 		found = 1;
752 		if (val)
753 			/* new connection */
754 			path->connect = invert ? 0:1;
755 		else
756 			/* old connection must be powered down */
757 			path->connect = invert ? 1:0;
758 		break;
759 	}
760 
761 	if (found) {
762 		dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
763 		dump_dapm(widget->codec, "mixer power update");
764 	}
765 
766 	return 0;
767 }
768 
769 /* show dapm widget status in sys fs */
770 static ssize_t dapm_widget_show(struct device *dev,
771 	struct device_attribute *attr, char *buf)
772 {
773 	struct snd_soc_device *devdata = dev_get_drvdata(dev);
774 	struct snd_soc_codec *codec = devdata->codec;
775 	struct snd_soc_dapm_widget *w;
776 	int count = 0;
777 	char *state = "not set";
778 
779 	list_for_each_entry(w, &codec->dapm_widgets, list) {
780 
781 		/* only display widgets that burnm power */
782 		switch (w->id) {
783 		case snd_soc_dapm_hp:
784 		case snd_soc_dapm_mic:
785 		case snd_soc_dapm_spk:
786 		case snd_soc_dapm_line:
787 		case snd_soc_dapm_micbias:
788 		case snd_soc_dapm_dac:
789 		case snd_soc_dapm_adc:
790 		case snd_soc_dapm_pga:
791 		case snd_soc_dapm_mixer:
792 			if (w->name)
793 				count += sprintf(buf + count, "%s: %s\n",
794 					w->name, w->power ? "On":"Off");
795 		break;
796 		default:
797 		break;
798 		}
799 	}
800 
801 	switch (codec->bias_level) {
802 	case SND_SOC_BIAS_ON:
803 		state = "On";
804 		break;
805 	case SND_SOC_BIAS_PREPARE:
806 		state = "Prepare";
807 		break;
808 	case SND_SOC_BIAS_STANDBY:
809 		state = "Standby";
810 		break;
811 	case SND_SOC_BIAS_OFF:
812 		state = "Off";
813 		break;
814 	}
815 	count += sprintf(buf + count, "PM State: %s\n", state);
816 
817 	return count;
818 }
819 
820 static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
821 
822 int snd_soc_dapm_sys_add(struct device *dev)
823 {
824 	int ret = 0;
825 
826 	if (!dapm_status)
827 		return 0;
828 
829 	ret = device_create_file(dev, &dev_attr_dapm_widget);
830 	if (ret != 0)
831 		return ret;
832 
833 	asoc_debugfs = debugfs_create_dir("asoc", NULL);
834 	if (!IS_ERR(asoc_debugfs) && asoc_debugfs)
835 		debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs,
836 				   &pop_time);
837 	else
838 		asoc_debugfs = NULL;
839 
840 	return 0;
841 }
842 
843 static void snd_soc_dapm_sys_remove(struct device *dev)
844 {
845 	if (dapm_status) {
846 		device_remove_file(dev, &dev_attr_dapm_widget);
847 	}
848 
849 	if (asoc_debugfs)
850 		debugfs_remove_recursive(asoc_debugfs);
851 }
852 
853 /* free all dapm widgets and resources */
854 static void dapm_free_widgets(struct snd_soc_codec *codec)
855 {
856 	struct snd_soc_dapm_widget *w, *next_w;
857 	struct snd_soc_dapm_path *p, *next_p;
858 
859 	list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) {
860 		list_del(&w->list);
861 		kfree(w);
862 	}
863 
864 	list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) {
865 		list_del(&p->list);
866 		kfree(p->long_name);
867 		kfree(p);
868 	}
869 }
870 
871 static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
872 	char *pin, int status)
873 {
874 	struct snd_soc_dapm_widget *w;
875 
876 	list_for_each_entry(w, &codec->dapm_widgets, list) {
877 		if (!strcmp(w->name, pin)) {
878 			pr_debug("dapm: %s: pin %s\n", codec->name, pin);
879 			w->connected = status;
880 			return 0;
881 		}
882 	}
883 
884 	pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin);
885 	return -EINVAL;
886 }
887 
888 /**
889  * snd_soc_dapm_sync - scan and power dapm paths
890  * @codec: audio codec
891  *
892  * Walks all dapm audio paths and powers widgets according to their
893  * stream or path usage.
894  *
895  * Returns 0 for success.
896  */
897 int snd_soc_dapm_sync(struct snd_soc_codec *codec)
898 {
899 	int ret = dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
900 	dump_dapm(codec, "sync");
901 	return ret;
902 }
903 EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
904 
905 static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
906 	const char *sink, const char *control, const char *source)
907 {
908 	struct snd_soc_dapm_path *path;
909 	struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
910 	int ret = 0;
911 
912 	/* find src and dest widgets */
913 	list_for_each_entry(w, &codec->dapm_widgets, list) {
914 
915 		if (!wsink && !(strcmp(w->name, sink))) {
916 			wsink = w;
917 			continue;
918 		}
919 		if (!wsource && !(strcmp(w->name, source))) {
920 			wsource = w;
921 		}
922 	}
923 
924 	if (wsource == NULL || wsink == NULL)
925 		return -ENODEV;
926 
927 	path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL);
928 	if (!path)
929 		return -ENOMEM;
930 
931 	path->source = wsource;
932 	path->sink = wsink;
933 	INIT_LIST_HEAD(&path->list);
934 	INIT_LIST_HEAD(&path->list_source);
935 	INIT_LIST_HEAD(&path->list_sink);
936 
937 	/* check for external widgets */
938 	if (wsink->id == snd_soc_dapm_input) {
939 		if (wsource->id == snd_soc_dapm_micbias ||
940 			wsource->id == snd_soc_dapm_mic ||
941 			wsink->id == snd_soc_dapm_line ||
942 			wsink->id == snd_soc_dapm_output)
943 			wsink->ext = 1;
944 	}
945 	if (wsource->id == snd_soc_dapm_output) {
946 		if (wsink->id == snd_soc_dapm_spk ||
947 			wsink->id == snd_soc_dapm_hp ||
948 			wsink->id == snd_soc_dapm_line ||
949 			wsink->id == snd_soc_dapm_input)
950 			wsource->ext = 1;
951 	}
952 
953 	/* connect static paths */
954 	if (control == NULL) {
955 		list_add(&path->list, &codec->dapm_paths);
956 		list_add(&path->list_sink, &wsink->sources);
957 		list_add(&path->list_source, &wsource->sinks);
958 		path->connect = 1;
959 		return 0;
960 	}
961 
962 	/* connect dynamic paths */
963 	switch(wsink->id) {
964 	case snd_soc_dapm_adc:
965 	case snd_soc_dapm_dac:
966 	case snd_soc_dapm_pga:
967 	case snd_soc_dapm_input:
968 	case snd_soc_dapm_output:
969 	case snd_soc_dapm_micbias:
970 	case snd_soc_dapm_vmid:
971 	case snd_soc_dapm_pre:
972 	case snd_soc_dapm_post:
973 		list_add(&path->list, &codec->dapm_paths);
974 		list_add(&path->list_sink, &wsink->sources);
975 		list_add(&path->list_source, &wsource->sinks);
976 		path->connect = 1;
977 		return 0;
978 	case snd_soc_dapm_mux:
979 		ret = dapm_connect_mux(codec, wsource, wsink, path, control,
980 			&wsink->kcontrols[0]);
981 		if (ret != 0)
982 			goto err;
983 		break;
984 	case snd_soc_dapm_switch:
985 	case snd_soc_dapm_mixer:
986 		ret = dapm_connect_mixer(codec, wsource, wsink, path, control);
987 		if (ret != 0)
988 			goto err;
989 		break;
990 	case snd_soc_dapm_hp:
991 	case snd_soc_dapm_mic:
992 	case snd_soc_dapm_line:
993 	case snd_soc_dapm_spk:
994 		list_add(&path->list, &codec->dapm_paths);
995 		list_add(&path->list_sink, &wsink->sources);
996 		list_add(&path->list_source, &wsource->sinks);
997 		path->connect = 0;
998 		return 0;
999 	}
1000 	return 0;
1001 
1002 err:
1003 	printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source,
1004 		control, sink);
1005 	kfree(path);
1006 	return ret;
1007 }
1008 
1009 /**
1010  * snd_soc_dapm_connect_input - connect dapm widgets
1011  * @codec: audio codec
1012  * @sink: name of target widget
1013  * @control: mixer control name
1014  * @source: name of source name
1015  *
1016  * Connects 2 dapm widgets together via a named audio path. The sink is
1017  * the widget receiving the audio signal, whilst the source is the sender
1018  * of the audio signal.
1019  *
1020  * This function has been deprecated in favour of snd_soc_dapm_add_routes().
1021  *
1022  * Returns 0 for success else error.
1023  */
1024 int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink,
1025 	const char *control, const char *source)
1026 {
1027 	return snd_soc_dapm_add_route(codec, sink, control, source);
1028 }
1029 EXPORT_SYMBOL_GPL(snd_soc_dapm_connect_input);
1030 
1031 /**
1032  * snd_soc_dapm_add_routes - Add routes between DAPM widgets
1033  * @codec: codec
1034  * @route: audio routes
1035  * @num: number of routes
1036  *
1037  * Connects 2 dapm widgets together via a named audio path. The sink is
1038  * the widget receiving the audio signal, whilst the source is the sender
1039  * of the audio signal.
1040  *
1041  * Returns 0 for success else error. On error all resources can be freed
1042  * with a call to snd_soc_card_free().
1043  */
1044 int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
1045 			    const struct snd_soc_dapm_route *route, int num)
1046 {
1047 	int i, ret;
1048 
1049 	for (i = 0; i < num; i++) {
1050 		ret = snd_soc_dapm_add_route(codec, route->sink,
1051 					     route->control, route->source);
1052 		if (ret < 0) {
1053 			printk(KERN_ERR "Failed to add route %s->%s\n",
1054 			       route->source,
1055 			       route->sink);
1056 			return ret;
1057 		}
1058 		route++;
1059 	}
1060 
1061 	return 0;
1062 }
1063 EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
1064 
1065 /**
1066  * snd_soc_dapm_new_widgets - add new dapm widgets
1067  * @codec: audio codec
1068  *
1069  * Checks the codec for any new dapm widgets and creates them if found.
1070  *
1071  * Returns 0 for success.
1072  */
1073 int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1074 {
1075 	struct snd_soc_dapm_widget *w;
1076 
1077 	list_for_each_entry(w, &codec->dapm_widgets, list)
1078 	{
1079 		if (w->new)
1080 			continue;
1081 
1082 		switch(w->id) {
1083 		case snd_soc_dapm_switch:
1084 		case snd_soc_dapm_mixer:
1085 			dapm_new_mixer(codec, w);
1086 			break;
1087 		case snd_soc_dapm_mux:
1088 			dapm_new_mux(codec, w);
1089 			break;
1090 		case snd_soc_dapm_adc:
1091 		case snd_soc_dapm_dac:
1092 		case snd_soc_dapm_pga:
1093 			dapm_new_pga(codec, w);
1094 			break;
1095 		case snd_soc_dapm_input:
1096 		case snd_soc_dapm_output:
1097 		case snd_soc_dapm_micbias:
1098 		case snd_soc_dapm_spk:
1099 		case snd_soc_dapm_hp:
1100 		case snd_soc_dapm_mic:
1101 		case snd_soc_dapm_line:
1102 		case snd_soc_dapm_vmid:
1103 		case snd_soc_dapm_pre:
1104 		case snd_soc_dapm_post:
1105 			break;
1106 		}
1107 		w->new = 1;
1108 	}
1109 
1110 	dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
1111 	return 0;
1112 }
1113 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
1114 
1115 /**
1116  * snd_soc_dapm_get_volsw - dapm mixer get callback
1117  * @kcontrol: mixer control
1118  * @uinfo: control element information
1119  *
1120  * Callback to get the value of a dapm mixer control.
1121  *
1122  * Returns 0 for success.
1123  */
1124 int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
1125 	struct snd_ctl_elem_value *ucontrol)
1126 {
1127 	struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1128 	struct soc_mixer_control *mc =
1129 		(struct soc_mixer_control *)kcontrol->private_value;
1130 	unsigned int reg = mc->reg;
1131 	unsigned int shift = mc->shift;
1132 	unsigned int rshift = mc->rshift;
1133 	int max = mc->max;
1134 	unsigned int invert = mc->invert;
1135 	unsigned int mask = (1 << fls(max)) - 1;
1136 
1137 	/* return the saved value if we are powered down */
1138 	if (widget->id == snd_soc_dapm_pga && !widget->power) {
1139 		ucontrol->value.integer.value[0] = widget->saved_value;
1140 		return 0;
1141 	}
1142 
1143 	ucontrol->value.integer.value[0] =
1144 		(snd_soc_read(widget->codec, reg) >> shift) & mask;
1145 	if (shift != rshift)
1146 		ucontrol->value.integer.value[1] =
1147 			(snd_soc_read(widget->codec, reg) >> rshift) & mask;
1148 	if (invert) {
1149 		ucontrol->value.integer.value[0] =
1150 			max - ucontrol->value.integer.value[0];
1151 		if (shift != rshift)
1152 			ucontrol->value.integer.value[1] =
1153 				max - ucontrol->value.integer.value[1];
1154 	}
1155 
1156 	return 0;
1157 }
1158 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
1159 
1160 /**
1161  * snd_soc_dapm_put_volsw - dapm mixer set callback
1162  * @kcontrol: mixer control
1163  * @uinfo: control element information
1164  *
1165  * Callback to set the value of a dapm mixer control.
1166  *
1167  * Returns 0 for success.
1168  */
1169 int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1170 	struct snd_ctl_elem_value *ucontrol)
1171 {
1172 	struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1173 	struct soc_mixer_control *mc =
1174 		(struct soc_mixer_control *)kcontrol->private_value;
1175 	unsigned int reg = mc->reg;
1176 	unsigned int shift = mc->shift;
1177 	unsigned int rshift = mc->rshift;
1178 	int max = mc->max;
1179 	unsigned int mask = (1 << fls(max)) - 1;
1180 	unsigned int invert = mc->invert;
1181 	unsigned short val, val2, val_mask;
1182 	int ret;
1183 
1184 	val = (ucontrol->value.integer.value[0] & mask);
1185 
1186 	if (invert)
1187 		val = max - val;
1188 	val_mask = mask << shift;
1189 	val = val << shift;
1190 	if (shift != rshift) {
1191 		val2 = (ucontrol->value.integer.value[1] & mask);
1192 		if (invert)
1193 			val2 = max - val2;
1194 		val_mask |= mask << rshift;
1195 		val |= val2 << rshift;
1196 	}
1197 
1198 	mutex_lock(&widget->codec->mutex);
1199 	widget->value = val;
1200 
1201 	/* save volume value if the widget is powered down */
1202 	if (widget->id == snd_soc_dapm_pga && !widget->power) {
1203 		widget->saved_value = val;
1204 		mutex_unlock(&widget->codec->mutex);
1205 		return 1;
1206 	}
1207 
1208 	dapm_mixer_update_power(widget, kcontrol, reg, val_mask, val, invert);
1209 	if (widget->event) {
1210 		if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1211 			ret = widget->event(widget, kcontrol,
1212 						SND_SOC_DAPM_PRE_REG);
1213 			if (ret < 0) {
1214 				ret = 1;
1215 				goto out;
1216 			}
1217 		}
1218 		ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
1219 		if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1220 			ret = widget->event(widget, kcontrol,
1221 						SND_SOC_DAPM_POST_REG);
1222 	} else
1223 		ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
1224 
1225 out:
1226 	mutex_unlock(&widget->codec->mutex);
1227 	return ret;
1228 }
1229 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
1230 
1231 /**
1232  * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
1233  * @kcontrol: mixer control
1234  * @uinfo: control element information
1235  *
1236  * Callback to get the value of a dapm enumerated double mixer control.
1237  *
1238  * Returns 0 for success.
1239  */
1240 int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
1241 	struct snd_ctl_elem_value *ucontrol)
1242 {
1243 	struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1244 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1245 	unsigned short val, bitmask;
1246 
1247 	for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1248 		;
1249 	val = snd_soc_read(widget->codec, e->reg);
1250 	ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
1251 	if (e->shift_l != e->shift_r)
1252 		ucontrol->value.enumerated.item[1] =
1253 			(val >> e->shift_r) & (bitmask - 1);
1254 
1255 	return 0;
1256 }
1257 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
1258 
1259 /**
1260  * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
1261  * @kcontrol: mixer control
1262  * @uinfo: control element information
1263  *
1264  * Callback to set the value of a dapm enumerated double mixer control.
1265  *
1266  * Returns 0 for success.
1267  */
1268 int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1269 	struct snd_ctl_elem_value *ucontrol)
1270 {
1271 	struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1272 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1273 	unsigned short val, mux;
1274 	unsigned short mask, bitmask;
1275 	int ret = 0;
1276 
1277 	for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1278 		;
1279 	if (ucontrol->value.enumerated.item[0] > e->max - 1)
1280 		return -EINVAL;
1281 	mux = ucontrol->value.enumerated.item[0];
1282 	val = mux << e->shift_l;
1283 	mask = (bitmask - 1) << e->shift_l;
1284 	if (e->shift_l != e->shift_r) {
1285 		if (ucontrol->value.enumerated.item[1] > e->max - 1)
1286 			return -EINVAL;
1287 		val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1288 		mask |= (bitmask - 1) << e->shift_r;
1289 	}
1290 
1291 	mutex_lock(&widget->codec->mutex);
1292 	widget->value = val;
1293 	dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
1294 	if (widget->event) {
1295 		if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1296 			ret = widget->event(widget,
1297 				kcontrol, SND_SOC_DAPM_PRE_REG);
1298 			if (ret < 0)
1299 				goto out;
1300 		}
1301 		ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1302 		if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1303 			ret = widget->event(widget,
1304 				kcontrol, SND_SOC_DAPM_POST_REG);
1305 	} else
1306 		ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1307 
1308 out:
1309 	mutex_unlock(&widget->codec->mutex);
1310 	return ret;
1311 }
1312 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1313 
1314 /**
1315  * snd_soc_dapm_new_control - create new dapm control
1316  * @codec: audio codec
1317  * @widget: widget template
1318  *
1319  * Creates a new dapm control based upon the template.
1320  *
1321  * Returns 0 for success else error.
1322  */
1323 int snd_soc_dapm_new_control(struct snd_soc_codec *codec,
1324 	const struct snd_soc_dapm_widget *widget)
1325 {
1326 	struct snd_soc_dapm_widget *w;
1327 
1328 	if ((w = dapm_cnew_widget(widget)) == NULL)
1329 		return -ENOMEM;
1330 
1331 	w->codec = codec;
1332 	INIT_LIST_HEAD(&w->sources);
1333 	INIT_LIST_HEAD(&w->sinks);
1334 	INIT_LIST_HEAD(&w->list);
1335 	list_add(&w->list, &codec->dapm_widgets);
1336 
1337 	/* machine layer set ups unconnected pins and insertions */
1338 	w->connected = 1;
1339 	return 0;
1340 }
1341 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
1342 
1343 /**
1344  * snd_soc_dapm_new_controls - create new dapm controls
1345  * @codec: audio codec
1346  * @widget: widget array
1347  * @num: number of widgets
1348  *
1349  * Creates new DAPM controls based upon the templates.
1350  *
1351  * Returns 0 for success else error.
1352  */
1353 int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
1354 	const struct snd_soc_dapm_widget *widget,
1355 	int num)
1356 {
1357 	int i, ret;
1358 
1359 	for (i = 0; i < num; i++) {
1360 		ret = snd_soc_dapm_new_control(codec, widget);
1361 		if (ret < 0)
1362 			return ret;
1363 		widget++;
1364 	}
1365 	return 0;
1366 }
1367 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
1368 
1369 
1370 /**
1371  * snd_soc_dapm_stream_event - send a stream event to the dapm core
1372  * @codec: audio codec
1373  * @stream: stream name
1374  * @event: stream event
1375  *
1376  * Sends a stream event to the dapm core. The core then makes any
1377  * necessary widget power changes.
1378  *
1379  * Returns 0 for success else error.
1380  */
1381 int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
1382 	char *stream, int event)
1383 {
1384 	struct snd_soc_dapm_widget *w;
1385 
1386 	if (stream == NULL)
1387 		return 0;
1388 
1389 	mutex_lock(&codec->mutex);
1390 	list_for_each_entry(w, &codec->dapm_widgets, list)
1391 	{
1392 		if (!w->sname)
1393 			continue;
1394 		pr_debug("widget %s\n %s stream %s event %d\n",
1395 			 w->name, w->sname, stream, event);
1396 		if (strstr(w->sname, stream)) {
1397 			switch(event) {
1398 			case SND_SOC_DAPM_STREAM_START:
1399 				w->active = 1;
1400 				break;
1401 			case SND_SOC_DAPM_STREAM_STOP:
1402 				w->active = 0;
1403 				break;
1404 			case SND_SOC_DAPM_STREAM_SUSPEND:
1405 				if (w->active)
1406 					w->suspend = 1;
1407 				w->active = 0;
1408 				break;
1409 			case SND_SOC_DAPM_STREAM_RESUME:
1410 				if (w->suspend) {
1411 					w->active = 1;
1412 					w->suspend = 0;
1413 				}
1414 				break;
1415 			case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
1416 				break;
1417 			case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
1418 				break;
1419 			}
1420 		}
1421 	}
1422 	mutex_unlock(&codec->mutex);
1423 
1424 	dapm_power_widgets(codec, event);
1425 	dump_dapm(codec, __func__);
1426 	return 0;
1427 }
1428 EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
1429 
1430 /**
1431  * snd_soc_dapm_set_bias_level - set the bias level for the system
1432  * @socdev: audio device
1433  * @level: level to configure
1434  *
1435  * Configure the bias (power) levels for the SoC audio device.
1436  *
1437  * Returns 0 for success else error.
1438  */
1439 int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
1440 				enum snd_soc_bias_level level)
1441 {
1442 	struct snd_soc_codec *codec = socdev->codec;
1443 	struct snd_soc_machine *machine = socdev->machine;
1444 	int ret = 0;
1445 
1446 	if (machine->set_bias_level)
1447 		ret = machine->set_bias_level(machine, level);
1448 	if (ret == 0 && codec->set_bias_level)
1449 		ret = codec->set_bias_level(codec, level);
1450 
1451 	return ret;
1452 }
1453 
1454 /**
1455  * snd_soc_dapm_enable_pin - enable pin.
1456  * @snd_soc_codec: SoC codec
1457  * @pin: pin name
1458  *
1459  * Enables input/output pin and it's parents or children widgets iff there is
1460  * a valid audio route and active audio stream.
1461  * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1462  * do any widget power switching.
1463  */
1464 int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin)
1465 {
1466 	return snd_soc_dapm_set_pin(codec, pin, 1);
1467 }
1468 EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
1469 
1470 /**
1471  * snd_soc_dapm_disable_pin - disable pin.
1472  * @codec: SoC codec
1473  * @pin: pin name
1474  *
1475  * Disables input/output pin and it's parents or children widgets.
1476  * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1477  * do any widget power switching.
1478  */
1479 int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin)
1480 {
1481 	return snd_soc_dapm_set_pin(codec, pin, 0);
1482 }
1483 EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
1484 
1485 /**
1486  * snd_soc_dapm_nc_pin - permanently disable pin.
1487  * @codec: SoC codec
1488  * @pin: pin name
1489  *
1490  * Marks the specified pin as being not connected, disabling it along
1491  * any parent or child widgets.  At present this is identical to
1492  * snd_soc_dapm_disable_pin() but in future it will be extended to do
1493  * additional things such as disabling controls which only affect
1494  * paths through the pin.
1495  *
1496  * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1497  * do any widget power switching.
1498  */
1499 int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin)
1500 {
1501 	return snd_soc_dapm_set_pin(codec, pin, 0);
1502 }
1503 EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
1504 
1505 /**
1506  * snd_soc_dapm_get_pin_status - get audio pin status
1507  * @codec: audio codec
1508  * @pin: audio signal pin endpoint (or start point)
1509  *
1510  * Get audio pin status - connected or disconnected.
1511  *
1512  * Returns 1 for connected otherwise 0.
1513  */
1514 int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin)
1515 {
1516 	struct snd_soc_dapm_widget *w;
1517 
1518 	list_for_each_entry(w, &codec->dapm_widgets, list) {
1519 		if (!strcmp(w->name, pin))
1520 			return w->connected;
1521 	}
1522 
1523 	return 0;
1524 }
1525 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
1526 
1527 /**
1528  * snd_soc_dapm_free - free dapm resources
1529  * @socdev: SoC device
1530  *
1531  * Free all dapm widgets and resources.
1532  */
1533 void snd_soc_dapm_free(struct snd_soc_device *socdev)
1534 {
1535 	struct snd_soc_codec *codec = socdev->codec;
1536 
1537 	snd_soc_dapm_sys_remove(socdev->dev);
1538 	dapm_free_widgets(codec);
1539 }
1540 EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
1541 
1542 /* Module information */
1543 MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
1544 MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");
1545 MODULE_LICENSE("GPL");
1546