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: Sudheer Papothi <spapothi@codeaurora.org>
This commit is contained in:
Sudheer Papothi 2020-02-18 10:56:54 +05:30
commit c8231cf9e5
2 changed files with 135 additions and 0 deletions

View file

@ -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)
{

View file

@ -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;