Message ID | 20191020153007.206070-2-stephan@gerhold.net (mailing list archive) |
---|---|
State | Accepted |
Commit | 7d2f70f248ab0e4251591cf7b36cc43281941f56 |
Headers | show |
Series | [1/2] ASoC: msm8916-wcd-analog: Fix RX1 selection in RDAC2 MUX | expand |
On 20/10/2019 16:30, Stephan Gerhold wrote: > PM8916 supports an earpiece as another (small) speaker. > The earpiece is routed through RX MIX1 similarly to > the headphones, except that RDAC2 MUX is set to RX1. > > Signed-off-by: Stephan Gerhold <stephan@gerhold.net> Looks good to me. Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > --- > This patch is based on code from the downstream driver > (msm8x16-wcd.c, [1]) with some cleanup. > > This enables the earpiece on the Samsung Galaxy A5 (2015), > which has recently gained mainline support in [2]. > > [1]: https://source.codeaurora.org/quic/la/kernel/msm-3.10/tree/sound/soc/codecs/msm8x16-wcd.c?h=LA.BR.1.2.9.1-02310-8x16.0 > [2]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1329c1ab0730b521e6cd3051c56a2ff3d55f21e6 > --- > sound/soc/codecs/msm8916-wcd-analog.c | 54 ++++++++++++++++++++++++++- > 1 file changed, 52 insertions(+), 2 deletions(-) > > diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c > index e3d311fb510e..f53235be77d9 100644 > --- a/sound/soc/codecs/msm8916-wcd-analog.c > +++ b/sound/soc/codecs/msm8916-wcd-analog.c > @@ -228,6 +228,10 @@ > #define CDC_A_RX_EAR_CTL (0xf19E) > #define RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK BIT(0) > #define RX_EAR_CTL_SPK_VBAT_LDO_EN_ENABLE BIT(0) > +#define RX_EAR_CTL_PA_EAR_PA_EN_MASK BIT(6) > +#define RX_EAR_CTL_PA_EAR_PA_EN_ENABLE BIT(6) > +#define RX_EAR_CTL_PA_SEL_MASK BIT(7) > +#define RX_EAR_CTL_PA_SEL BIT(7) > > #define CDC_A_SPKR_DAC_CTL (0xf1B0) > #define SPKR_DAC_CTL_DAC_RESET_MASK BIT(4) > @@ -312,6 +316,7 @@ static const char *const hph_text[] = { "ZERO", "Switch", }; > static const struct soc_enum hph_enum = SOC_ENUM_SINGLE_VIRT( > ARRAY_SIZE(hph_text), hph_text); > > +static const struct snd_kcontrol_new ear_mux = SOC_DAPM_ENUM("EAR_S", hph_enum); > static const struct snd_kcontrol_new hphl_mux = SOC_DAPM_ENUM("HPHL", hph_enum); > static const struct snd_kcontrol_new hphr_mux = SOC_DAPM_ENUM("HPHR", hph_enum); > > @@ -685,6 +690,34 @@ static int pm8916_wcd_analog_enable_spk_pa(struct snd_soc_dapm_widget *w, > return 0; > } > > +static int pm8916_wcd_analog_enable_ear_pa(struct snd_soc_dapm_widget *w, > + struct snd_kcontrol *kcontrol, > + int event) > +{ > + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); > + > + switch (event) { > + case SND_SOC_DAPM_PRE_PMU: > + snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL, > + RX_EAR_CTL_PA_SEL_MASK, RX_EAR_CTL_PA_SEL); > + break; > + case SND_SOC_DAPM_POST_PMU: > + snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL, > + RX_EAR_CTL_PA_EAR_PA_EN_MASK, > + RX_EAR_CTL_PA_EAR_PA_EN_ENABLE); > + break; > + case SND_SOC_DAPM_POST_PMD: > + snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL, > + RX_EAR_CTL_PA_EAR_PA_EN_MASK, 0); > + /* Delay to reduce ear turn off pop */ > + usleep_range(7000, 7100); > + snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL, > + RX_EAR_CTL_PA_SEL_MASK, 0); > + break; > + } > + return 0; > +} > + > static const struct reg_default wcd_reg_defaults_2_0[] = { > {CDC_A_RX_COM_OCP_CTL, 0xD1}, > {CDC_A_RX_COM_OCP_COUNT, 0xFF}, > @@ -801,12 +834,20 @@ static const struct snd_soc_dapm_route pm8916_wcd_analog_audio_map[] = { > {"PDM_TX", NULL, "A_MCLK2"}, > {"A_MCLK2", NULL, "A_MCLK"}, > > + /* Earpiece (RX MIX1) */ > + {"EAR", NULL, "EAR_S"}, > + {"EAR_S", "Switch", "EAR PA"}, > + {"EAR PA", NULL, "RX_BIAS"}, > + {"EAR PA", NULL, "HPHL DAC"}, > + {"EAR PA", NULL, "HPHR DAC"}, > + {"EAR PA", NULL, "EAR CP"}, > + > /* Headset (RX MIX1 and RX MIX2) */ > {"HEADPHONE", NULL, "HPHL PA"}, > {"HEADPHONE", NULL, "HPHR PA"}, > > - {"HPHL PA", NULL, "EAR_HPHL_CLK"}, > - {"HPHR PA", NULL, "EAR_HPHR_CLK"}, > + {"HPHL DAC", NULL, "EAR_HPHL_CLK"}, > + {"HPHR DAC", NULL, "EAR_HPHR_CLK"}, > > {"CP", NULL, "NCP_CLK"}, > > @@ -847,11 +888,20 @@ static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = { > SND_SOC_DAPM_INPUT("AMIC1"), > SND_SOC_DAPM_INPUT("AMIC3"), > SND_SOC_DAPM_INPUT("AMIC2"), > + SND_SOC_DAPM_OUTPUT("EAR"), > SND_SOC_DAPM_OUTPUT("HEADPHONE"), > > /* RX stuff */ > SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0), > > + SND_SOC_DAPM_PGA_E("EAR PA", SND_SOC_NOPM, > + 0, 0, NULL, 0, > + pm8916_wcd_analog_enable_ear_pa, > + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | > + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), > + SND_SOC_DAPM_MUX("EAR_S", SND_SOC_NOPM, 0, 0, &ear_mux), > + SND_SOC_DAPM_SUPPLY("EAR CP", CDC_A_NCP_EN, 4, 0, NULL, 0), > + > SND_SOC_DAPM_PGA("HPHL PA", CDC_A_RX_HPH_CNP_EN, 5, 0, NULL, 0), > SND_SOC_DAPM_MUX("HPHL", SND_SOC_NOPM, 0, 0, &hphl_mux), > SND_SOC_DAPM_MIXER("HPHL DAC", CDC_A_RX_HPH_L_PA_DAC_CTL, 3, 0, NULL, >
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index e3d311fb510e..f53235be77d9 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -228,6 +228,10 @@ #define CDC_A_RX_EAR_CTL (0xf19E) #define RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK BIT(0) #define RX_EAR_CTL_SPK_VBAT_LDO_EN_ENABLE BIT(0) +#define RX_EAR_CTL_PA_EAR_PA_EN_MASK BIT(6) +#define RX_EAR_CTL_PA_EAR_PA_EN_ENABLE BIT(6) +#define RX_EAR_CTL_PA_SEL_MASK BIT(7) +#define RX_EAR_CTL_PA_SEL BIT(7) #define CDC_A_SPKR_DAC_CTL (0xf1B0) #define SPKR_DAC_CTL_DAC_RESET_MASK BIT(4) @@ -312,6 +316,7 @@ static const char *const hph_text[] = { "ZERO", "Switch", }; static const struct soc_enum hph_enum = SOC_ENUM_SINGLE_VIRT( ARRAY_SIZE(hph_text), hph_text); +static const struct snd_kcontrol_new ear_mux = SOC_DAPM_ENUM("EAR_S", hph_enum); static const struct snd_kcontrol_new hphl_mux = SOC_DAPM_ENUM("HPHL", hph_enum); static const struct snd_kcontrol_new hphr_mux = SOC_DAPM_ENUM("HPHR", hph_enum); @@ -685,6 +690,34 @@ static int pm8916_wcd_analog_enable_spk_pa(struct snd_soc_dapm_widget *w, return 0; } +static int pm8916_wcd_analog_enable_ear_pa(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL, + RX_EAR_CTL_PA_SEL_MASK, RX_EAR_CTL_PA_SEL); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL, + RX_EAR_CTL_PA_EAR_PA_EN_MASK, + RX_EAR_CTL_PA_EAR_PA_EN_ENABLE); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL, + RX_EAR_CTL_PA_EAR_PA_EN_MASK, 0); + /* Delay to reduce ear turn off pop */ + usleep_range(7000, 7100); + snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL, + RX_EAR_CTL_PA_SEL_MASK, 0); + break; + } + return 0; +} + static const struct reg_default wcd_reg_defaults_2_0[] = { {CDC_A_RX_COM_OCP_CTL, 0xD1}, {CDC_A_RX_COM_OCP_COUNT, 0xFF}, @@ -801,12 +834,20 @@ static const struct snd_soc_dapm_route pm8916_wcd_analog_audio_map[] = { {"PDM_TX", NULL, "A_MCLK2"}, {"A_MCLK2", NULL, "A_MCLK"}, + /* Earpiece (RX MIX1) */ + {"EAR", NULL, "EAR_S"}, + {"EAR_S", "Switch", "EAR PA"}, + {"EAR PA", NULL, "RX_BIAS"}, + {"EAR PA", NULL, "HPHL DAC"}, + {"EAR PA", NULL, "HPHR DAC"}, + {"EAR PA", NULL, "EAR CP"}, + /* Headset (RX MIX1 and RX MIX2) */ {"HEADPHONE", NULL, "HPHL PA"}, {"HEADPHONE", NULL, "HPHR PA"}, - {"HPHL PA", NULL, "EAR_HPHL_CLK"}, - {"HPHR PA", NULL, "EAR_HPHR_CLK"}, + {"HPHL DAC", NULL, "EAR_HPHL_CLK"}, + {"HPHR DAC", NULL, "EAR_HPHR_CLK"}, {"CP", NULL, "NCP_CLK"}, @@ -847,11 +888,20 @@ static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AMIC1"), SND_SOC_DAPM_INPUT("AMIC3"), SND_SOC_DAPM_INPUT("AMIC2"), + SND_SOC_DAPM_OUTPUT("EAR"), SND_SOC_DAPM_OUTPUT("HEADPHONE"), /* RX stuff */ SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0), + SND_SOC_DAPM_PGA_E("EAR PA", SND_SOC_NOPM, + 0, 0, NULL, 0, + pm8916_wcd_analog_enable_ear_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("EAR_S", SND_SOC_NOPM, 0, 0, &ear_mux), + SND_SOC_DAPM_SUPPLY("EAR CP", CDC_A_NCP_EN, 4, 0, NULL, 0), + SND_SOC_DAPM_PGA("HPHL PA", CDC_A_RX_HPH_CNP_EN, 5, 0, NULL, 0), SND_SOC_DAPM_MUX("HPHL", SND_SOC_NOPM, 0, 0, &hphl_mux), SND_SOC_DAPM_MIXER("HPHL DAC", CDC_A_RX_HPH_L_PA_DAC_CTL, 3, 0, NULL,
PM8916 supports an earpiece as another (small) speaker. The earpiece is routed through RX MIX1 similarly to the headphones, except that RDAC2 MUX is set to RX1. Signed-off-by: Stephan Gerhold <stephan@gerhold.net> --- This patch is based on code from the downstream driver (msm8x16-wcd.c, [1]) with some cleanup. This enables the earpiece on the Samsung Galaxy A5 (2015), which has recently gained mainline support in [2]. [1]: https://source.codeaurora.org/quic/la/kernel/msm-3.10/tree/sound/soc/codecs/msm8x16-wcd.c?h=LA.BR.1.2.9.1-02310-8x16.0 [2]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1329c1ab0730b521e6cd3051c56a2ff3d55f21e6 --- sound/soc/codecs/msm8916-wcd-analog.c | 54 ++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-)