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

Commit c8231cf9 authored by Sudheer Papothi's avatar Sudheer Papothi
Browse files

ASoC: wcd938x: Add micbias control API for SWR DMICs



Add micbias control API to enable SWR DMICs on lahaina target.

Change-Id: I48152971e1af8dedc98ada20e4e808cf18720869
Signed-off-by: default avatarSudheer Papothi <spapothi@codeaurora.org>
parent e84db582
Loading
Loading
Loading
Loading
+126 −0
Original line number Diff line number Diff line
@@ -2095,6 +2095,132 @@ static int wcd938x_codec_force_enable_micbias(struct snd_soc_dapm_widget *w,
	return ret;
}

static int wcd938x_enable_micbias(struct wcd938x_priv *wcd938x,
					int micb_num, int req)
{
	int micb_index = micb_num - 1;
	u16 micb_reg;

	if (NULL == wcd938x) {
		pr_err("%s: wcd938x private data is NULL\n", __func__);
		return -EINVAL;
	}

	switch (micb_num) {
	case MIC_BIAS_1:
		micb_reg = WCD938X_ANA_MICB1;
		break;
	case MIC_BIAS_2:
		micb_reg = WCD938X_ANA_MICB2;
		break;
	case MIC_BIAS_3:
		micb_reg = WCD938X_ANA_MICB3;
		break;
	case MIC_BIAS_4:
		micb_reg = WCD938X_ANA_MICB4;
		break;
	default:
		pr_err("%s: Invalid micbias number: %d\n", __func__, micb_num);
		return -EINVAL;
	};

	mutex_lock(&wcd938x->micb_lock);

	switch (req) {
	case MICB_ENABLE:
		wcd938x->micb_ref[micb_index]++;
		if (wcd938x->micb_ref[micb_index] == 1) {
			regmap_update_bits(wcd938x->regmap,
				WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0);
			regmap_update_bits(wcd938x->regmap,
				WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10);
			regmap_update_bits(wcd938x->regmap,
			       WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL, 0x01, 0x01);
			regmap_update_bits(wcd938x->regmap,
				WCD938X_MICB1_TEST_CTL_2, 0x01, 0x01);
			regmap_update_bits(wcd938x->regmap,
				WCD938X_MICB2_TEST_CTL_2, 0x01, 0x01);
			regmap_update_bits(wcd938x->regmap,
				WCD938X_MICB3_TEST_CTL_2, 0x01, 0x01);
			regmap_update_bits(wcd938x->regmap,
				WCD938X_MICB4_TEST_CTL_2, 0x01, 0x01);
			regmap_update_bits(wcd938x->regmap,
				micb_reg, 0xC0, 0x40);
			regmap_update_bits(wcd938x->regmap, micb_reg, 0x3F, 0x10);
		}
		break;
	case MICB_PULLUP_ENABLE:
		wcd938x->pullup_ref[micb_index]++;
		if ((wcd938x->pullup_ref[micb_index] == 1) &&
		    (wcd938x->micb_ref[micb_index] == 0))
			regmap_update_bits(wcd938x->regmap, micb_reg,
							0xC0, 0x80);
		break;
	case MICB_PULLUP_DISABLE:
		if (wcd938x->pullup_ref[micb_index] > 0)
			wcd938x->pullup_ref[micb_index]--;

		if ((wcd938x->pullup_ref[micb_index] == 0) &&
		    (wcd938x->micb_ref[micb_index] == 0))
			regmap_update_bits(wcd938x->regmap, micb_reg,
							0xC0, 0x00);
		break;
	case MICB_DISABLE:
		if (wcd938x->micb_ref[micb_index] > 0)
			wcd938x->micb_ref[micb_index]--;

		if ((wcd938x->micb_ref[micb_index] == 0) &&
		    (wcd938x->pullup_ref[micb_index] > 0))
			regmap_update_bits(wcd938x->regmap, micb_reg,
							0xC0, 0x80);
		else if ((wcd938x->micb_ref[micb_index] == 0) &&
			 (wcd938x->pullup_ref[micb_index] == 0))
			regmap_update_bits(wcd938x->regmap, micb_reg,
							0xC0, 0x00);
		break;
	};

	mutex_unlock(&wcd938x->micb_lock);
	return 0;
}

int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *component,
					int event, int micb_num)
{
	struct wcd938x_priv *wcd938x_priv = NULL;

	if(NULL == component) {
		pr_err("%s: wcd938x component is NULL\n", __func__);
		return -EINVAL;
	}
	if(event != SND_SOC_DAPM_PRE_PMU && event != SND_SOC_DAPM_POST_PMD) {
		pr_err("%s: invalid event: %d\n", __func__, event);
		return -EINVAL;
	}
	if(micb_num < MIC_BIAS_1 || micb_num > MIC_BIAS_4) {
		pr_err("%s: invalid mic bias num: %d\n", __func__, micb_num);
		return -EINVAL;
	}

	wcd938x_priv = snd_soc_component_get_drvdata(component);

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		wcd938x_wakeup(wcd938x_priv, true);
		wcd938x_enable_micbias(wcd938x_priv, micb_num, MICB_PULLUP_ENABLE);
		wcd938x_wakeup(wcd938x_priv, false);
		break;
	case SND_SOC_DAPM_POST_PMD:
		wcd938x_wakeup(wcd938x_priv, true);
		wcd938x_enable_micbias(wcd938x_priv, micb_num, MICB_PULLUP_DISABLE);
		wcd938x_wakeup(wcd938x_priv, false);
		break;
	}

	return 0;
}
EXPORT_SYMBOL(wcd938x_codec_force_enable_micbias_v2);

static inline int wcd938x_tx_path_get(const char *wname,
				      unsigned int *path_num)
{
+9 −0
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root,
				    struct snd_soc_component *component);

int wcd938x_get_codec_variant(struct snd_soc_component *component);
int wcd938x_codec_force_enable_micbias_v2(struct snd_soc_component *wcd938x,
					int event, int micb_num);

static inline int wcd938x_slave_get_master_ch_val(int ch)
{
@@ -96,6 +98,13 @@ static inline int wcd938x_get_codec_variant(struct snd_soc_component *component)
{
	return 0;
}
static inline int wcd938x_codec_force_enable_micbias_v2(
					struct snd_soc_component *wcd938x,
					int event, int micb_num)
{
	return 0;
}

static inline int wcd938x_slave_get_master_ch_val(int ch)
{
	return 0;