diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-04-13 06:29:10 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-04-13 06:59:01 -0400 |
commit | 6bbcb459cd50807511491ddf96bca1ef92006bf8 (patch) | |
tree | e66605e1130e2d32cb602abe73aad59bfdb0d20d /sound/soc/codecs/wm9713.c | |
parent | f6d655a6e6974e474a11b25052c29d10b80814b3 (diff) |
ASoC: Move the WM9713 voice DAC powerdown to a DAPM event
This ensures that we sync with the DAPM powerdown sequencing properly
and don't need to bounce the power on the voice DAC so often.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm9713.c')
-rw-r--r-- | sound/soc/codecs/wm9713.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index aa94cc68f0c0..a6feb7842314 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c | |||
@@ -189,6 +189,26 @@ SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0), | |||
189 | SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), | 189 | SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), |
190 | }; | 190 | }; |
191 | 191 | ||
192 | static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w, | ||
193 | struct snd_kcontrol *kcontrol, int event) | ||
194 | { | ||
195 | struct snd_soc_codec *codec = w->codec; | ||
196 | u16 status, rate; | ||
197 | |||
198 | BUG_ON(event != SND_SOC_DAPM_PRE_PMD); | ||
199 | |||
200 | /* Gracefully shut down the voice interface. */ | ||
201 | status = ac97_read(codec, AC97_EXTENDED_MID) | 0x1000; | ||
202 | rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF; | ||
203 | ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200); | ||
204 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | ||
205 | ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00); | ||
206 | ac97_write(codec, AC97_EXTENDED_MID, status); | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | |||
192 | /* We have to create a fake left and right HP mixers because | 212 | /* We have to create a fake left and right HP mixers because |
193 | * the codec only has a single control that is shared by both channels. | 213 | * the codec only has a single control that is shared by both channels. |
194 | * This makes it impossible to determine the audio path using the current | 214 | * This makes it impossible to determine the audio path using the current |
@@ -400,7 +420,8 @@ SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | |||
400 | SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 420 | SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
401 | SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 421 | SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
402 | SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | 422 | SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), |
403 | SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1), | 423 | SND_SOC_DAPM_DAC_E("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1, |
424 | wm9713_voice_shutdown, SND_SOC_DAPM_PRE_PMD), | ||
404 | SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1), | 425 | SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1), |
405 | SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0), | 426 | SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0), |
406 | SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0), | 427 | SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0), |
@@ -936,21 +957,6 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream, | |||
936 | return 0; | 957 | return 0; |
937 | } | 958 | } |
938 | 959 | ||
939 | static void wm9713_voiceshutdown(struct snd_pcm_substream *substream, | ||
940 | struct snd_soc_dai *dai) | ||
941 | { | ||
942 | struct snd_soc_codec *codec = dai->codec; | ||
943 | u16 status, rate; | ||
944 | |||
945 | /* Gracefully shut down the voice interface. */ | ||
946 | status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000; | ||
947 | rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF; | ||
948 | ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200); | ||
949 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | ||
950 | ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00); | ||
951 | ac97_write(codec, AC97_EXTENDED_MID, status); | ||
952 | } | ||
953 | |||
954 | static int ac97_hifi_prepare(struct snd_pcm_substream *substream, | 960 | static int ac97_hifi_prepare(struct snd_pcm_substream *substream, |
955 | struct snd_soc_dai *dai) | 961 | struct snd_soc_dai *dai) |
956 | { | 962 | { |
@@ -1019,7 +1025,6 @@ static struct snd_soc_dai_ops wm9713_dai_ops_aux = { | |||
1019 | 1025 | ||
1020 | static struct snd_soc_dai_ops wm9713_dai_ops_voice = { | 1026 | static struct snd_soc_dai_ops wm9713_dai_ops_voice = { |
1021 | .hw_params = wm9713_pcm_hw_params, | 1027 | .hw_params = wm9713_pcm_hw_params, |
1022 | .shutdown = wm9713_voiceshutdown, | ||
1023 | .set_clkdiv = wm9713_set_dai_clkdiv, | 1028 | .set_clkdiv = wm9713_set_dai_clkdiv, |
1024 | .set_pll = wm9713_set_dai_pll, | 1029 | .set_pll = wm9713_set_dai_pll, |
1025 | .set_fmt = wm9713_set_dai_fmt, | 1030 | .set_fmt = wm9713_set_dai_fmt, |