Merge "asoc: codecs: Update LPM voting support for vdd-mic-bias-supply"

This commit is contained in:
qctecmdr 2020-06-05 01:54:03 -07:00 • committed by Gerrit - the friendly Code Review server
commit c1a9199e09
8 changed files with 242 additions and 11 deletions

View file

@ -60,9 +60,22 @@ static int msm_cdc_dt_parse_vreg_info(struct device *dev,
}
cdc_vreg->optimum_uA = prop_val;
dev_info(dev, "%s: %s: vol=[%d %d]uV, curr=[%d]uA, ond %d\n",
/* Parse supply - LPM or NOM mode(default NOM) */
snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "qcom,%s-lpm-supported", name);
rc = of_property_read_u32(dev->of_node, prop_name, &prop_val);
if (rc) {
dev_dbg(dev, "%s: Looking up %s property in node %s failed",
__func__, prop_name, dev->of_node->full_name);
cdc_vreg->lpm_supported = 0;
rc = 0;
} else {
cdc_vreg->lpm_supported = prop_val;
}
dev_info(dev, "%s: %s: vol=[%d %d]uV, curr=[%d]uA, ond %d lpm %d\n",
__func__, cdc_vreg->name, cdc_vreg->min_uV, cdc_vreg->max_uV,
cdc_vreg->optimum_uA, cdc_vreg->ondemand);
cdc_vreg->optimum_uA, cdc_vreg->ondemand,
cdc_vreg->lpm_supported);
done:
return rc;
@ -260,6 +273,59 @@ int msm_cdc_enable_ondemand_supply(struct device *dev,
}
EXPORT_SYMBOL(msm_cdc_enable_ondemand_supply);
/*
* msm_cdc_set_supplies_lpm_mode:
* Update load for given supply string
*
* @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
* @min_max: Apply optimum or 0 current
*
* Return error code if set current fail
*/
int msm_cdc_set_supplies_lpm_mode(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies,
bool flag)
{
int rc = 0, i;
if (!supplies) {
pr_err("%s: supplies is NULL\n",
__func__);
return -EINVAL;
}
/* input parameter validation */
rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
if (rc)
return rc;
for (i = 0; i < num_supplies; i++) {
if (cdc_vreg[i].lpm_supported) {
rc = regulator_set_load(
supplies[i].consumer,
flag ? 0 : cdc_vreg[i].optimum_uA);
if (rc)
dev_err(dev,
"%s: failed to set supply %s to %s, err:%d\n",
__func__, supplies[i].supply,
flag ? "LPM" : "NOM",
rc);
else
dev_dbg(dev, "%s: regulator %s load set to %s\n",
__func__, supplies[i].supply,
flag ? "LPM" : "NOM");
}
}
return rc;
}
EXPORT_SYMBOL(msm_cdc_set_supplies_lpm_mode);
/*
* msm_cdc_disable_static_supplies:
* Disable codec static supplies

View file

@ -50,6 +50,7 @@ struct rouleur_priv {
bool comp1_enable;
bool comp2_enable;
bool dapm_bias_off;
struct irq_domain *virq;
struct wcd_irq_info irq_info;

View file

@ -46,6 +46,7 @@ enum {
HPH_COMP_DELAY,
HPH_PA_DELAY,
AMIC2_BCS_ENABLE,
WCD_SUPPLIES_LPM_MODE,
};
/* TODO: Check on the step values */
@ -1986,6 +1987,26 @@ static void rouleur_soc_codec_remove(struct snd_soc_component *component)
false);
}
static int rouleur_soc_codec_suspend(struct snd_soc_component *component)
{
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
if (!rouleur)
return 0;
rouleur->dapm_bias_off = true;
return 0;
}
static int rouleur_soc_codec_resume(struct snd_soc_component *component)
{
struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
if (!rouleur)
return 0;
rouleur->dapm_bias_off = false;
return 0;
}
static const struct snd_soc_component_driver soc_codec_dev_rouleur = {
.name = DRV_NAME,
.probe = rouleur_soc_codec_probe,
@ -1996,6 +2017,8 @@ static const struct snd_soc_component_driver soc_codec_dev_rouleur = {
.num_dapm_widgets = ARRAY_SIZE(rouleur_dapm_widgets),
.dapm_routes = rouleur_audio_map,
.num_dapm_routes = ARRAY_SIZE(rouleur_audio_map),
.suspend = rouleur_soc_codec_suspend,
.resume = rouleur_soc_codec_resume,
};
#ifdef CONFIG_PM_SLEEP
@ -2032,11 +2055,45 @@ static int rouleur_suspend(struct device *dev)
}
clear_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask);
}
if (rouleur->dapm_bias_off) {
msm_cdc_set_supplies_lpm_mode(rouleur->dev,
rouleur->supplies,
pdata->regulator,
pdata->num_supplies,
true);
set_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask);
}
return 0;
}
static int rouleur_resume(struct device *dev)
{
struct rouleur_priv *rouleur = NULL;
struct rouleur_pdata *pdata = NULL;
if (!dev)
return -ENODEV;
rouleur = dev_get_drvdata(dev);
if (!rouleur)
return -EINVAL;
pdata = dev_get_platdata(rouleur->dev);
if (!pdata) {
dev_err(dev, "%s: pdata is NULL\n", __func__);
return -EINVAL;
}
if (test_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask)) {
msm_cdc_set_supplies_lpm_mode(rouleur->dev,
rouleur->supplies,
pdata->regulator,
pdata->num_supplies,
false);
clear_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask);
}
return 0;
}
#endif
@ -2467,10 +2524,8 @@ static int rouleur_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static const struct dev_pm_ops rouleur_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(
rouleur_suspend,
rouleur_resume
)
.suspend_late = rouleur_suspend,
.resume_early = rouleur_resume
};
#endif

View file

@ -73,6 +73,7 @@ struct wcd938x_priv {
bool comp2_enable;
bool ldoh;
bool bcs_dis;
bool dapm_bias_off;
struct irq_domain *virq;
struct wcd_irq_info irq_info;
u32 rx_clk_cnt;

View file

@ -72,6 +72,7 @@ enum {
HPH_COMP_DELAY,
HPH_PA_DELAY,
AMIC2_BCS_ENABLE,
WCD_SUPPLIES_LPM_MODE,
};
enum {
@ -3713,6 +3714,26 @@ static void wcd938x_soc_codec_remove(struct snd_soc_component *component)
false);
}
static int wcd938x_soc_codec_suspend(struct snd_soc_component *component)
{
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
if (!wcd938x)
return 0;
wcd938x->dapm_bias_off = true;
return 0;
}
static int wcd938x_soc_codec_resume(struct snd_soc_component *component)
{
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
if (!wcd938x)
return 0;
wcd938x->dapm_bias_off = false;
return 0;
}
static struct snd_soc_component_driver soc_codec_dev_wcd938x = {
.name = WCD938X_DRV_NAME,
.probe = wcd938x_soc_codec_probe,
@ -3723,6 +3744,8 @@ static struct snd_soc_component_driver soc_codec_dev_wcd938x = {
.num_dapm_widgets = ARRAY_SIZE(wcd938x_dapm_widgets),
.dapm_routes = wcd938x_audio_map,
.num_dapm_routes = ARRAY_SIZE(wcd938x_audio_map),
.suspend = wcd938x_soc_codec_suspend,
.resume = wcd938x_soc_codec_resume,
};
static int wcd938x_reset(struct device *dev)
@ -4242,19 +4265,51 @@ static int wcd938x_suspend(struct device *dev)
}
clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
}
if (wcd938x->dapm_bias_off) {
msm_cdc_set_supplies_lpm_mode(wcd938x->dev,
wcd938x->supplies,
pdata->regulator,
pdata->num_supplies,
true);
set_bit(WCD_SUPPLIES_LPM_MODE, &wcd938x->status_mask);
}
return 0;
}
static int wcd938x_resume(struct device *dev)
{
struct wcd938x_priv *wcd938x = NULL;
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(WCD_SUPPLIES_LPM_MODE, &wcd938x->status_mask)) {
msm_cdc_set_supplies_lpm_mode(wcd938x->dev,
wcd938x->supplies,
pdata->regulator,
pdata->num_supplies,
false);
clear_bit(WCD_SUPPLIES_LPM_MODE, &wcd938x->status_mask);
}
return 0;
}
static const struct dev_pm_ops wcd938x_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(
wcd938x_suspend,
wcd938x_resume
)
.suspend_late = wcd938x_suspend,
.resume_early = wcd938x_resume,
};
#endif

View file

@ -97,6 +97,7 @@ struct wsa883x_priv {
bool comp_enable;
bool visense_enable;
bool ext_vdd_spk;
bool dapm_bias_off;
struct swr_port port[WSA883X_MAX_SWR_PORTS];
int global_pa_cnt;
int dev_mode;

View file

@ -132,6 +132,7 @@ enum {
enum {
SPKR_STATUS = 0,
WSA_SUPPLIES_LPM_MODE,
};
enum {
@ -1220,6 +1221,28 @@ static void wsa883x_codec_remove(struct snd_soc_component *component)
return;
}
static int wsa883x_soc_codec_suspend(struct snd_soc_component *component)
{
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
if (!wsa883x)
return 0;
wsa883x->dapm_bias_off = true;
return 0;
}
static int wsa883x_soc_codec_resume(struct snd_soc_component *component)
{
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
if (!wsa883x)
return 0;
wsa883x->dapm_bias_off = false;
return 0;
}
static const struct snd_soc_component_driver soc_codec_dev_wsa883x_wsa = {
.name = "",
.probe = wsa883x_codec_probe,
@ -1230,6 +1253,8 @@ static const struct snd_soc_component_driver soc_codec_dev_wsa883x_wsa = {
.num_dapm_widgets = ARRAY_SIZE(wsa883x_dapm_widgets),
.dapm_routes = wsa883x_audio_map,
.num_dapm_routes = ARRAY_SIZE(wsa883x_audio_map),
.suspend = wsa883x_soc_codec_suspend,
.resume = wsa883x_soc_codec_resume,
};
static int wsa883x_gpio_ctrl(struct wsa883x_priv *wsa883x, bool enable)
@ -1692,7 +1717,20 @@ static int wsa883x_swr_remove(struct swr_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int wsa883x_swr_suspend(struct device *dev)
{
struct wsa883x_priv *wsa883x = swr_get_dev_data(to_swr_device(dev));
if (!wsa883x) {
dev_err(dev, "%s: wsa883x private data is NULL\n", __func__);
return -EINVAL;
}
dev_dbg(dev, "%s: system suspend\n", __func__);
if (wsa883x->dapm_bias_off) {
msm_cdc_set_supplies_lpm_mode(dev, wsa883x->supplies,
wsa883x->regulator,
wsa883x->num_supplies,
true);
set_bit(WSA_SUPPLIES_LPM_MODE, &wsa883x->status_mask);
}
return 0;
}
@ -1704,13 +1742,21 @@ static int wsa883x_swr_resume(struct device *dev)
dev_err(dev, "%s: wsa883x private data is NULL\n", __func__);
return -EINVAL;
}
if (test_bit(WSA_SUPPLIES_LPM_MODE, &wsa883x->status_mask)) {
msm_cdc_set_supplies_lpm_mode(dev, wsa883x->supplies,
wsa883x->regulator,
wsa883x->num_supplies,
false);
clear_bit(WSA_SUPPLIES_LPM_MODE, &wsa883x->status_mask);
}
dev_dbg(dev, "%s: system resume\n", __func__);
return 0;
}
#endif /* CONFIG_PM_SLEEP */
static const struct dev_pm_ops wsa883x_swr_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(wsa883x_swr_suspend, wsa883x_swr_resume)
.suspend_late = wsa883x_swr_suspend,
.resume_early = wsa883x_swr_resume,
};
static const struct swr_device_id wsa883x_swr_id[] = {

View file

@ -15,6 +15,7 @@ struct cdc_regulator {
int max_uV;
int optimum_uA;
bool ondemand;
bool lpm_supported;
struct regulator *regulator;
};
@ -51,6 +52,11 @@ extern int msm_cdc_enable_static_supplies(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies);
extern int msm_cdc_set_supplies_lpm_mode(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies,
bool flag);
extern int msm_cdc_init_supplies(struct device *dev,
struct regulator_bulk_data **supplies,
struct cdc_regulator *cdc_vreg,