Lines Matching +full:mic +full:- +full:int

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * wm9713.c -- ALSA Soc WM9713 codec support
5 * Copyright 2006-10 Wolfson Microelectronics PLC.
8 * Features:-
38 unsigned int hp_mixer[2];
46 static const char *wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
49 {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone", "Speaker",
66 static const char *wm9713_mic_select[] = {"Mic 1", "Mic 2 A", "Mic 2 B"};
70 SOC_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), /* record mic mixer 0 */
88 SOC_ENUM_SINGLE(AC97_3D_CONTROL, 12, 3, wm9713_mic_select), /* mic selection 18 */
89 SOC_ENUM_SINGLE_VIRT(2, wm9713_micb_select), /* mic selection 19 */
92 static const DECLARE_TLV_DB_SCALE(out_tlv, -4650, 150, 0);
93 static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
94 static const DECLARE_TLV_DB_SCALE(misc_tlv, -1500, 300, 0);
108 SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
109 SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
110 SOC_SINGLE_TLV("Mic 1 Preamp Volume", AC97_3D_CONTROL, 10, 3, 0, mic_tlv),
111 SOC_SINGLE_TLV("Mic 2 Preamp Volume", AC97_3D_CONTROL, 12, 3, 0, mic_tlv),
113 SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
114 SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
181 SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
182 SOC_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1),
183 SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0),
187 SOC_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0),
188 SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
192 static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w, in wm9713_voice_shutdown()
193 struct snd_kcontrol *kcontrol, int event) in wm9713_voice_shutdown()
195 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wm9713_voice_shutdown()
198 return -EINVAL; in wm9713_voice_shutdown()
209 static const unsigned int wm9713_mixer_mute_regs[] = {
224 static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol, in wm9713_hp_mixer_put()
230 unsigned int val = ucontrol->value.integer.value[0]; in wm9713_hp_mixer_put()
232 (struct soc_mixer_control *)kcontrol->private_value; in wm9713_hp_mixer_put()
233 unsigned int mixer, mask, shift, old; in wm9713_hp_mixer_put()
237 mixer = mc->shift >> 8; in wm9713_hp_mixer_put()
238 shift = mc->shift & 0xff; in wm9713_hp_mixer_put()
241 mutex_lock(&wm9713->lock); in wm9713_hp_mixer_put()
242 old = wm9713->hp_mixer[mixer]; in wm9713_hp_mixer_put()
243 if (ucontrol->value.integer.value[0]) in wm9713_hp_mixer_put()
244 wm9713->hp_mixer[mixer] |= mask; in wm9713_hp_mixer_put()
246 wm9713->hp_mixer[mixer] &= ~mask; in wm9713_hp_mixer_put()
248 change = old != wm9713->hp_mixer[mixer]; in wm9713_hp_mixer_put()
253 if ((wm9713->hp_mixer[0] & mask) || in wm9713_hp_mixer_put()
254 (wm9713->hp_mixer[1] & mask)) in wm9713_hp_mixer_put()
263 mutex_unlock(&wm9713->lock); in wm9713_hp_mixer_put()
268 static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol, in wm9713_hp_mixer_get()
275 (struct soc_mixer_control *)kcontrol->private_value; in wm9713_hp_mixer_get()
276 unsigned int mixer, shift; in wm9713_hp_mixer_get()
278 mixer = mc->shift >> 8; in wm9713_hp_mixer_get()
279 shift = mc->shift & 0xff; in wm9713_hp_mixer_get()
281 ucontrol->value.integer.value[0] = in wm9713_hp_mixer_get()
282 (wm9713->hp_mixer[mixer] >> shift) & 1; in wm9713_hp_mixer_get()
319 /* headphone mic mux */
341 SOC_DAPM_SINGLE("Mic 1 Sidetone Switch", AC97_LINE, 7, 1, 1),
342 SOC_DAPM_SINGLE("Mic 2 Sidetone Switch", AC97_LINE, 6, 1, 1),
345 /* mono mic mux */
393 /* mic source */
397 /* mic source B virtual control */
430 SND_SOC_DAPM_MUX("Mic A Source", SND_SOC_NOPM, 0, 0,
432 SND_SOC_DAPM_MUX("Mic B Source", SND_SOC_NOPM, 0, 0,
468 SND_SOC_DAPM_PGA("Mic A PGA", AC97_EXTENDED_MSTATUS, 3, 1, NULL, 0),
469 SND_SOC_DAPM_PGA("Mic B PGA", AC97_EXTENDED_MSTATUS, 2, 1, NULL, 0),
470 SND_SOC_DAPM_PGA("Mic A Pre Amp", AC97_EXTENDED_MSTATUS, 1, 1, NULL, 0),
471 SND_SOC_DAPM_PGA("Mic B Pre Amp", AC97_EXTENDED_MSTATUS, 0, 1, NULL, 0),
472 SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_EXTENDED_MSTATUS, 14, 1),
509 /* virtual mixer - mixes left & right channels for spk and mono */
533 {"Mono Mixer", "Mic 1 Sidetone Switch", "Mic A PGA"},
534 {"Mono Mixer", "Mic 2 Sidetone Switch", "Mic B PGA"},
597 {"Mic A PGA", NULL, "Mic A Pre Amp"},
598 {"Mic B PGA", NULL, "Mic B Pre Amp"},
601 {"Left Capture Source", "Mic 1", "Mic A Pre Amp"},
602 {"Left Capture Source", "Mic 2", "Mic B Pre Amp"},
610 {"Right Capture Source", "Mic 1", "Mic A Pre Amp"},
611 {"Right Capture Source", "Mic 2", "Mic B Pre Amp"},
628 /* mic */
629 {"Mic A Pre Amp", NULL, "Mic A Source"},
630 {"Mic A Source", "Mic 1", "MIC1"},
631 {"Mic A Source", "Mic 2 A", "MIC2A"},
632 {"Mic A Source", "Mic 2 B", "Mic B Source"},
633 {"Mic B Pre Amp", "MPB", "Mic B Source"},
634 {"Mic B Source", NULL, "MIC2B"},
647 static bool wm9713_readable_reg(struct device *dev, unsigned int reg) in wm9713_readable_reg()
663 static bool wm9713_writeable_reg(struct device *dev, unsigned int reg) in wm9713_writeable_reg()
681 { 0x0e, 0x0808 }, /* MIC PGA Volume */
682 { 0x10, 0x00da }, /* MIC Routing Control */
691 { 0x22, 0x0040 }, /* MIC Input Select & Bias */
704 { 0x42, 0x0000 }, /* Fast Power-Up Control */
710 { 0x52, 0x0000 }, /* GPIO Pin Wake-Up */
753 struct _pll_div *pll_div, unsigned int source) in pll_factors()
756 unsigned int K, Ndiv, Nmod, target; in pll_factors()
764 pll_div->divsel = 1; in pll_factors()
768 pll_div->divctl = 1; in pll_factors()
770 pll_div->divctl = 0; in pll_factors()
773 pll_div->divsel = 0; in pll_factors()
774 pll_div->divctl = 0; in pll_factors()
781 pll_div->lf = 1; in pll_factors()
784 pll_div->lf = 0; in pll_factors()
788 dev_warn(component->dev, in pll_factors()
792 pll_div->n = Ndiv; in pll_factors()
807 pll_div->k = K; in pll_factors()
814 static int wm9713_set_pll(struct snd_soc_component *component, in wm9713_set_pll()
815 int pll_id, unsigned int freq_in, unsigned int freq_out) in wm9713_set_pll()
826 wm9713->pll_in = 0; in wm9713_set_pll()
868 wm9713->pll_in = freq_in; in wm9713_set_pll()
875 static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, in wm9713_set_dai_pll()
876 int source, unsigned int freq_in, unsigned int freq_out) in wm9713_set_dai_pll()
878 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_pll()
886 static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai, in wm9713_set_dai_tristate()
887 int tristate) in wm9713_set_dai_tristate()
889 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_tristate()
902 static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai, in wm9713_set_dai_clkdiv()
903 int div_id, int div) in wm9713_set_dai_clkdiv()
905 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_clkdiv()
932 return -EINVAL; in wm9713_set_dai_clkdiv()
938 static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai, in wm9713_set_dai_fmt()
939 unsigned int fmt) in wm9713_set_dai_fmt()
941 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_fmt()
1000 static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream, in wm9713_pcm_hw_params()
1004 struct snd_soc_component *component = dai->component; in wm9713_pcm_hw_params()
1026 static int ac97_hifi_prepare(struct snd_pcm_substream *substream, in ac97_hifi_prepare()
1029 struct snd_soc_component *component = dai->component; in ac97_hifi_prepare()
1030 struct snd_pcm_runtime *runtime = substream->runtime; in ac97_hifi_prepare()
1031 int reg; in ac97_hifi_prepare()
1035 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in ac97_hifi_prepare()
1040 return snd_soc_component_write(component, reg, runtime->rate); in ac97_hifi_prepare()
1043 static int ac97_aux_prepare(struct snd_pcm_substream *substream, in ac97_aux_prepare()
1046 struct snd_soc_component *component = dai->component; in ac97_aux_prepare()
1047 struct snd_pcm_runtime *runtime = substream->runtime; in ac97_aux_prepare()
1052 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) in ac97_aux_prepare()
1053 return -ENODEV; in ac97_aux_prepare()
1055 return snd_soc_component_write(component, AC97_PCM_SURR_DAC_RATE, runtime->rate); in ac97_aux_prepare()
1097 .name = "wm9713-hifi",
1113 .name = "wm9713-aux",
1123 .name = "wm9713-voice",
1141 static int wm9713_set_bias_level(struct snd_soc_component *component, in wm9713_set_bias_level()
1166 static int wm9713_soc_suspend(struct snd_soc_component *component) in wm9713_soc_suspend()
1168 /* Disable everything except touchpanel - that will be handled in wm9713_soc_suspend()
1180 static int wm9713_soc_resume(struct snd_soc_component *component) in wm9713_soc_resume()
1183 int ret; in wm9713_soc_resume()
1185 ret = snd_ac97_reset(wm9713->ac97, true, WM9713_VENDOR_ID, in wm9713_soc_resume()
1192 /* do we need to re-start the PLL ? */ in wm9713_soc_resume()
1193 if (wm9713->pll_in) in wm9713_soc_resume()
1194 wm9713_set_pll(component, 0, wm9713->pll_in, 0); in wm9713_soc_resume()
1198 regcache_mark_dirty(component->regmap); in wm9713_soc_resume()
1205 static int wm9713_soc_probe(struct snd_soc_component *component) in wm9713_soc_probe()
1210 if (wm9713->mfd_pdata) { in wm9713_soc_probe()
1211 wm9713->ac97 = wm9713->mfd_pdata->ac97; in wm9713_soc_probe()
1212 regmap = wm9713->mfd_pdata->regmap; in wm9713_soc_probe()
1214 wm9713->ac97 = snd_soc_new_ac97_component(component, WM9713_VENDOR_ID, in wm9713_soc_probe()
1216 if (IS_ERR(wm9713->ac97)) in wm9713_soc_probe()
1217 return PTR_ERR(wm9713->ac97); in wm9713_soc_probe()
1218 regmap = regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config); in wm9713_soc_probe()
1220 snd_soc_free_ac97_component(wm9713->ac97); in wm9713_soc_probe()
1224 return -ENXIO; in wm9713_soc_probe()
1229 /* unmute the adc - move to kcontrol */ in wm9713_soc_probe()
1239 if (IS_ENABLED(CONFIG_SND_SOC_AC97_BUS) && !wm9713->mfd_pdata) { in wm9713_soc_remove()
1241 snd_soc_free_ac97_component(wm9713->ac97); in wm9713_soc_remove()
1262 static int wm9713_probe(struct platform_device *pdev) in wm9713_probe()
1266 wm9713 = devm_kzalloc(&pdev->dev, sizeof(*wm9713), GFP_KERNEL); in wm9713_probe()
1268 return -ENOMEM; in wm9713_probe()
1270 mutex_init(&wm9713->lock); in wm9713_probe()
1272 wm9713->mfd_pdata = dev_get_platdata(&pdev->dev); in wm9713_probe()
1275 return devm_snd_soc_register_component(&pdev->dev, in wm9713_probe()
1281 .name = "wm9713-codec",