summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/pcm.h5
-rw-r--r--include/sound/soc.h10
-rw-r--r--sound/soc/soc-pcm.c21
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;
}