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

Commit 8ffae7c0 authored by Sudheer Papothi's avatar Sudheer Papothi
Browse files

ASoC: wcd9335: Update flyback configuration on v2 hardware



Update flyback current and headset enable mode settings
on wcd9335 v2 codec to optimize click and pop.

Change-Id: Ic45a6d6b3ee9f0980874d13ec196133ba5078d78
Signed-off-by: default avatarSudheer Papothi <spapothi@codeaurora.org>
parent b245a027
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -330,4 +330,9 @@
#define WCD9XXX_A_ANA_HPH				(0x609)
#define WCD9XXX_A_CDC_CLSH_CRC				(0xC01)
#define WCD9XXX_FLYBACK_EN				(0x6A4)
#define WCD9XXX_RX_BIAS_FLYB_BUFF			(0x6C7)
#define WCD9XXX_HPH_L_EN				(0x6D3)
#define WCD9XXX_HPH_R_EN				(0x6D6)
#define WCD9XXX_HPH_REFBUFF_UHQA_CTL			(0x6DD)
#define WCD9XXX_CLASSH_CTRL_VCL_2                       (0x69B)
#endif
+32 −19
Original line number Diff line number Diff line
@@ -2584,6 +2584,14 @@ static int tasha_set_compander(struct snd_kcontrol *kcontrol,
	return 0;
}

static void tasha_codec_init_flyback(struct snd_soc_codec *codec)
{
	snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x00);
	snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x00);
	snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0x0F, 0x00);
	snd_soc_update_bits(codec, WCD9335_RX_BIAS_FLYB_BUFF, 0xF0, 0x00);
}

static int tasha_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
		struct snd_kcontrol *kcontrol, int event)
{
@@ -2595,9 +2603,12 @@ static int tasha_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		tasha->rx_bias_count++;
		if (tasha->rx_bias_count == 1)
		if (tasha->rx_bias_count == 1) {
			if (TASHA_IS_2_0(tasha->wcd9xxx->version))
				tasha_codec_init_flyback(codec);
			snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES,
					    0x01, 0x01);
		}
		break;
	case SND_SOC_DAPM_POST_PMD:
		tasha->rx_bias_count--;
@@ -9218,9 +9229,11 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_val_1_0[] = {

static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = {
	{WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
	{WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
	{WCD9335_HPH_OCP_CTL, 0xFF, 0x5A},
	{WCD9335_HPH_L_TEST, 0x01, 0x01},
	{WCD9335_HPH_R_TEST, 0x01, 0x01},
	{WCD9335_FLYBACK_VNEG_DAC_CTRL_2, 0xE0, 0x20},
};

static const struct tasha_reg_mask_val tasha_codec_reg_defaults[] = {
@@ -9253,6 +9266,24 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_common_val[] = {
	{WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80},
	{WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01},
	{WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01},
	{WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01},
};

static const struct tasha_reg_mask_val tasha_codec_reg_init_1_x_val[] = {
@@ -9307,15 +9338,6 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_1_x_val[] = {
	{WCD9335_CLASSH_CTRL_CCL_5, 0xFF, 0x40},
	{WCD9335_RX_TIMER_DIV, 0xFF, 0x32},
	{WCD9335_SE_LO_COM2, 0xFF, 0x01},
	{WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01},
	{WCD9335_MBHC_ZDET_ANA_CTL, 0x0F, 0x07},
	{WCD9335_RX_BIAS_HPH_PA, 0xF0, 0x60},
	{WCD9335_HPH_RDAC_LDO_CTL, 0x88, 0x88},
@@ -9324,15 +9346,6 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_1_x_val[] = {
	{WCD9335_DIFF_LO_CORE_OUT_PROG, 0xFC, 0xD8},
	{WCD9335_CDC_RX5_RX_PATH_SEC3, 0xBD, 0xBD},
	{WCD9335_CDC_RX6_RX_PATH_SEC3, 0xBD, 0xBD},
	{WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01},
	{WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01},
};

static void tasha_update_reg_reset_values(struct snd_soc_codec *codec)
+70 −0
Original line number Diff line number Diff line
@@ -22,6 +22,17 @@

#define WCD_USLEEP_RANGE 50

enum {
	DAC_GAIN_0DB = 0,
	DAC_GAIN_0P2DB,
	DAC_GAIN_0P4DB,
	DAC_GAIN_0P6DB,
	DAC_GAIN_0P8DB,
	DAC_GAIN_M0P2DB,
	DAC_GAIN_M0P4DB,
	DAC_GAIN_M0P6DB,
};

static void (*clsh_state_fp[NUM_CLSH_STATES_V2])(struct snd_soc_codec *,
					      struct wcd_clsh_cdc_data *,
					      u8 req_state, bool en, int mode);
@@ -215,25 +226,74 @@ static void wcd_clsh_flyback_ctrl(struct snd_soc_codec *codec,
	usleep_range(500, 500 + WCD_USLEEP_RANGE);
}

static void wcd_clsh_set_gain_path(struct snd_soc_codec *codec,
				   int mode)
{
	u8 val;
	struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);

	if (!TASHA_IS_2_0(wcd9xxx->version))
		return;

	switch (mode) {
	case CLS_H_NORMAL:
	case CLS_AB:
		val = 0x00;
		break;
	case CLS_H_HIFI:
		val = 0x02;
		break;
	case CLS_H_LP:
		val = 0x01;
		break;
	};
	snd_soc_update_bits(codec, WCD9XXX_HPH_L_EN, 0xC0, (val << 6));
	snd_soc_update_bits(codec, WCD9XXX_HPH_R_EN, 0xC0, (val << 6));
}

static void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec,
				  int mode)
{
	u8 val;
	u8 gain;
	struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);

	switch (mode) {
	case CLS_H_NORMAL:
	case CLS_AB:
		val = 0x00;
		gain = DAC_GAIN_0DB;
		break;
	case CLS_H_HIFI:
		val = 0x08;
		gain = DAC_GAIN_M0P2DB;
		break;
	case CLS_H_LP:
		val = 0x04;
		gain = DAC_GAIN_0P2DB;
		break;
	};

	snd_soc_update_bits(codec, WCD9XXX_A_ANA_HPH, 0x0C, val);
	if (TASHA_IS_2_0(wcd9xxx->version)) {
		snd_soc_update_bits(codec, WCD9XXX_CLASSH_CTRL_VCL_2,
				    0x30, 0x00);
		snd_soc_update_bits(codec, WCD9XXX_HPH_REFBUFF_UHQA_CTL,
				    0x07, gain);
	}
}

static void wcd_clsh_set_flyback_current(struct snd_soc_codec *codec, int mode)
{
	struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);

	if (!TASHA_IS_2_0(wcd9xxx->version))
		return;

	snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0x0F, 0x0A);
	snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0xF0, 0xA0);
	/* Sleep needed to avoid click and pop as per HW requirement */
	usleep_range(100, 110);
}

