diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-03-01 14:21:10 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-03-06 08:37:13 -0500 |
commit | 42aa3418ebd7b79be0e1ee7515e365c1574114f9 (patch) | |
tree | 90c88f661128faf37b9f3219a4701ebc7de8a2f5 /sound/soc/soc-dapm.c | |
parent | 20a41eac4fbaa22d051d0fbaeaf3315d2d8c4860 (diff) |
ASoC: Factor out DAPM widget power check into separate function
Essentially simple code motion to facilitate refactoring of the power
decisions.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r-- | sound/soc/soc-dapm.c | 258 |
1 files changed, 137 insertions, 121 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 4b8dbbfe2efb..7da6d0db40f2 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -523,6 +523,137 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, | |||
523 | EXPORT_SYMBOL_GPL(dapm_reg_event); | 523 | EXPORT_SYMBOL_GPL(dapm_reg_event); |
524 | 524 | ||
525 | /* | 525 | /* |
526 | * Scan a single DAPM widget for a complete audio path and update the | ||
527 | * power status appropriately. | ||
528 | */ | ||
529 | static int dapm_power_widget(struct snd_soc_codec *codec, int event, | ||
530 | struct snd_soc_dapm_widget *w) | ||
531 | { | ||
532 | int in, out, power_change, power, ret; | ||
533 | |||
534 | /* vmid - no action */ | ||
535 | if (w->id == snd_soc_dapm_vmid) | ||
536 | return 0; | ||
537 | |||
538 | /* active ADC */ | ||
539 | if (w->id == snd_soc_dapm_adc && w->active) { | ||
540 | in = is_connected_input_ep(w); | ||
541 | dapm_clear_walk(w->codec); | ||
542 | w->power = (in != 0) ? 1 : 0; | ||
543 | dapm_update_bits(w); | ||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | /* active DAC */ | ||
548 | if (w->id == snd_soc_dapm_dac && w->active) { | ||
549 | out = is_connected_output_ep(w); | ||
550 | dapm_clear_walk(w->codec); | ||
551 | w->power = (out != 0) ? 1 : 0; | ||
552 | dapm_update_bits(w); | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | /* pre and post event widgets */ | ||
557 | if (w->id == snd_soc_dapm_pre) { | ||
558 | if (!w->event) | ||
559 | return 0; | ||
560 | |||
561 | if (event == SND_SOC_DAPM_STREAM_START) { | ||
562 | ret = w->event(w, | ||
563 | NULL, SND_SOC_DAPM_PRE_PMU); | ||
564 | if (ret < 0) | ||
565 | return ret; | ||
566 | } else if (event == SND_SOC_DAPM_STREAM_STOP) { | ||
567 | ret = w->event(w, | ||
568 | NULL, SND_SOC_DAPM_PRE_PMD); | ||
569 | if (ret < 0) | ||
570 | return ret; | ||
571 | } | ||
572 | return 0; | ||
573 | } | ||
574 | if (w->id == snd_soc_dapm_post) { | ||
575 | if (!w->event) | ||
576 | return 0; | ||
577 | |||
578 | if (event == SND_SOC_DAPM_STREAM_START) { | ||
579 | ret = w->event(w, | ||
580 | NULL, SND_SOC_DAPM_POST_PMU); | ||
581 | if (ret < 0) | ||
582 | return ret; | ||
583 | } else if (event == SND_SOC_DAPM_STREAM_STOP) { | ||
584 | ret = w->event(w, | ||
585 | NULL, SND_SOC_DAPM_POST_PMD); | ||
586 | if (ret < 0) | ||
587 | return ret; | ||
588 | } | ||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | /* all other widgets */ | ||
593 | in = is_connected_input_ep(w); | ||
594 | dapm_clear_walk(w->codec); | ||
595 | out = is_connected_output_ep(w); | ||
596 | dapm_clear_walk(w->codec); | ||
597 | power = (out != 0 && in != 0) ? 1 : 0; | ||
598 | power_change = (w->power == power) ? 0 : 1; | ||
599 | w->power = power; | ||
600 | |||
601 | if (!power_change) | ||
602 | return 0; | ||
603 | |||
604 | /* call any power change event handlers */ | ||
605 | if (w->event) | ||
606 | pr_debug("power %s event for %s flags %x\n", | ||
607 | w->power ? "on" : "off", | ||
608 | w->name, w->event_flags); | ||
609 | |||
610 | /* power up pre event */ | ||
611 | if (power && w->event && | ||
612 | (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { | ||
613 | ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); | ||
614 | if (ret < 0) | ||
615 | return ret; | ||
616 | } | ||
617 | |||
618 | /* power down pre event */ | ||
619 | if (!power && w->event && | ||
620 | (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { | ||
621 | ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); | ||
622 | if (ret < 0) | ||
623 | return ret; | ||
624 | } | ||
625 | |||
626 | /* Lower PGA volume to reduce pops */ | ||
627 | if (w->id == snd_soc_dapm_pga && !power) | ||
628 | dapm_set_pga(w, power); | ||
629 | |||
630 | dapm_update_bits(w); | ||
631 | |||
632 | /* Raise PGA volume to reduce pops */ | ||
633 | if (w->id == snd_soc_dapm_pga && power) | ||
634 | dapm_set_pga(w, power); | ||
635 | |||
636 | /* power up post event */ | ||
637 | if (power && w->event && | ||
638 | (w->event_flags & SND_SOC_DAPM_POST_PMU)) { | ||
639 | ret = w->event(w, | ||
640 | NULL, SND_SOC_DAPM_POST_PMU); | ||
641 | if (ret < 0) | ||
642 | return ret; | ||
643 | } | ||
644 | |||
645 | /* power down post event */ | ||
646 | if (!power && w->event && | ||
647 | (w->event_flags & SND_SOC_DAPM_POST_PMD)) { | ||
648 | ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); | ||
649 | if (ret < 0) | ||
650 | return ret; | ||
651 | } | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | /* | ||
526 | * Scan each dapm widget for complete audio path. | 657 | * Scan each dapm widget for complete audio path. |
527 | * A complete path is a route that has valid endpoints i.e.:- | 658 | * A complete path is a route that has valid endpoints i.e.:- |
528 | * | 659 | * |
@@ -534,7 +665,7 @@ EXPORT_SYMBOL_GPL(dapm_reg_event); | |||
534 | static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | 665 | static int dapm_power_widgets(struct snd_soc_codec *codec, int event) |
535 | { | 666 | { |
536 | struct snd_soc_dapm_widget *w; | 667 | struct snd_soc_dapm_widget *w; |
537 | int in, out, i, c = 1, *seq = NULL, ret = 0, power_change, power; | 668 | int i, c = 1, *seq = NULL, ret = 0; |
538 | 669 | ||
539 | /* do we have a sequenced stream event */ | 670 | /* do we have a sequenced stream event */ |
540 | if (event == SND_SOC_DAPM_STREAM_START) { | 671 | if (event == SND_SOC_DAPM_STREAM_START) { |
@@ -545,135 +676,20 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
545 | seq = dapm_down_seq; | 676 | seq = dapm_down_seq; |
546 | } | 677 | } |
547 | 678 | ||
548 | for(i = 0; i < c; i++) { | 679 | for (i = 0; i < c; i++) { |
549 | list_for_each_entry(w, &codec->dapm_widgets, list) { | 680 | list_for_each_entry(w, &codec->dapm_widgets, list) { |
550 | 681 | ||
551 | /* is widget in stream order */ | 682 | /* is widget in stream order */ |
552 | if (seq && seq[i] && w->id != seq[i]) | 683 | if (seq && seq[i] && w->id != seq[i]) |
553 | continue; | 684 | continue; |
554 | 685 | ||
555 | /* vmid - no action */ | 686 | ret = dapm_power_widget(codec, event, w); |
556 | if (w->id == snd_soc_dapm_vmid) | 687 | if (ret != 0) |
557 | continue; | 688 | return ret; |
558 | |||
559 | /* active ADC */ | ||
560 | if (w->id == snd_soc_dapm_adc && w->active) { | ||
561 | in = is_connected_input_ep(w); | ||
562 | dapm_clear_walk(w->codec); | ||
563 | w->power = (in != 0) ? 1 : 0; | ||
564 | dapm_update_bits(w); | ||
565 | continue; | ||
566 | } | ||
567 | |||
568 | /* active DAC */ | ||
569 | if (w->id == snd_soc_dapm_dac && w->active) { | ||
570 | out = is_connected_output_ep(w); | ||
571 | dapm_clear_walk(w->codec); | ||
572 | w->power = (out != 0) ? 1 : 0; | ||
573 | dapm_update_bits(w); | ||
574 | continue; | ||
575 | } | ||
576 | |||
577 | /* pre and post event widgets */ | ||
578 | if (w->id == snd_soc_dapm_pre) { | ||
579 | if (!w->event) | ||
580 | continue; | ||
581 | |||
582 | if (event == SND_SOC_DAPM_STREAM_START) { | ||
583 | ret = w->event(w, | ||
584 | NULL, SND_SOC_DAPM_PRE_PMU); | ||
585 | if (ret < 0) | ||
586 | return ret; | ||
587 | } else if (event == SND_SOC_DAPM_STREAM_STOP) { | ||
588 | ret = w->event(w, | ||
589 | NULL, SND_SOC_DAPM_PRE_PMD); | ||
590 | if (ret < 0) | ||
591 | return ret; | ||
592 | } | ||
593 | continue; | ||
594 | } | ||
595 | if (w->id == snd_soc_dapm_post) { | ||
596 | if (!w->event) | ||
597 | continue; | ||
598 | |||
599 | if (event == SND_SOC_DAPM_STREAM_START) { | ||
600 | ret = w->event(w, | ||
601 | NULL, SND_SOC_DAPM_POST_PMU); | ||
602 | if (ret < 0) | ||
603 | return ret; | ||
604 | } else if (event == SND_SOC_DAPM_STREAM_STOP) { | ||
605 | ret = w->event(w, | ||
606 | NULL, SND_SOC_DAPM_POST_PMD); | ||
607 | if (ret < 0) | ||
608 | return ret; | ||
609 | } | ||
610 | continue; | ||
611 | } | ||
612 | |||
613 | /* all other widgets */ | ||
614 | in = is_connected_input_ep(w); | ||
615 | dapm_clear_walk(w->codec); | ||
616 | out = is_connected_output_ep(w); | ||
617 | dapm_clear_walk(w->codec); | ||
618 | power = (out != 0 && in != 0) ? 1 : 0; | ||
619 | power_change = (w->power == power) ? 0: 1; | ||
620 | w->power = power; | ||
621 | |||
622 | if (!power_change) | ||
623 | continue; | ||
624 | |||
625 | /* call any power change event handlers */ | ||
626 | if (w->event) | ||
627 | pr_debug("power %s event for %s flags %x\n", | ||
628 | w->power ? "on" : "off", | ||
629 | w->name, w->event_flags); | ||
630 | |||
631 | /* power up pre event */ | ||
632 | if (power && w->event && | ||
633 | (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { | ||
634 | ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); | ||
635 | if (ret < 0) | ||
636 | return ret; | ||
637 | } | ||
638 | |||
639 | /* power down pre event */ | ||
640 | if (!power && w->event && | ||
641 | (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { | ||
642 | ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); | ||
643 | if (ret < 0) | ||
644 | return ret; | ||
645 | } | ||
646 | |||
647 | /* Lower PGA volume to reduce pops */ | ||
648 | if (w->id == snd_soc_dapm_pga && !power) | ||
649 | dapm_set_pga(w, power); | ||
650 | |||
651 | dapm_update_bits(w); | ||
652 | |||
653 | /* Raise PGA volume to reduce pops */ | ||
654 | if (w->id == snd_soc_dapm_pga && power) | ||
655 | dapm_set_pga(w, power); | ||
656 | |||
657 | /* power up post event */ | ||
658 | if (power && w->event && | ||
659 | (w->event_flags & SND_SOC_DAPM_POST_PMU)) { | ||
660 | ret = w->event(w, | ||
661 | NULL, SND_SOC_DAPM_POST_PMU); | ||
662 | if (ret < 0) | ||
663 | return ret; | ||
664 | } | ||
665 | |||
666 | /* power down post event */ | ||
667 | if (!power && w->event && | ||
668 | (w->event_flags & SND_SOC_DAPM_POST_PMD)) { | ||
669 | ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); | ||
670 | if (ret < 0) | ||
671 | return ret; | ||
672 | } | ||
673 | } | 689 | } |
674 | } | 690 | } |
675 | 691 | ||
676 | return ret; | 692 | return 0; |
677 | } | 693 | } |
678 | 694 | ||
679 | #ifdef DEBUG | 695 | #ifdef DEBUG |