From d44c6114da8c9e83407397d06b5cd909a1cc9135 Mon Sep 17 00:00:00 2001 From: Zidan Wang Date: Thu, 24 Dec 2015 11:42:11 +0800 Subject: [PATCH] ASoC: fsl_asrc: sound is wrong after suspend/resume The register ASRCFG is volatile, but some bits need to be recovered after suspend/resume. Signed-off-by: Zidan Wang Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_asrc.c | 7 +++++++ sound/soc/fsl/fsl_asrc.h | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 7b811485a8e5..73fd2c683b78 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -996,6 +996,9 @@ static int fsl_asrc_suspend(struct device *dev) { struct fsl_asrc *asrc_priv = dev_get_drvdata(dev); + regmap_read(asrc_priv->regmap, REG_ASRCFG, + &asrc_priv->regcache_cfg); + regcache_cache_only(asrc_priv->regmap, true); regcache_mark_dirty(asrc_priv->regmap); @@ -1016,6 +1019,10 @@ static int fsl_asrc_resume(struct device *dev) regcache_cache_only(asrc_priv->regmap, false); regcache_sync(asrc_priv->regmap); + regmap_update_bits(asrc_priv->regmap, REG_ASRCFG, + ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK | + ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg); + /* Restart enabled pairs */ regmap_update_bits(asrc_priv->regmap, REG_ASRCTR, ASRCTR_ASRCEi_ALL_MASK, asrctr); diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 68802cdc3f28..0f163abe4ba3 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h @@ -132,10 +132,13 @@ #define ASRCFG_INIRQi (1 << ASRCFG_INIRQi_SHIFT(i)) #define ASRCFG_NDPRi_SHIFT(i) (18 + i) #define ASRCFG_NDPRi_MASK(i) (1 << ASRCFG_NDPRi_SHIFT(i)) +#define ASRCFG_NDPRi_ALL_SHIFT 18 +#define ASRCFG_NDPRi_ALL_MASK (7 << ASRCFG_NDPRi_ALL_SHIFT) #define ASRCFG_NDPRi (1 << ASRCFG_NDPRi_SHIFT(i)) #define ASRCFG_POSTMODi_SHIFT(i) (8 + (i << 2)) #define ASRCFG_POSTMODi_WIDTH 2 #define ASRCFG_POSTMODi_MASK(i) (((1 << ASRCFG_POSTMODi_WIDTH) - 1) << ASRCFG_POSTMODi_SHIFT(i)) +#define ASRCFG_POSTMODi_ALL_MASK (ASRCFG_POSTMODi_MASK(0) | ASRCFG_POSTMODi_MASK(1) | ASRCFG_POSTMODi_MASK(2)) #define ASRCFG_POSTMOD(i, v) ((v) << ASRCFG_POSTMODi_SHIFT(i)) #define ASRCFG_POSTMODi_UP(i) (0 << ASRCFG_POSTMODi_SHIFT(i)) #define ASRCFG_POSTMODi_DCON(i) (1 << ASRCFG_POSTMODi_SHIFT(i)) @@ -143,6 +146,7 @@ #define ASRCFG_PREMODi_SHIFT(i) (6 + (i << 2)) #define ASRCFG_PREMODi_WIDTH 2 #define ASRCFG_PREMODi_MASK(i) (((1 << ASRCFG_PREMODi_WIDTH) - 1) << ASRCFG_PREMODi_SHIFT(i)) +#define ASRCFG_PREMODi_ALL_MASK (ASRCFG_PREMODi_MASK(0) | ASRCFG_PREMODi_MASK(1) | ASRCFG_PREMODi_MASK(2)) #define ASRCFG_PREMOD(i, v) ((v) << ASRCFG_PREMODi_SHIFT(i)) #define ASRCFG_PREMODi_UP(i) (0 << ASRCFG_PREMODi_SHIFT(i)) #define ASRCFG_PREMODi_DCON(i) (1 << ASRCFG_PREMODi_SHIFT(i)) @@ -434,6 +438,7 @@ struct fsl_asrc_pair { * @channel_avail: non-occupied channel numbers * @asrc_rate: default sample rate for ASoC Back-Ends * @asrc_width: default sample width for ASoC Back-Ends + * @regcache_cfg: store register value of REG_ASRCFG */ struct fsl_asrc { struct snd_dmaengine_dai_dma_data dma_params_rx; @@ -453,6 +458,8 @@ struct fsl_asrc { int asrc_rate; int asrc_width; + + u32 regcache_cfg; }; extern struct snd_soc_platform_driver fsl_asrc_platform; -- 2.20.1