static void wcd_clsh_set_buck_regulator_mode(struct snd_soc_codec *codec,
@@ -265,6 +325,7 @@ static void wcd_clsh_state_lo(struct snd_soc_codec *codec,
		wcd_clsh_set_buck_mode(codec, mode);
		wcd_clsh_set_flyback_mode(codec, mode);
		wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
		wcd_clsh_set_flyback_current(codec, mode);
		wcd_clsh_buck_ctrl(codec, clsh_d, mode, true);
	} else {
		wcd_clsh_buck_ctrl(codec, clsh_d, mode, false);
@@ -312,6 +373,7 @@ static void wcd_clsh_state_hph_ear(struct snd_soc_codec *codec,
					    0x40, 0x40);
		if ((req_state == WCD_CLSH_STATE_HPHL) ||
		    (req_state == WCD_CLSH_STATE_HPHR)) {
			wcd_clsh_set_gain_path(codec, mode);
			wcd_clsh_set_flyback_mode(codec, mode);
			wcd_clsh_set_buck_mode(codec, mode);
		}
@@ -412,6 +474,9 @@ static void wcd_clsh_state_hph_lo(struct snd_soc_codec *codec,
		else {
			wcd_clsh_set_flyback_mode(codec, mode);
			wcd_clsh_set_buck_mode(codec, mode);
			if ((req_state == WCD_CLSH_STATE_HPHL) ||
			    (req_state == WCD_CLSH_STATE_HPHR))
				wcd_clsh_set_gain_path(codec, mode);
		}
	} else {
		if ((req_state == WCD_CLSH_STATE_HPHL) ||
@@ -537,7 +602,9 @@ static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec,
		wcd_clsh_set_buck_mode(codec, mode);
		wcd_clsh_set_flyback_mode(codec, mode);
		wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
		wcd_clsh_set_flyback_current(codec, mode);
		wcd_clsh_buck_ctrl(codec, clsh_d, mode, true);
		wcd_clsh_set_gain_path(codec, mode);
		wcd_clsh_set_hph_mode(codec, mode);
	} else {
		wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL);
@@ -589,7 +656,9 @@ static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec,
		wcd_clsh_set_buck_mode(codec, mode);
		wcd_clsh_set_flyback_mode(codec, mode);
		wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
		wcd_clsh_set_flyback_current(codec, mode);
		wcd_clsh_buck_ctrl(codec, clsh_d, mode, true);
		wcd_clsh_set_gain_path(codec, mode);
		wcd_clsh_set_hph_mode(codec, mode);
	} else {
		wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL);
@@ -630,6 +699,7 @@ static void wcd_clsh_state_ear(struct snd_soc_codec *codec,
		wcd_clsh_set_buck_mode(codec, mode);
		wcd_clsh_set_flyback_mode(codec, mode);
		wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
		wcd_clsh_set_flyback_current(codec, mode);
		wcd_clsh_buck_ctrl(codec, clsh_d, mode, true);
	} else {
		snd_soc_update_bits(codec,