LF-276: ASoC: fsl_easi: constrain period size for edma case
authorShengjiu Wang <shengjiu.wang@nxp.com>
Mon, 2 Dec 2019 06:59:29 +0000 (14:59 +0800)
committerDong Aisheng <aisheng.dong@nxp.com>
Mon, 14 Dec 2020 02:56:26 +0000 (10:56 +0800)
There is limitaion for EDMA, which can only accept the period bytes
that can be divided by maxburst with no remainder. Otherwise EDMA
will not copy the left data in the end, and it will cause noise.
so add constraint for these chips.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
sound/soc/fsl/fsl_esai.c

index 284950e..54a0374 100644 (file)
  * struct fsl_esai_soc_data - soc specific data
  * @imx: for imx platform
  * @reset_at_xrun: flags for enable reset operaton
+ * @use_edma: edma is used.
  */
 struct fsl_esai_soc_data {
        bool imx;
        bool reset_at_xrun;
+       bool use_edma;
 };
 
 /**
@@ -88,16 +90,25 @@ struct fsl_esai {
 static struct fsl_esai_soc_data fsl_esai_vf610 = {
        .imx = false,
        .reset_at_xrun = true,
+       .use_edma = false,
 };
 
 static struct fsl_esai_soc_data fsl_esai_imx35 = {
        .imx = true,
        .reset_at_xrun = true,
+       .use_edma = false,
 };
 
 static struct fsl_esai_soc_data fsl_esai_imx6ull = {
        .imx = true,
        .reset_at_xrun = false,
+       .use_edma = false,
+};
+
+static struct fsl_esai_soc_data fsl_esai_imx8qm = {
+       .imx = true,
+       .reset_at_xrun = false,
+       .use_edma = true,
 };
 
 static irqreturn_t esai_isr(int irq, void *devid)
@@ -544,6 +555,7 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
                            struct snd_soc_dai *dai)
 {
        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
+       bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
        if (!snd_soc_dai_active(dai)) {
                /* Set synchronous mode */
@@ -558,6 +570,12 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
                                   ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
        }
 
+       if (esai_priv->soc->use_edma)
+               snd_pcm_hw_constraint_step(substream->runtime, 0,
+                                          SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+                                          tx ? esai_priv->dma_params_tx.maxburst :
+                                          esai_priv->dma_params_rx.maxburst);
+
        return 0;
 
 }
@@ -1135,6 +1153,7 @@ static const struct of_device_id fsl_esai_dt_ids[] = {
        { .compatible = "fsl,imx35-esai", .data = &fsl_esai_imx35 },
        { .compatible = "fsl,vf610-esai", .data = &fsl_esai_vf610 },
        { .compatible = "fsl,imx6ull-esai", .data = &fsl_esai_imx6ull },
+       { .compatible = "fsl,imx8qm-esai", .data = &fsl_esai_imx8qm },
        {}
 };
 MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);