aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc-dai.h6
-rw-r--r--include/sound/soc.h7
-rw-r--r--sound/soc/soc-core.c18
3 files changed, 31 insertions, 0 deletions
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 20de0bcaa13..6cf76a41501 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -182,6 +182,12 @@ struct snd_soc_dai_ops {
struct snd_soc_dai *);
int (*trigger)(struct snd_pcm_substream *, int,
struct snd_soc_dai *);
+ /*
+ * For hardware based FIFO caused delay reporting.
+ * Optional.
+ */
+ snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
+ struct snd_soc_dai *);
};
/*
diff --git a/include/sound/soc.h b/include/sound/soc.h
index f792c1881b0..dbfec16015d 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -470,6 +470,13 @@ struct snd_soc_platform {
struct snd_pcm *);
void (*pcm_free)(struct snd_pcm *);
+ /*
+ * For platform caused delay reporting.
+ * Optional.
+ */
+ snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
+ struct snd_soc_dai *);
+
/* platform stream ops */
struct snd_pcm_ops *pcm_ops;
};
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index feb572c616c..4011ad3dc57 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -802,6 +802,8 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
/*
* soc level wrapper for pointer callback
+ * If cpu_dai, codec_dai, platform driver has the delay callback, than
+ * the runtime->delay will be updated accordingly.
*/
static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
{
@@ -809,11 +811,27 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_card *card = socdev->card;
struct snd_soc_platform *platform = card->platform;
+ struct snd_soc_dai_link *machine = rtd->dai;
+ struct snd_soc_dai *cpu_dai = machine->cpu_dai;
+ struct snd_soc_dai *codec_dai = machine->codec_dai;
+ struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_uframes_t offset = 0;
+ snd_pcm_sframes_t delay = 0;
if (platform->pcm_ops->pointer)
offset = platform->pcm_ops->pointer(substream);
+ if (cpu_dai->ops->delay)
+ delay += cpu_dai->ops->delay(substream, cpu_dai);
+
+ if (codec_dai->ops->delay)
+ delay += codec_dai->ops->delay(substream, codec_dai);
+
+ if (platform->delay)
+ delay += platform->delay(substream, codec_dai);
+
+ runtime->delay = delay;
+
return offset;
}