All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] Add CS35L41 shared boost feature
@ 2023-02-07 16:25 Lucas Tanure
  2023-02-07 16:25 ` [PATCH v2 1/5] ASoC: cs35l41: Only disable internal boost Lucas Tanure
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Lucas Tanure @ 2023-02-07 16:25 UTC (permalink / raw)
  To: David Rhodes, Charles Keepax, Liam Girdwood, Krzysztof Kozlowski,
	Mark Brown, Rob Herring, Jaroslav Kysela, Takashi Iwai
  Cc: alsa-devel, devicetree, patches, linux-kernel, kernel, Lucas Tanure

Valve's Steam Deck uses CS35L41 in shared boost mode,
where both speakers share the boost circuit.
Add this support in the shared lib, but for now,
shared boost is not supported in HDA systems as
would require BIOS changes.
Based on David Rhodes shared boost patches.

Also, fix boost config overwriting in IRQ found
in the review and do a small refactor of the code.

Changes from V1:
 - Fix Documentation patch subject
 - New patch for External boost without VSPK Documentation
 - New patch to fix boost IRQ overwriting issue
 - New patch to refactor IRQ release error code
 - reinit_completion on pcm_startup
 - fix DRE switch overwriting
 - return IRQ_HANDLED in PLL_LOCK case

Lucas Tanure (5):
  ASoC: cs35l41: Only disable internal boost
  ASoC: cs35l41: Refactor error release code
  ALSA: cs35l41: Add shared boost feature
  ASoC: cs35l41: Document CS35l41 external boost without VSPK
  ASoC: cs35l41: Document CS35l41 shared boost

 .../bindings/sound/cirrus,cs35l41.yaml        |  12 +-
 include/sound/cs35l41.h                       |  10 +-
 sound/pci/hda/cs35l41_hda.c                   |   6 +-
 sound/soc/codecs/cs35l41-lib.c                |  56 +++++++-
 sound/soc/codecs/cs35l41.c                    | 125 +++++++++---------
 sound/soc/codecs/cs35l41.h                    |   1 +
 6 files changed, 139 insertions(+), 71 deletions(-)

-- 
2.39.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 1/5] ASoC: cs35l41: Only disable internal boost
  2023-02-07 16:25 [PATCH v2 0/5] Add CS35L41 shared boost feature Lucas Tanure
@ 2023-02-07 16:25 ` Lucas Tanure
  2023-02-08 10:02     ` Charles Keepax
  2023-02-07 16:25 ` [PATCH v2 2/5] ASoC: cs35l41: Refactor error release code Lucas Tanure
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Lucas Tanure @ 2023-02-07 16:25 UTC (permalink / raw)
  To: David Rhodes, Charles Keepax, Liam Girdwood, Krzysztof Kozlowski,
	Mark Brown, Rob Herring, Jaroslav Kysela, Takashi Iwai
  Cc: alsa-devel, devicetree, patches, linux-kernel, kernel, Lucas Tanure

In error situations, only the internal boost case
should be disabled and re-enabled.
Also, for other boost cases re-enabling the boost
to the default internal boost config is incorrect.

Fixes: 6450ef559056 ("ASoC: cs35l41: CS35L41 Boosted Smart Amplifier")
Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
---
 sound/soc/codecs/cs35l41.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
index c223d83e02cf..f2b5032daa6a 100644
--- a/sound/soc/codecs/cs35l41.c
+++ b/sound/soc/codecs/cs35l41.c
@@ -356,6 +356,19 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
 	WM_ADSP_FW_CONTROL("DSP1", 0),
 };
 
+static void cs35l41_boost_enable(struct cs35l41_private *cs35l41, unsigned int enable)
+{
+	switch (cs35l41->hw_cfg.bst_type) {
+	case CS35L41_INT_BOOST:
+		enable = enable ? CS35L41_BST_EN_DEFAULT : CS35L41_BST_DIS_FET_OFF;
+		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK,
+				enable << CS35L41_BST_EN_SHIFT);
+		break;
+	default:
+		break;
+	}
+}
+
 static irqreturn_t cs35l41_irq(int irq, void *data)
 {
 	struct cs35l41_private *cs35l41 = data;
@@ -431,8 +444,7 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
 
 	if (status[0] & CS35L41_BST_OVP_ERR) {
 		dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
-		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
-				   CS35L41_BST_EN_MASK, 0);
+		cs35l41_boost_enable(cs35l41, 0);
 		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 			     CS35L41_BST_OVP_ERR);
 		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
@@ -441,16 +453,13 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
 				   CS35L41_BST_OVP_ERR_RLS);
 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 				   CS35L41_BST_OVP_ERR_RLS, 0);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
-				   CS35L41_BST_EN_MASK,
-				   CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
+		cs35l41_boost_enable(cs35l41, 1);
 		ret = IRQ_HANDLED;
 	}
 
 	if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
 		dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
-		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
-				   CS35L41_BST_EN_MASK, 0);
+		cs35l41_boost_enable(cs35l41, 0);
 		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 			     CS35L41_BST_DCM_UVP_ERR);
 		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
@@ -459,16 +468,13 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
 				   CS35L41_BST_UVP_ERR_RLS);
 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 				   CS35L41_BST_UVP_ERR_RLS, 0);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
-				   CS35L41_BST_EN_MASK,
-				   CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
+		cs35l41_boost_enable(cs35l41, 1);
 		ret = IRQ_HANDLED;
 	}
 
 	if (status[0] & CS35L41_BST_SHORT_ERR) {
 		dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
-		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
-				   CS35L41_BST_EN_MASK, 0);
+		cs35l41_boost_enable(cs35l41, 0);
 		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 			     CS35L41_BST_SHORT_ERR);
 		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
