diff options
Diffstat (limited to 'sound/soc/codecs/arizona.c')
-rw-r--r-- | sound/soc/codecs/arizona.c | 78 |
1 files changed, 69 insertions, 9 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 9550d7433ad0..29202610dd0d 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -84,7 +84,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, | |||
84 | struct snd_kcontrol *kcontrol, | 84 | struct snd_kcontrol *kcontrol, |
85 | int event) | 85 | int event) |
86 | { | 86 | { |
87 | struct snd_soc_codec *codec = w->codec; | 87 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
88 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | 88 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); |
89 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | 89 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); |
90 | bool manual_ena = false; | 90 | bool manual_ena = false; |
@@ -692,7 +692,8 @@ static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) | |||
692 | int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, | 692 | int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, |
693 | int event) | 693 | int event) |
694 | { | 694 | { |
695 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); | 695 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
696 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
696 | unsigned int reg; | 697 | unsigned int reg; |
697 | 698 | ||
698 | if (w->shift % 2) | 699 | if (w->shift % 2) |
@@ -705,25 +706,25 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, | |||
705 | priv->in_pending++; | 706 | priv->in_pending++; |
706 | break; | 707 | break; |
707 | case SND_SOC_DAPM_POST_PMU: | 708 | case SND_SOC_DAPM_POST_PMU: |
708 | snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); | 709 | snd_soc_update_bits(codec, reg, ARIZONA_IN1L_MUTE, 0); |
709 | 710 | ||
710 | /* If this is the last input pending then allow VU */ | 711 | /* If this is the last input pending then allow VU */ |
711 | priv->in_pending--; | 712 | priv->in_pending--; |
712 | if (priv->in_pending == 0) { | 713 | if (priv->in_pending == 0) { |
713 | msleep(1); | 714 | msleep(1); |
714 | arizona_in_set_vu(w->codec, 1); | 715 | arizona_in_set_vu(codec, 1); |
715 | } | 716 | } |
716 | break; | 717 | break; |
717 | case SND_SOC_DAPM_PRE_PMD: | 718 | case SND_SOC_DAPM_PRE_PMD: |
718 | snd_soc_update_bits(w->codec, reg, | 719 | snd_soc_update_bits(codec, reg, |
719 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU, | 720 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU, |
720 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU); | 721 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU); |
721 | break; | 722 | break; |
722 | case SND_SOC_DAPM_POST_PMD: | 723 | case SND_SOC_DAPM_POST_PMD: |
723 | /* Disable volume updates if no inputs are enabled */ | 724 | /* Disable volume updates if no inputs are enabled */ |
724 | reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES); | 725 | reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES); |
725 | if (reg == 0) | 726 | if (reg == 0) |
726 | arizona_in_set_vu(w->codec, 0); | 727 | arizona_in_set_vu(codec, 0); |
727 | } | 728 | } |
728 | 729 | ||
729 | return 0; | 730 | return 0; |
@@ -734,7 +735,25 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
734 | struct snd_kcontrol *kcontrol, | 735 | struct snd_kcontrol *kcontrol, |
735 | int event) | 736 | int event) |
736 | { | 737 | { |
738 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
739 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
740 | |||
737 | switch (event) { | 741 | switch (event) { |
742 | case SND_SOC_DAPM_PRE_PMU: | ||
743 | switch (w->shift) { | ||
744 | case ARIZONA_OUT1L_ENA_SHIFT: | ||
745 | case ARIZONA_OUT1R_ENA_SHIFT: | ||
746 | case ARIZONA_OUT2L_ENA_SHIFT: | ||
747 | case ARIZONA_OUT2R_ENA_SHIFT: | ||
748 | case ARIZONA_OUT3L_ENA_SHIFT: | ||
749 | case ARIZONA_OUT3R_ENA_SHIFT: | ||
750 | priv->out_up_pending++; | ||
751 | priv->out_up_delay += 17; | ||
752 | break; | ||
753 | default: | ||
754 | break; | ||
755 | } | ||
756 | break; | ||
738 | case SND_SOC_DAPM_POST_PMU: | 757 | case SND_SOC_DAPM_POST_PMU: |
739 | switch (w->shift) { | 758 | switch (w->shift) { |
740 | case ARIZONA_OUT1L_ENA_SHIFT: | 759 | case ARIZONA_OUT1L_ENA_SHIFT: |
@@ -743,13 +762,50 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
743 | case ARIZONA_OUT2R_ENA_SHIFT: | 762 | case ARIZONA_OUT2R_ENA_SHIFT: |
744 | case ARIZONA_OUT3L_ENA_SHIFT: | 763 | case ARIZONA_OUT3L_ENA_SHIFT: |
745 | case ARIZONA_OUT3R_ENA_SHIFT: | 764 | case ARIZONA_OUT3R_ENA_SHIFT: |
746 | msleep(17); | 765 | priv->out_up_pending--; |
766 | if (!priv->out_up_pending) { | ||
767 | msleep(priv->out_up_delay); | ||
768 | priv->out_up_delay = 0; | ||
769 | } | ||
747 | break; | 770 | break; |
748 | 771 | ||
749 | default: | 772 | default: |
750 | break; | 773 | break; |
751 | } | 774 | } |
752 | break; | 775 | break; |
776 | case SND_SOC_DAPM_PRE_PMD: | ||
777 | switch (w->shift) { | ||
778 | case ARIZONA_OUT1L_ENA_SHIFT: | ||
779 | case ARIZONA_OUT1R_ENA_SHIFT: | ||
780 | case ARIZONA_OUT2L_ENA_SHIFT: | ||
781 | case ARIZONA_OUT2R_ENA_SHIFT: | ||
782 | case ARIZONA_OUT3L_ENA_SHIFT: | ||
783 | case ARIZONA_OUT3R_ENA_SHIFT: | ||
784 | priv->out_down_pending++; | ||
785 | priv->out_down_delay++; | ||
786 | break; | ||
787 | default: | ||
788 | break; | ||
789 | } | ||
790 | break; | ||
791 | case SND_SOC_DAPM_POST_PMD: | ||
792 | switch (w->shift) { | ||
793 | case ARIZONA_OUT1L_ENA_SHIFT: | ||
794 | case ARIZONA_OUT1R_ENA_SHIFT: | ||
795 | case ARIZONA_OUT2L_ENA_SHIFT: | ||
796 | case ARIZONA_OUT2R_ENA_SHIFT: | ||
797 | case ARIZONA_OUT3L_ENA_SHIFT: | ||
798 | case ARIZONA_OUT3R_ENA_SHIFT: | ||
799 | priv->out_down_pending--; | ||
800 | if (!priv->out_down_pending) { | ||
801 | msleep(priv->out_down_delay); | ||
802 | priv->out_down_delay = 0; | ||
803 | } | ||
804 | break; | ||
805 | default: | ||
806 | break; | ||
807 | } | ||
808 | break; | ||
753 | } | 809 | } |
754 | 810 | ||
755 | return 0; | 811 | return 0; |
@@ -760,7 +816,8 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, | |||
760 | struct snd_kcontrol *kcontrol, | 816 | struct snd_kcontrol *kcontrol, |
761 | int event) | 817 | int event) |
762 | { | 818 | { |
763 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); | 819 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); |
820 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
764 | struct arizona *arizona = priv->arizona; | 821 | struct arizona *arizona = priv->arizona; |
765 | unsigned int mask = 1 << w->shift; | 822 | unsigned int mask = 1 << w->shift; |
766 | unsigned int val; | 823 | unsigned int val; |
@@ -772,6 +829,9 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, | |||
772 | case SND_SOC_DAPM_PRE_PMD: | 829 | case SND_SOC_DAPM_PRE_PMD: |
773 | val = 0; | 830 | val = 0; |
774 | break; | 831 | break; |
832 | case SND_SOC_DAPM_PRE_PMU: | ||
833 | case SND_SOC_DAPM_POST_PMD: | ||
834 | return arizona_out_ev(w, kcontrol, event); | ||
775 | default: | 835 | default: |
776 | return -EINVAL; | 836 | return -EINVAL; |
777 | } | 837 | } |