diff options
Diffstat (limited to 'sound/soc/codecs/wm9713.c')
-rw-r--r-- | sound/soc/codecs/wm9713.c | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 523bad077fa0..abed37acf787 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), |
@@ -689,7 +710,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int source) | |||
689 | Ndiv = target / source; | 710 | Ndiv = target / source; |
690 | if ((Ndiv < 5) || (Ndiv > 12)) | 711 | if ((Ndiv < 5) || (Ndiv > 12)) |
691 | printk(KERN_WARNING | 712 | printk(KERN_WARNING |
692 | "WM9713 PLL N value %d out of recommended range!\n", | 713 | "WM9713 PLL N value %u out of recommended range!\n", |
693 | Ndiv); | 714 | Ndiv); |
694 | 715 | ||
695 | pll_div->n = Ndiv; | 716 | pll_div->n = Ndiv; |
@@ -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, |
@@ -1035,13 +1040,13 @@ struct snd_soc_dai wm9713_dai[] = { | |||
1035 | .channels_min = 1, | 1040 | .channels_min = 1, |
1036 | .channels_max = 2, | 1041 | .channels_max = 2, |
1037 | .rates = WM9713_RATES, | 1042 | .rates = WM9713_RATES, |
1038 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 1043 | .formats = SND_SOC_STD_AC97_FMTS,}, |
1039 | .capture = { | 1044 | .capture = { |
1040 | .stream_name = "HiFi Capture", | 1045 | .stream_name = "HiFi Capture", |
1041 | .channels_min = 1, | 1046 | .channels_min = 1, |
1042 | .channels_max = 2, | 1047 | .channels_max = 2, |
1043 | .rates = WM9713_RATES, | 1048 | .rates = WM9713_RATES, |
1044 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 1049 | .formats = SND_SOC_STD_AC97_FMTS,}, |
1045 | .ops = &wm9713_dai_ops_hifi, | 1050 | .ops = &wm9713_dai_ops_hifi, |
1046 | }, | 1051 | }, |
1047 | { | 1052 | { |
@@ -1051,7 +1056,7 @@ struct snd_soc_dai wm9713_dai[] = { | |||
1051 | .channels_min = 1, | 1056 | .channels_min = 1, |
1052 | .channels_max = 1, | 1057 | .channels_max = 1, |
1053 | .rates = WM9713_RATES, | 1058 | .rates = WM9713_RATES, |
1054 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 1059 | .formats = SND_SOC_STD_AC97_FMTS,}, |
1055 | .ops = &wm9713_dai_ops_aux, | 1060 | .ops = &wm9713_dai_ops_aux, |
1056 | }, | 1061 | }, |
1057 | { | 1062 | { |
@@ -1069,6 +1074,7 @@ struct snd_soc_dai wm9713_dai[] = { | |||
1069 | .rates = WM9713_PCM_RATES, | 1074 | .rates = WM9713_PCM_RATES, |
1070 | .formats = WM9713_PCM_FORMATS,}, | 1075 | .formats = WM9713_PCM_FORMATS,}, |
1071 | .ops = &wm9713_dai_ops_voice, | 1076 | .ops = &wm9713_dai_ops_voice, |
1077 | .symmetric_rates = 1, | ||
1072 | }, | 1078 | }, |
1073 | }; | 1079 | }; |
1074 | EXPORT_SYMBOL_GPL(wm9713_dai); | 1080 | EXPORT_SYMBOL_GPL(wm9713_dai); |