Lines Matching +full:left +full:- +full:right
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:-
47 static const char *wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"};
52 static const char *wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"};
62 {"Off", "Mono", "Speaker", "Left Headphone", "Right Headphone",
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*/
78 SOC_ENUM_SINGLE(AC97_REC_GAIN, 11, 8, wm9713_spk_pga), /* speaker left input select 8 */
79 SOC_ENUM_SINGLE(AC97_REC_GAIN, 8, 8, wm9713_spk_pga), /* speaker right input select 9 */
80 SOC_ENUM_SINGLE(AC97_REC_GAIN, 6, 3, wm9713_hp_pga), /* headphone left input 10 */
81 SOC_ENUM_SINGLE(AC97_REC_GAIN, 4, 3, wm9713_hp_pga), /* headphone right input 11 */
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()
218 /* We have to create a fake left and right HP mixers because
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()
295 /* Left Headphone Mixers */
305 /* Right Headphone Mixers */
353 /* speaker left output mux */
357 /* speaker right output mux */
361 /* headphone left output mux */
365 /* headphone right output mux */
385 /* Capture source left */
389 /* Capture source right */
410 SND_SOC_DAPM_MUX("Left Speaker Out Mux", SND_SOC_NOPM, 0, 0,
412 SND_SOC_DAPM_MUX("Right Speaker Out Mux", SND_SOC_NOPM, 0, 0,
414 SND_SOC_DAPM_MUX("Left Headphone Out Mux", SND_SOC_NOPM, 0, 0,
416 SND_SOC_DAPM_MUX("Right Headphone Out Mux", SND_SOC_NOPM, 0, 0,
426 SND_SOC_DAPM_MUX("Left Capture Source", SND_SOC_NOPM, 0, 0,
428 SND_SOC_DAPM_MUX("Right Capture Source", SND_SOC_NOPM, 0, 0,
434 SND_SOC_DAPM_MIXER("Left HP Mixer", AC97_EXTENDED_MID, 3, 1,
436 SND_SOC_DAPM_MIXER("Right HP Mixer", AC97_EXTENDED_MID, 2, 1,
443 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", AC97_EXTENDED_MID, 7, 1),
444 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", AC97_EXTENDED_MID, 6, 1),
452 SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0),
453 SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0),
454 SND_SOC_DAPM_ADC("Left HiFi ADC", "Left HiFi Capture", SND_SOC_NOPM, 0, 0),
455 SND_SOC_DAPM_ADC("Right HiFi ADC", "Right HiFi Capture", SND_SOC_NOPM, 0, 0),
456 SND_SOC_DAPM_ADC("Left Voice ADC", "Left Voice Capture", SND_SOC_NOPM, 0, 0),
457 SND_SOC_DAPM_ADC("Right Voice ADC", "Right Voice Capture", SND_SOC_NOPM, 0, 0),
458 SND_SOC_DAPM_PGA("Left Headphone", AC97_EXTENDED_MSTATUS, 10, 1, NULL, 0),
459 SND_SOC_DAPM_PGA("Right Headphone", AC97_EXTENDED_MSTATUS, 9, 1, NULL, 0),
460 SND_SOC_DAPM_PGA("Left Speaker", AC97_EXTENDED_MSTATUS, 8, 1, NULL, 0),
461 SND_SOC_DAPM_PGA("Right Speaker", AC97_EXTENDED_MSTATUS, 7, 1, NULL, 0),
465 SND_SOC_DAPM_PGA("Left Line In", AC97_EXTENDED_MSTATUS, 6, 1, NULL, 0),
466 SND_SOC_DAPM_PGA("Right Line In", AC97_EXTENDED_MSTATUS, 5, 1, NULL, 0),
491 /* left HP mixer */
492 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"},
493 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
494 {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"},
495 {"Left HP Mixer", "Bypass Playback Switch", "Left Line In"},
496 {"Left HP Mixer", "PCM Playback Switch", "Left DAC"},
497 {"Left HP Mixer", "MonoIn Playback Switch", "Mono In"},
498 {"Left HP Mixer", NULL, "Capture Headphone Mux"},
500 /* right HP mixer */
501 {"Right HP Mixer", "Beep Playback Switch", "PCBEEP"},
502 {"Right HP Mixer", "Voice Playback Switch", "Voice DAC"},
503 {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"},
504 {"Right HP Mixer", "Bypass Playback Switch", "Right Line In"},
505 {"Right HP Mixer", "PCM Playback Switch", "Right DAC"},
506 {"Right HP Mixer", "MonoIn Playback Switch", "Mono In"},
507 {"Right HP Mixer", NULL, "Capture Headphone Mux"},
509 /* virtual mixer - mixes left & right channels for spk and mono */
510 {"AC97 Mixer", NULL, "Left DAC"},
511 {"AC97 Mixer", NULL, "Right DAC"},
512 {"Line Mixer", NULL, "Right Line In"},
513 {"Line Mixer", NULL, "Left Line In"},
514 {"HP Mixer", NULL, "Left HP Mixer"},
515 {"HP Mixer", NULL, "Right HP Mixer"},
516 {"Capture Mixer", NULL, "Left Capture Source"},
517 {"Capture Mixer", NULL, "Right Capture Source"},
540 {"DAC Inv Mux 1", "Left Headphone", "Left HP Mixer"},
541 {"DAC Inv Mux 1", "Right Headphone", "Right HP Mixer"},
547 {"DAC Inv Mux 2", "Left Headphone", "Left HP Mixer"},
548 {"DAC Inv Mux 2", "Right Headphone", "Right HP Mixer"},
551 /* headphone left mux */
552 {"Left Headphone Out Mux", "Headphone", "Left HP Mixer"},
554 /* headphone right mux */
555 {"Right Headphone Out Mux", "Headphone", "Right HP Mixer"},
557 /* speaker left mux */
558 {"Left Speaker Out Mux", "Headphone", "Left HP Mixer"},
559 {"Left Speaker Out Mux", "Speaker", "Speaker Mixer"},
560 {"Left Speaker Out Mux", "Inv", "DAC Inv Mux 1"},
562 /* speaker right mux */
563 {"Right Speaker Out Mux", "Headphone", "Right HP Mixer"},
564 {"Right Speaker Out Mux", "Speaker", "Speaker Mixer"},
565 {"Right Speaker Out Mux", "Inv", "DAC Inv Mux 2"},
578 {"HPL", NULL, "Left Headphone"},
579 {"Left Headphone", NULL, "Left Headphone Out Mux"},
580 {"HPR", NULL, "Right Headphone"},
581 {"Right Headphone", NULL, "Right Headphone Out Mux"},
586 {"SPKL", NULL, "Left Speaker"},
587 {"Left Speaker", NULL, "Left Speaker Out Mux"},
588 {"SPKR", NULL, "Right Speaker"},
589 {"Right Speaker", NULL, "Right Speaker Out Mux"},
594 {"Left Line In", NULL, "LINEL"},
595 {"Right Line In", NULL, "LINER"},
600 /* left capture select */
601 {"Left Capture Source", "Mic 1", "Mic A Pre Amp"},
602 {"Left Capture Source", "Mic 2", "Mic B Pre Amp"},
603 {"Left Capture Source", "Line", "LINEL"},
604 {"Left Capture Source", "Mono In", "MONOIN"},
605 {"Left Capture Source", "Headphone", "Left HP Mixer"},
606 {"Left Capture Source", "Speaker", "Speaker Mixer"},
607 {"Left Capture Source", "Mono Out", "Mono Mixer"},
609 /* right capture select */
610 {"Right Capture Source", "Mic 1", "Mic A Pre Amp"},
611 {"Right Capture Source", "Mic 2", "Mic B Pre Amp"},
612 {"Right Capture Source", "Line", "LINER"},
613 {"Right Capture Source", "Mono In", "MONOIN"},
614 {"Right Capture Source", "Headphone", "Right HP Mixer"},
615 {"Right Capture Source", "Speaker", "Speaker Mixer"},
616 {"Right Capture Source", "Mono Out", "Mono Mixer"},
618 /* left ADC */
619 {"Left ADC", NULL, "Left Capture Source"},
620 {"Left Voice ADC", NULL, "Left ADC"},
621 {"Left HiFi ADC", NULL, "Left ADC"},
623 /* right ADC */
624 {"Right ADC", NULL, "Right Capture Source"},
625 {"Right Voice ADC", NULL, "Right ADC"},
626 {"Right HiFi ADC", NULL, "Right ADC"},
638 {"Capture Headphone Mux", "Left", "Left Capture Source"},
639 {"Capture Headphone Mux", "Right", "Right Capture Source"},
643 {"Capture Mono Mux", "Left", "Left Capture Source"},
644 {"Capture Mono Mux", "Right", "Right Capture Source"},
704 { 0x42, 0x0000 }, /* Fast Power-Up Control */
710 { 0x52, 0x0000 }, /* GPIO Pin Wake-Up */
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()
826 wm9713->pll_in = 0; in wm9713_set_pll()
868 wm9713->pll_in = freq_in; in wm9713_set_pll()
878 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_pll()
889 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_tristate()
905 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_clkdiv()
932 return -EINVAL; in wm9713_set_dai_clkdiv()
941 struct snd_soc_component *component = codec_dai->component; in wm9713_set_dai_fmt()
1004 struct snd_soc_component *component = dai->component; in wm9713_pcm_hw_params()
1029 struct snd_soc_component *component = dai->component; in ac97_hifi_prepare()
1030 struct snd_pcm_runtime *runtime = substream->runtime; 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()
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",
1168 /* Disable everything except touchpanel - that will be handled in wm9713_soc_suspend()
1169 * by the touch driver and left disabled if touch is not in in wm9713_soc_suspend()
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()
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()
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",