diff mbox series

[v2] ASoC: rt711-sdca: change capture switch controls

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

Commit Message

Shuming [范書銘] April 21, 2021, 9:14 a.m. UTC
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(-)

Comments

Jaroslav Kysela April 21, 2021, 9:31 a.m. UTC | #1
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
Shuming [范書銘] April 21, 2021, 10:11 a.m. UTC | #2
> >
> > +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 mbox series

Patch

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 {