diff options
Diffstat (limited to 'sound/soc/sunxi')
-rw-r--r-- | sound/soc/sunxi/sun50i-codec-analog.c | 176 |
1 files changed, 111 insertions, 65 deletions
diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c index f5b7069bcca2..a41e25ad0aaf 100644 --- a/sound/soc/sunxi/sun50i-codec-analog.c +++ b/sound/soc/sunxi/sun50i-codec-analog.c @@ -121,50 +121,50 @@ /* mixer controls */ static const struct snd_kcontrol_new sun50i_a64_codec_mixer_controls[] = { - SOC_DAPM_DOUBLE_R("DAC Playback Switch", + SOC_DAPM_DOUBLE_R("Mic1 Playback Switch", SUN50I_ADDA_OL_MIX_CTRL, SUN50I_ADDA_OR_MIX_CTRL, - SUN50I_ADDA_OL_MIX_CTRL_DACL, 1, 0), - SOC_DAPM_DOUBLE_R("DAC Reversed Playback Switch", + SUN50I_ADDA_OL_MIX_CTRL_MIC1, 1, 0), + SOC_DAPM_DOUBLE_R("Mic2 Playback Switch", SUN50I_ADDA_OL_MIX_CTRL, SUN50I_ADDA_OR_MIX_CTRL, - SUN50I_ADDA_OL_MIX_CTRL_DACR, 1, 0), + SUN50I_ADDA_OL_MIX_CTRL_MIC2, 1, 0), SOC_DAPM_DOUBLE_R("Line In Playback Switch", SUN50I_ADDA_OL_MIX_CTRL, SUN50I_ADDA_OR_MIX_CTRL, SUN50I_ADDA_OL_MIX_CTRL_LINEINL, 1, 0), - SOC_DAPM_DOUBLE_R("Mic1 Playback Switch", + SOC_DAPM_DOUBLE_R("DAC Playback Switch", SUN50I_ADDA_OL_MIX_CTRL, SUN50I_ADDA_OR_MIX_CTRL, - SUN50I_ADDA_OL_MIX_CTRL_MIC1, 1, 0), - SOC_DAPM_DOUBLE_R("Mic2 Playback Switch", + SUN50I_ADDA_OL_MIX_CTRL_DACL, 1, 0), + SOC_DAPM_DOUBLE_R("DAC Reversed Playback Switch", SUN50I_ADDA_OL_MIX_CTRL, SUN50I_ADDA_OR_MIX_CTRL, - SUN50I_ADDA_OL_MIX_CTRL_MIC2, 1, 0), + SUN50I_ADDA_OL_MIX_CTRL_DACR, 1, 0), }; /* ADC mixer controls */ static const struct snd_kcontrol_new sun50i_codec_adc_mixer_controls[] = { - SOC_DAPM_DOUBLE_R("Mixer Capture Switch", + SOC_DAPM_DOUBLE_R("Mic1 Capture Switch", SUN50I_ADDA_L_ADCMIX_SRC, SUN50I_ADDA_R_ADCMIX_SRC, - SUN50I_ADDA_L_ADCMIX_SRC_OMIXRL, 1, 0), - SOC_DAPM_DOUBLE_R("Mixer Reversed Capture Switch", + SUN50I_ADDA_L_ADCMIX_SRC_MIC1, 1, 0), + SOC_DAPM_DOUBLE_R("Mic2 Capture Switch", SUN50I_ADDA_L_ADCMIX_SRC, SUN50I_ADDA_R_ADCMIX_SRC, - SUN50I_ADDA_L_ADCMIX_SRC_OMIXRR, 1, 0), + SUN50I_ADDA_L_ADCMIX_SRC_MIC2, 1, 0), SOC_DAPM_DOUBLE_R("Line In Capture Switch", SUN50I_ADDA_L_ADCMIX_SRC, SUN50I_ADDA_R_ADCMIX_SRC, SUN50I_ADDA_L_ADCMIX_SRC_LINEINL, 1, 0), - SOC_DAPM_DOUBLE_R("Mic1 Capture Switch", + SOC_DAPM_DOUBLE_R("Mixer Capture Switch", SUN50I_ADDA_L_ADCMIX_SRC, SUN50I_ADDA_R_ADCMIX_SRC, - SUN50I_ADDA_L_ADCMIX_SRC_MIC1, 1, 0), - SOC_DAPM_DOUBLE_R("Mic2 Capture Switch", + SUN50I_ADDA_L_ADCMIX_SRC_OMIXRL, 1, 0), + SOC_DAPM_DOUBLE_R("Mixer Reversed Capture Switch", SUN50I_ADDA_L_ADCMIX_SRC, SUN50I_ADDA_R_ADCMIX_SRC, - SUN50I_ADDA_L_ADCMIX_SRC_MIC2, 1, 0), + SUN50I_ADDA_L_ADCMIX_SRC_OMIXRR, 1, 0), }; static const DECLARE_TLV_DB_SCALE(sun50i_codec_out_mixer_pregain_scale, @@ -193,11 +193,6 @@ static const struct snd_kcontrol_new sun50i_a64_codec_controls[] = { SUN50I_ADDA_HP_CTRL_HPVOL, 0x3f, 0, sun50i_codec_hp_vol_scale), - SOC_DOUBLE("Headphone Playback Switch", - SUN50I_ADDA_MIX_DAC_CTRL, - SUN50I_ADDA_MIX_DAC_CTRL_LHPPAMUTE, - SUN50I_ADDA_MIX_DAC_CTRL_RHPPAMUTE, 1, 0), - /* Mixer pre-gain */ SOC_SINGLE_TLV("Mic1 Playback Volume", SUN50I_ADDA_MIC1_CTRL, SUN50I_ADDA_MIC1_CTRL_MIC1G, @@ -233,20 +228,10 @@ static const struct snd_kcontrol_new sun50i_a64_codec_controls[] = { SUN50I_ADDA_LINEOUT_CTRL1_VOL, 0x1f, 0, sun50i_codec_lineout_vol_scale), - SOC_DOUBLE("Line Out Playback Switch", - SUN50I_ADDA_LINEOUT_CTRL0, - SUN50I_ADDA_LINEOUT_CTRL0_LEN, - SUN50I_ADDA_LINEOUT_CTRL0_REN, 1, 0), - SOC_SINGLE_TLV("Earpiece Playback Volume", SUN50I_ADDA_EARPIECE_CTRL1, SUN50I_ADDA_EARPIECE_CTRL1_ESP_VOL, 0x1f, 0, sun50i_codec_earpiece_vol_scale), - - SOC_SINGLE("Earpiece Playback Switch", - SUN50I_ADDA_EARPIECE_CTRL1, - SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE, 1, 0), - }; static const char * const sun50i_codec_hp_src_enum_text[] = { @@ -264,6 +249,12 @@ static const struct snd_kcontrol_new sun50i_codec_hp_src[] = { sun50i_codec_hp_src_enum), }; +static const struct snd_kcontrol_new sun50i_codec_hp_switch = + SOC_DAPM_DOUBLE("Headphone Playback Switch", + SUN50I_ADDA_MIX_DAC_CTRL, + SUN50I_ADDA_MIX_DAC_CTRL_LHPPAMUTE, + SUN50I_ADDA_MIX_DAC_CTRL_RHPPAMUTE, 1, 0); + static const char * const sun50i_codec_lineout_src_enum_text[] = { "Stereo", "Mono Differential", }; @@ -279,6 +270,12 @@ static const struct snd_kcontrol_new sun50i_codec_lineout_src[] = { sun50i_codec_lineout_src_enum), }; +static const struct snd_kcontrol_new sun50i_codec_lineout_switch = + SOC_DAPM_DOUBLE("Line Out Playback Switch", + SUN50I_ADDA_LINEOUT_CTRL0, + SUN50I_ADDA_LINEOUT_CTRL0_LEN, + SUN50I_ADDA_LINEOUT_CTRL0_REN, 1, 0); + static const char * const sun50i_codec_earpiece_src_enum_text[] = { "DACR", "DACL", "Right Mixer", "Left Mixer", }; @@ -293,6 +290,12 @@ static const struct snd_kcontrol_new sun50i_codec_earpiece_src[] = { sun50i_codec_earpiece_src_enum), }; +static const struct snd_kcontrol_new sun50i_codec_earpiece_switch[] = { + SOC_DAPM_SINGLE("Earpiece Playback Switch", + SUN50I_ADDA_EARPIECE_CTRL1, + SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE, 1, 0), +}; + static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = { /* DAC */ SND_SOC_DAPM_DAC("Left DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL, @@ -311,18 +314,37 @@ static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = { */ SND_SOC_DAPM_REGULATOR_SUPPLY("cpvdd", 0, 0), - SND_SOC_DAPM_MUX("Headphone Source Playback Route", + SND_SOC_DAPM_MUX("Left Headphone Source", + SND_SOC_NOPM, 0, 0, sun50i_codec_hp_src), + SND_SOC_DAPM_MUX("Right Headphone Source", SND_SOC_NOPM, 0, 0, sun50i_codec_hp_src), - SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN50I_ADDA_HP_CTRL, + SND_SOC_DAPM_SWITCH("Left Headphone Switch", + SND_SOC_NOPM, 0, 0, &sun50i_codec_hp_switch), + SND_SOC_DAPM_SWITCH("Right Headphone Switch", + SND_SOC_NOPM, 0, 0, &sun50i_codec_hp_switch), + SND_SOC_DAPM_OUT_DRV("Left Headphone Amp", + SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_OUT_DRV("Right Headphone Amp", + SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Headphone Amp", SUN50I_ADDA_HP_CTRL, SUN50I_ADDA_HP_CTRL_HPPA_EN, 0, NULL, 0), SND_SOC_DAPM_OUTPUT("HP"), - SND_SOC_DAPM_MUX("Line Out Source Playback Route", + SND_SOC_DAPM_MUX("Left Line Out Source", SND_SOC_NOPM, 0, 0, sun50i_codec_lineout_src), + SND_SOC_DAPM_MUX("Right Line Out Source", + SND_SOC_NOPM, 0, 0, sun50i_codec_lineout_src), + SND_SOC_DAPM_SWITCH("Left Line Out Switch", + SND_SOC_NOPM, 0, 0, &sun50i_codec_lineout_switch), + SND_SOC_DAPM_SWITCH("Right Line Out Switch", + SND_SOC_NOPM, 0, 0, &sun50i_codec_lineout_switch), SND_SOC_DAPM_OUTPUT("LINEOUT"), SND_SOC_DAPM_MUX("Earpiece Source Playback Route", SND_SOC_NOPM, 0, 0, sun50i_codec_earpiece_src), + SOC_MIXER_NAMED_CTL_ARRAY("Earpiece Switch", + SND_SOC_NOPM, 0, 0, + sun50i_codec_earpiece_switch), SND_SOC_DAPM_OUT_DRV("Earpiece Amp", SUN50I_ADDA_EARPIECE_CTRL1, SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_EN, 0, NULL, 0), SND_SOC_DAPM_OUTPUT("EARPIECE"), @@ -363,83 +385,105 @@ static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = { SUN50I_ADDA_MIX_DAC_CTRL_RMIXEN, 0, sun50i_a64_codec_mixer_controls, ARRAY_SIZE(sun50i_a64_codec_mixer_controls)), - SND_SOC_DAPM_MIXER("Left ADC Mixer", SUN50I_ADDA_ADC_CTRL, - SUN50I_ADDA_ADC_CTRL_ADCLEN, 0, + SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0, sun50i_codec_adc_mixer_controls, ARRAY_SIZE(sun50i_codec_adc_mixer_controls)), - SND_SOC_DAPM_MIXER("Right ADC Mixer", SUN50I_ADDA_ADC_CTRL, - SUN50I_ADDA_ADC_CTRL_ADCREN, 0, + SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0, sun50i_codec_adc_mixer_controls, ARRAY_SIZE(sun50i_codec_adc_mixer_controls)), }; static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = { /* Left Mixer Routes */ + { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, + { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" }, + { "Left Mixer", "Line In Playback Switch", "LINEIN" }, { "Left Mixer", "DAC Playback Switch", "Left DAC" }, { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" }, - { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, /* Right Mixer Routes */ + { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, + { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" }, + { "Right Mixer", "Line In Playback Switch", "LINEIN" }, { "Right Mixer", "DAC Playback Switch", "Right DAC" }, { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" }, - { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, /* Left ADC Mixer Routes */ + { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, + { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" }, + { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" }, { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" }, { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" }, - { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, /* Right ADC Mixer Routes */ + { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, + { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" }, + { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" }, { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" }, { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" }, - { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, /* ADC Routes */ { "Left ADC", NULL, "Left ADC Mixer" }, { "Right ADC", NULL, "Right ADC Mixer" }, /* Headphone Routes */ - { "Headphone Source Playback Route", "DAC", "Left DAC" }, - { "Headphone Source Playback Route", "DAC", "Right DAC" }, - { "Headphone Source Playback Route", "Mixer", "Left Mixer" }, - { "Headphone Source Playback Route", "Mixer", "Right Mixer" }, - { "Headphone Amp", NULL, "Headphone Source Playback Route" }, + { "Left Headphone Source", "DAC", "Left DAC" }, + { "Left Headphone Source", "Mixer", "Left Mixer" }, + { "Left Headphone Switch", "Headphone Playback Switch", "Left Headphone Source" }, + { "Left Headphone Amp", NULL, "Left Headphone Switch" }, + { "Left Headphone Amp", NULL, "Headphone Amp" }, + { "HP", NULL, "Left Headphone Amp" }, + + { "Right Headphone Source", "DAC", "Right DAC" }, + { "Right Headphone Source", "Mixer", "Right Mixer" }, + { "Right Headphone Switch", "Headphone Playback Switch", "Right Headphone Source" }, + { "Right Headphone Amp", NULL, "Right Headphone Switch" }, + { "Right Headphone Amp", NULL, "Headphone Amp" }, + { "HP", NULL, "Right Headphone Amp" }, + { "Headphone Amp", NULL, "cpvdd" }, - { "HP", NULL, "Headphone Amp" }, /* Microphone Routes */ { "Mic1 Amplifier", NULL, "MIC1"}, /* Microphone Routes */ { "Mic2 Amplifier", NULL, "MIC2"}, - { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" }, - { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" }, - { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" }, - { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" }, - - /* Line-in Routes */ - { "Left Mixer", "Line In Playback Switch", "LINEIN" }, - { "Right Mixer", "Line In Playback Switch", "LINEIN" }, - { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" }, - { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" }, /* Line-out Routes */ - { "Line Out Source Playback Route", "Stereo", "Left Mixer" }, - { "Line Out Source Playback Route", "Stereo", "Right Mixer" }, - { "Line Out Source Playback Route", "Mono Differential", "Left Mixer" }, - { "Line Out Source Playback Route", "Mono Differential", - "Right Mixer" }, - { "LINEOUT", NULL, "Line Out Source Playback Route" }, + { "Left Line Out Source", "Stereo", "Left Mixer" }, + { "Left Line Out Source", "Mono Differential", "Left Mixer" }, + { "Left Line Out Source", "Mono Differential", "Right Mixer" }, + { "Left Line Out Switch", "Line Out Playback Switch", "Left Line Out Source" }, + { "LINEOUT", NULL, "Left Line Out Switch" }, + + { "Right Line Out Switch", "Line Out Playback Switch", "Right Mixer" }, + { "Right Line Out Source", "Stereo", "Right Line Out Switch" }, + { "Right Line Out Source", "Mono Differential", "Left Line Out Switch" }, + { "LINEOUT", NULL, "Right Line Out Source" }, /* Earpiece Routes */ { "Earpiece Source Playback Route", "DACL", "Left DAC" }, { "Earpiece Source Playback Route", "DACR", "Right DAC" }, { "Earpiece Source Playback Route", "Left Mixer", "Left Mixer" }, { "Earpiece Source Playback Route", "Right Mixer", "Right Mixer" }, - { "Earpiece Amp", NULL, "Earpiece Source Playback Route" }, + { "Earpiece Switch", "Earpiece Playback Switch", "Earpiece Source Playback Route" }, + { "Earpiece Amp", NULL, "Earpiece Switch" }, { "EARPIECE", NULL, "Earpiece Amp" }, }; +static int sun50i_a64_codec_suspend(struct snd_soc_component *component) +{ + return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL, + BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE), + BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE)); +} + +static int sun50i_a64_codec_resume(struct snd_soc_component *component) +{ + return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL, + BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE), 0); +} + static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = { .controls = sun50i_a64_codec_controls, .num_controls = ARRAY_SIZE(sun50i_a64_codec_controls), @@ -447,6 +491,8 @@ static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = { .num_dapm_widgets = ARRAY_SIZE(sun50i_a64_codec_widgets), .dapm_routes = sun50i_a64_codec_routes, .num_dapm_routes = ARRAY_SIZE(sun50i_a64_codec_routes), + .suspend = sun50i_a64_codec_suspend, + .resume = sun50i_a64_codec_resume, }; static const struct of_device_id sun50i_codec_analog_of_match[] = { |