Merge "SoC: pcm: Add delay_blk feature"

This commit is contained in:
qctecmdr 2019-12-30 13:08:31 -08:00 • committed by Gerrit - the friendly Code Review server
commit fcd01ea326
3 changed files with 85 additions and 1 deletions

View file

@ -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,

View file

@ -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;

View file

@ -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)
@ -2460,6 +2497,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 +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;
@ -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) {