@@ -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 *);
};
/*
@@ -469,6 +469,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;
};
@@ -799,6 +799,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)
{
@@ -806,11 +808,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;
}