asoc: wcd938x: Add vdd-buck as on demand supply

On lagoon, vdd-buck need to be dynamic supply.
Add required support to handle buck as dynamic supply.

Change-Id: If6c27fffe0d0c44f178e61a6eae6ef63775c8988
Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
This commit is contained in:
Laxminath Kasam
2020-03-12 17:40:47 +05:30
committed by Gerrit - the friendly Code Review server
parent 93afa626ed
commit 1ecf8184d2
3 changed files with 144 additions and 0 deletions

View File

@@ -119,6 +119,47 @@ static int msm_cdc_check_supply_param(struct device *dev,
return 0;
}
/*
* msm_cdc_is_ondemand_supply:
* return if ondemand supply true or not
*
* @dev: pointer to codec device
* @supplies: pointer to regulator bulk data
* @cdc_vreg: pointer to platform regulator data
* @num_supplies: number of supplies
* @supply_name: supply name to be checked
*
* Return true/false
*/
bool msm_cdc_is_ondemand_supply(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies,
char *supply_name)
{
bool rc = false;
int ret, i;
if ((!supply_name) || (!supplies)) {
pr_err("%s: either dev or supplies or cdc_vreg is NULL\n",
__func__);
return rc;
}
/* input parameter validation */
ret = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
if (ret)
return rc;
for (i = 0; i < num_supplies; i++) {
if (cdc_vreg[i].ondemand &&
!strcmp(cdc_vreg[i].name, supply_name))
return true;
}
return rc;
}
EXPORT_SYMBOL(msm_cdc_is_ondemand_supply);
/*
* msm_cdc_disable_ondemand_supply:
* Disable codec ondemand supply

View File

@@ -2563,6 +2563,67 @@ static int wcd938x_set_compander(struct snd_kcontrol *kcontrol,
return 0;
}
static int wcd938x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol,
int event)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
struct wcd938x_pdata *pdata = NULL;
int ret = 0;
pdata = dev_get_platdata(wcd938x->dev);
if (!pdata) {
dev_err(component->dev, "%s: pdata is NULL\n", __func__);
return -EINVAL;
}
if (!msm_cdc_is_ondemand_supply(wcd938x->dev,
wcd938x->supplies,
pdata->regulator,
pdata->num_supplies,
"cdc-vdd-buck"))
return 0;
dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
w->name, event);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (test_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask)) {
dev_dbg(component->dev,
"%s: buck already in enabled state\n",
__func__);
clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
return 0;
}
ret = msm_cdc_enable_ondemand_supply(wcd938x->dev,
wcd938x->supplies,
pdata->regulator,
pdata->num_supplies,
"cdc-vdd-buck");
if (ret == -EINVAL) {
dev_err(component->dev, "%s: vdd buck is not enabled\n",
__func__);
return ret;
}
clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
/*
* 200us sleep is required after LDO is enabled as per
* HW requirement
*/
usleep_range(200, 250);
break;
case SND_SOC_DAPM_POST_PMD:
set_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
break;
}
return 0;
}
static int wcd938x_ldoh_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -3111,6 +3172,10 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
wcd938x_codec_force_enable_micbias,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0,
wcd938x_codec_enable_vdd_buck,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0,
wcd938x_enable_clsh,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
@@ -3257,6 +3322,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
{"WCD_TX_OUTPUT", NULL, "DMIC8_MIXER"},
{"DMIC8_MIXER", "Switch", "DMIC8"},
{"IN1_HPHL", NULL, "VDD_BUCK"},
{"IN1_HPHL", NULL, "CLS_H_PORT"},
{"RX1", NULL, "IN1_HPHL"},
{"RDAC1", NULL, "RX1"},
@@ -3264,6 +3330,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
{"HPHL PGA", NULL, "HPHL_RDAC"},
{"HPHL", NULL, "HPHL PGA"},
{"IN2_HPHR", NULL, "VDD_BUCK"},
{"IN2_HPHR", NULL, "CLS_H_PORT"},
{"RX2", NULL, "IN2_HPHR"},
{"RDAC2", NULL, "RX2"},
@@ -3271,6 +3338,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
{"HPHR PGA", NULL, "HPHR_RDAC"},
{"HPHR", NULL, "HPHR PGA"},
{"IN3_AUX", NULL, "VDD_BUCK"},
{"IN3_AUX", NULL, "CLS_H_PORT"},
{"RX3", NULL, "IN3_AUX"},
{"RDAC4", NULL, "RX3"},
@@ -4122,6 +4190,37 @@ static int wcd938x_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int wcd938x_suspend(struct device *dev)
{
struct wcd938x_priv *wcd938x = NULL;
int ret = 0;
struct wcd938x_pdata *pdata = NULL;
if (!dev)
return -ENODEV;
wcd938x = dev_get_drvdata(dev);
if (!wcd938x)
return -EINVAL;
pdata = dev_get_platdata(wcd938x->dev);
if (!pdata) {
dev_err(dev, "%s: pdata is NULL\n", __func__);
return -EINVAL;
}
if (test_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask)) {
ret = msm_cdc_disable_ondemand_supply(wcd938x->dev,
wcd938x->supplies,
pdata->regulator,
pdata->num_supplies,
"cdc-vdd-buck");
if (ret == -EINVAL) {
dev_err(dev, "%s: vdd buck is not disabled\n",
__func__);
return 0;
}
clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
}
return 0;
}

View File

@@ -27,6 +27,10 @@ struct cdc_wcd_supply {
extern int msm_cdc_get_power_supplies(struct device *dev,
struct cdc_regulator **cdc_vreg,
int *total_num_supplies);
extern bool msm_cdc_is_ondemand_supply(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies, char *supply_name);
extern int msm_cdc_disable_ondemand_supply(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,