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

Commit 47ff43e0 authored by Jay Wang's avatar Jay Wang
Browse files

ASoC: wcd9330: Add ANC loopback path and cache HPF bypass control



Add route to connect ANC FB tune signal back to decimator
DEC7 to DEC10. These paths are used to evalute the device acoustics
and provide a way to tune ANC algorithm. In addition, a logic is
implemented to cache the TX HPF bypass control to allow user
bypass the TX HPF during ANC tuning.

Change-Id: I9aacd9d8717bfadbf4de750d7dfccd1f38da4bc8
Signed-off-by: default avatarJay Wang <jaywang@codeaurora.org>
parent 05f59b8b
Loading
Loading
Loading
Loading
+115 −24
Original line number Diff line number Diff line
@@ -348,6 +348,7 @@ struct hpf_work {
	struct tomtom_priv *tomtom;
	u32 decimator;
	u8 tx_hpf_cut_of_freq;
	bool tx_hpf_bypass;
	struct delayed_work dwork;
};

@@ -1246,6 +1247,52 @@ static int tomtom_mad_input_put(struct snd_kcontrol *kcontrol,
	}
}

static int tomtom_tx_hpf_bypass_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	u32	tx_index;

	tx_index = (u32)kcontrol->private_value;

	if (tx_index > NUM_DECIMATORS) {
		pr_err("%s: Invalid TX decimator %d\n", __func__,
			   tx_index);
		return -EINVAL;
	}

	ucontrol->value.integer.value[0] =
		tx_hpf_work[tx_index-1].tx_hpf_bypass;

	return 0;
}

static int tomtom_tx_hpf_bypass_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	bool tx_hpf_bypass_cfg;
	u32	tx_index;

	tx_hpf_bypass_cfg = (bool)ucontrol->value.integer.value[0];

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

	tx_index = (u32)kcontrol->private_value;

	if (tx_index > NUM_DECIMATORS) {
		pr_err("%s: Invalid TX decimator %d\n", __func__,
			   tx_index);
		return -EINVAL;
	}
	if (tx_hpf_work[tx_index-1].tx_hpf_bypass != tx_hpf_bypass_cfg)
		tx_hpf_work[tx_index-1].tx_hpf_bypass = tx_hpf_bypass_cfg;

	pr_debug("%s: Set TX%d HPF bypass configuration %d",
			 __func__, tx_index,
			 tx_hpf_work[tx_index-1].tx_hpf_bypass);

	return 0;
}

