From 3f886242114a6db505b83b550ebbced3fe5190a5 Mon Sep 17 00:00:00 2001
From: Thierry Strudel <tstrudel@google.com>
Date: Sun, 5 Nov 2017 14:05:04 -0800
Subject: [PATCH] sound: tas2557: set FAST mode for VBOB in requested case

Some capacitance on VBOB power rail as causing a buzzing sound.
VBOB is by default in AUTO mode and alternate between PFM and PWM
modes based on the rail load. Forcing rail to PWM reduces the buzzing
sound but is less efficient at low current than PFM so this patch
will force VBOB to FAST mode (PWM) only on the selected route
configuration set by device tree.

This patch also allows FAST mode to be requested on the VBOB regulator.

Bug: 64839820
Change-Id: I965269ce9ffde33e017090e776c003db81533959
Signed-off-by: Thierry Strudel <tstrudel@google.com>
---
 drivers/regulator/rpm-smd-regulator.c   |  3 ++
 sound/soc/codecs/tas2557/tas2557-core.c | 38 +++++++++++++++++++++++++
 sound/soc/codecs/tas2557/tas2557.h      |  3 ++
 3 files changed, 44 insertions(+)

diff --git a/drivers/regulator/rpm-smd-regulator.c b/drivers/regulator/rpm-smd-regulator.c
index d26fd3bea788..dbee7f06b316 100644
--- a/drivers/regulator/rpm-smd-regulator.c
+++ b/drivers/regulator/rpm-smd-regulator.c
@@ -1691,6 +1691,9 @@ static int rpm_vreg_device_probe(struct platform_device *pdev)
 			|= REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_DRMS;
 		init_data->constraints.valid_modes_mask
 			|= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE;
+		if (regulator_type == RPM_REGULATOR_TYPE_BOB)
+			init_data->constraints.valid_modes_mask
+				|= REGULATOR_MODE_FAST;
 	}
 
 	reg->rdesc.name		= init_data->constraints.name;
diff --git a/sound/soc/codecs/tas2557/tas2557-core.c b/sound/soc/codecs/tas2557/tas2557-core.c
index d7e1930a10c2..402b0a0fa2bc 100644
--- a/sound/soc/codecs/tas2557/tas2557-core.c
+++ b/sound/soc/codecs/tas2557/tas2557-core.c
@@ -126,6 +126,18 @@ static unsigned int p_tas2557_shutdown_data[] = {
 	0xFFFFFFFF, 0xFFFFFFFF
 };
 
+
+static void force_vbob_pwm_mode(struct tas2557_priv *pTAS2557, bool enable)
+{
+	if (pTAS2557->vbob_regulator == NULL)
+		return;
+
+	if (regulator_set_mode(pTAS2557->vbob_regulator, enable ?
+			       REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL))
+		dev_err(pTAS2557->dev, "failed to set BoB to %s\n",
+			enable ? "FAST" : "NORMAL");
+}
+
 static int tas2557_dev_load_data(struct tas2557_priv *pTAS2557,
 	enum channel chl, unsigned int *pData)
 {
@@ -1067,6 +1079,12 @@ end:
 		if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
 			failsafe(pTAS2557);
 		/* TAS2557_RELOAD_FIRMWARE_END */
+	} else {
+		if ((pTAS2557->bob_fast_profile != UINT_MAX) &&
+		    (pTAS2557->bob_fast_profile ==
+		     pTAS2557->mnCurrentConfiguration)) {
+			force_vbob_pwm_mode(pTAS2557, pTAS2557->mbPowerUp);
+		}
 	}
 
 	return nResult;
@@ -2284,6 +2302,11 @@ int tas2557_set_config(struct tas2557_priv *pTAS2557, int config)
 	dev_dbg(pTAS2557->dev, "%s, load new conf %s\n", __func__, pConfiguration->mpName);
 	nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
 
+	if ((pTAS2557->bob_fast_profile != UINT_MAX) && (pTAS2557->mbPowerUp)) {
+		force_vbob_pwm_mode(pTAS2557,
+				    pTAS2557->bob_fast_profile ==
+				    pTAS2557->mnCurrentConfiguration);
+	}
 end:
 
 	return nResult;
@@ -2936,6 +2959,21 @@ int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557)
 	else
 		dev_dbg(pTAS2557->dev, "ti,cal-file-name=%s\n",
 			pTAS2557->cal_file_name);
+
+	rc = of_property_read_u32(np, "ti,bob-fast-profile", &value);
+
+	if (rc) {
+		dev_dbg(pTAS2557->dev, "ti,bob-fast-profile not set\n");
+		pTAS2557->bob_fast_profile = UINT_MAX;
+	} else {
+		pTAS2557->bob_fast_profile = value;
+		dev_info(pTAS2557->dev, "ti,bob-fast-profile set to %d\n",
+			 pTAS2557->bob_fast_profile);
+		pTAS2557->vbob_regulator = devm_regulator_get(pTAS2557->dev,
+							      "pm8998_bob");
+		if (pTAS2557->vbob_regulator == NULL)
+			dev_err(pTAS2557->dev, "failed to get BoB regulator\n");
+	}
 end:
 
 	return ret;
diff --git a/sound/soc/codecs/tas2557/tas2557.h b/sound/soc/codecs/tas2557/tas2557.h
index e9eedaf06509..c2c4c1e848dc 100644
--- a/sound/soc/codecs/tas2557/tas2557.h
+++ b/sound/soc/codecs/tas2557/tas2557.h
@@ -536,6 +536,9 @@ struct tas2557_priv {
 	*/
 	bool mbBypassTMax;
 
+	unsigned int bob_fast_profile;
+	struct regulator *vbob_regulator;
+
 #ifdef CONFIG_TAS2557_CODEC_STEREO
 	struct mutex codec_lock;
 #endif
-- 
GitLab