@@ -477,9 +483,7 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
 				   CS35L41_BST_SHORT_ERR_RLS);
 		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 				   CS35L41_BST_SHORT_ERR_RLS, 0);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
-				   CS35L41_BST_EN_MASK,
-				   CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
+		cs35l41_boost_enable(cs35l41, 1);
 		ret = IRQ_HANDLED;
 	}
 
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 2/5] ASoC: cs35l41: Refactor error release code
  2023-02-07 16:25 [PATCH v2 0/5] Add CS35L41 shared boost feature Lucas Tanure
  2023-02-07 16:25 ` [PATCH v2 1/5] ASoC: cs35l41: Only disable internal boost Lucas Tanure
@ 2023-02-07 16:25 ` Lucas Tanure
  2023-02-08 10:03     ` Charles Keepax
  2023-02-07 16:25 ` [PATCH v2 3/5] ALSA: cs35l41: Add shared boost feature Lucas Tanure
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Lucas Tanure @ 2023-02-07 16:25 UTC (permalink / raw)
  To: David Rhodes, Charles Keepax, Liam Girdwood, Krzysztof Kozlowski,
	Mark Brown, Rob Herring, Jaroslav Kysela, Takashi Iwai
  Cc: alsa-devel, devicetree, patches, linux-kernel, kernel, Lucas Tanure

Add cs35l41_error_release function to handle
error release sequences.

Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
---
 sound/soc/codecs/cs35l41.c | 64 ++++++++++----------------------------
 1 file changed, 16 insertions(+), 48 deletions(-)

diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
index f2b5032daa6a..c006364e5335 100644
--- a/sound/soc/codecs/cs35l41.c
+++ b/sound/soc/codecs/cs35l41.c
@@ -369,6 +369,16 @@ static void cs35l41_boost_enable(struct cs35l41_private *cs35l41, unsigned int e
 	}
 }
 
+
+static void cs35l41_error_release(struct cs35l41_private *cs35l41, unsigned int irq_err_bit,
+				  unsigned int rel_err_bit)
+{
+	regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, irq_err_bit);
+	regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
+	regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, rel_err_bit, rel_err_bit);
+	regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, rel_err_bit, 0);
+}
+
 static irqreturn_t cs35l41_irq(int irq, void *data)
 {
 	struct cs35l41_private *cs35l41 = data;
@@ -405,54 +415,26 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
 	 */
 	if (status[0] & CS35L41_AMP_SHORT_ERR) {
 		dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");
-		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
-			     CS35L41_AMP_SHORT_ERR);
-		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_AMP_SHORT_ERR_RLS,
-				   CS35L41_AMP_SHORT_ERR_RLS);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_AMP_SHORT_ERR_RLS, 0);
+		cs35l41_error_release(cs35l41, CS35L41_AMP_SHORT_ERR, CS35L41_AMP_SHORT_ERR_RLS);
 		ret = IRQ_HANDLED;
 	}
 
 	if (status[0] & CS35L41_TEMP_WARN) {
 		dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");
-		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
-			     CS35L41_TEMP_WARN);
-		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_TEMP_WARN_ERR_RLS,
-				   CS35L41_TEMP_WARN_ERR_RLS);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_TEMP_WARN_ERR_RLS, 0);
+		cs35l41_error_release(cs35l41, CS35L41_TEMP_WARN, CS35L41_TEMP_WARN_ERR_RLS);
 		ret = IRQ_HANDLED;
 	}
 
 	if (status[0] & CS35L41_TEMP_ERR) {
 		dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");
-		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
-			     CS35L41_TEMP_ERR);
-		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_TEMP_ERR_RLS,
-				   CS35L41_TEMP_ERR_RLS);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_TEMP_ERR_RLS, 0);
+		cs35l41_error_release(cs35l41, CS35L41_TEMP_ERR, CS35L41_TEMP_ERR_RLS);
 		ret = IRQ_HANDLED;
 	}
 
 	if (status[0] & CS35L41_BST_OVP_ERR) {
 		dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
 		cs35l41_boost_enable(cs35l41, 0);
-		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
-			     CS35L41_BST_OVP_ERR);
-		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_BST_OVP_ERR_RLS,
-				   CS35L41_BST_OVP_ERR_RLS);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_BST_OVP_ERR_RLS, 0);
+		cs35l41_error_release(cs35l41, CS35L41_BST_OVP_ERR, CS35L41_BST_OVP_ERR_RLS);
 		cs35l41_boost_enable(cs35l41, 1);
 		ret = IRQ_HANDLED;
 	}
@@ -460,14 +442,7 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
 	if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
 		dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
 		cs35l41_boost_enable(cs35l41, 0);
-		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
-			     CS35L41_BST_DCM_UVP_ERR);
-		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_BST_UVP_ERR_RLS,
-				   CS35L41_BST_UVP_ERR_RLS);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_BST_UVP_ERR_RLS, 0);
+		cs35l41_error_release(cs35l41, CS35L41_BST_DCM_UVP_ERR, CS35L41_BST_UVP_ERR_RLS);
 		cs35l41_boost_enable(cs35l41, 1);
 		ret = IRQ_HANDLED;
 	}
