aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c427
1 files changed, 285 insertions, 142 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 735903a74675..21c69074aa17 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -12,7 +12,7 @@
12 * Features: 12 * Features:
13 * o Changes power status of internal codec blocks depending on the 13 * o Changes power status of internal codec blocks depending on the
14 * dynamic configuration of codec internal audio paths and active 14 * dynamic configuration of codec internal audio paths and active
15 * DAC's/ADC's. 15 * DACs/ADCs.
16 * o Platform power domain - can support external components i.e. amps and 16 * o Platform power domain - can support external components i.e. amps and
17 * mic/meadphone insertion events. 17 * mic/meadphone insertion events.
18 * o Automatic Mic Bias support 18 * o Automatic Mic Bias support
@@ -52,23 +52,21 @@
52 52
53/* dapm power sequences - make this per codec in the future */ 53/* dapm power sequences - make this per codec in the future */
54static int dapm_up_seq[] = { 54static int dapm_up_seq[] = {
55 snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, 55 snd_soc_dapm_pre, snd_soc_dapm_supply, snd_soc_dapm_micbias,
56 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac, 56 snd_soc_dapm_mic, snd_soc_dapm_mux, snd_soc_dapm_value_mux,
57 snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_pga, 57 snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl,
58 snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post 58 snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
59 snd_soc_dapm_post
59}; 60};
60 61
61static int dapm_down_seq[] = { 62static int dapm_down_seq[] = {
62 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, 63 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
63 snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer, 64 snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer,
64 snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias, 65 snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias,
65 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_post 66 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_supply,
67 snd_soc_dapm_post
66}; 68};
67 69
68static int dapm_status = 1;
69module_param(dapm_status, int, 0);
70MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
71
72static void pop_wait(u32 pop_time) 70static void pop_wait(u32 pop_time)
73{ 71{
74 if (pop_time) 72 if (pop_time)
@@ -96,6 +94,48 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
96 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); 94 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
97} 95}
98 96
97/**
98 * snd_soc_dapm_set_bias_level - set the bias level for the system
99 * @socdev: audio device
100 * @level: level to configure
101 *
102 * Configure the bias (power) levels for the SoC audio device.
103 *
104 * Returns 0 for success else error.
105 */
106static int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
107 enum snd_soc_bias_level level)
108{
109 struct snd_soc_card *card = socdev->card;
110 struct snd_soc_codec *codec = socdev->card->codec;
111 int ret = 0;
112
113 switch (level) {
114 case SND_SOC_BIAS_ON:
115 dev_dbg(socdev->dev, "Setting full bias\n");
116 break;
117 case SND_SOC_BIAS_PREPARE:
118 dev_dbg(socdev->dev, "Setting bias prepare\n");
119 break;
120 case SND_SOC_BIAS_STANDBY:
121 dev_dbg(socdev->dev, "Setting standby bias\n");
122 break;
123 case SND_SOC_BIAS_OFF:
124 dev_dbg(socdev->dev, "Setting bias off\n");
125 break;
126 default:
127 dev_err(socdev->dev, "Setting invalid bias %d\n", level);
128 return -EINVAL;
129 }
130
131 if (card->set_bias_level)
132 ret = card->set_bias_level(card, level);
133 if (ret == 0 && codec->set_bias_level)
134 ret = codec->set_bias_level(codec, level);
135
136 return ret;
137}
138
99/* set up initial codec paths */ 139/* set up initial codec paths */
100static void dapm_set_path_status(struct snd_soc_dapm_widget *w, 140static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
101 struct snd_soc_dapm_path *p, int i) 141 struct snd_soc_dapm_path *p, int i)
@@ -165,6 +205,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
165 case snd_soc_dapm_dac: 205 case snd_soc_dapm_dac:
166 case snd_soc_dapm_micbias: 206 case snd_soc_dapm_micbias:
167 case snd_soc_dapm_vmid: 207 case snd_soc_dapm_vmid:
208 case snd_soc_dapm_supply:
168 p->connect = 1; 209 p->connect = 1;
169 break; 210 break;
170 /* does effect routing - dynamically connected */ 211 /* does effect routing - dynamically connected */
@@ -179,7 +220,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
179 } 220 }
180} 221}
181 222
182/* connect mux widget to it's interconnecting audio paths */ 223/* connect mux widget to its interconnecting audio paths */
183static int dapm_connect_mux(struct snd_soc_codec *codec, 224static int dapm_connect_mux(struct snd_soc_codec *codec,
184 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 225 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
185 struct snd_soc_dapm_path *path, const char *control_name, 226 struct snd_soc_dapm_path *path, const char *control_name,
@@ -202,7 +243,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
202 return -ENODEV; 243 return -ENODEV;
203} 244}
204 245
205/* connect mixer widget to it's interconnecting audio paths */ 246/* connect mixer widget to its interconnecting audio paths */
206static int dapm_connect_mixer(struct snd_soc_codec *codec, 247static int dapm_connect_mixer(struct snd_soc_codec *codec,
207 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 248 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
208 struct snd_soc_dapm_path *path, const char *control_name) 249 struct snd_soc_dapm_path *path, const char *control_name)
@@ -357,8 +398,9 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
357 path->long_name); 398 path->long_name);
358 ret = snd_ctl_add(codec->card, path->kcontrol); 399 ret = snd_ctl_add(codec->card, path->kcontrol);
359 if (ret < 0) { 400 if (ret < 0) {
360 printk(KERN_ERR "asoc: failed to add dapm kcontrol %s\n", 401 printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n",
361 path->long_name); 402 path->long_name,
403 ret);
362 kfree(path->long_name); 404 kfree(path->long_name);
363 path->long_name = NULL; 405 path->long_name = NULL;
364 return ret; 406 return ret;
@@ -434,6 +476,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
434 struct snd_soc_dapm_path *path; 476 struct snd_soc_dapm_path *path;
435 int con = 0; 477 int con = 0;
436 478
479 if (widget->id == snd_soc_dapm_supply)
480 return 0;
481
437 if (widget->id == snd_soc_dapm_adc && widget->active) 482 if (widget->id == snd_soc_dapm_adc && widget->active)
438 return 1; 483 return 1;
439 484
@@ -470,6 +515,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
470 struct snd_soc_dapm_path *path; 515 struct snd_soc_dapm_path *path;
471 int con = 0; 516 int con = 0;
472 517
518 if (widget->id == snd_soc_dapm_supply)
519 return 0;
520
473 /* active stream ? */ 521 /* active stream ? */
474 if (widget->id == snd_soc_dapm_dac && widget->active) 522 if (widget->id == snd_soc_dapm_dac && widget->active)
475 return 1; 523 return 1;
@@ -521,84 +569,12 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
521} 569}
522EXPORT_SYMBOL_GPL(dapm_reg_event); 570EXPORT_SYMBOL_GPL(dapm_reg_event);
523 571
524/* 572/* Standard power change method, used to apply power changes to most
525 * Scan a single DAPM widget for a complete audio path and update the 573 * widgets.
526 * power status appropriately.
527 */ 574 */
528static int dapm_power_widget(struct snd_soc_codec *codec, int event, 575static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
529 struct snd_soc_dapm_widget *w)
530{ 576{
531 int in, out, power_change, power, ret; 577 int ret;
532
533 /* vmid - no action */
534 if (w->id == snd_soc_dapm_vmid)
535 return 0;
536
537 /* active ADC */
538 if (w->id == snd_soc_dapm_adc && w->active) {
539 in = is_connected_input_ep(w);
540 dapm_clear_walk(w->codec);
541 w->power = (in != 0) ? 1 : 0;
542 dapm_update_bits(w);
543 return 0;
544 }
545
546 /* active DAC */
547 if (w->id == snd_soc_dapm_dac && w->active) {
548 out = is_connected_output_ep(w);
549 dapm_clear_walk(w->codec);
550 w->power = (out != 0) ? 1 : 0;
551 dapm_update_bits(w);
552 return 0;
553 }
554
555 /* pre and post event widgets */
556 if (w->id == snd_soc_dapm_pre) {
557 if (!w->event)
558 return 0;
559
560 if (event == SND_SOC_DAPM_STREAM_START) {
561 ret = w->event(w,
562 NULL, SND_SOC_DAPM_PRE_PMU);
563 if (ret < 0)
564 return ret;
565 } else if (event == SND_SOC_DAPM_STREAM_STOP) {
566 ret = w->event(w,
567 NULL, SND_SOC_DAPM_PRE_PMD);
568 if (ret < 0)
569 return ret;
570 }
571 return 0;
572 }
573 if (w->id == snd_soc_dapm_post) {
574 if (!w->event)
575 return 0;
576
577 if (event == SND_SOC_DAPM_STREAM_START) {
578 ret = w->event(w,
579 NULL, SND_SOC_DAPM_POST_PMU);
580 if (ret < 0)
581 return ret;
582 } else if (event == SND_SOC_DAPM_STREAM_STOP) {
583 ret = w->event(w,
584 NULL, SND_SOC_DAPM_POST_PMD);
585 if (ret < 0)
586 return ret;
587 }
588 return 0;
589 }
590
591 /* all other widgets */
592 in = is_connected_input_ep(w);
593 dapm_clear_walk(w->codec);
594 out = is_connected_output_ep(w);
595 dapm_clear_walk(w->codec);
596 power = (out != 0 && in != 0) ? 1 : 0;
597 power_change = (w->power == power) ? 0 : 1;
598 w->power = power;
599
600 if (!power_change)
601 return 0;
602 578
603 /* call any power change event handlers */ 579 /* call any power change event handlers */
604 if (w->event) 580 if (w->event)
@@ -607,7 +583,7 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event,
607 w->name, w->event_flags); 583 w->name, w->event_flags);
608 584
609 /* power up pre event */ 585 /* power up pre event */
610 if (power && w->event && 586 if (w->power && w->event &&
611 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { 587 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
612 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); 588 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
613 if (ret < 0) 589 if (ret < 0)
@@ -615,7 +591,7 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event,
615 } 591 }
616 592
617 /* power down pre event */ 593 /* power down pre event */
618 if (!power && w->event && 594 if (!w->power && w->event &&
619 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { 595 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
620 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); 596 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
621 if (ret < 0) 597 if (ret < 0)
@@ -623,17 +599,17 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event,
623 } 599 }
624 600
625 /* Lower PGA volume to reduce pops */ 601 /* Lower PGA volume to reduce pops */
626 if (w->id == snd_soc_dapm_pga && !power) 602 if (w->id == snd_soc_dapm_pga && !w->power)
627 dapm_set_pga(w, power); 603 dapm_set_pga(w, w->power);
628 604
629 dapm_update_bits(w); 605 dapm_update_bits(w);
630 606
631 /* Raise PGA volume to reduce pops */ 607 /* Raise PGA volume to reduce pops */
632 if (w->id == snd_soc_dapm_pga && power) 608 if (w->id == snd_soc_dapm_pga && w->power)
633 dapm_set_pga(w, power); 609 dapm_set_pga(w, w->power);
634 610
635 /* power up post event */ 611 /* power up post event */
636 if (power && w->event && 612 if (w->power && w->event &&
637 (w->event_flags & SND_SOC_DAPM_POST_PMU)) { 613 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
638 ret = w->event(w, 614 ret = w->event(w,
639 NULL, SND_SOC_DAPM_POST_PMU); 615 NULL, SND_SOC_DAPM_POST_PMU);
@@ -642,7 +618,7 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event,
642 } 618 }
643 619
644 /* power down post event */ 620 /* power down post event */
645 if (!power && w->event && 621 if (!w->power && w->event &&
646 (w->event_flags & SND_SOC_DAPM_POST_PMD)) { 622 (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
647 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); 623 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
648 if (ret < 0) 624 if (ret < 0)
@@ -652,6 +628,116 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event,
652 return 0; 628 return 0;
653} 629}
654 630
631/* Generic check to see if a widget should be powered.
632 */
633static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
634{
635 int in, out;
636
637 in = is_connected_input_ep(w);
638 dapm_clear_walk(w->codec);
639 out = is_connected_output_ep(w);
640 dapm_clear_walk(w->codec);
641 return out != 0 && in != 0;
642}
643
644/* Check to see if an ADC has power */
645static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
646{
647 int in;
648
649 if (w->active) {
650 in = is_connected_input_ep(w);
651 dapm_clear_walk(w->codec);
652 return in != 0;
653 } else {
654 return dapm_generic_check_power(w);
655 }
656}
657
658/* Check to see if a DAC has power */
659static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
660{
661 int out;
662
663 if (w->active) {
664 out = is_connected_output_ep(w);
665 dapm_clear_walk(w->codec);
666 return out != 0;
667 } else {
668 return dapm_generic_check_power(w);
669 }
670}
671
672/* Check to see if a power supply is needed */
673static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
674{
675 struct snd_soc_dapm_path *path;
676 int power = 0;
677
678 /* Check if one of our outputs is connected */
679 list_for_each_entry(path, &w->sinks, list_source) {
680 if (path->sink && path->sink->power_check &&
681 path->sink->power_check(path->sink)) {
682 power = 1;
683 break;
684 }
685 }
686
687 dapm_clear_walk(w->codec);
688
689 return power;
690}
691
692/*
693 * Scan a single DAPM widget for a complete audio path and update the
694 * power status appropriately.
695 */
696static int dapm_power_widget(struct snd_soc_codec *codec, int event,
697 struct snd_soc_dapm_widget *w)
698{
699 int ret;
700
701 switch (w->id) {
702 case snd_soc_dapm_pre:
703 if (!w->event)
704 return 0;
705
706 if (event == SND_SOC_DAPM_STREAM_START) {
707 ret = w->event(w,
708 NULL, SND_SOC_DAPM_PRE_PMU);
709 if (ret < 0)
710 return ret;
711 } else if (event == SND_SOC_DAPM_STREAM_STOP) {
712 ret = w->event(w,
713 NULL, SND_SOC_DAPM_PRE_PMD);
714 if (ret < 0)
715 return ret;
716 }
717 return 0;
718
719 case snd_soc_dapm_post:
720 if (!w->event)
721 return 0;
722
723 if (event == SND_SOC_DAPM_STREAM_START) {
724 ret = w->event(w,
725 NULL, SND_SOC_DAPM_POST_PMU);
726 if (ret < 0)
727 return ret;
728 } else if (event == SND_SOC_DAPM_STREAM_STOP) {
729 ret = w->event(w,
730 NULL, SND_SOC_DAPM_POST_PMD);
731 if (ret < 0)
732 return ret;
733 }
734 return 0;
735
736 default:
737 return dapm_generic_apply_power(w);
738 }
739}
740
655/* 741/*
656 * Scan each dapm widget for complete audio path. 742 * Scan each dapm widget for complete audio path.
657 * A complete path is a route that has valid endpoints i.e.:- 743 * A complete path is a route that has valid endpoints i.e.:-
@@ -663,31 +749,102 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event,
663 */ 749 */
664static int dapm_power_widgets(struct snd_soc_codec *codec, int event) 750static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
665{ 751{
752 struct snd_soc_device *socdev = codec->socdev;
666 struct snd_soc_dapm_widget *w; 753 struct snd_soc_dapm_widget *w;
667 int i, c = 1, *seq = NULL, ret = 0; 754 int ret = 0;
668 755 int i, power;
669 /* do we have a sequenced stream event */ 756 int sys_power = 0;
670 if (event == SND_SOC_DAPM_STREAM_START) { 757
671 c = ARRAY_SIZE(dapm_up_seq); 758 INIT_LIST_HEAD(&codec->up_list);
672 seq = dapm_up_seq; 759 INIT_LIST_HEAD(&codec->down_list);
673 } else if (event == SND_SOC_DAPM_STREAM_STOP) { 760
674 c = ARRAY_SIZE(dapm_down_seq); 761 /* Check which widgets we need to power and store them in
675 seq = dapm_down_seq; 762 * lists indicating if they should be powered up or down.
763 */
764 list_for_each_entry(w, &codec->dapm_widgets, list) {
765 switch (w->id) {
766 case snd_soc_dapm_pre:
767 list_add_tail(&codec->down_list, &w->power_list);
768 break;
769 case snd_soc_dapm_post:
770 list_add_tail(&codec->up_list, &w->power_list);
771 break;
772
773 default:
774 if (!w->power_check)
775 continue;
776
777 power = w->power_check(w);
778 if (power)
779 sys_power = 1;
780
781 if (w->power == power)
782 continue;
783
784 if (power)
785 list_add_tail(&w->power_list, &codec->up_list);
786 else
787 list_add_tail(&w->power_list,
788 &codec->down_list);
789
790 w->power = power;
791 break;
792 }
676 } 793 }
677 794
678 for (i = 0; i < c; i++) { 795 /* If we're changing to all on or all off then prepare */
679 list_for_each_entry(w, &codec->dapm_widgets, list) { 796 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) ||
797 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) {
798 ret = snd_soc_dapm_set_bias_level(socdev,
799 SND_SOC_BIAS_PREPARE);
800 if (ret != 0)
801 pr_err("Failed to prepare bias: %d\n", ret);
802 }
680 803
804 /* Power down widgets first; try to avoid amplifying pops. */
805 for (i = 0; i < ARRAY_SIZE(dapm_down_seq); i++) {
806 list_for_each_entry(w, &codec->down_list, power_list) {
681 /* is widget in stream order */ 807 /* is widget in stream order */
682 if (seq && seq[i] && w->id != seq[i]) 808 if (w->id != dapm_down_seq[i])
683 continue; 809 continue;
684 810
685 ret = dapm_power_widget(codec, event, w); 811 ret = dapm_power_widget(codec, event, w);
686 if (ret != 0) 812 if (ret != 0)
687 return ret; 813 pr_err("Failed to power down %s: %d\n",
814 w->name, ret);
688 } 815 }
689 } 816 }
690 817
818 /* Now power up. */
819 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++) {
820 list_for_each_entry(w, &codec->up_list, power_list) {
821 /* is widget in stream order */
822 if (w->id != dapm_up_seq[i])
823 continue;
824
825 ret = dapm_power_widget(codec, event, w);
826 if (ret != 0)
827 pr_err("Failed to power up %s: %d\n",
828 w->name, ret);
829 }
830 }
831
832 /* If we just powered the last thing off drop to standby bias */
833 if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) {
834 ret = snd_soc_dapm_set_bias_level(socdev,
835 SND_SOC_BIAS_STANDBY);
836 if (ret != 0)
837 pr_err("Failed to apply standby bias: %d\n", ret);
838 }
839
840 /* If we just powered up then move to active bias */
841 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
842 ret = snd_soc_dapm_set_bias_level(socdev,
843 SND_SOC_BIAS_ON);
844 if (ret != 0)
845 pr_err("Failed to apply active bias: %d\n", ret);
846 }
847
691 return 0; 848 return 0;
692} 849}
693 850
@@ -723,6 +880,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
723 case snd_soc_dapm_pga: 880 case snd_soc_dapm_pga:
724 case snd_soc_dapm_mixer: 881 case snd_soc_dapm_mixer:
725 case snd_soc_dapm_mixer_named_ctl: 882 case snd_soc_dapm_mixer_named_ctl:
883 case snd_soc_dapm_supply:
726 if (w->name) { 884 if (w->name) {
727 in = is_connected_input_ep(w); 885 in = is_connected_input_ep(w);
728 dapm_clear_walk(w->codec); 886 dapm_clear_walk(w->codec);
@@ -851,6 +1009,7 @@ static ssize_t dapm_widget_show(struct device *dev,
851 case snd_soc_dapm_pga: 1009 case snd_soc_dapm_pga:
852 case snd_soc_dapm_mixer: 1010 case snd_soc_dapm_mixer:
853 case snd_soc_dapm_mixer_named_ctl: 1011 case snd_soc_dapm_mixer_named_ctl:
1012 case snd_soc_dapm_supply:
854 if (w->name) 1013 if (w->name)
855 count += sprintf(buf + count, "%s: %s\n", 1014 count += sprintf(buf + count, "%s: %s\n",
856 w->name, w->power ? "On":"Off"); 1015 w->name, w->power ? "On":"Off");
@@ -883,16 +1042,12 @@ static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
883 1042
884int snd_soc_dapm_sys_add(struct device *dev) 1043int snd_soc_dapm_sys_add(struct device *dev)
885{ 1044{
886 if (!dapm_status)
887 return 0;
888 return device_create_file(dev, &dev_attr_dapm_widget); 1045 return device_create_file(dev, &dev_attr_dapm_widget);
889} 1046}
890 1047
891static void snd_soc_dapm_sys_remove(struct device *dev) 1048static void snd_soc_dapm_sys_remove(struct device *dev)
892{ 1049{
893 if (dapm_status) { 1050 device_remove_file(dev, &dev_attr_dapm_widget);
894 device_remove_file(dev, &dev_attr_dapm_widget);
895 }
896} 1051}
897 1052
898/* free all dapm widgets and resources */ 1053/* free all dapm widgets and resources */
@@ -1015,6 +1170,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1015 case snd_soc_dapm_vmid: 1170 case snd_soc_dapm_vmid:
1016 case snd_soc_dapm_pre: 1171 case snd_soc_dapm_pre:
1017 case snd_soc_dapm_post: 1172 case snd_soc_dapm_post:
1173 case snd_soc_dapm_supply:
1018 list_add(&path->list, &codec->dapm_paths); 1174 list_add(&path->list, &codec->dapm_paths);
1019 list_add(&path->list_sink, &wsink->sources); 1175 list_add(&path->list_sink, &wsink->sources);
1020 list_add(&path->list_source, &wsource->sinks); 1176 list_add(&path->list_source, &wsource->sinks);
@@ -1108,15 +1264,22 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1108 case snd_soc_dapm_switch: 1264 case snd_soc_dapm_switch:
1109 case snd_soc_dapm_mixer: 1265 case snd_soc_dapm_mixer:
1110 case snd_soc_dapm_mixer_named_ctl: 1266 case snd_soc_dapm_mixer_named_ctl:
1267 w->power_check = dapm_generic_check_power;
1111 dapm_new_mixer(codec, w); 1268 dapm_new_mixer(codec, w);
1112 break; 1269 break;
1113 case snd_soc_dapm_mux: 1270 case snd_soc_dapm_mux:
1114 case snd_soc_dapm_value_mux: 1271 case snd_soc_dapm_value_mux:
1272 w->power_check = dapm_generic_check_power;
1115 dapm_new_mux(codec, w); 1273 dapm_new_mux(codec, w);
1116 break; 1274 break;
1117 case snd_soc_dapm_adc: 1275 case snd_soc_dapm_adc:
1276 w->power_check = dapm_adc_check_power;
1277 break;
1118 case snd_soc_dapm_dac: 1278 case snd_soc_dapm_dac:
1279 w->power_check = dapm_dac_check_power;
1280 break;
1119 case snd_soc_dapm_pga: 1281 case snd_soc_dapm_pga:
1282 w->power_check = dapm_generic_check_power;
1120 dapm_new_pga(codec, w); 1283 dapm_new_pga(codec, w);
1121 break; 1284 break;
1122 case snd_soc_dapm_input: 1285 case snd_soc_dapm_input:
@@ -1126,6 +1289,10 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1126 case snd_soc_dapm_hp: 1289 case snd_soc_dapm_hp:
1127 case snd_soc_dapm_mic: 1290 case snd_soc_dapm_mic:
1128 case snd_soc_dapm_line: 1291 case snd_soc_dapm_line:
1292 w->power_check = dapm_generic_check_power;
1293 break;
1294 case snd_soc_dapm_supply:
1295 w->power_check = dapm_supply_check_power;
1129 case snd_soc_dapm_vmid: 1296 case snd_soc_dapm_vmid:
1130 case snd_soc_dapm_pre: 1297 case snd_soc_dapm_pre:
1131 case snd_soc_dapm_post: 1298 case snd_soc_dapm_post:
@@ -1626,35 +1793,11 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
1626EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); 1793EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
1627 1794
1628/** 1795/**
1629 * snd_soc_dapm_set_bias_level - set the bias level for the system
1630 * @socdev: audio device
1631 * @level: level to configure
1632 *
1633 * Configure the bias (power) levels for the SoC audio device.
1634 *
1635 * Returns 0 for success else error.
1636 */
1637int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
1638 enum snd_soc_bias_level level)
1639{
1640 struct snd_soc_card *card = socdev->card;
1641 struct snd_soc_codec *codec = socdev->card->codec;
1642 int ret = 0;
1643
1644 if (card->set_bias_level)
1645 ret = card->set_bias_level(card, level);
1646 if (ret == 0 && codec->set_bias_level)
1647 ret = codec->set_bias_level(codec, level);
1648
1649 return ret;
1650}
1651
1652/**
1653 * snd_soc_dapm_enable_pin - enable pin. 1796 * snd_soc_dapm_enable_pin - enable pin.
1654 * @codec: SoC codec 1797 * @codec: SoC codec
1655 * @pin: pin name 1798 * @pin: pin name
1656 * 1799 *
1657 * Enables input/output pin and it's parents or children widgets iff there is 1800 * Enables input/output pin and its parents or children widgets iff there is
1658 * a valid audio route and active audio stream. 1801 * a valid audio route and active audio stream.
1659 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 1802 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1660 * do any widget power switching. 1803 * do any widget power switching.
@@ -1670,7 +1813,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
1670 * @codec: SoC codec 1813 * @codec: SoC codec
1671 * @pin: pin name 1814 * @pin: pin name
1672 * 1815 *
1673 * Disables input/output pin and it's parents or children widgets. 1816 * Disables input/output pin and its parents or children widgets.
1674 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 1817 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1675 * do any widget power switching. 1818 * do any widget power switching.
1676 */ 1819 */