static const struct snd_kcontrol_new tomtom_snd_controls[] = {

@@ -1320,16 +1367,36 @@ static const struct snd_kcontrol_new tomtom_snd_controls[] = {
	SOC_ENUM("TX9 HPF cut off", cf_dec9_enum),
	SOC_ENUM("TX10 HPF cut off", cf_dec10_enum),

	SOC_SINGLE("TX1 HPF Switch", TOMTOM_A_CDC_TX1_MUX_CTL, 3, 1, 0),
	SOC_SINGLE("TX2 HPF Switch", TOMTOM_A_CDC_TX2_MUX_CTL, 3, 1, 0),
	SOC_SINGLE("TX3 HPF Switch", TOMTOM_A_CDC_TX3_MUX_CTL, 3, 1, 0),
	SOC_SINGLE("TX4 HPF Switch", TOMTOM_A_CDC_TX4_MUX_CTL, 3, 1, 0),
	SOC_SINGLE("TX5 HPF Switch", TOMTOM_A_CDC_TX5_MUX_CTL, 3, 1, 0),
	SOC_SINGLE("TX6 HPF Switch", TOMTOM_A_CDC_TX6_MUX_CTL, 3, 1, 0),
	SOC_SINGLE("TX7 HPF Switch", TOMTOM_A_CDC_TX7_MUX_CTL, 3, 1, 0),
	SOC_SINGLE("TX8 HPF Switch", TOMTOM_A_CDC_TX8_MUX_CTL, 3, 1, 0),
	SOC_SINGLE("TX9 HPF Switch", TOMTOM_A_CDC_TX9_MUX_CTL, 3, 1, 0),
	SOC_SINGLE("TX10 HPF Switch", TOMTOM_A_CDC_TX10_MUX_CTL, 3, 1, 0),
	SOC_SINGLE_BOOL_EXT("TX1 HPF Switch", 1,
				tomtom_tx_hpf_bypass_get,
				tomtom_tx_hpf_bypass_put),
	SOC_SINGLE_BOOL_EXT("TX2 HPF Switch", 2,
				tomtom_tx_hpf_bypass_get,
				tomtom_tx_hpf_bypass_put),
	SOC_SINGLE_BOOL_EXT("TX3 HPF Switch", 3,
				tomtom_tx_hpf_bypass_get,
				tomtom_tx_hpf_bypass_put),
	SOC_SINGLE_BOOL_EXT("TX4 HPF Switch", 4,
				tomtom_tx_hpf_bypass_get,
				tomtom_tx_hpf_bypass_put),
	SOC_SINGLE_BOOL_EXT("TX5 HPF Switch", 5,
				tomtom_tx_hpf_bypass_get,
				tomtom_tx_hpf_bypass_put),
	SOC_SINGLE_BOOL_EXT("TX6 HPF Switch", 6,
				tomtom_tx_hpf_bypass_get,
				tomtom_tx_hpf_bypass_put),
	SOC_SINGLE_BOOL_EXT("TX7 HPF Switch", 7,
				tomtom_tx_hpf_bypass_get,
				tomtom_tx_hpf_bypass_put),
	SOC_SINGLE_BOOL_EXT("TX8 HPF Switch", 8,
				tomtom_tx_hpf_bypass_get,
				tomtom_tx_hpf_bypass_put),
	SOC_SINGLE_BOOL_EXT("TX9 HPF Switch", 9,
				tomtom_tx_hpf_bypass_get,
				tomtom_tx_hpf_bypass_put),
	SOC_SINGLE_BOOL_EXT("TX10 HPF Switch", 10,
				tomtom_tx_hpf_bypass_get,
				tomtom_tx_hpf_bypass_put),

	SOC_SINGLE("RX1 HPF Switch", TOMTOM_A_CDC_RX1_B5_CTL, 2, 1, 0),
	SOC_SINGLE("RX2 HPF Switch", TOMTOM_A_CDC_RX2_B5_CTL, 2, 1, 0),
@@ -3064,7 +3131,11 @@ static int tomtom_codec_enable_dec(struct snd_soc_dapm_widget *w,
			1 << w->shift);
		snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);

		dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg);
		pr_debug("%s: decimator = %u, bypass = %d\n", __func__,
			decimator, tx_hpf_work[decimator - 1].tx_hpf_bypass);
		if (tx_hpf_work[decimator - 1].tx_hpf_bypass != true) {
			dec_hpf_cut_of_freq = snd_soc_read(codec,
							tx_mux_ctl_reg);

			dec_hpf_cut_of_freq = (dec_hpf_cut_of_freq & 0x30) >> 4;

@@ -3080,6 +3151,9 @@ static int tomtom_codec_enable_dec(struct snd_soc_dapm_widget *w,

			/* enable HPF */
			snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x00);
		} else
			/* bypass HPF */
			snd_soc_update_bits(codec, tx_mux_ctl_reg , 0x08, 0x08);

		break;