@@ -475,14 +450,7 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
 	if (status[0] & CS35L41_BST_SHORT_ERR) {
 		dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
 		cs35l41_boost_enable(cs35l41, 0);
-		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
-			     CS35L41_BST_SHORT_ERR);
-		regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_BST_SHORT_ERR_RLS,
-				   CS35L41_BST_SHORT_ERR_RLS);
-		regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
-				   CS35L41_BST_SHORT_ERR_RLS, 0);
+		cs35l41_error_release(cs35l41, CS35L41_BST_SHORT_ERR, CS35L41_BST_SHORT_ERR_RLS);
 		cs35l41_boost_enable(cs35l41, 1);
 		ret = IRQ_HANDLED;
 	}
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 3/5] ALSA: cs35l41: Add shared boost feature
  2023-02-07 16:25 [PATCH v2 0/5] Add CS35L41 shared boost feature Lucas Tanure
  2023-02-07 16:25 ` [PATCH v2 1/5] ASoC: cs35l41: Only disable internal boost Lucas Tanure
  2023-02-07 16:25 ` [PATCH v2 2/5] ASoC: cs35l41: Refactor error release code Lucas Tanure
@ 2023-02-07 16:25 ` Lucas Tanure
  2023-02-08 10:09     ` Charles Keepax
  2023-02-07 16:25 ` [PATCH v2 4/5] ASoC: cs35l41: Document CS35l41 external boost without VSPK Lucas Tanure
  2023-02-07 16:25 ` [PATCH v2 5/5] ASoC: cs35l41: Document CS35l41 shared boost Lucas Tanure
  4 siblings, 1 reply; 14+ messages in thread
From: Lucas Tanure @ 2023-02-07 16:25 UTC (permalink / raw)
  To: David Rhodes, Charles Keepax, Liam Girdwood, Krzysztof Kozlowski,
	Mark Brown, Rob Herring, Jaroslav Kysela, Takashi Iwai
  Cc: alsa-devel, devicetree, patches, linux-kernel, kernel, Lucas Tanure

Shared boost allows two amplifiers to share a single boost
circuit by communicating on the MDSYNC bus.
The passive amplifier does not control the boost and receives
data from the active amplifier.

Shared Boost is not supported in HDA Systems.
Based on David Rhodes shared boost patches.

Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
---
 include/sound/cs35l41.h        | 10 +++++-
 sound/pci/hda/cs35l41_hda.c    |  6 ++--
 sound/soc/codecs/cs35l41-lib.c | 56 +++++++++++++++++++++++++++++++++-
 sound/soc/codecs/cs35l41.c     | 27 ++++++++++++++--
 sound/soc/codecs/cs35l41.h     |  1 +
 5 files changed, 93 insertions(+), 7 deletions(-)

diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h
index 9ac5918269a5..a034ebe03a0e 100644
--- a/include/sound/cs35l41.h
+++ b/include/sound/cs35l41.h
@@ -11,6 +11,7 @@
 #define __CS35L41_H
 
 #include <linux/regmap.h>
+#include <linux/completion.h>
 #include <linux/firmware/cirrus/cs_dsp.h>
 
 #define CS35L41_FIRSTREG		0x00000000
@@ -677,6 +678,7 @@
 
 #define CS35L36_PUP_DONE_IRQ_UNMASK	0x5F
 #define CS35L36_PUP_DONE_IRQ_MASK	0xBF
+#define CS35L41_SYNC_EN_MASK		BIT(8)
 
 #define CS35L41_AMP_SHORT_ERR		0x80000000
 #define CS35L41_BST_SHORT_ERR		0x0100
@@ -686,6 +688,7 @@
 #define CS35L41_BST_DCM_UVP_ERR		0x80
 #define CS35L41_OTP_BOOT_DONE		0x02
 #define CS35L41_PLL_UNLOCK		0x10
+#define CS35L41_PLL_LOCK		BIT(1)
 #define CS35L41_OTP_BOOT_ERR		0x80000000
 
 #define CS35L41_AMP_SHORT_ERR_RLS	0x02
@@ -705,6 +708,8 @@
 #define CS35L41_INT1_MASK_DEFAULT	0x7FFCFE3F
 #define CS35L41_INT1_UNMASK_PUP		0xFEFFFFFF
 #define CS35L41_INT1_UNMASK_PDN		0xFF7FFFFF
+#define CS35L41_INT3_PLL_LOCK_SHIFT	1
+#define CS35L41_INT3_PLL_LOCK_MASK	BIT(CS35L41_INT3_PLL_LOCK_SHIFT)
 
 #define CS35L41_GPIO_DIR_MASK		0x80000000
 #define CS35L41_GPIO_DIR_SHIFT		31
@@ -743,6 +748,8 @@ enum cs35l41_boost_type {
 	CS35L41_INT_BOOST,
 	CS35L41_EXT_BOOST,
 	CS35L41_EXT_BOOST_NO_VSPK_SWITCH,
+	CS35L41_SHD_BOOST_ACTV,
+	CS35L41_SHD_BOOST_PASS,
 };
 
 enum cs35l41_clk_ids {
@@ -891,6 +898,7 @@ int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap);
 int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
 		       struct cs35l41_hw_cfg *hw_cfg);
 bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type);
-int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable);
+int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,
+			  struct completion *pll_lock);
 
 #endif /* __CS35L41_H */
diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index f7815ee24f83..38c0079ef303 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -515,13 +515,13 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action)
 		break;
 	case HDA_GEN_PCM_ACT_PREPARE:
 		mutex_lock(&cs35l41->fw_mutex);
-		ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 1);
+		ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 1, NULL);
 		mutex_unlock(&cs35l41->fw_mutex);
 		break;
 	case HDA_GEN_PCM_ACT_CLEANUP:
 		mutex_lock(&cs35l41->fw_mutex);
 		regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute));
