Message ID | 20210421091410.2300-1-shumingf@realtek.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [v2] ASoC: rt711-sdca: change capture switch controls | expand |
Dne 21. 04. 21 v 11:14 shumingf@realtek.com napsal(a): > From: Shuming Fan <shumingf@realtek.com> > > The DAPM event and mixer control could mute/unmute the capture directly. > That will be confused that capture still works if the user settings is unmute before the capture. > Therefore, this patch uses the variables to record the capture switch status of DAPM and mixer. > > Signed-off-by: Shuming Fan <shumingf@realtek.com> > --- > sound/soc/codecs/rt711-sdca.c | 125 ++++++++++++++++++++++------------ > sound/soc/codecs/rt711-sdca.h | 2 + > 2 files changed, 84 insertions(+), 43 deletions(-) > > diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c > index bfb7f1c8ec8f..95ca0d74bd10 100644 > --- a/sound/soc/codecs/rt711-sdca.c > +++ b/sound/soc/codecs/rt711-sdca.c > @@ -642,6 +642,73 @@ static int rt711_sdca_set_gain_get(struct snd_kcontrol *kcontrol, > return 0; > } > > +static void rt711_sdca_set_fu0f_capture_ctl(struct rt711_sdca_priv *rt711) > +{ > + if (rt711->fu0f_dapm_mute || rt711->fu0f_mixer_mute) { > + regmap_write(rt711->regmap, > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, > + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x01); > + regmap_write(rt711->regmap, > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, > + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x01); > + } else { > + regmap_write(rt711->regmap, > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, > + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x00); > + regmap_write(rt711->regmap, > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, > + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x00); > + } > +} > + Please, keep the idependent mute functionality for left and right channel. Use bitmap instead bool for kcontrol put/get . I appologize, if my example code confused you. I just wanted to describe the logic. Also, perhaps, you may change the register with one regmap_write() ? > +static void rt711_sdca_set_fu1e_capture_ctl(struct rt711_sdca_priv *rt711) > +{ > + if (rt711->fu1e_dapm_mute || rt711->fu1e_mixer_mute) { > + regmap_write(rt711->regmap, > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU1E, > + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x01); > + regmap_write(rt711->regmap, > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU1E, > + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x01); > + } else { > + regmap_write(rt711->regmap, > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU1E, > + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x00); > + regmap_write(rt711->regmap, > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU1E, > + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x00); > + } > +} > + > +static int rt711_sdca_capture_switch_get(struct snd_kcontrol *kcontrol, > + struct snd_ctl_elem_value *ucontrol) > +{ > + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); > + struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); > + > + if (strstr(ucontrol->id.name, "FU1E Capture Switch")) > + ucontrol->value.integer.value[0] = !rt711->fu1e_mixer_mute; > + else if (strstr(ucontrol->id.name, "FU0F Capture Switch")) > + ucontrol->value.integer.value[0] = !rt711->fu0f_mixer_mute; > + return 0; > +} It's not so nice (strstr). Please, use diferent functions to set/get FU1E and FU0F controls. > + > +static int rt711_sdca_capture_switch_put(struct snd_kcontrol *kcontrol, > + struct snd_ctl_elem_value *ucontrol) > +{ > + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); > + struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); > + > + if (strstr(ucontrol->id.name, "FU1E Capture Switch")) { > + rt711->fu1e_mixer_mute = !ucontrol->value.integer.value[0]; > + rt711_sdca_set_fu1e_capture_ctl(rt711); > + } else if (strstr(ucontrol->id.name, "FU0F Capture Switch")) { > + rt711->fu0f_mixer_mute = !ucontrol->value.integer.value[0]; > + rt711_sdca_set_fu0f_capture_ctl(rt711); > + } > + return 0; > +} The return value for the kcontrol put callback should be: a) a negative error code b) 0 - no change c) 1 - the value was changed If you don't return 1 on change, the other user space applications which are monitoring the given kcontrol won't be notified about changes. Perhaps, other put callbacks (functions) in this driver require this cleanup, too. Jaroslav
> > > > +static void rt711_sdca_set_fu0f_capture_ctl(struct rt711_sdca_priv > > +*rt711) { > > + if (rt711->fu0f_dapm_mute || rt711->fu0f_mixer_mute) { > > + regmap_write(rt711->regmap, > > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, > RT711_SDCA_ENT_USER_FU0F, > > + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x01); > > + regmap_write(rt711->regmap, > > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, > RT711_SDCA_ENT_USER_FU0F, > > + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x01); > > + } else { > > + regmap_write(rt711->regmap, > > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, > RT711_SDCA_ENT_USER_FU0F, > > + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x00); > > + regmap_write(rt711->regmap, > > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, > RT711_SDCA_ENT_USER_FU0F, > > + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x00); > > + } > > +} > > + > > Please, keep the idependent mute functionality for left and right channel. Use > bitmap instead bool for kcontrol put/get . I appologize, if my example code > confused you. I just wanted to describe the logic. > > Also, perhaps, you may change the register with one regmap_write() ? I see. I think the kcontrol could use 'SOC_DOUBLE_EXT' macro to create it. The put callback function checks the bitmap to mute/unmute the left/right channel. > > +static void rt711_sdca_set_fu1e_capture_ctl(struct rt711_sdca_priv > > +*rt711) { > > + if (rt711->fu1e_dapm_mute || rt711->fu1e_mixer_mute) { > > + regmap_write(rt711->regmap, > > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, > RT711_SDCA_ENT_USER_FU1E, > > + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x01); > > + regmap_write(rt711->regmap, > > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, > RT711_SDCA_ENT_USER_FU1E, > > + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x01); > > + } else { > > + regmap_write(rt711->regmap, > > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, > RT711_SDCA_ENT_USER_FU1E, > > + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x00); > > + regmap_write(rt711->regmap, > > + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, > RT711_SDCA_ENT_USER_FU1E, > > + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x00); > > + } > > +} > > + > > +static int rt711_sdca_capture_switch_get(struct snd_kcontrol *kcontrol, > > + struct snd_ctl_elem_value *ucontrol) { > > + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); > > + struct rt711_sdca_priv *rt711 = > > +snd_soc_component_get_drvdata(component); > > + > > + if (strstr(ucontrol->id.name, "FU1E Capture Switch")) > > + ucontrol->value.integer.value[0] = !rt711->fu1e_mixer_mute; > > + else if (strstr(ucontrol->id.name, "FU0F Capture Switch")) > > + ucontrol->value.integer.value[0] = !rt711->fu0f_mixer_mute; > > + return 0; > > +} > > It's not so nice (strstr). Please, use diferent functions to set/get FU1E and FU0F > controls. OK, I will create the different functions for FU1E and FU0F. > > + > > +static int rt711_sdca_capture_switch_put(struct snd_kcontrol *kcontrol, > > + struct snd_ctl_elem_value *ucontrol) { > > + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); > > + struct rt711_sdca_priv *rt711 = > > +snd_soc_component_get_drvdata(component); > > + > > + if (strstr(ucontrol->id.name, "FU1E Capture Switch")) { > > + rt711->fu1e_mixer_mute = !ucontrol->value.integer.value[0]; > > + rt711_sdca_set_fu1e_capture_ctl(rt711); > > + } else if (strstr(ucontrol->id.name, "FU0F Capture Switch")) { > > + rt711->fu0f_mixer_mute = !ucontrol->value.integer.value[0]; > > + rt711_sdca_set_fu0f_capture_ctl(rt711); > > + } > > + return 0; > > +} > > The return value for the kcontrol put callback should be: > > a) a negative error code > b) 0 - no change > c) 1 - the value was changed > > If you don't return 1 on change, the other user space applications which are > monitoring the given kcontrol won't be notified about changes. > > Perhaps, other put callbacks (functions) in this driver require this cleanup, too. Ok, I will add the return value and test that. Thanks. > Jaroslav > > -- > Jaroslav Kysela <perex@perex.cz> > Linux Sound Maintainer; ALSA Project; Red Hat, Inc. > ------Please consider the environment before printing this e-mail.
diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index bfb7f1c8ec8f..95ca0d74bd10 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -642,6 +642,73 @@ static int rt711_sdca_set_gain_get(struct snd_kcontrol *kcontrol, return 0; } +static void rt711_sdca_set_fu0f_capture_ctl(struct rt711_sdca_priv *rt711) +{ + if (rt711->fu0f_dapm_mute || rt711->fu0f_mixer_mute) { + regmap_write(rt711->regmap, + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x01); + regmap_write(rt711->regmap, + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x01); + } else { + regmap_write(rt711->regmap, + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x00); + regmap_write(rt711->regmap, + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x00); + } +} + +static void rt711_sdca_set_fu1e_capture_ctl(struct rt711_sdca_priv *rt711) +{ + if (rt711->fu1e_dapm_mute || rt711->fu1e_mixer_mute) { + regmap_write(rt711->regmap, + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU1E, + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x01); + regmap_write(rt711->regmap, + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU1E, + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x01); + } else { + regmap_write(rt711->regmap, + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU1E, + RT711_SDCA_CTL_FU_MUTE, CH_L), 0x00); + regmap_write(rt711->regmap, + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU1E, + RT711_SDCA_CTL_FU_MUTE, CH_R), 0x00); + } +} + +static int rt711_sdca_capture_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); + + if (strstr(ucontrol->id.name, "FU1E Capture Switch")) + ucontrol->value.integer.value[0] = !rt711->fu1e_mixer_mute; + else if (strstr(ucontrol->id.name, "FU0F Capture Switch")) + ucontrol->value.integer.value[0] = !rt711->fu0f_mixer_mute; + return 0; +} + +static int rt711_sdca_capture_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); + + if (strstr(ucontrol->id.name, "FU1E Capture Switch")) { + rt711->fu1e_mixer_mute = !ucontrol->value.integer.value[0]; + rt711_sdca_set_fu1e_capture_ctl(rt711); + } else if (strstr(ucontrol->id.name, "FU0F Capture Switch")) { + rt711->fu0f_mixer_mute = !ucontrol->value.integer.value[0]; + rt711_sdca_set_fu0f_capture_ctl(rt711); + } + return 0; +} + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0); static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0); static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); @@ -652,14 +719,10 @@ static const struct snd_kcontrol_new rt711_sdca_snd_controls[] = { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU05, RT711_SDCA_CTL_FU_VOLUME, CH_R), 0x57, 0x57, 0, rt711_sdca_set_gain_get, rt711_sdca_set_gain_put, out_vol_tlv), - SOC_DOUBLE_R("FU1E Capture Switch", - SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, RT711_SDCA_CTL_FU_MUTE, CH_L), - SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, RT711_SDCA_CTL_FU_MUTE, CH_R), - 0, 1, 1), - SOC_DOUBLE_R("FU0F Capture Switch", - SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, RT711_SDCA_CTL_FU_MUTE, CH_L), - SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, RT711_SDCA_CTL_FU_MUTE, CH_R), - 0, 1, 1), + SOC_SINGLE_EXT("FU1E Capture Switch", SND_SOC_NOPM, 0, 1, 0, + rt711_sdca_capture_switch_get, rt711_sdca_capture_switch_put), + SOC_SINGLE_EXT("FU0F Capture Switch", SND_SOC_NOPM, 0, 1, 0, + rt711_sdca_capture_switch_get, rt711_sdca_capture_switch_put), SOC_DOUBLE_R_EXT_TLV("FU1E Capture Volume", SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, RT711_SDCA_CTL_FU_VOLUME, CH_L), SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, RT711_SDCA_CTL_FU_VOLUME, CH_R), @@ -809,28 +872,15 @@ static int rt711_sdca_fu0f_event(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); - unsigned char unmute = 0x0, mute = 0x1; switch (event) { case SND_SOC_DAPM_POST_PMU: - regmap_write(rt711->regmap, - SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, - RT711_SDCA_CTL_FU_MUTE, CH_L), - unmute); - regmap_write(rt711->regmap, - SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, - RT711_SDCA_CTL_FU_MUTE, CH_R), - unmute); + rt711->fu0f_dapm_mute = false; + rt711_sdca_set_fu0f_capture_ctl(rt711); break; case SND_SOC_DAPM_PRE_PMD: - regmap_write(rt711->regmap, - SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, - RT711_SDCA_CTL_FU_MUTE, CH_L), - mute); - regmap_write(rt711->regmap, - SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_USER_FU0F, - RT711_SDCA_CTL_FU_MUTE, CH_R), - mute); + rt711->fu0f_dapm_mute = true; + rt711_sdca_set_fu0f_capture_ctl(rt711); break; } return 0; @@ -842,29 +892,16 @@ static int rt711_sdca_fu1e_event(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); - unsigned char unmute = 0x0, mute = 0x1; switch (event) { case SND_SOC_DAPM_POST_PMU: - regmap_write(rt711->regmap, - SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, - RT711_SDCA_CTL_FU_MUTE, CH_L), - unmute); - regmap_write(rt711->regmap, - SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, - RT711_SDCA_CTL_FU_MUTE, CH_R), - unmute); + rt711->fu1e_dapm_mute = false; + rt711_sdca_set_fu1e_capture_ctl(rt711); break; case SND_SOC_DAPM_PRE_PMD: - regmap_write(rt711->regmap, - SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, - RT711_SDCA_CTL_FU_MUTE, CH_L), - mute); - regmap_write(rt711->regmap, - SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_USER_FU1E, - RT711_SDCA_CTL_FU_MUTE, CH_R), - mute); - break; + rt711->fu1e_dapm_mute = true; + rt711_sdca_set_fu1e_capture_ctl(rt711); + break; } return 0; } @@ -1330,6 +1367,8 @@ int rt711_sdca_init(struct device *dev, struct regmap *regmap, */ rt711->hw_init = false; rt711->first_hw_init = false; + rt711->fu0f_dapm_mute = rt711->fu0f_mixer_mute = true; + rt711->fu1e_dapm_mute = rt711->fu1e_mixer_mute = true; /* JD source uses JD2 in default */ rt711->jd_src = RT711_JD2; diff --git a/sound/soc/codecs/rt711-sdca.h b/sound/soc/codecs/rt711-sdca.h index 98a022cec0bd..a3b3a95094c0 100644 --- a/sound/soc/codecs/rt711-sdca.h +++ b/sound/soc/codecs/rt711-sdca.h @@ -30,6 +30,8 @@ struct rt711_sdca_priv { int jack_type, jd_src; unsigned int scp_sdca_stat1, scp_sdca_stat2; int hw_ver; + bool fu0f_dapm_mute, fu0f_mixer_mute; + bool fu1e_dapm_mute, fu1e_mixer_mute; }; struct sdw_stream_data {