Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32c2ea1f authored by Kenneth Westfield's avatar Kenneth Westfield
Browse files

ASoC: pcm: Add delay_blk feature



Add delay_blk() to pcm, platform and DAI ops.
The pcm delay_blk() op collects the audio DSP path
delays from the low-level drivers and sets the
runtime->delay field to their aggregate.

Change-Id: Ib7e10f44ab8ccb46dc2f5825081d0afef662d827
Signed-off-by: default avatarKenneth Westfield <kwestfie@codeaurora.org>
parent a5f9d251
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ struct snd_pcm_ops {
	int (*prepare)(struct snd_pcm_substream *substream);
	int (*trigger)(struct snd_pcm_substream *substream, int cmd);
	snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *substream);
	int (*delay_blk)(struct snd_pcm_substream *substream);
	int (*wall_clock)(struct snd_pcm_substream *substream,
			  struct timespec *audio_ts);
	int (*copy)(struct snd_pcm_substream *substream, int channel,
+10 −0
Original line number Diff line number Diff line
@@ -907,6 +907,16 @@ struct snd_soc_platform_driver {
	snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
		struct snd_soc_dai *);

	/*
	 * For platform-caused delay reporting, where the thread blocks waiting
	 * for the delay amount to be determined.  Defining this will cause the
	 * ASoC core to skip calling the delay callbacks for all components in
	 * the runtime.
	 * Optional.
	 */
	snd_pcm_sframes_t (*delay_blk)(struct snd_pcm_substream *,
		struct snd_soc_dai *);

	/* platform stream pcm ops */
	const struct snd_pcm_ops *ops;

+21 −0
Original line number Diff line number Diff line
@@ -1128,6 +1128,9 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
	if (platform->driver->ops && platform->driver->ops->pointer)
		offset = platform->driver->ops->pointer(substream);

	if (platform->driver->delay_blk)
		return offset;

	if (cpu_dai->driver->ops && cpu_dai->driver->ops->delay)
		delay += cpu_dai->driver->ops->delay(substream, cpu_dai);

@@ -1152,6 +1155,22 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
	return offset;
}

static int soc_pcm_delay_blk(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_platform *platform = rtd->platform;
	struct snd_pcm_runtime *runtime = substream->runtime;
	snd_pcm_sframes_t delay = 0;

	if (platform->driver->delay_blk)
		delay = platform->driver->delay_blk(substream,
				rtd->codec_dais[0]);

	runtime->delay = delay;

	return 0;
}

/* connect a FE and BE */
static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
		struct snd_soc_pcm_runtime *be, int stream)
@@ -2630,6 +2649,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
		rtd->ops.hw_free	= dpcm_fe_dai_hw_free;
		rtd->ops.close		= dpcm_fe_dai_close;
		rtd->ops.pointer	= soc_pcm_pointer;
		rtd->ops.delay_blk	= soc_pcm_delay_blk;
		rtd->ops.ioctl		= soc_pcm_ioctl;
		rtd->ops.compat_ioctl   = soc_pcm_compat_ioctl;
	} else {
@@ -2640,6 +2660,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
		rtd->ops.hw_free	= soc_pcm_hw_free;
		rtd->ops.close		= soc_pcm_close;
		rtd->ops.pointer	= soc_pcm_pointer;
		rtd->ops.delay_blk	= soc_pcm_delay_blk;
		rtd->ops.ioctl		= soc_pcm_ioctl;
		rtd->ops.compat_ioctl   = soc_pcm_compat_ioctl;
	}