ASoC: davinci-mcasp: Add support for FIFO usage caused delay reporting
authorPeter Ujfalusi <peter.ujfalusi@ti.com>
Fri, 31 Aug 2018 08:24:56 +0000 (11:24 +0300)
committerMark Brown <broonie@kernel.org>
Fri, 31 Aug 2018 10:31:03 +0000 (11:31 +0100)
McASP have write and read FIFO, each 64 words deep.

From the WFIFOS/RFIFOS registers we can read the amount of data currently
in the FIFO which can be directly reported as delay.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/davinci/davinci-mcasp.c

index f70db8412c7ccb17915b7cf914677d2e1da24f70..267aee776b2d54d5a3fcb76f24d09148e08a3134 100644 (file)
@@ -1041,6 +1041,42 @@ static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp,
        return error_ppm;
 }
 
+static inline u32 davinci_mcasp_tx_delay(struct davinci_mcasp *mcasp)
+{
+       if (!mcasp->txnumevt)
+               return 0;
+
+       return mcasp_get_reg(mcasp, mcasp->fifo_base + MCASP_WFIFOSTS_OFFSET);
+}
+
+static inline u32 davinci_mcasp_rx_delay(struct davinci_mcasp *mcasp)
+{
+       if (!mcasp->rxnumevt)
+               return 0;
+
+       return mcasp_get_reg(mcasp, mcasp->fifo_base + MCASP_RFIFOSTS_OFFSET);
+}
+
+static snd_pcm_sframes_t davinci_mcasp_delay(
+                       struct snd_pcm_substream *substream,
+                       struct snd_soc_dai *cpu_dai)
+{
+       struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
+       u32 fifo_use;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               fifo_use = davinci_mcasp_tx_delay(mcasp);
+       else
+               fifo_use = davinci_mcasp_rx_delay(mcasp);
+
+       /*
+        * Divide the used locations with the channel count to get the
+        * FIFO usage in samples (don't care about partial samples in the
+        * buffer).
+        */
+       return fifo_use / substream->runtime->channels;
+}
+
 static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
                                        struct snd_pcm_hw_params *params,
                                        struct snd_soc_dai *cpu_dai)
@@ -1365,6 +1401,7 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
        .startup        = davinci_mcasp_startup,
        .shutdown       = davinci_mcasp_shutdown,
        .trigger        = davinci_mcasp_trigger,
+       .delay          = davinci_mcasp_delay,
        .hw_params      = davinci_mcasp_hw_params,
        .set_fmt        = davinci_mcasp_set_dai_fmt,
        .set_clkdiv     = davinci_mcasp_set_clkdiv,