aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci/davinci-mcasp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/davinci/davinci-mcasp.c')
-rw-r--r--sound/soc/davinci/davinci-mcasp.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index f70db8412c7c..267aee776b2d 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -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,