-		ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 0);
+		ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 0, NULL);
 		mutex_unlock(&cs35l41->fw_mutex);
 		break;
 	case HDA_GEN_PCM_ACT_CLOSE:
@@ -673,7 +673,7 @@ static int cs35l41_runtime_suspend(struct device *dev)
 	if (cs35l41->playback_started) {
 		regmap_multi_reg_write(cs35l41->regmap, cs35l41_hda_mute,
 				       ARRAY_SIZE(cs35l41_hda_mute));
-		cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0);
+		cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0, NULL);
 		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
 				   CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);
 		if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c
index 04be71435491..138eb352551a 100644
--- a/sound/soc/codecs/cs35l41-lib.c
+++ b/sound/soc/codecs/cs35l41-lib.c
@@ -1114,12 +1114,31 @@ static const struct reg_sequence cs35l41_reset_to_safe[] = {
 	{ 0x00000040,			0x00000033 },
 };
 
+static const struct reg_sequence cs35l41_actv_seq[] = {
+	/* SYNC_BST_CTL_RX_EN = 0; SYNC_BST_CTL_TX_EN = 1 */
+	{CS35L41_MDSYNC_EN,        0x00001000},
+	/* BST_CTL_SEL = CLASSH */
+	{CS35L41_BSTCVRT_VCTRL2,    0x00000001},
+};
+
+static const struct reg_sequence cs35l41_pass_seq[] = {
+	/* SYNC_BST_CTL_RX_EN = 1; SYNC_BST_CTL_TX_EN = 0 */
+	{CS35L41_MDSYNC_EN,        0x00002000},
+	/* BST_EN = 0 */
+	{CS35L41_PWR_CTRL2,        0x00003300},
+	/* BST_CTL_SEL = MDSYNC */
+	{CS35L41_BSTCVRT_VCTRL2,    0x00000002},
+};
+
 int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
 		       struct cs35l41_hw_cfg *hw_cfg)
 {
 	int ret;
 
 	switch (hw_cfg->bst_type) {
+	case CS35L41_SHD_BOOST_ACTV:
+		regmap_multi_reg_write(regmap, cs35l41_actv_seq, ARRAY_SIZE(cs35l41_actv_seq));
+		fallthrough;
 	case CS35L41_INT_BOOST:
 		ret = cs35l41_boost_config(dev, regmap, hw_cfg->bst_ind,
 					   hw_cfg->bst_cap, hw_cfg->bst_ipk);
@@ -1138,6 +1157,9 @@ int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
 		ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK,
 					 CS35L41_BST_DIS_FET_OFF << CS35L41_BST_EN_SHIFT);
 		break;
+	case CS35L41_SHD_BOOST_PASS:
+		regmap_multi_reg_write(regmap, cs35l41_pass_seq, ARRAY_SIZE(cs35l41_pass_seq));
+		break;
 	default:
 		dev_err(dev, "Boost type %d not supported\n", hw_cfg->bst_type);
 		ret = -EINVAL;
@@ -1165,11 +1187,43 @@ bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type)
 }
 EXPORT_SYMBOL_GPL(cs35l41_safe_reset);
 
-int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable)
+int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,
+			  struct completion *pll_lock)
 {
 	int ret;
+	unsigned int gpio1;
 
 	switch (b_type) {
+	case CS35L41_SHD_BOOST_ACTV:
+	case CS35L41_SHD_BOOST_PASS:
+		regmap_update_bits(regmap, CS35L41_PWR_CTRL3, CS35L41_SYNC_EN_MASK, 0);
+
+		gpio1 = enable ? CS35L41_GPIO1_MDSYNC : CS35L41_GPIO1_HIZ;
+		regmap_update_bits(regmap, CS35L41_GPIO_PAD_CONTROL, CS35L41_GPIO1_CTRL_MASK,
+				   gpio1 << CS35L41_GPIO1_CTRL_SHIFT);
+
+		ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
+					 enable << CS35L41_GLOBAL_EN_SHIFT);
+		usleep_range(3000, 3100);
+		if (!enable)
+			break;
+
+		if (!pll_lock)
+			return -EINVAL;
+
+		ret = wait_for_completion_timeout(pll_lock, msecs_to_jiffies(1000));
+		if (ret == 0) {
+			ret = -ETIMEDOUT;
+		} else {
+			regmap_update_bits(regmap, CS35L41_PWR_CTRL3, CS35L41_SYNC_EN_MASK, 0);
+			regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
+								 0 << CS35L41_GLOBAL_EN_SHIFT);
+			usleep_range(3000, 3100);
+			regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
+								 1 << CS35L41_GLOBAL_EN_SHIFT);
+			usleep_range(3000, 3100);
+		}
+		break;
 	case CS35L41_INT_BOOST:
 		ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
 					 enable << CS35L41_GLOBAL_EN_SHIFT);
diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
index c006364e5335..1624510d09c0 100644
--- a/sound/soc/codecs/cs35l41.c
+++ b/sound/soc/codecs/cs35l41.c
@@ -360,6 +360,7 @@ static void cs35l41_boost_enable(struct cs35l41_private *cs35l41, unsigned int e
 {
 	switch (cs35l41->hw_cfg.bst_type) {
 	case CS35L41_INT_BOOST:
+	case CS35L41_SHD_BOOST_ACTV:
 		enable = enable ? CS35L41_BST_EN_DEFAULT : CS35L41_BST_DIS_FET_OFF;
 		regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK,
 				enable << CS35L41_BST_EN_SHIFT);
@@ -455,6 +456,12 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
 		ret = IRQ_HANDLED;
 	}
 
+	if (status[2] & CS35L41_PLL_LOCK) {
+		regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS3, CS35L41_PLL_LOCK);
+		complete(&cs35l41->pll_lock);
+		ret = IRQ_HANDLED;
+	}
+
 done:
 	pm_runtime_mark_last_busy(cs35l41->dev);
 	pm_runtime_put_autosuspend(cs35l41->dev);
@@ -492,10 +499,12 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
 						cs35l41_pup_patch,
 						ARRAY_SIZE(cs35l41_pup_patch));
 
-		cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 1);
+		cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 1,
+				      &cs35l41->pll_lock);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0);
+		cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0,
+				      &cs35l41->pll_lock);
 
 		ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 					       val, val &  CS35L41_PDN_DONE_MASK,
@@ -802,6 +811,10 @@ static const struct snd_pcm_hw_constraint_list cs35l41_constraints = {
 static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,
 			       struct snd_soc_dai *dai)
 {
+	struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
+
+	reinit_completion(&cs35l41->pll_lock);
+
 	if (substream->runtime)
 		return snd_pcm_hw_constraint_list(substream->runtime, 0,
 						  SNDRV_PCM_HW_PARAM_RATE,
@@ -1252,6 +1265,10 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
 	/* Set interrupt masks for critical errors */
 	regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,
 		     CS35L41_INT1_MASK_DEFAULT);
+	if (cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_PASS ||
+	    cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_ACTV)
+		regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK3, CS35L41_INT3_PLL_LOCK_MASK,
+				   0 << CS35L41_INT3_PLL_LOCK_SHIFT);
 
 	ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq,
 					IRQF_ONESHOT | IRQF_SHARED | irq_pol,
@@ -1275,6 +1292,8 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
 	if (ret < 0)
 		goto err;
 
+	init_completion(&cs35l41->pll_lock);
+
 	pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000);
 	pm_runtime_use_autosuspend(cs35l41->dev);
 	pm_runtime_mark_last_busy(cs35l41->dev);
@@ -1317,6 +1336,10 @@ void cs35l41_remove(struct cs35l41_private *cs35l41)
 	pm_runtime_disable(cs35l41->dev);
 
 	regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
+	if (cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_PASS ||
+	    cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_ACTV)
+		regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK3, CS35L41_INT3_PLL_LOCK_MASK,
+				   1 << CS35L41_INT3_PLL_LOCK_SHIFT);
 	kfree(cs35l41->dsp.system_name);
 	wm_adsp2_remove(&cs35l41->dsp);
 	cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h
index c85cbc1dd333..34d967d4372b 100644
--- a/sound/soc/codecs/cs35l41.h
+++ b/sound/soc/codecs/cs35l41.h
@@ -33,6 +33,7 @@ struct cs35l41_private {
 	int irq;
 	/* GPIO for /RST */
 	struct gpio_desc *reset_gpio;
+	struct completion pll_lock;
 };
 
 int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg);
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 4/5] ASoC: cs35l41: Document CS35l41 external boost without VSPK
  2023-02-07 16:25 [PATCH v2 0/5] Add CS35L41 shared boost feature Lucas Tanure
                   ` (2 preceding siblings ...)
  2023-02-07 16:25 ` [PATCH v2 3/5] ALSA: cs35l41: Add shared boost feature Lucas Tanure
@ 2023-02-07 16:25 ` Lucas Tanure
  2023-02-07 16:48   ` Krzysztof Kozlowski
  2023-02-07 16:25 ` [PATCH v2 5/5] ASoC: cs35l41: Document CS35l41 shared boost Lucas Tanure
  4 siblings, 1 reply; 14+ messages in thread
From: Lucas Tanure @ 2023-02-07 16:25 UTC (permalink / raw)
  To: David Rhodes, Charles Keepax, Liam Girdwood, Krzysztof Kozlowski,
	Mark Brown, Rob Herring, Jaroslav Kysela, Takashi Iwai
  Cc: alsa-devel, devicetree, patches, linux-kernel, kernel, Lucas Tanure

External Boost without GPIO1 as VSPK switch
is no longer supported, but there is laptop
models using this feature.

Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
---
 Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml
index 18fb471aa891..8465623bbd96 100644
--- a/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml
+++ b/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml
@@ -85,11 +85,13 @@ properties:
       boost-cap-microfarad.
       External Boost must have GPIO1 as GPIO output. GPIO1 will be set high to
       enable boost voltage.
+      External Boost without GPIO1 as VSPK switch is no longer supported.
       0 = Internal Boost
       1 = External Boost
+      2 = External Boost without VPSK switch (Do not use in new systems)
     $ref: /schemas/types.yaml#/definitions/uint32
     minimum: 0
-    maximum: 1
+    maximum: 2
 
   cirrus,gpio1-polarity-invert:
     description:
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 5/5] ASoC: cs35l41: Document CS35l41 shared boost
  2023-02-07 16:25 [PATCH v2 0/5] Add CS35L41 shared boost feature Lucas Tanure
                   ` (3 preceding siblings ...)
  2023-02-07 16:25 ` [PATCH v2 4/5] ASoC: cs35l41: Document CS35l41 external boost without VSPK Lucas Tanure
@ 2023-02-07 16:25 ` Lucas Tanure
  4 siblings, 0 replies; 14+ messages in thread
