diff options
author | Kenneth Westfield <kwestfie@codeaurora.org> | 2015-05-19 12:03:55 -0700 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:11:06 -0700 |
commit | 579b5a94176cabd6a7b8f65f04426070f0513d15 (patch) | |
tree | b6980e6e75cbdd174301ff3109bf0b6037642f51 | |
parent | 27c55476251a73d77631e5bb1892b9e24c7c04b5 (diff) |
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>
-rw-r--r-- | include/sound/pcm.h | 5 | ||||
-rw-r--r-- | include/sound/soc.h | 10 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 21 |
3 files changed, 35 insertions, 1 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 6e98f4f08541..e1f4920053ed 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -80,10 +80,13 @@ struct snd_pcm_ops { struct timespec *system_ts, struct timespec *audio_ts, struct snd_pcm_audio_tstamp_config *audio_tstamp_config, 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, snd_pcm_uframes_t pos, void __user *buf, snd_pcm_uframes_t count); - int (*silence)(struct snd_pcm_substream *substream, int channel, + int (*silence)(struct snd_pcm_substream *substream, int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t count); struct page *(*page)(struct snd_pcm_substream *substream, unsigned long offset); diff --git a/include/sound/soc.h b/include/sound/soc.h index fa5a06590955..c51647e34221 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -941,6 +941,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; diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index cd14cbad3482..2373c065fa0c 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -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) 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); @@ -1191,6 +1194,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) @@ -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.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 { @@ -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.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; } |