Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32f93e49 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: sdm845: add independent clock support on codec"

parents 5c7942b8 eef10ca6
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
@@ -180,6 +180,8 @@ enum {
	ANC_MIC_AMIC2,
	ANC_MIC_AMIC3,
	ANC_MIC_AMIC4,
	CLK_INTERNAL,
	CLK_MODE,
};

enum {
@@ -1071,6 +1073,40 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w,
	return ret;
}

static int tavil_get_clkmode(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);

	if (test_bit(CLK_MODE, &tavil_p->status_mask))
		ucontrol->value.enumerated.item[0] = 1;
	else
		ucontrol->value.enumerated.item[0] = 0;

	dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__,
		test_bit(CLK_MODE, &tavil_p->status_mask) ? "true" : "false");

	return 0;
}

static int tavil_put_clkmode(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);

	if (ucontrol->value.enumerated.item[0])
		set_bit(CLK_MODE, &tavil_p->status_mask);
	else
		clear_bit(CLK_MODE, &tavil_p->status_mask);

	dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__,
		test_bit(CLK_MODE, &tavil_p->status_mask) ? "true" : "false");

	return 0;
}

static int tavil_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
@@ -5576,6 +5612,9 @@ static const char *const tavil_anc_func_text[] = {"OFF", "ON"};
static const struct soc_enum tavil_anc_func_enum =
	SOC_ENUM_SINGLE_EXT(2, tavil_anc_func_text);

static const char *const tavil_clkmode_text[] = {"EXTERNAL", "INTERNAL"};
static SOC_ENUM_SINGLE_EXT_DECL(tavil_clkmode_enum, tavil_clkmode_text);

/* Cutoff frequency for high pass filter */
static const char * const cf_text[] = {
	"CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
@@ -5755,6 +5794,9 @@ static const struct snd_kcontrol_new tavil_snd_controls[] = {
	SOC_ENUM_EXT("ANC Function", tavil_anc_func_enum, tavil_get_anc_func,
		tavil_put_anc_func),

	SOC_ENUM_EXT("CLK MODE", tavil_clkmode_enum, tavil_get_clkmode,
		     tavil_put_clkmode),

	SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
	SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
	SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
@@ -8417,6 +8459,50 @@ static int tavil_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
	return ret;
}

/*
 * tavil_cdc_mclk_tx_enable: Enable/Disable codec's clock for TX path
 * @codec: Handle to codec
 * @enable: Indicates whether clock should be enabled or disabled
 */
int tavil_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable)
{
	struct tavil_priv *tavil_p;
	int ret = 0;
	bool clk_mode;
	bool clk_internal;

	if (!codec)
		return -EINVAL;

	tavil_p = snd_soc_codec_get_drvdata(codec);
	clk_mode = test_bit(CLK_MODE, &tavil_p->status_mask);
	clk_internal = test_bit(CLK_INTERNAL, &tavil_p->status_mask);

	dev_dbg(codec->dev, "%s: clkmode: %d, enable: %d, clk_internal: %d\n",
		__func__, clk_mode, enable, clk_internal);

	if (clk_mode || clk_internal) {
		if (enable) {
			wcd_resmgr_enable_master_bias(tavil_p->resmgr);
			tavil_dig_core_power_collapse(tavil_p, POWER_RESUME);
			tavil_vote_svs(tavil_p, true);
			ret = tavil_codec_internal_rco_ctrl(codec, enable);
			set_bit(CLK_INTERNAL, &tavil_p->status_mask);
		} else {
			clear_bit(CLK_INTERNAL, &tavil_p->status_mask);
			tavil_codec_internal_rco_ctrl(codec, enable);
			tavil_vote_svs(tavil_p, false);
			tavil_dig_core_power_collapse(tavil_p, POWER_COLLAPSE);
			wcd_resmgr_disable_master_bias(tavil_p->resmgr);
		}
	} else {
		ret = __tavil_cdc_mclk_enable(tavil_p, enable);
	}

	return ret;
}
EXPORT_SYMBOL(tavil_cdc_mclk_tx_enable);

static const struct wcd_resmgr_cb tavil_resmgr_cb = {
	.cdc_rco_ctrl = __tavil_codec_internal_rco_ctrl,
};
+1 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ struct tavil_reg_mask_val {
extern void *tavil_get_afe_config(struct snd_soc_codec *codec,
				  enum afe_config_type config_type);
extern int tavil_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable);
extern int tavil_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable);
extern int tavil_set_spkr_mode(struct snd_soc_codec *codec, int mode);
extern int tavil_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset);
extern struct wcd_dsp_cntl *tavil_get_wcd_dsp_cntl(struct device *dev);
+37 −5
Original line number Diff line number Diff line
@@ -538,10 +538,10 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = {
};

static struct snd_soc_dapm_route wcd_audio_paths[] = {
	{"MIC BIAS1", NULL, "MCLK"},
	{"MIC BIAS2", NULL, "MCLK"},
	{"MIC BIAS3", NULL, "MCLK"},
	{"MIC BIAS4", NULL, "MCLK"},
	{"MIC BIAS1", NULL, "MCLK TX"},
	{"MIC BIAS2", NULL, "MCLK TX"},
	{"MIC BIAS3", NULL, "MCLK TX"},
	{"MIC BIAS4", NULL, "MCLK TX"},
};

static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
@@ -2784,6 +2784,38 @@ static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec,
	return ret;
}

static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec,
					   int enable, bool dapm)
{
	int ret = 0;

	if (!strcmp(dev_name(codec->dev), "tavil_codec")) {
		ret = tavil_cdc_mclk_tx_enable(codec, enable);
	} else {
		dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n",
			__func__);
		ret = -EINVAL;
	}

	return ret;
}

static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w,
			     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);

	pr_debug("%s: event = %d\n", __func__, event);

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		return msm_snd_enable_codec_ext_tx_clk(codec, 1, true);
	case SND_SOC_DAPM_POST_PMD:
		return msm_snd_enable_codec_ext_tx_clk(codec, 0, true);
	}
	return 0;
}

static int msm_mclk_event(struct snd_soc_dapm_widget *w,
				 struct snd_kcontrol *kcontrol, int event)
{
@@ -2840,7 +2872,7 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_SUPPLY("MCLK TX",  SND_SOC_NOPM, 0, 0,
	NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
	msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_SPK("Lineout_1 amp", NULL),
	SND_SOC_DAPM_SPK("Lineout_2 amp", NULL),