From: Lucas Tanure @ 2023-02-07 16:25 UTC (permalink / raw)
  To: David Rhodes, Charles Keepax, Liam Girdwood, Krzysztof Kozlowski,
	Mark Brown, Rob Herring, Jaroslav Kysela, Takashi Iwai
  Cc: alsa-devel, devicetree, patches, linux-kernel, kernel, Lucas Tanure

Describe the properties used for shared boost
configuration.
Based on David Rhodes shared boost patches.

Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
---
 .../devicetree/bindings/sound/cirrus,cs35l41.yaml      | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml
index 8465623bbd96..54f769159ce4 100644
--- a/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml
+++ b/Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml
@@ -86,12 +86,20 @@ properties:
       External Boost must have GPIO1 as GPIO output. GPIO1 will be set high to
       enable boost voltage.
       External Boost without GPIO1 as VSPK switch is no longer supported.
+      Shared boost allows two amplifiers to share a single boost circuit by
+      communicating on the MDSYNC bus. The passive amplifier does not control
+      the boost and receives data from the active amplifier. GPIO1 should be
+      configured for Sync when shared boost is used. Shared boost is not
+      compatible with External boost. Active amplifier requires
+      boost-peak-milliamp, boost-ind-nanohenry and boost-cap-microfarad.
       0 = Internal Boost
       1 = External Boost
       2 = External Boost without VPSK switch (Do not use in new systems)
+      3 = Shared Boost Active
+      4 = Shared Boost Passive
     $ref: /schemas/types.yaml#/definitions/uint32
     minimum: 0
-    maximum: 2
+    maximum: 4
 
   cirrus,gpio1-polarity-invert:
     description:
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 4/5] ASoC: cs35l41: Document CS35l41 external boost without VSPK
  2023-02-07 16:25 ` [PATCH v2 4/5] ASoC: cs35l41: Document CS35l41 external boost without VSPK Lucas Tanure
@ 2023-02-07 16:48   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 14+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-07 16:48 UTC (permalink / raw)
  To: Lucas Tanure, David Rhodes, Charles Keepax, Liam Girdwood,
	Krzysztof Kozlowski, Mark Brown, Rob Herring, Jaroslav Kysela,
	Takashi Iwai
  Cc: alsa-devel, devicetree, patches, linux-kernel, kernel

On 07/02/2023 17:25, Lucas Tanure wrote:
> External Boost without GPIO1 as VSPK switch
> is no longer supported, but there is laptop
> models using this feature.


No, because:

1. We did not finish discussion
2. Subject prefix is still not correct.
3. Please wrap commit message according to Linux coding style /
submission process (neither too early nor over the limit):
https://elixir.bootlin.com/linux/v5.18-rc4/source/Documentation/process/submitting-patches.rst#L586


Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/5] ASoC: cs35l41: Only disable internal boost
  2023-02-07 16:25 ` [PATCH v2 1/5] ASoC: cs35l41: Only disable internal boost Lucas Tanure
@ 2023-02-08 10:02     ` Charles Keepax
  0 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2023-02-08 10:02 UTC (permalink / raw)
  To: Lucas Tanure
  Cc: David Rhodes, Liam Girdwood, Krzysztof Kozlowski, Mark Brown,
	Rob Herring, Jaroslav Kysela, Takashi Iwai, alsa-devel,
	devicetree, patches, linux-kernel, kernel

On Tue, Feb 07, 2023 at 04:25:22PM +0000, Lucas Tanure wrote:
> In error situations, only the internal boost case
> should be disabled and re-enabled.
> Also, for other boost cases re-enabling the boost
> to the default internal boost config is incorrect.
> 
> Fixes: 6450ef559056 ("ASoC: cs35l41: CS35L41 Boosted Smart Amplifier")
> Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
> ---

Would quite like David to review as well, but looks good to me.

Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>

Thanks,
Charles

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/5] ASoC: cs35l41: Only disable internal boost
@ 2023-02-08 10:02     ` Charles Keepax
  0 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2023-02-08 10:02 UTC (permalink / raw)
  To: Lucas Tanure
  Cc: David Rhodes, Liam Girdwood, Krzysztof Kozlowski, Mark Brown,
	Rob Herring, Takashi Iwai, alsa-devel, devicetree, patches,
	linux-kernel, kernel

On Tue, Feb 07, 2023 at 04:25:22PM +0000, Lucas Tanure wrote:
> In error situations, only the internal boost case
> should be disabled and re-enabled.
> Also, for other boost cases re-enabling the boost
> to the default internal boost config is incorrect.
> 
> Fixes: 6450ef559056 ("ASoC: cs35l41: CS35L41 Boosted Smart Amplifier")
> Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
> ---

Would quite like David to review as well, but looks good to me.

Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>

Thanks,
Charles

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 2/5] ASoC: cs35l41: Refactor error release code
  2023-02-07 16:25 ` [PATCH v2 2/5] ASoC: cs35l41: Refactor error release code Lucas Tanure
@ 2023-02-08 10:03     ` Charles Keepax
  0 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2023-02-08 10:03 UTC (permalink / raw)
  To: Lucas Tanure
  Cc: David Rhodes, Liam Girdwood, Krzysztof Kozlowski, Mark Brown,
	Rob Herring, Takashi Iwai, alsa-devel, devicetree, patches,
	linux-kernel, kernel

On Tue, Feb 07, 2023 at 04:25:23PM +0000, Lucas Tanure wrote:
> Add cs35l41_error_release function to handle
> error release sequences.
> 
> Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
> ---

Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>

