Dne 21. 04. 21 v 11:14 shumingf@xxxxxxxxxxx napsal(a): > From: Shuming Fan <shumingf@xxxxxxxxxxx> > > 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@xxxxxxxxxxx> > --- > 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 -- Jaroslav Kysela <perex@xxxxxxxx> Linux Sound Maintainer; ALSA Project; Red Hat, Inc.