diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c index 34868fa1d6..e268a734c1 100644 --- a/asoc/codecs/wcd934x/wcd934x.c +++ b/asoc/codecs/wcd934x/wcd934x.c @@ -68,6 +68,9 @@ #define WCD934X_FORMATS_S16_LE (SNDRV_PCM_FMTBIT_S16_LE) +#define MICB_LOAD_PROP "qcom,vreg-micb" +#define MICB_LOAD_DEFAULT 30400 + /* Macros for packing register writes into a U32 */ #define WCD934X_PACKED_REG_SIZE sizeof(u32) #define WCD934X_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ @@ -637,6 +640,9 @@ struct tavil_priv { struct platform_device *pdev_child_devices [WCD934X_CHILD_DEVICES_MAX]; int child_count; + struct regulator *micb_load; + int micb_load_low; + int micb_load_high; }; static const struct tavil_reg_mask_val tavil_spkr_default[] = { @@ -4888,6 +4894,9 @@ int tavil_micbias_control(struct snd_soc_codec *codec, case MICB_ENABLE: tavil->micb_ref[micb_index]++; if (tavil->micb_ref[micb_index] == 1) { + if (tavil->micb_load) + regulator_set_load(tavil->micb_load, + tavil->micb_load_high); snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40); if (post_on_event && tavil->mbhc) blocking_notifier_call_chain( @@ -4918,6 +4927,9 @@ int tavil_micbias_control(struct snd_soc_codec *codec, &tavil->mbhc->notifier, post_off_event, &tavil->mbhc->wcd_mbhc); + if (tavil->micb_load) + regulator_set_load(tavil->micb_load, + tavil->micb_load_low); } if (is_dapm && post_dapm_off && tavil->mbhc) blocking_notifier_call_chain(&tavil->mbhc->notifier, @@ -10953,11 +10965,12 @@ static const struct snd_event_ops wcd934x_ssr_ops = { static int tavil_probe(struct platform_device *pdev) { - int ret = 0; + int ret = 0, len = 0; struct tavil_priv *tavil; struct clk *wcd_ext_clk; struct wcd9xxx_resmgr_v2 *resmgr; struct wcd9xxx_power_region *cdc_pwr; + const __be32 *micb_prop; tavil = devm_kzalloc(&pdev->dev, sizeof(struct tavil_priv), GFP_KERNEL); @@ -11084,6 +11097,26 @@ static int tavil_probe(struct platform_device *pdev) ret = 0; } + tavil->micb_load = NULL; + + if (of_get_property(tavil->wcd9xxx->dev->of_node, + "qcom,vreg-micb-supply", NULL)) { + micb_prop = of_get_property(tavil->wcd9xxx->dev->of_node, + "qcom,cdc-vdd-mic-bias-current", + &len); + if (!micb_prop || (len != (2 * sizeof(__be32)))) { + tavil->micb_load_low = MICB_LOAD_DEFAULT; + tavil->micb_load_high = MICB_LOAD_DEFAULT; + } else { + tavil->micb_load_low = be32_to_cpup(&micb_prop[0]); + tavil->micb_load_high = be32_to_cpup(&micb_prop[1]); + } + tavil->micb_load = regulator_get(&pdev->dev, MICB_LOAD_PROP); + if (IS_ERR(tavil->micb_load)) + dev_dbg(tavil->dev, "%s micb load get failed\n", + __func__); + } + return ret; err_cdc_reg: @@ -11125,6 +11158,9 @@ static int tavil_remove(struct platform_device *pdev) count < WCD934X_CHILD_DEVICES_MAX; count++) platform_device_unregister(tavil->pdev_child_devices[count]); + if (tavil->micb_load) + regulator_put(tavil->micb_load); + mutex_destroy(&tavil->micb_lock); mutex_destroy(&tavil->svs_mutex); mutex_destroy(&tavil->codec_mutex);