Loading include/sound/pcm.h +5 −0 Original line number Diff line number Diff line Loading @@ -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, Loading include/sound/soc-component.h +11 −1 Original line number Diff line number Diff line Loading @@ -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; Loading sound/soc/soc-pcm.c +69 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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) Loading Loading @@ -2460,6 +2497,30 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) 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 = Loading Loading @@ -2924,6 +2985,10 @@ 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; rtd->ops.delay_blk = soc_pcm_delay_blk; #endif } else { rtd->ops.open = soc_pcm_open; rtd->ops.hw_params = soc_pcm_hw_params; Loading @@ -2933,6 +2998,10 @@ 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; rtd->ops.delay_blk = soc_pcm_delay_blk; #endif } for_each_rtdcom(rtd, rtdcom) { Loading Loading
include/sound/pcm.h +5 −0 Original line number Diff line number Diff line Loading @@ -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, Loading
include/sound/soc-component.h +11 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
sound/soc/soc-pcm.c +69 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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) Loading Loading @@ -2460,6 +2497,30 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) 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 = Loading Loading @@ -2924,6 +2985,10 @@ 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; rtd->ops.delay_blk = soc_pcm_delay_blk; #endif } else { rtd->ops.open = soc_pcm_open; rtd->ops.hw_params = soc_pcm_hw_params; Loading @@ -2933,6 +2998,10 @@ 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; rtd->ops.delay_blk = soc_pcm_delay_blk; #endif } for_each_rtdcom(rtd, rtdcom) { Loading