summaryrefslogtreecommitdiff
path: root/sound/soc/fsl/fsl_easrc.c
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2019-09-17 13:29:17 +0800
committerDong Aisheng <aisheng.dong@nxp.com>2019-11-25 15:48:52 +0800
commit03944b23b2f2da1b05e79dad3d46db3cd31fd1c6 (patch)
tree6d516924a285b3ed56f2f07517499da23c0cf1b1 /sound/soc/fsl/fsl_easrc.c
parent8a4b48b55237890f15762bd2fdf89dca4f56f4df (diff)
MLK-22591: ASoC: fsl_easrc: Add RUN_STOP in stop context
When record bitstream with ASRC+AK5558, there may be I/O error for the high sample rate case (352kHz/768kHz). The reason is that the context is not fully reset after conversion, the ASRC does not start to work in next conversion. In order to fully reset the context, we need to enable RUN_STOP, then clear the RUN_EN bit. Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> (cherry picked from commit 7b44c3c653acf078b6477fbc0393f88708ccb24c)
Diffstat (limited to 'sound/soc/fsl/fsl_easrc.c')
-rw-r--r--sound/soc/fsl/fsl_easrc.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index 4769c350acb3..d35957c85a9a 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -1505,11 +1505,47 @@ int fsl_easrc_start_context(struct fsl_easrc_context *ctx)
int fsl_easrc_stop_context(struct fsl_easrc_context *ctx)
{
struct fsl_easrc *easrc = ctx->easrc;
- int ret;
+ int ret, val, i;
+ int size = 0;
+ int retry = 200;
+
+ regmap_read(easrc->regmap, REG_EASRC_CC(ctx->index), &val);
+
+ if (val & EASRC_CC_EN_MASK) {
+ ret = regmap_update_bits(easrc->regmap,
+ REG_EASRC_CC(ctx->index),
+ EASRC_CC_STOP_MASK, EASRC_CC_STOP);
+ if (ret)
+ return ret;
+
+ do {
+ regmap_read(easrc->regmap, REG_EASRC_SFS(ctx->index), &val);
+ val &= EASRC_SFS_NSGO_MASK;
+ size = val >> EASRC_SFS_NSGO_SHIFT;
+
+ /* Read FIFO, drop the data */
+ for (i = 0; i < size * ctx->channels; i++)
+ regmap_read(easrc->regmap, REG_EASRC_RDFIFO(ctx->index), &val);
+ /* Check RUN_STOP_DONE */
+ regmap_read(easrc->regmap, REG_EASRC_IRQF, &val);
+ if (val & EASRC_IRQF_RSD(1 << ctx->index)) {
+ /*Clear RUN_STOP_DONE*/
+ regmap_write_bits(easrc->regmap,
+ REG_EASRC_IRQF,
+ EASRC_IRQF_RSD(1 << ctx->index),
+ EASRC_IRQF_RSD(1 << ctx->index));
+ break;
+ }
+ udelay(100);
+ } while (--retry);
+
+ if (retry == 0)
+ dev_err(&easrc->pdev->dev, "RUN STOP fail\n");
+ }
ret = regmap_update_bits(easrc->regmap,
REG_EASRC_CC(ctx->index),
- EASRC_CC_EN_MASK, 0);
+ EASRC_CC_EN_MASK | EASRC_CC_STOP_MASK, 0);
if (ret)
return ret;
@@ -2107,6 +2143,7 @@ static bool fsl_easrc_volatile_reg(struct device *dev, unsigned int reg)
case REG_EASRC_SFS(1):
case REG_EASRC_SFS(2):
case REG_EASRC_SFS(3):
+ case REG_EASRC_IRQF:
case REG_EASRC_DBGS:
return true;
default: