From 2a7ee68f738b08378defa6922f8d6d2968fdd7b7 Mon Sep 17 00:00:00 2001 From: Xingyu Wu Date: Wed, 11 Jan 2023 10:22:29 +0800 Subject: [PATCH] sound: starfive: spdif: Fixed playback failed after hibernation Fixed playback failed after hibernation by saving and restoring registers' data. Signed-off-by: Xingyu Wu --- sound/soc/starfive/starfive_spdif.c | 25 +++++++++++++++++++++++-- sound/soc/starfive/starfive_spdif.h | 4 +++- sound/soc/starfive/starfive_spdif_pcm.c | 4 +++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/sound/soc/starfive/starfive_spdif.c b/sound/soc/starfive/starfive_spdif.c index ee97627507bf..d7886d3639ed 100644 --- a/sound/soc/starfive/starfive_spdif.c +++ b/sound/soc/starfive/starfive_spdif.c @@ -423,12 +423,34 @@ static const struct snd_soc_dai_ops sf_spdif_dai_ops = { #ifdef CONFIG_PM_SLEEP static int spdif_system_suspend(struct device *dev) { + struct sf_spdif_dev *spdif = dev_get_drvdata(dev); + + /* save the register value */ + regmap_read(spdif->regmap, SPDIF_CTRL, &spdif->reg_spdif_ctrl); + regmap_read(spdif->regmap, SPDIF_INT_REG, &spdif->reg_spdif_int); + regmap_read(spdif->regmap, SPDIF_FIFO_CTRL, &spdif->reg_spdif_fifo_ctrl); + return pm_runtime_force_suspend(dev); } static int spdif_system_resume(struct device *dev) { - return pm_runtime_force_resume(dev); + struct sf_spdif_dev *spdif = dev_get_drvdata(dev); + int ret; + + ret = pm_runtime_force_resume(dev); + if (ret) + return ret; + + /* restore the register value */ + regmap_update_bits(spdif->regmap, SPDIF_CTRL, + ALLBITMASK, spdif->reg_spdif_ctrl); + regmap_update_bits(spdif->regmap, SPDIF_INT_REG, + ALLBITMASK, spdif->reg_spdif_int); + regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL, + ALLBITMASK, spdif->reg_spdif_fifo_ctrl); + + return 0; } #endif @@ -453,7 +475,6 @@ static const struct dev_pm_ops spdif_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(spdif_system_suspend, spdif_system_resume) }; - #define SF_PCM_RATE_44100_192000 (SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | \ SNDRV_PCM_RATE_96000 | \ diff --git a/sound/soc/starfive/starfive_spdif.h b/sound/soc/starfive/starfive_spdif.h index bc1cc9631c75..a0c91ae804d6 100644 --- a/sound/soc/starfive/starfive_spdif.h +++ b/sound/soc/starfive/starfive_spdif.h @@ -156,6 +156,9 @@ struct sf_spdif_dev { struct clk *mclk; struct clk *mclk_ext; struct reset_control *rst_apb; + unsigned int reg_spdif_ctrl; + unsigned int reg_spdif_int; + unsigned int reg_spdif_fifo_ctrl; struct snd_dmaengine_dai_dma_data dma_data; }; @@ -173,5 +176,4 @@ int sf_spdif_pcm_register(struct platform_device *pdev) } #endif - #endif /* __SND_SOC_STARFIVE_SPDIF_H */ diff --git a/sound/soc/starfive/starfive_spdif_pcm.c b/sound/soc/starfive/starfive_spdif_pcm.c index 582383765a5d..78ed55a046aa 100644 --- a/sound/soc/starfive/starfive_spdif_pcm.c +++ b/sound/soc/starfive/starfive_spdif_pcm.c @@ -149,7 +149,9 @@ static const struct snd_pcm_hardware sf_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_BLOCK_TRANSFER, + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME, .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | -- 2.34.1