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: Kenneth Westfield <kwestfie@codeaurora.org>
This commit is contained in:
parent
27c5547625
commit
579b5a9417
3 changed files with 35 additions and 1 deletions
|
@ -80,6 +80,9 @@ struct snd_pcm_ops {
|
||||||
struct timespec *system_ts, struct timespec *audio_ts,
|
struct timespec *system_ts, struct timespec *audio_ts,
|
||||||
struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
|
struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
|
||||||
struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
|
struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
|
||||||
|
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,
|
int (*copy)(struct snd_pcm_substream *substream, int channel,
|
||||||
snd_pcm_uframes_t pos,
|
snd_pcm_uframes_t pos,
|
||||||
void __user *buf, snd_pcm_uframes_t count);
|
void __user *buf, snd_pcm_uframes_t count);
|
||||||
|
|
|
@ -941,6 +941,16 @@ struct snd_soc_platform_driver {
|
||||||
snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
|
snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
|
||||||
struct snd_soc_dai *);
|
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 */
|
/* platform stream pcm ops */
|
||||||
const struct snd_pcm_ops *ops;
|
const struct snd_pcm_ops *ops;
|
||||||
|
|
||||||
|
|
|
@ -1167,6 +1167,9 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
|
||||||
if (platform->driver->ops && platform->driver->ops->pointer)
|
if (platform->driver->ops && platform->driver->ops->pointer)
|
||||||
offset = platform->driver->ops->pointer(substream);
|
offset = platform->driver->ops->pointer(substream);
|
||||||
|
|
||||||
|
if (platform->driver->delay_blk)
|
||||||
|
return offset;
|
||||||
|
|
||||||
if (cpu_dai->driver->ops && cpu_dai->driver->ops->delay)
|
if (cpu_dai->driver->ops && cpu_dai->driver->ops->delay)
|
||||||
delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
|
delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
|
||||||
|
|
||||||
|
@ -1191,6 +1194,22 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
|
||||||
return offset;
|
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 */
|
/* connect a FE and BE */
|
||||||
static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
|
static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
|
||||||
struct snd_soc_pcm_runtime *be, int stream)
|
struct snd_soc_pcm_runtime *be, int stream)
|
||||||
|
@ -2722,6 +2741,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
|
||||||
rtd->ops.hw_free = dpcm_fe_dai_hw_free;
|
rtd->ops.hw_free = dpcm_fe_dai_hw_free;
|
||||||
rtd->ops.close = dpcm_fe_dai_close;
|
rtd->ops.close = dpcm_fe_dai_close;
|
||||||
rtd->ops.pointer = soc_pcm_pointer;
|
rtd->ops.pointer = soc_pcm_pointer;
|
||||||
|
rtd->ops.delay_blk = soc_pcm_delay_blk;
|
||||||
rtd->ops.ioctl = soc_pcm_ioctl;
|
rtd->ops.ioctl = soc_pcm_ioctl;
|
||||||
rtd->ops.compat_ioctl = soc_pcm_compat_ioctl;
|
rtd->ops.compat_ioctl = soc_pcm_compat_ioctl;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2732,6 +2752,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
|
||||||
rtd->ops.hw_free = soc_pcm_hw_free;
|
rtd->ops.hw_free = soc_pcm_hw_free;
|
||||||
rtd->ops.close = soc_pcm_close;
|
rtd->ops.close = soc_pcm_close;
|
||||||
rtd->ops.pointer = soc_pcm_pointer;
|
rtd->ops.pointer = soc_pcm_pointer;
|
||||||
|
rtd->ops.delay_blk = soc_pcm_delay_blk;
|
||||||
rtd->ops.ioctl = soc_pcm_ioctl;
|
rtd->ops.ioctl = soc_pcm_ioctl;
|
||||||
rtd->ops.compat_ioctl = soc_pcm_compat_ioctl;
|
rtd->ops.compat_ioctl = soc_pcm_compat_ioctl;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue