asoc: codecs: enable dynamic RX & TX supplies for WCD9335
Enable and vote RX and TX supplies dynamically during respective
usecases.
Change-Id: I671c14b34ce0325e102d94083905329d473d4a78
Signed-off-by: Mangesh Kunchamwar <mangeshk@codeaurora.org>
Signed-off-by: Surendar Karka <skarka@codeaurora.org>
diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c
index b0cb9c7..fd2e933 100644
--- a/asoc/codecs/wcd9xxx-core.c
+++ b/asoc/codecs/wcd9xxx-core.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@@ -98,6 +98,65 @@
struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE];
+/*
+ * wcd9xxx_vote_ondemand_regulator: Initialize codec dynamic supplies
+ *
+ * @wcd9xxx: Pointer to wcd9xxx structure
+ * @wcd9xxx_pdata: Pointer to wcd9xxx_pdata structure
+ * @supply_name: supply parameter to initialize regulator
+ * @enable: flag to initialize/uninitialize supply
+ *
+ * Return error code if supply init is failed
+ */
+int wcd9xxx_vote_ondemand_regulator(struct wcd9xxx *wcd9xxx,
+ struct wcd9xxx_pdata *pdata,
+ const char *supply_name,
+ bool enable)
+{
+ int i, rc, index = -EINVAL;
+
+ pr_debug("%s: enable %d\n", __func__, enable);
+
+ for (i = 0; i < wcd9xxx->num_of_supplies; ++i) {
+ if (pdata->regulator[i].ondemand &&
+ wcd9xxx->supplies[i].supply &&
+ !strcmp(wcd9xxx->supplies[i].supply, supply_name)) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index < 0) {
+ pr_err("%s: no matching regulator found\n", __func__);
+ return -EINVAL;
+ }
+
+ if (enable) {
+ rc = regulator_set_voltage(wcd9xxx->supplies[index].consumer,
+ pdata->regulator[index].min_uV,
+ pdata->regulator[index].max_uV);
+ if (rc) {
+ pr_err("%s: set regulator voltage failed for %s, err:%d\n",
+ __func__, supply_name, rc);
+ return rc;
+ }
+ rc = regulator_set_load(wcd9xxx->supplies[index].consumer,
+ pdata->regulator[index].optimum_uA);
+ if (rc < 0) {
+ pr_err("%s: set regulator optimum mode failed for %s, err:%d\n",
+ __func__, supply_name, rc);
+ return rc;
+ }
+ } else {
+ regulator_set_voltage(wcd9xxx->supplies[index].consumer, 0,
+ pdata->regulator[index].max_uV);
+ regulator_set_load(wcd9xxx->supplies[index].consumer, 0);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(wcd9xxx_vote_ondemand_regulator);
+
static int wcd9xxx_slim_multi_reg_write(struct wcd9xxx *wcd9xxx,
const void *data, size_t count)
{
@@ -1069,9 +1128,10 @@
wcd9xxx->mclk_rate = pdata->mclk_rate;
wcd9xxx->num_of_supplies = pdata->num_supplies;
- ret = msm_cdc_init_supplies(wcd9xxx->dev, &wcd9xxx->supplies,
- pdata->regulator,
- pdata->num_supplies);
+ ret = msm_cdc_init_supplies_v2(wcd9xxx->dev, &wcd9xxx->supplies,
+ pdata->regulator,
+ pdata->num_supplies,
+ pdata->vote_regulator_on_demand);
if (!wcd9xxx->supplies) {
dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n",
__func__);
@@ -1327,9 +1387,10 @@
}
wcd9xxx->num_of_supplies = pdata->num_supplies;
- ret = msm_cdc_init_supplies(&slim->dev, &wcd9xxx->supplies,
- pdata->regulator,
- pdata->num_supplies);
+ ret = msm_cdc_init_supplies_v2(&slim->dev, &wcd9xxx->supplies,
+ pdata->regulator,
+ pdata->num_supplies,
+ pdata->vote_regulator_on_demand);
if (!wcd9xxx->supplies) {
dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n",
__func__);