Thanks,
Charles

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 2/5] ASoC: cs35l41: Refactor error release code
@ 2023-02-08 10:03     ` Charles Keepax
  0 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2023-02-08 10:03 UTC (permalink / raw)
  To: Lucas Tanure
  Cc: David Rhodes, Liam Girdwood, Krzysztof Kozlowski, Mark Brown,
	Rob Herring, Jaroslav Kysela, Takashi Iwai, alsa-devel,
	devicetree, patches, linux-kernel, kernel

On Tue, Feb 07, 2023 at 04:25:23PM +0000, Lucas Tanure wrote:
> Add cs35l41_error_release function to handle
> error release sequences.
> 
> Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
> ---

Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>

Thanks,
Charles

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/5] ALSA: cs35l41: Add shared boost feature
  2023-02-07 16:25 ` [PATCH v2 3/5] ALSA: cs35l41: Add shared boost feature Lucas Tanure
@ 2023-02-08 10:09     ` Charles Keepax
  0 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2023-02-08 10:09 UTC (permalink / raw)
  To: Lucas Tanure
  Cc: David Rhodes, Liam Girdwood, Krzysztof Kozlowski, Mark Brown,
	Rob Herring, Jaroslav Kysela, Takashi Iwai, alsa-devel,
	devicetree, patches, linux-kernel, kernel

On Tue, Feb 07, 2023 at 04:25:24PM +0000, Lucas Tanure wrote:
> Shared boost allows two amplifiers to share a single boost
> circuit by communicating on the MDSYNC bus.
> The passive amplifier does not control the boost and receives
> data from the active amplifier.
> 
> Shared Boost is not supported in HDA Systems.
> Based on David Rhodes shared boost patches.
> 
> Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
> ---
> -int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable)
> +int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,
> +			  struct completion *pll_lock)
>  {
>  	int ret;
> +	unsigned int gpio1;
>  
>  	switch (b_type) {
> +	case CS35L41_SHD_BOOST_ACTV:
> +	case CS35L41_SHD_BOOST_PASS:
> +		regmap_update_bits(regmap, CS35L41_PWR_CTRL3, CS35L41_SYNC_EN_MASK, 0);
> +
> +		gpio1 = enable ? CS35L41_GPIO1_MDSYNC : CS35L41_GPIO1_HIZ;
> +		regmap_update_bits(regmap, CS35L41_GPIO_PAD_CONTROL, CS35L41_GPIO1_CTRL_MASK,
> +				   gpio1 << CS35L41_GPIO1_CTRL_SHIFT);
> +
> +		ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
> +					 enable << CS35L41_GLOBAL_EN_SHIFT);
> +		usleep_range(3000, 3100);
> +		if (!enable)
> +			break;
> +
> +		if (!pll_lock)
> +			return -EINVAL;
> +
> +		ret = wait_for_completion_timeout(pll_lock, msecs_to_jiffies(1000));
> +		if (ret == 0) {
> +			ret = -ETIMEDOUT;
> +		} else {
> +			regmap_update_bits(regmap, CS35L41_PWR_CTRL3, CS35L41_SYNC_EN_MASK, 0);
> +			regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
> +								 0 << CS35L41_GLOBAL_EN_SHIFT);
> +			usleep_range(3000, 3100);
> +			regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
> +								 1 << CS35L41_GLOBAL_EN_SHIFT);
> +			usleep_range(3000, 3100);
> +		}

This approach also makes me nervous, I was somewhat imagining the
usage of regmap_multi_reg_write for this sequence was because it
was very important that no other register writes could interleave
in between these writes. But I don't know, so it could also have
just been a random design choice. So we probably need David to
confirm if that was the reason for the original code here.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/5] ALSA: cs35l41: Add shared boost feature
@ 2023-02-08 10:09     ` Charles Keepax
  0 siblings, 0 replies; 14+ messages in thread
From: Charles Keepax @ 2023-02-08 10:09 UTC (permalink / raw)
  To: Lucas Tanure
  Cc: David Rhodes, Liam Girdwood, Krzysztof Kozlowski, Mark Brown,
	Rob Herring, Takashi Iwai, alsa-devel, devicetree, patches,
	linux-kernel, kernel

On Tue, Feb 07, 2023 at 04:25:24PM +0000, Lucas Tanure wrote:
> Shared boost allows two amplifiers to share a single boost
> circuit by communicating on the MDSYNC bus.
> The passive amplifier does not control the boost and receives
> data from the active amplifier.
> 
> Shared Boost is not supported in HDA Systems.
> Based on David Rhodes shared boost patches.
> 
> Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
> ---
> -int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable)
> +int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,
> +			  struct completion *pll_lock)
>  {
>  	int ret;
> +	unsigned int gpio1;
>  
>  	switch (b_type) {
> +	case CS35L41_SHD_BOOST_ACTV:
> +	case CS35L41_SHD_BOOST_PASS:
> +		regmap_update_bits(regmap, CS35L41_PWR_CTRL3, CS35L41_SYNC_EN_MASK, 0);
> +
> +		gpio1 = enable ? CS35L41_GPIO1_MDSYNC : CS35L41_GPIO1_HIZ;
> +		regmap_update_bits(regmap, CS35L41_GPIO_PAD_CONTROL, CS35L41_GPIO1_CTRL_MASK,
> +				   gpio1 << CS35L41_GPIO1_CTRL_SHIFT);
> +
> +		ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
> +					 enable << CS35L41_GLOBAL_EN_SHIFT);
> +		usleep_range(3000, 3100);
> +		if (!enable)
> +			break;
> +
> +		if (!pll_lock)
> +			return -EINVAL;
> +
> +		ret = wait_for_completion_timeout(pll_lock, msecs_to_jiffies(1000));
> +		if (ret == 0) {
> +			ret = -ETIMEDOUT;
> +		} else {
> +			regmap_update_bits(regmap, CS35L41_PWR_CTRL3, CS35L41_SYNC_EN_MASK, 0);
> +			regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
> +								 0 << CS35L41_GLOBAL_EN_SHIFT);
> +			usleep_range(3000, 3100);
> +			regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
> +								 1 << CS35L41_GLOBAL_EN_SHIFT);
> +			usleep_range(3000, 3100);
> +		}

