]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: rt712-sdca: Add FU05 playback switch control
authorShuming Fan <shumingf@realtek.com>
Wed, 26 Feb 2025 08:47:28 +0000 (16:47 +0800)
committerMark Brown <broonie@kernel.org>
Wed, 26 Feb 2025 12:25:39 +0000 (12:25 +0000)
Because there is no playback switch control for rt712-sdw headphone endpoint,
it causes there is no way to control HP on and off in ALSA UCM config.

Signed-off-by: derek.fang <derek.fang@realtek.com>
Signed-off-by: Shuming Fan <shumingf@realtek.com>
Link: https://patch.msgid.link/20250226084728.1889082-1-shumingf@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/rt712-sdca.c
sound/soc/codecs/rt712-sdca.h

index 78dbf9eed494bb6f50c1d89c41a1f800582dde3d..19d99b9d4ab26e8e940bfe9ed6a0ff65b715dd88 100644 (file)
@@ -652,6 +652,61 @@ static int rt712_sdca_fu0f_capture_put(struct snd_kcontrol *kcontrol,
        return 1;
 }
 
+static int rt712_sdca_set_fu05_playback_ctl(struct rt712_sdca_priv *rt712)
+{
+       int err;
+       unsigned int ch_01, ch_02;
+
+       ch_01 = (rt712->fu05_dapm_mute || rt712->fu05_mixer_l_mute) ? 0x01 : 0x00;
+       ch_02 = (rt712->fu05_dapm_mute || rt712->fu05_mixer_r_mute) ? 0x01 : 0x00;
+
+       err = regmap_write(rt712->regmap,
+                       SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05,
+                       RT712_SDCA_CTL_FU_MUTE, CH_01), ch_01);
+       if (err < 0)
+               return err;
+
+       err = regmap_write(rt712->regmap,
+                       SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05,
+                       RT712_SDCA_CTL_FU_MUTE, CH_02), ch_02);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+
+static int rt712_sdca_fu05_playback_get(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);
+
+       ucontrol->value.integer.value[0] = !rt712->fu05_mixer_l_mute;
+       ucontrol->value.integer.value[1] = !rt712->fu05_mixer_r_mute;
+       return 0;
+}
+
+static int rt712_sdca_fu05_playback_put(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);
+       int err;
+
+       if (rt712->fu05_mixer_l_mute == !ucontrol->value.integer.value[0] &&
+               rt712->fu05_mixer_r_mute == !ucontrol->value.integer.value[1])
+               return 0;
+
+       rt712->fu05_mixer_l_mute = !ucontrol->value.integer.value[0];
+       rt712->fu05_mixer_r_mute = !ucontrol->value.integer.value[1];
+
+       err = rt712_sdca_set_fu05_playback_ctl(rt712);
+       if (err < 0)
+               return err;
+
+       return 1;
+}
+
 static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0);
 static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -1725, 75, 0);
 static const DECLARE_TLV_DB_SCALE(boost_vol_tlv, 0, 1000, 0);
@@ -674,6 +729,8 @@ static const struct snd_kcontrol_new rt712_sdca_controls[] = {
                SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PLATFORM_FU44, RT712_SDCA_CTL_FU_CH_GAIN, CH_02),
                8, 3, 0,
                rt712_sdca_set_gain_get, rt712_sdca_set_gain_put, boost_vol_tlv),
+       SOC_DOUBLE_EXT("FU05 Playback Switch", SND_SOC_NOPM, 0, 1, 1, 0,
+               rt712_sdca_fu05_playback_get, rt712_sdca_fu05_playback_put),
 };
 
 static const struct snd_kcontrol_new rt712_sdca_spk_controls[] = {
@@ -766,28 +823,15 @@ static int rt712_sdca_fu05_event(struct snd_soc_dapm_widget *w,
        struct snd_soc_component *component =
                snd_soc_dapm_to_component(w->dapm);
        struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component);
-       unsigned char unmute = 0x0, mute = 0x1;
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               regmap_write(rt712->regmap,
-                       SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05,
-                               RT712_SDCA_CTL_FU_MUTE, CH_01),
-                               unmute);
-               regmap_write(rt712->regmap,
-                       SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05,
-                               RT712_SDCA_CTL_FU_MUTE, CH_02),
-                               unmute);
+               rt712->fu05_dapm_mute = false;
+               rt712_sdca_set_fu05_playback_ctl(rt712);
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               regmap_write(rt712->regmap,
-                       SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05,
-                               RT712_SDCA_CTL_FU_MUTE, CH_01),
-                               mute);
-               regmap_write(rt712->regmap,
-                       SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05,
-                               RT712_SDCA_CTL_FU_MUTE, CH_02),
-                               mute);
+               rt712->fu05_dapm_mute = true;
+               rt712_sdca_set_fu05_playback_ctl(rt712);
                break;
        }
        return 0;
@@ -1640,6 +1684,8 @@ int rt712_sdca_init(struct device *dev, struct regmap *regmap,
        rt712->fu1e_dapm_mute = true;
        rt712->fu1e_mixer_mute[0] = rt712->fu1e_mixer_mute[1] =
                rt712->fu1e_mixer_mute[2] = rt712->fu1e_mixer_mute[3] = true;
+       rt712->fu05_dapm_mute = true;
+       rt712->fu05_mixer_l_mute = rt712->fu05_mixer_r_mute = false;
 
        /* JD source uses JD1 in default */
        rt712->jd_src = RT712_JD1;
index a08491496d9013dae0978b4b7f3e0c4fc661cba2..7ab7d5feb50a29802d6baafe73a4b75ab2c19051 100644 (file)
@@ -42,6 +42,9 @@ struct  rt712_sdca_priv {
        bool fu0f_mixer_r_mute;
        bool fu1e_dapm_mute;
        bool fu1e_mixer_mute[4];
+       bool fu05_dapm_mute;
+       bool fu05_mixer_l_mute;
+       bool fu05_mixer_r_mute;
 };
 
 struct rt712_dmic_kctrl_priv {