@@ -3088,8 +3162,9 @@ static int tomtom_codec_enable_dec(struct snd_soc_dapm_widget *w,
		/* Disable TX digital mute */
		snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);

		if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
				CF_MIN_3DB_150HZ) {
		if ((tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
				CF_MIN_3DB_150HZ) &&
			(tx_hpf_work[decimator - 1].tx_hpf_bypass != true)) {

			schedule_delayed_work(&tx_hpf_work[decimator - 1].dwork,
					msecs_to_jiffies(300));
@@ -3762,6 +3837,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
	{"ANC2 MUX", "ADC2", "ADC2"},
	{"ANC2 MUX", "ADC3", "ADC3"},
	{"ANC2 MUX", "ADC4", "ADC4"},
	{"ANC2 MUX", "DMIC1", "DMIC1"},
	{"ANC2 MUX", "DMIC2", "DMIC2"},
	{"ANC2 MUX", "DMIC3", "DMIC3"},
	{"ANC2 MUX", "DMIC4", "DMIC4"},
	{"ANC2 MUX", "DMIC5", "DMIC5"},
	{"ANC2 MUX", "DMIC6", "DMIC6"},

	{"ANC HPHR", NULL, "CDC_CONN"},

@@ -4088,21 +4169,29 @@ static const struct snd_soc_dapm_route audio_map[] = {
	{"DEC7 MUX", "DMIC6", "DMIC6"},
	{"DEC7 MUX", "ADC1", "ADC1"},
	{"DEC7 MUX", "ADC6", "ADC6"},
	{"DEC7 MUX", "ANC1_FB", "ANC1 MUX"},
	{"DEC7 MUX", "ANC2_FB", "ANC2 MUX"},
	{"DEC7 MUX", NULL, "CDC_CONN"},
	{"DEC8 MUX", "DMIC2", "DMIC2"},
	{"DEC8 MUX", "DMIC5", "DMIC5"},
	{"DEC8 MUX", "ADC2", "ADC2"},
	{"DEC8 MUX", "ADC5", "ADC5"},
	{"DEC8 MUX", "ANC1_FB", "ANC1 MUX"},
	{"DEC8 MUX", "ANC2_FB", "ANC2 MUX"},
	{"DEC8 MUX", NULL, "CDC_CONN"},
	{"DEC9 MUX", "DMIC4", "DMIC4"},
	{"DEC9 MUX", "DMIC5", "DMIC5"},
	{"DEC9 MUX", "ADC2", "ADC2"},
	{"DEC9 MUX", "ADC3", "ADC3"},
	{"DEC9 MUX", "ANC1_FB", "ANC1 MUX"},
	{"DEC9 MUX", "ANC2_FB", "ANC2 MUX"},
	{"DEC9 MUX", NULL, "CDC_CONN"},
	{"DEC10 MUX", "DMIC3", "DMIC3"},
	{"DEC10 MUX", "DMIC6", "DMIC6"},
	{"DEC10 MUX", "ADC1", "ADC1"},
	{"DEC10 MUX", "ADC4", "ADC4"},
	{"DEC10 MUX", "ANC1_FB", "ANC1 MUX"},
	{"DEC10 MUX", "ANC2_FB", "ANC2 MUX"},
	{"DEC10 MUX", NULL, "CDC_CONN"},

	/* ADC Connections */
@@ -6341,7 +6430,8 @@ static int tomtom_handle_pdata(struct tomtom_priv *tomtom)
		0x7E, dmic_b2_ctl_value);
	snd_soc_update_bits(codec, TOMTOM_A_CDC_ANC1_B2_CTL,
		0x1, anc_ctl_value);

	snd_soc_update_bits(codec, TOMTOM_A_CDC_ANC2_B2_CTL,
		0x1, anc_ctl_value);
done:
	return rc;
}
@@ -7139,6 +7229,7 @@ static int tomtom_codec_probe(struct snd_soc_codec *codec)
	for (i = 0; i < NUM_DECIMATORS; i++) {
		tx_hpf_work[i].tomtom = tomtom;
		tx_hpf_work[i].decimator = i + 1;
		tx_hpf_work[i].tx_hpf_bypass = false;
		INIT_DELAYED_WORK(&tx_hpf_work[i].dwork,
			tx_hpf_corner_freq_callback);
	}