Unverified Commit 62142da2 authored by Shuming Fan's avatar Shuming Fan Committed by Mark Brown
Browse files

ASoC: rt712-sdca: Add FU05 playback switch control



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: default avatarderek.fang <derek.fang@realtek.com>
Signed-off-by: default avatarShuming Fan <shumingf@realtek.com>
Link: https://patch.msgid.link/20250226084728.1889082-1-shumingf@realtek.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent dc64e1b9
Loading
Loading
Loading
Loading
+63 −17
Original line number Diff line number Diff line
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -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 {