From f61bddd3045e567f9b50efc31a5dff90fb67948e Mon Sep 17 00:00:00 2001 From: Gopikrishnaiah Anand Date: Fri, 30 May 2014 11:29:56 -0700 Subject: [PATCH 1/2] ASoC: pcm: Add support for compat mode When kernel is compiled for 64 bit and userspace client is in 32 bit mode compat ioctl path will be taken. If platform driver supports compat mode asoc framework should call compat function pointers. Change adds support in asoc framework to support compat mode. Change-Id: I4929bc89c2ad467cdc83f5a00fe9d38e425c3ca2 Signed-off-by: Gopikrishnaiah Anand Signed-off-by: Banajit Goswami Signed-off-by: Meng Wang --- sound/soc/soc-pcm.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 42f72c9b78ba..292f17f4fd7d 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2460,6 +2460,30 @@ out: return ret; } +#ifdef CONFIG_AUDIO_QGKI +static int soc_pcm_compat_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; + + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + + if (!component->driver->ops || + !component->driver->ops->compat_ioctl) + continue; + + /* FIXME: use 1st ioctl */ + return component->driver->ops->compat_ioctl( + substream, cmd, arg); + } + + return snd_pcm_lib_ioctl(substream, cmd, arg); +} +#endif + static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_pcm_substream *substream = @@ -2924,6 +2948,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) rtd->ops.close = dpcm_fe_dai_close; rtd->ops.pointer = soc_pcm_pointer; rtd->ops.ioctl = snd_soc_pcm_component_ioctl; +#ifdef CONFIG_AUDIO_QGKI + rtd->ops.compat_ioctl = soc_pcm_compat_ioctl; +#endif } else { rtd->ops.open = soc_pcm_open; rtd->ops.hw_params = soc_pcm_hw_params; @@ -2933,6 +2960,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) rtd->ops.close = soc_pcm_close; rtd->ops.pointer = soc_pcm_pointer; rtd->ops.ioctl = snd_soc_pcm_component_ioctl; +#ifdef CONFIG_AUDIO_QGKI + rtd->ops.compat_ioctl = soc_pcm_compat_ioctl; +#endif } for_each_rtdcom(rtd, rtdcom) { From d1eb1c28450f17694130d50d90d071cf2efd3eb2 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Thu, 7 Sep 2017 15:15:08 +0800 Subject: [PATCH 2/2] SoC: pcm: Add delay_blk feature Add delay_blk() to pcm, platform and DAI ops. The pcm delay_blk() op collects the audio DSP path delay from the low-level drivers and sets the runtime->delay field to their aggregate. Change-Id: Ib7e10f44ab8ccb46dc2f5825081d0afef662d827 Signed-off-by: Kenneth Westfield Signed-off-by: Meng Wang --- include/sound/pcm.h | 5 +++++ include/sound/soc-component.h | 12 ++++++++++- sound/soc/soc-pcm.c | 39 +++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 9576a47f2baf..b9863f650273 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -64,6 +64,11 @@ 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); +#ifdef CONFIG_AUDIO_QGKI + int (*delay_blk)(struct snd_pcm_substream *substream); + int (*wall_clock)(struct snd_pcm_substream *substream, + struct timespec *audio_ts); +#endif int (*fill_silence)(struct snd_pcm_substream *substream, int channel, unsigned long pos, unsigned long bytes); int (*copy_user)(struct snd_pcm_substream *substream, int channel, diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 5d80b2eef525..0077f46710e5 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -73,7 +73,17 @@ struct snd_soc_component_driver { int (*stream_event)(struct snd_soc_component *component, int event); int (*set_bias_level)(struct snd_soc_component *component, enum snd_soc_bias_level level); - +#ifdef CONFIG_AUDIO_QGKI + /* + * 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 *substream, + struct snd_soc_dai *dai); +#endif const struct snd_pcm_ops *ops; const struct snd_compr_ops *compr_ops; diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 292f17f4fd7d..38a705dae4de 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1113,6 +1113,10 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai; +#ifdef CONFIG_AUDIO_QGKI + struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; +#endif struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t offset = 0; snd_pcm_sframes_t delay = 0; @@ -1123,7 +1127,18 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) runtime->delay = 0; offset = snd_soc_pcm_component_pointer(substream); +#ifdef CONFIG_AUDIO_QGKI + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + if (!component->driver->ops || + !component->driver->ops->pointer) + continue; + + if (component->driver->delay_blk) + return offset; + } +#endif /* base delay if assigned in pointer callback */ delay = runtime->delay; @@ -1140,6 +1155,28 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) return offset; } +#ifdef CONFIG_AUDIO_QGKI +static int soc_pcm_delay_blk(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; + struct snd_pcm_runtime *runtime = substream->runtime; + snd_pcm_sframes_t delay = 0; + + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + + if (component->driver->delay_blk) + delay = component->driver->delay_blk(substream, + rtd->codec_dais[0]); + } + runtime->delay = delay; + + return 0; +} +#endif + /* connect a FE and BE */ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, struct snd_soc_pcm_runtime *be, int stream) @@ -2950,6 +2987,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) rtd->ops.ioctl = snd_soc_pcm_component_ioctl; #ifdef CONFIG_AUDIO_QGKI rtd->ops.compat_ioctl = soc_pcm_compat_ioctl; + rtd->ops.delay_blk = soc_pcm_delay_blk; #endif } else { rtd->ops.open = soc_pcm_open; @@ -2962,6 +3000,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) rtd->ops.ioctl = snd_soc_pcm_component_ioctl; #ifdef CONFIG_AUDIO_QGKI rtd->ops.compat_ioctl = soc_pcm_compat_ioctl; + rtd->ops.delay_blk = soc_pcm_delay_blk; #endif }