summarylogtreecommitdiffstats
path: root/0006-ALSA-hda-cs35l41-Move-Play-and-Pause-into-separate-f.patch
diff options
context:
space:
mode:
Diffstat (limited to '0006-ALSA-hda-cs35l41-Move-Play-and-Pause-into-separate-f.patch')
-rw-r--r--0006-ALSA-hda-cs35l41-Move-Play-and-Pause-into-separate-f.patch193
1 files changed, 193 insertions, 0 deletions
diff --git a/0006-ALSA-hda-cs35l41-Move-Play-and-Pause-into-separate-f.patch b/0006-ALSA-hda-cs35l41-Move-Play-and-Pause-into-separate-f.patch
new file mode 100644
index 000000000000..b79792840f63
--- /dev/null
+++ b/0006-ALSA-hda-cs35l41-Move-Play-and-Pause-into-separate-f.patch
@@ -0,0 +1,193 @@
+From f352ce9e5389e4746f25bfec33f4e0ee4dcbf690 Mon Sep 17 00:00:00 2001
+From: Stefan Binding <sbinding@opensource.cirrus.com>
+Date: Fri, 21 Jul 2023 16:18:11 +0100
+Subject: [PATCH 06/11] ALSA: hda: cs35l41: Move Play and Pause into separate
+ functions
+
+This allows play and pause to be called from multiple places,
+which is necessary for system suspend and resume.
+
+Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
+---
+ sound/pci/hda/cs35l41_hda.c | 131 ++++++++++++++++++++++--------------
+ 1 file changed, 79 insertions(+), 52 deletions(-)
+
+diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
+index d4a11f7b5dbd..f77583b46b6b 100644
+--- a/sound/pci/hda/cs35l41_hda.c
++++ b/sound/pci/hda/cs35l41_hda.c
+@@ -483,63 +483,103 @@ static void cs35l41_irq_release(struct cs35l41_hda *cs35l41)
+ cs35l41->irq_errors = 0;
+ }
+
+-static void cs35l41_hda_playback_hook(struct device *dev, int action)
++static void cs35l41_hda_play_start(struct device *dev)
+ {
+ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
+ struct regmap *reg = cs35l41->regmap;
+- int ret = 0;
++
++ dev_dbg(dev, "Play (Start)\n");
++
++ if (cs35l41->playback_started) {
++ dev_dbg(dev, "Playback already started.");
++ return;
++ }
++
++ cs35l41->playback_started = true;
++
++ if (cs35l41->firmware_running) {
++ regmap_multi_reg_write(reg, cs35l41_hda_config_dsp,
++ ARRAY_SIZE(cs35l41_hda_config_dsp));
++ regmap_update_bits(reg, CS35L41_PWR_CTRL2,
++ CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
++ 1 << CS35L41_VMON_EN_SHIFT | 1 << CS35L41_IMON_EN_SHIFT);
++ cs35l41_set_cspl_mbox_cmd(cs35l41->dev, reg, CSPL_MBOX_CMD_RESUME);
++ } else {
++ regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config));
++ }
++ regmap_update_bits(reg, CS35L41_PWR_CTRL2, CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT);
++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
++ regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00008001);
++
++}
++
++static void cs35l41_hda_play_done(struct device *dev)
++{
++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
++ struct regmap *reg = cs35l41->regmap;
++
++ dev_dbg(dev, "Play (Complete)\n");
++
++ cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 1, NULL,
++ cs35l41->firmware_running);
++}
++
++static void cs35l41_hda_pause_start(struct device *dev)
++{
++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
++ struct regmap *reg = cs35l41->regmap;
++
++ dev_dbg(dev, "Pause (Start)\n");
++
++ regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute));
++ cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 0, NULL,
++ cs35l41->firmware_running);
++}
++
++static void cs35l41_hda_pause_done(struct device *dev)
++{
++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
++ struct regmap *reg = cs35l41->regmap;
++
++ dev_dbg(dev, "Pause (Complete)\n");
++
++ regmap_update_bits(reg, CS35L41_PWR_CTRL2, CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);
++ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
++ regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001);
++ if (cs35l41->firmware_running) {
++ cs35l41_set_cspl_mbox_cmd(dev, reg, CSPL_MBOX_CMD_PAUSE);
++ regmap_update_bits(reg, CS35L41_PWR_CTRL2,
++ CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
++ 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT);
++ }
++ cs35l41_irq_release(cs35l41);
++ cs35l41->playback_started = false;
++}
++
++static void cs35l41_hda_playback_hook(struct device *dev, int action)
++{
++ struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
+
+ switch (action) {
+ case HDA_GEN_PCM_ACT_OPEN:
+ pm_runtime_get_sync(dev);
+ mutex_lock(&cs35l41->fw_mutex);
+- cs35l41->playback_started = true;
+- if (cs35l41->firmware_running) {
+- regmap_multi_reg_write(reg, cs35l41_hda_config_dsp,
+- ARRAY_SIZE(cs35l41_hda_config_dsp));
+- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
+- CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
+- 1 << CS35L41_VMON_EN_SHIFT | 1 << CS35L41_IMON_EN_SHIFT);
+- cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap,
+- CSPL_MBOX_CMD_RESUME);
+- } else {
+- regmap_multi_reg_write(reg, cs35l41_hda_config,
+- ARRAY_SIZE(cs35l41_hda_config));
+- }
+- ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2,
+- CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT);
+- if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
+- regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00008001);
++ cs35l41_hda_play_start(dev);
+ mutex_unlock(&cs35l41->fw_mutex);
+ break;
+ case HDA_GEN_PCM_ACT_PREPARE:
+ mutex_lock(&cs35l41->fw_mutex);
+- ret = cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 1, NULL,
+- cs35l41->firmware_running);
++ cs35l41_hda_play_done(dev);
+ 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(dev, reg, cs35l41->hw_cfg.bst_type, 0, NULL,
+- cs35l41->firmware_running);
++ cs35l41_hda_pause_start(dev);
+ mutex_unlock(&cs35l41->fw_mutex);
+ break;
+ case HDA_GEN_PCM_ACT_CLOSE:
+ mutex_lock(&cs35l41->fw_mutex);
+- ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2,
+- CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);
+- if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
+- regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001);
+- if (cs35l41->firmware_running) {
+- cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap,
+- CSPL_MBOX_CMD_PAUSE);
+- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
+- CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
+- 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT);
+- }
+- cs35l41_irq_release(cs35l41);
+- cs35l41->playback_started = false;
++ cs35l41_hda_pause_done(dev);
+ mutex_unlock(&cs35l41->fw_mutex);
+
+ pm_runtime_mark_last_busy(dev);
+@@ -549,9 +589,6 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action)
+ dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action);
+ break;
+ }
+-
+- if (ret)
+- dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret);
+ }
+
+ static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsigned int *tx_slot,
+@@ -703,18 +740,8 @@ static int cs35l41_runtime_suspend(struct device *dev)
+ mutex_lock(&cs35l41->fw_mutex);
+
+ if (cs35l41->playback_started) {
+- regmap_multi_reg_write(cs35l41->regmap, cs35l41_hda_mute,
+- ARRAY_SIZE(cs35l41_hda_mute));
+- cs35l41_global_enable(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0,
+- NULL, cs35l41->firmware_running);
+- 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)
+- regmap_write(cs35l41->regmap, CS35L41_GPIO1_CTRL1, 0x00000001);
+- regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
+- CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
+- 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT);
+- cs35l41->playback_started = false;
++ cs35l41_hda_pause_start(dev);
++ cs35l41_hda_pause_done(dev);
+ }
+
+ if (cs35l41->firmware_running) {
+--
+2.41.0
+