diff options
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.patch | 193 |
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 + |