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

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

Merge "ASoC: wcd: enable speaker boost feature"

parents 4a6cf4c5 88c6550b
Loading
Loading
Loading
Loading
+105 −9
Original line number Diff line number Diff line
@@ -135,6 +135,7 @@ struct msm8x16_wcd_priv {
	bool mclk_enabled;
	bool clock_active;
	bool config_mode_active;
	bool spk_boost_set;
	struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX];
	/* mbhc module */
	struct wcd_mbhc mbhc;
@@ -703,6 +704,30 @@ static int msm8x16_wcd_pa_gain_put(struct snd_kcontrol *kcontrol,
	return 0;
}

static int msm8x16_wcd_spk_boost_set(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
		__func__, ucontrol->value.integer.value[0]);

	switch (ucontrol->value.integer.value[0]) {
	case 0:
		msm8x16_wcd->spk_boost_set = false;
		break;
	case 1:
		msm8x16_wcd->spk_boost_set = true;
		break;
	default:
		return -EINVAL;
	}
	dev_dbg(codec->dev, "%s: msm8x16_wcd->spk_boost_set = %d\n",
		__func__, msm8x16_wcd->spk_boost_set);
	return 0;
}

static int msm8x16_wcd_get_iir_enable_audio_mixer(
					struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
@@ -906,6 +931,12 @@ static const struct soc_enum msm8x16_wcd_ear_pa_gain_enum[] = {
		SOC_ENUM_SINGLE_EXT(2, msm8x16_wcd_ear_pa_gain_text),
};

static const char * const msm8x16_wcd_spk_boost_ctrl_text[] = {
		"DISABLE", "ENABLE"};
static const struct soc_enum msm8x16_wcd_spk_boost_ctl_enum[] = {
		SOC_ENUM_SINGLE_EXT(2, msm8x16_wcd_spk_boost_ctrl_text),
};

/*cut of frequency for high pass filter*/
static const char * const cf_text[] = {
	"MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz"
@@ -931,6 +962,9 @@ static const struct snd_kcontrol_new msm8x16_wcd_snd_controls[] = {
	SOC_ENUM_EXT("EAR PA Gain", msm8x16_wcd_ear_pa_gain_enum[0],
		msm8x16_wcd_pa_gain_get, msm8x16_wcd_pa_gain_put),

	SOC_ENUM_EXT("Speaker Boost", msm8x16_wcd_spk_boost_ctl_enum[0],
		NULL, msm8x16_wcd_spk_boost_set),

	SOC_SINGLE_SX_TLV("RX1 Digital Volume",
			  MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL,
			0,  -84, 40, digital_gain),
@@ -1385,6 +1419,7 @@ static int msm8x16_wcd_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
				     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;
	struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);

	dev_dbg(w->codec->dev, "%s %d %s\n", __func__, event, w->name);
	switch (event) {
@@ -1393,6 +1428,7 @@ static int msm8x16_wcd_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
			MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10);
		snd_soc_update_bits(codec,
			MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x01);
		if (!msm8x16_wcd->spk_boost_set)
			snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x10, 0x10);
		usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS);
@@ -1401,6 +1437,10 @@ static int msm8x16_wcd_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
		break;
	case SND_SOC_DAPM_POST_PMU:
		usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS);
		if (msm8x16_wcd->spk_boost_set)
			snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL, 0xEF, 0xEF);
		else
			snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x10, 0x00);
		snd_soc_update_bits(codec,
@@ -1416,6 +1456,12 @@ static int msm8x16_wcd_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
		snd_soc_update_bits(codec,
			MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0x01, 0x01);
		snd_soc_update_bits(codec, w->reg, 0x80, 0x00);
		if (msm8x16_wcd->spk_boost_set)
			snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL, 0xEF, 0x00);
		else
			snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x10, 0x00);
		break;
	case SND_SOC_DAPM_POST_PMD:
		snd_soc_update_bits(codec,
@@ -1434,16 +1480,57 @@ static int msm8x16_wcd_codec_enable_dig_clk(struct snd_soc_dapm_widget *w,
				     struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;
	struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);

	dev_err(w->codec->dev, "%s %d %s\n", __func__, event, w->name);
	dev_dbg(w->codec->dev, "%s event %d w->name %s\n", __func__,
			event, w->name);
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		if (msm8x16_wcd->spk_boost_set) {
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL,
					0x20, 0x20);
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_ANALOG_SEC_ACCESS,
					0xA5, 0xA5);
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL3,
					0x07, 0x07);
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL,
					0xDF, 0xDF);
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT,
					0x03, 0x03);
		} else {
			if (w->shift == 2)
				snd_soc_update_bits(codec, w->reg, 0x80, 0x80);
		snd_soc_update_bits(codec, w->reg, 1<<w->shift, 1<<w->shift);
			snd_soc_update_bits(codec, w->reg, 1<<w->shift,
					1<<w->shift);
		}
		break;
	case SND_SOC_DAPM_POST_PMD:
		if (msm8x16_wcd->spk_boost_set) {
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL,
					0x20, 0x00);
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL,
					0xDF, 0x00);
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT,
					0x03, 0x00);
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_ANALOG_SEC_ACCESS,
					0xA5, 0x0);
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL3,
					0x07, 0x0);
		} else {
			if (w->shift == 2)
				snd_soc_update_bits(codec, w->reg, 0x80, 0x00);
			snd_soc_update_bits(codec, w->reg, 1<<w->shift, 0x00);
		}
		break;
	}
	return 0;
@@ -1716,6 +1803,7 @@ static int msm8x16_wcd_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
						 int event)
{
	struct snd_soc_codec *codec = w->codec;
	struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);

@@ -1733,6 +1821,10 @@ static int msm8x16_wcd_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
				  snd_soc_read(codec,
				  rx_digital_gain_reg[w->shift])
				  );
		if (msm8x16_wcd->spk_boost_set)
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL,
					0x80, 0x80);
		break;
	case SND_SOC_DAPM_POST_PMD:
		snd_soc_update_bits(codec,
@@ -1741,6 +1833,10 @@ static int msm8x16_wcd_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
		snd_soc_update_bits(codec,
			MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL,
			1 << w->shift, 0x0);
		if (msm8x16_wcd->spk_boost_set)
			snd_soc_update_bits(codec,
					MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL,
					0x80, 0x00);
	}
	return 0;
}