Loading asoc/codecs/wcd938x/wcd938x.c +126 −0 Original line number Diff line number Diff line Loading @@ -2117,6 +2117,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) { Loading asoc/codecs/wcd938x/wcd938x.h +9 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; Loading Loading
asoc/codecs/wcd938x/wcd938x.c +126 −0 Original line number Diff line number Diff line Loading @@ -2117,6 +2117,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) { Loading
asoc/codecs/wcd938x/wcd938x.h +9 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; Loading