This approach also makes me nervous, I was somewhat imagining the
usage of regmap_multi_reg_write for this sequence was because it
was very important that no other register writes could interleave
in between these writes. But I don't know, so it could also have
just been a random design choice. So we probably need David to
confirm if that was the reason for the original code here.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/5] ALSA: cs35l41: Add shared boost feature
  2023-02-08 10:09     ` Charles Keepax
  (?)
@ 2023-02-08 12:27     ` lucas.tanure
  -1 siblings, 0 replies; 14+ messages in thread
From: lucas.tanure @ 2023-02-08 12:27 UTC (permalink / raw)
  To: Charles Keepax, David Rhodes, Liam Girdwood, Krzysztof Kozlowski,
	Mark Brown, Rob Herring, Jaroslav Kysela, Takashi Iwai,
	alsa-devel, devicetree, patches, linux-kernel, kernel

On 2/8/23 10:09 AM, Charles Keepax <ckeepax@opensource.cirrus.com> wrote:
> On Tue, Feb 07, 2023 at 04:25:24PM +0000, Lucas Tanure wrote:
> > Shared boost allows two amplifiers to share a single boost
> > circuit by communicating on the MDSYNC bus.
> > The passive amplifier does not control the boost and receives
> > data from the active amplifier.
> >
> > Shared Boost is not supported in HDA Systems.
> > Based on David Rhodes shared boost patches.
> >
> > Signed-off-by: Lucas Tanure <lucas.tanure@collabora.com>
> > ---
> > -int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable)
> > +int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,
> > +			  struct completion *pll_lock)
> >   {
> >   	int ret;
> > +	unsigned int gpio1;
> >   
> >   	switch (b_type) {
> > +	case CS35L41_SHD_BOOST_ACTV:
> > +	case CS35L41_SHD_BOOST_PASS:
> > +		regmap_update_bits(regmap, CS35L41_PWR_CTRL3, CS35L41_SYNC_EN_MASK, 0);
> > +
> > +		gpio1 = enable ? CS35L41_GPIO1_MDSYNC : CS35L41_GPIO1_HIZ;
> > +		regmap_update_bits(regmap, CS35L41_GPIO_PAD_CONTROL, CS35L41_GPIO1_CTRL_MASK,
> > +				   gpio1 << CS35L41_GPIO1_CTRL_SHIFT);
> > +
> > +		ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
> > +					 enable << CS35L41_GLOBAL_EN_SHIFT);
> > +		usleep_range(3000, 3100);
> > +		if (!enable)
> > +			break;
> > +
> > +		if (!pll_lock)
> > +			return -EINVAL;
> > +
> > +		ret = wait_for_completion_timeout(pll_lock, msecs_to_jiffies(1000));
> > +		if (ret == 0) {
> > +			ret = -ETIMEDOUT;
> > +		} else {
> > +			regmap_update_bits(regmap, CS35L41_PWR_CTRL3, CS35L41_SYNC_EN_MASK, 0);
Its wrong here. Should be enabling it not disable.
I will send v3. 

> > +			regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
> > +								 0 << CS35L41_GLOBAL_EN_SHIFT);
> > +			usleep_range(3000, 3100);
> > +			regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
> > +								 1 << CS35L41_GLOBAL_EN_SHIFT);
> > +			usleep_range(3000, 3100);
> > +		}
> 
> This approach also makes me nervous, I was somewhat imagining the
> usage of regmap_multi_reg_write for this sequence was because it
> was very important that no other register writes could interleave
> in between these writes. But I don't know, so it could also have
> just been a random design choice. So we probably need David to
> confirm if that was the reason for the original code here.
> 
> Thanks,
> Charles
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-02-08 12:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-07 16:25 [PATCH v2 0/5] Add CS35L41 shared boost feature Lucas Tanure
2023-02-07 16:25 ` [PATCH v2 1/5] ASoC: cs35l41: Only disable internal boost Lucas Tanure
2023-02-08 10:02   ` Charles Keepax
2023-02-08 10:02     ` Charles Keepax
2023-02-07 16:25 ` [PATCH v2 2/5] ASoC: cs35l41: Refactor error release code Lucas Tanure
2023-02-08 10:03   ` Charles Keepax
2023-02-08 10:03     ` Charles Keepax
2023-02-07 16:25 ` [PATCH v2 3/5] ALSA: cs35l41: Add shared boost feature Lucas Tanure
2023-02-08 10:09   ` Charles Keepax
2023-02-08 10:09     ` Charles Keepax
2023-02-08 12:27     ` lucas.tanure
2023-02-07 16:25 ` [PATCH v2 4/5] ASoC: cs35l41: Document CS35l41 external boost without VSPK Lucas Tanure
2023-02-07 16:48   ` Krzysztof Kozlowski
2023-02-07 16:25 ` [PATCH v2 5/5] ASoC: cs35l41: Document CS35l41 shared boost Lucas Tanure

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.