diff options
author | Peter Ujfalusi <peter.ujfalusi@nokia.com> | 2010-03-03 08:08:07 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-03-03 12:08:41 -0500 |
commit | 258020d0882e89c1462800a70eb414b8a4fec78c (patch) | |
tree | f2c9966e8d53db3c2fbf027407d45e2fd1b7f38d | |
parent | 377b6f62effcb91c53cd7ff8709a94d72d23b6ae (diff) |
ASoC: core: Add delay operation to snd_soc_dai_ops
The delay callback can be used by the core to query the delay
on the dai caused by FIFO or delay in the platform side.
In case if both CPU and CODEC dai has FIFO the delay reported
by each will be added to form the full delay on the chain.
If none of the dai has FIFO, than the delay will be kept as
zero.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | include/sound/soc-dai.h | 6 | ||||
-rw-r--r-- | include/sound/soc.h | 7 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 18 |
3 files changed, 31 insertions, 0 deletions
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 20de0bcaa137..6cf76a41501e 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h | |||
@@ -182,6 +182,12 @@ struct snd_soc_dai_ops { | |||
182 | struct snd_soc_dai *); | 182 | struct snd_soc_dai *); |
183 | int (*trigger)(struct snd_pcm_substream *, int, | 183 | int (*trigger)(struct snd_pcm_substream *, int, |
184 | struct snd_soc_dai *); | 184 | struct snd_soc_dai *); |
185 | /* | ||
186 | * For hardware based FIFO caused delay reporting. | ||
187 | * Optional. | ||
188 | */ | ||
189 | snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *, | ||
190 | struct snd_soc_dai *); | ||
185 | }; | 191 | }; |
186 | 192 | ||
187 | /* | 193 | /* |
diff --git a/include/sound/soc.h b/include/sound/soc.h index f792c1881b0a..dbfec16015de 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -470,6 +470,13 @@ struct snd_soc_platform { | |||
470 | struct snd_pcm *); | 470 | struct snd_pcm *); |
471 | void (*pcm_free)(struct snd_pcm *); | 471 | void (*pcm_free)(struct snd_pcm *); |
472 | 472 | ||
473 | /* | ||
474 | * For platform caused delay reporting. | ||
475 | * Optional. | ||
476 | */ | ||
477 | snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *, | ||
478 | struct snd_soc_dai *); | ||
479 | |||
473 | /* platform stream ops */ | 480 | /* platform stream ops */ |
474 | struct snd_pcm_ops *pcm_ops; | 481 | struct snd_pcm_ops *pcm_ops; |
475 | }; | 482 | }; |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index feb572c616cd..4011ad3dc57a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -802,6 +802,8 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
802 | 802 | ||
803 | /* | 803 | /* |
804 | * soc level wrapper for pointer callback | 804 | * soc level wrapper for pointer callback |
805 | * If cpu_dai, codec_dai, platform driver has the delay callback, than | ||
806 | * the runtime->delay will be updated accordingly. | ||
805 | */ | 807 | */ |
806 | static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) | 808 | static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) |
807 | { | 809 | { |
@@ -809,11 +811,27 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) | |||
809 | struct snd_soc_device *socdev = rtd->socdev; | 811 | struct snd_soc_device *socdev = rtd->socdev; |
810 | struct snd_soc_card *card = socdev->card; | 812 | struct snd_soc_card *card = socdev->card; |
811 | struct snd_soc_platform *platform = card->platform; | 813 | struct snd_soc_platform *platform = card->platform; |
814 | struct snd_soc_dai_link *machine = rtd->dai; | ||
815 | struct snd_soc_dai *cpu_dai = machine->cpu_dai; | ||
816 | struct snd_soc_dai *codec_dai = machine->codec_dai; | ||
817 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
812 | snd_pcm_uframes_t offset = 0; | 818 | snd_pcm_uframes_t offset = 0; |
819 | snd_pcm_sframes_t delay = 0; | ||
813 | 820 | ||
814 | if (platform->pcm_ops->pointer) | 821 | if (platform->pcm_ops->pointer) |
815 | offset = platform->pcm_ops->pointer(substream); | 822 | offset = platform->pcm_ops->pointer(substream); |
816 | 823 | ||
824 | if (cpu_dai->ops->delay) | ||
825 | delay += cpu_dai->ops->delay(substream, cpu_dai); | ||
826 | |||
827 | if (codec_dai->ops->delay) | ||
828 | delay += codec_dai->ops->delay(substream, codec_dai); | ||
829 | |||
830 | if (platform->delay) | ||
831 | delay += platform->delay(substream, codec_dai); | ||
832 | |||
833 | runtime->delay = delay; | ||
834 | |||
817 | return offset; | 835 | return offset; |
818 | } | 836 | } |
819 | 837 | ||