Lines Matching +full:single +full:- +full:mux +full:- +full:ctrl
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:-
71 SOC_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), /* record mux hp 1 */
72 SOC_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), /* record mux mono 2 */
73 SOC_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src), /* record mux left 3 */
74 SOC_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src), /* record mux right 4*/
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);
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),
195 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in wm9713_voice_shutdown()
198 return -EINVAL; in wm9713_voice_shutdown()
219 * the codec only has a single control that is shared by both channels.
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()
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()
275 (struct soc_mixer_control *)kcontrol->private_value; 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()
311 /* headphone capture mux */
315 /* headphone mic mux */
341 /* mono mic mux */
345 /* mono output mux */
349 /* speaker left output mux */
353 /* speaker right output mux */
357 /* headphone left output mux */
361 /* headphone right output mux */
365 /* Out3 mux */
369 /* Out4 mux */
373 /* DAC inv mux 1 */
377 /* DAC inv mux 2 */
398 SND_SOC_DAPM_MUX("Capture Headphone Mux", SND_SOC_NOPM, 0, 0,
400 SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0,
402 SND_SOC_DAPM_MUX("Capture Mono Mux", SND_SOC_NOPM, 0, 0,
404 SND_SOC_DAPM_MUX("Mono Out Mux", SND_SOC_NOPM, 0, 0,
406 SND_SOC_DAPM_MUX("Left Speaker Out Mux", SND_SOC_NOPM, 0, 0,
408 SND_SOC_DAPM_MUX("Right Speaker Out Mux", SND_SOC_NOPM, 0, 0,
410 SND_SOC_DAPM_MUX("Left Headphone Out Mux", SND_SOC_NOPM, 0, 0,
412 SND_SOC_DAPM_MUX("Right Headphone Out Mux", SND_SOC_NOPM, 0, 0,
414 SND_SOC_DAPM_MUX("Out 3 Mux", SND_SOC_NOPM, 0, 0,
416 SND_SOC_DAPM_MUX("Out 4 Mux", SND_SOC_NOPM, 0, 0,
418 SND_SOC_DAPM_MUX("DAC Inv Mux 1", SND_SOC_NOPM, 0, 0,
420 SND_SOC_DAPM_MUX("DAC Inv Mux 2", SND_SOC_NOPM, 0, 0,
494 {"Left HP Mixer", NULL, "Capture Headphone Mux"},
503 {"Right HP Mixer", NULL, "Capture Headphone Mux"},
505 /* virtual mixer - mixes left & right channels for spk and mono */
531 {"Mono Mixer", NULL, "Capture Mono Mux"},
533 /* DAC inv mux 1 */
534 {"DAC Inv Mux 1", "Mono", "Mono Mixer"},
535 {"DAC Inv Mux 1", "Speaker", "Speaker Mixer"},
536 {"DAC Inv Mux 1", "Left Headphone", "Left HP Mixer"},
537 {"DAC Inv Mux 1", "Right Headphone", "Right HP Mixer"},
538 {"DAC Inv Mux 1", "Headphone Mono", "HP Mixer"},
540 /* DAC inv mux 2 */
541 {"DAC Inv Mux 2", "Mono", "Mono Mixer"},
542 {"DAC Inv Mux 2", "Speaker", "Speaker Mixer"},
543 {"DAC Inv Mux 2", "Left Headphone", "Left HP Mixer"},
544 {"DAC Inv Mux 2", "Right Headphone", "Right HP Mixer"},
545 {"DAC Inv Mux 2", "Headphone Mono", "HP Mixer"},
547 /* headphone left mux */
548 {"Left Headphone Out Mux", "Headphone", "Left HP Mixer"},
550 /* headphone right mux */
551 {"Right Headphone Out Mux", "Headphone", "Right HP Mixer"},
553 /* speaker left mux */
554 {"Left Speaker Out Mux", "Headphone", "Left HP Mixer"},
555 {"Left Speaker Out Mux", "Speaker", "Speaker Mixer"},
556 {"Left Speaker Out Mux", "Inv", "DAC Inv Mux 1"},
558 /* speaker right mux */
559 {"Right Speaker Out Mux", "Headphone", "Right HP Mixer"},
560 {"Right Speaker Out Mux", "Speaker", "Speaker Mixer"},
561 {"Right Speaker Out Mux", "Inv", "DAC Inv Mux 2"},
563 /* mono mux */
564 {"Mono Out Mux", "Mono", "Mono Mixer"},
565 {"Mono Out Mux", "Inv", "DAC Inv Mux 1"},
567 /* out 3 mux */
568 {"Out 3 Mux", "Inv 1", "DAC Inv Mux 1"},
570 /* out 4 mux */
571 {"Out 4 Mux", "Inv 2", "DAC Inv Mux 2"},
575 {"Left Headphone", NULL, "Left Headphone Out Mux"},
577 {"Right Headphone", NULL, "Right Headphone Out Mux"},
579 {"Out 3", NULL, "Out 3 Mux"},
581 {"Out 4", NULL, "Out 4 Mux"},
583 {"Left Speaker", NULL, "Left Speaker Out Mux"},
585 {"Right Speaker", NULL, "Right Speaker Out Mux"},
587 {"Mono Out", NULL, "Mono Out Mux"},
633 {"Capture Headphone Mux", "Stereo", "Capture Mixer"},
634 {"Capture Headphone Mux", "Left", "Left Capture Source"},
635 {"Capture Headphone Mux", "Right", "Right Capture Source"},
638 {"Capture Mono Mux", "Stereo", "Capture Mixer"},
639 {"Capture Mono Mux", "Left", "Left Capture Source"},
640 {"Capture Mono Mux", "Right", "Right Capture Source"},
684 { 0x1c, 0x0000 }, /* Output PGA Mux */
689 { 0x26, 0x7f00 }, /* Powerdown Ctrl/Stat*/
691 { 0x2a, 0x0410 }, /* Extended Audio Start/Ctrl */
700 { 0x42, 0x0000 }, /* Fast Power-Up Control */
706 { 0x52, 0x0000 }, /* GPIO Pin Wake-Up */
760 pll_div->divsel = 1; in pll_factors()
764 pll_div->divctl = 1; in pll_factors()
766 pll_div->divctl = 0; in pll_factors()
769 pll_div->divsel = 0; in pll_factors()
770 pll_div->divctl = 0; in pll_factors()
777 pll_div->lf = 1; in pll_factors()
780 pll_div->lf = 0; in pll_factors()
784 dev_warn(component->dev, in pll_factors()
788 pll_div->n = Ndiv; in pll_factors()
803 pll_div->k = K; in pll_factors()
822 wm9713->pll_in = 0; in wm9713_set_pll()
864 wm9713->pll_in = freq_in; in wm9713_set_pll()
874 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_pll()
885 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_tristate()
901 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_clkdiv()
928 return -EINVAL; in wm9713_set_dai_clkdiv()
937 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_fmt()
1000 struct snd_soc_component *component = dai->component; in wm9713_pcm_hw_params()
1025 struct snd_soc_component *component = dai->component; in ac97_hifi_prepare()
1026 struct snd_pcm_runtime *runtime = substream->runtime; in ac97_hifi_prepare()
1031 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in ac97_hifi_prepare()
1036 return snd_soc_component_write(component, reg, runtime->rate); in ac97_hifi_prepare()
1042 struct snd_soc_component *component = dai->component; in ac97_aux_prepare()
1043 struct snd_pcm_runtime *runtime = substream->runtime; in ac97_aux_prepare()
1048 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) in ac97_aux_prepare()
1049 return -ENODEV; in ac97_aux_prepare()
1051 return snd_soc_component_write(component, AC97_PCM_SURR_DAC_RATE, runtime->rate); in ac97_aux_prepare()
1093 .name = "wm9713-hifi",
1109 .name = "wm9713-aux",
1119 .name = "wm9713-voice",
1164 /* Disable everything except touchpanel - that will be handled in wm9713_soc_suspend()
1181 ret = snd_ac97_reset(wm9713->ac97, true, WM9713_VENDOR_ID, in wm9713_soc_resume()
1188 /* do we need to re-start the PLL ? */ in wm9713_soc_resume()
1189 if (wm9713->pll_in) in wm9713_soc_resume()
1190 wm9713_set_pll(component, 0, wm9713->pll_in, 0); in wm9713_soc_resume()
1194 regcache_mark_dirty(component->regmap); in wm9713_soc_resume()
1206 if (wm9713->mfd_pdata) { in wm9713_soc_probe()
1207 wm9713->ac97 = wm9713->mfd_pdata->ac97; in wm9713_soc_probe()
1208 regmap = wm9713->mfd_pdata->regmap; in wm9713_soc_probe()
1210 wm9713->ac97 = snd_soc_new_ac97_component(component, WM9713_VENDOR_ID, in wm9713_soc_probe()
1212 if (IS_ERR(wm9713->ac97)) in wm9713_soc_probe()
1213 return PTR_ERR(wm9713->ac97); in wm9713_soc_probe()
1214 regmap = regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config); in wm9713_soc_probe()
1216 snd_soc_free_ac97_component(wm9713->ac97); in wm9713_soc_probe()
1220 return -ENXIO; in wm9713_soc_probe()
1225 /* unmute the adc - move to kcontrol */ in wm9713_soc_probe()
1235 if (IS_ENABLED(CONFIG_SND_SOC_AC97_BUS) && !wm9713->mfd_pdata) { in wm9713_soc_remove()
1237 snd_soc_free_ac97_component(wm9713->ac97); in wm9713_soc_remove()
1262 wm9713 = devm_kzalloc(&pdev->dev, sizeof(*wm9713), GFP_KERNEL); in wm9713_probe()
1264 return -ENOMEM; in wm9713_probe()
1266 mutex_init(&wm9713->lock); in wm9713_probe()
1268 wm9713->mfd_pdata = dev_get_platdata(&pdev->dev); in wm9713_probe()
1271 return devm_snd_soc_register_component(&pdev->dev, in wm9713_probe()
1277 .name = "wm9713-codec",