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

Commit 6e4097cd authored by Aditya Bavanari's avatar Aditya Bavanari
Browse files

ASoC: wcd934x: Add support to restore IIR coefficients after power collapse



Reduce the latency of device switch during voice call by caching
IIR Band registers at bootup and restore them in
tavil_dig_core_remove_power_collapse instead of updating
through mixer controls from userspace.

Change-Id: I87b41801d5f174f5fb11917a359635e91c04d05d
Signed-off-by: default avatarAditya Bavanari <abavanar@codeaurora.org>
parent 60be7160
Loading
Loading
Loading
Loading
+36 −10
Original line number Original line Diff line number Diff line
@@ -123,6 +123,7 @@ static const struct snd_kcontrol_new name##_mux = \
#define WCD934X_DEC_PWR_LVL_DF 0x00
#define WCD934X_DEC_PWR_LVL_DF 0x00
#define WCD934X_STRING_LEN 100
#define WCD934X_STRING_LEN 100


#define WCD934X_CDC_SIDETONE_IIR_COEFF_MAX 5
#define WCD934X_DIG_CORE_REG_MIN  WCD934X_CDC_ANC0_CLK_RESET_CTL
#define WCD934X_DIG_CORE_REG_MIN  WCD934X_CDC_ANC0_CLK_RESET_CTL
#define WCD934X_DIG_CORE_REG_MAX  0xFFF
#define WCD934X_DIG_CORE_REG_MAX  0xFFF


@@ -654,6 +655,8 @@ struct tavil_priv {
	struct tavil_idle_detect_config idle_det_cfg;
	struct tavil_idle_detect_config idle_det_cfg;


	int power_active_ref;
	int power_active_ref;
	int sidetone_coeff_array[IIR_MAX][BAND_MAX]
		[WCD934X_CDC_SIDETONE_IIR_COEFF_MAX];
};
};


static const struct tavil_reg_mask_val tavil_spkr_default[] = {
static const struct tavil_reg_mask_val tavil_spkr_default[] = {
@@ -5162,10 +5165,12 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
					struct snd_ctl_elem_value *ucontrol)
{
{
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
	int iir_idx = ((struct soc_multi_mixer_control *)
	int iir_idx = ((struct soc_multi_mixer_control *)
					kcontrol->private_value)->reg;
					kcontrol->private_value)->reg;
	int band_idx = ((struct soc_multi_mixer_control *)
	int band_idx = ((struct soc_multi_mixer_control *)
					kcontrol->private_value)->shift;
					kcontrol->private_value)->shift;
	int coeff_idx;


	/*
	/*
	 * Mask top bit it is reserved
	 * Mask top bit it is reserved
@@ -5175,16 +5180,15 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
		(WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
		(WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
		(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
		(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);


	/* Store the coefficients in sidetone coeff array */
	for (coeff_idx = 0; coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX;
		coeff_idx++) {
		tavil->sidetone_coeff_array[iir_idx][band_idx][coeff_idx] =
			ucontrol->value.integer.value[coeff_idx];
		set_iir_band_coeff(codec, iir_idx, band_idx,
		set_iir_band_coeff(codec, iir_idx, band_idx,
				ucontrol->value.integer.value[0]);
			tavil->sidetone_coeff_array[iir_idx][band_idx]
	set_iir_band_coeff(codec, iir_idx, band_idx,
							[coeff_idx]);
				ucontrol->value.integer.value[1]);
	}
	set_iir_band_coeff(codec, iir_idx, band_idx,
				ucontrol->value.integer.value[2]);
	set_iir_band_coeff(codec, iir_idx, band_idx,
				ucontrol->value.integer.value[3]);
	set_iir_band_coeff(codec, iir_idx, band_idx,
				ucontrol->value.integer.value[4]);


	pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
	pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
		"%s: IIR #%d band #%d b1 = 0x%x\n"
		"%s: IIR #%d band #%d b1 = 0x%x\n"
@@ -5204,6 +5208,26 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
	return 0;
	return 0;
}
}


static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx)
{
	int band_idx = 0, coeff_idx = 0;
	struct snd_soc_codec *codec = tavil->codec;

	for (band_idx = 0; band_idx < BAND_MAX; band_idx++) {
		snd_soc_write(codec,
		(WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
		(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);

		for (coeff_idx = 0;
			coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX;
			coeff_idx++) {
			set_iir_band_coeff(codec, iir_idx, band_idx,
				tavil->sidetone_coeff_array[iir_idx][band_idx]
								[coeff_idx]);
		}
	}
}

static int tavil_compander_get(struct snd_kcontrol *kcontrol,
static int tavil_compander_get(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
			       struct snd_ctl_elem_value *ucontrol)
{
{
@@ -8156,6 +8180,8 @@ static int tavil_dig_core_remove_power_collapse(struct tavil_priv *tavil)
			     WCD934X_DIG_CORE_REG_MIN,
			     WCD934X_DIG_CORE_REG_MIN,
			     WCD934X_DIG_CORE_REG_MAX);
			     WCD934X_DIG_CORE_REG_MAX);


	tavil_restore_iir_coeff(tavil, IIR0);
	tavil_restore_iir_coeff(tavil, IIR1);
	return 0;
	return 0;
}
}