At Thu, 4 Apr 2013 09:21:34 -0700, Dylan Reid wrote: > > On Thu, Apr 4, 2013 at 12:10 AM, Takashi Iwai <tiwai@xxxxxxx> wrote: > > At Wed, 3 Apr 2013 08:30:03 -0700, > > Dylan Reid wrote: > >> > >> Allow a codec to specify a delay in addition to the delay before > >> samples are passed through DMA. Some codecs have large processing > >> delays because of built-in DSPs that require codec-side buffers of > >> many milliseconds. Default to zero delay if the codec doesn't specify > >> a callback to get the processing delay. > >> > >> Signed-off-by: Dylan Reid <dgreid@xxxxxxxxxxxx> > >> --- > >> sound/pci/hda/hda_codec.c | 17 +++++++++++++++++ > >> sound/pci/hda/hda_codec.h | 4 ++++ > >> sound/pci/hda/hda_intel.c | 2 ++ > >> 3 files changed, 23 insertions(+) > >> > >> diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c > >> index 17286b3..1d792dd 100644 > >> --- a/sound/pci/hda/hda_codec.c > >> +++ b/sound/pci/hda/hda_codec.c > >> @@ -3724,6 +3724,23 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, > >> } > >> EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); > >> > >> +/** > >> + * snd_hda_codec_processing_delay - get the fixed delay through the codec > >> + * @codec: HD-audio codec > >> + * @stream: playback or capture > >> + * > >> + * This is needed for codecs that contain DSPs that cause long delays. > >> + */ > >> +unsigned int snd_hda_codec_processing_delay(struct hda_codec *codec, > >> + unsigned int stream) > >> +{ > >> + if (codec->patch_ops.get_processing_delay) > >> + return codec->patch_ops.get_processing_delay(codec, stream); > >> + > >> + return 0; > >> +} > >> +EXPORT_SYMBOL_HDA(snd_hda_codec_processing_delay); > > > > In the second thought, it would fit more better to pcm_ops than codec > > patch_ops. That is, the change would be like below. > > Yes this looks better. I'll modify the subsequent patch and run our > latency tests on it to make sure it works then resend based on this. I found a missing substream->runtime check (the function may be called even without running the PCM). The revised patch below was committed to for-next branch in the end. thanks, Takashi --- From: Takashi Iwai <tiwai@xxxxxxx> Subject: [PATCH] ALSA: hda - Introduce get_delay codec PCM ops Add a new codec PCM ops, get_delay(), to obtain the codec/stream- specific PCM delay count. When it's NULL, nothing changes. This new feature was requested for CA0132, which has significant delays in the path depending on the running DSP code. Signed-off-by: Takashi Iwai <tiwai@xxxxxxx> --- sound/pci/hda/hda_codec.h | 3 +++ sound/pci/hda/hda_intel.c | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 23ca172..c93f902 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -757,6 +757,9 @@ struct hda_pcm_ops { struct snd_pcm_substream *substream); int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec, struct snd_pcm_substream *substream); + unsigned int (*get_delay)(struct hda_pcm_stream *info, + struct hda_codec *codec, + struct snd_pcm_substream *substream); }; /* PCM information for each substream */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 418bfc0..735567e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2349,8 +2349,11 @@ static unsigned int azx_get_position(struct azx *chip, struct azx_dev *azx_dev, bool with_check) { + struct snd_pcm_substream *substream = azx_dev->substream; + struct azx_pcm *apcm = snd_pcm_substream_chip(substream); unsigned int pos; - int stream = azx_dev->substream->stream; + int stream = substream->stream; + struct hda_pcm_stream *hinfo = apcm->hinfo[stream]; int delay = 0; switch (chip->position_fix[stream]) { @@ -2381,7 +2384,7 @@ static unsigned int azx_get_position(struct azx *chip, pos = 0; /* calculate runtime delay from LPIB */ - if (azx_dev->substream->runtime && + if (substream->runtime && chip->position_fix[stream] == POS_FIX_POSBUF && (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) { unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB); @@ -2399,9 +2402,16 @@ static unsigned int azx_get_position(struct azx *chip, delay = 0; chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY; } - azx_dev->substream->runtime->delay = - bytes_to_frames(azx_dev->substream->runtime, delay); + delay = bytes_to_frames(substream->runtime, delay); } + + if (substream->runtime) { + if (hinfo->ops.get_delay) + delay += hinfo->ops.get_delay(hinfo, apcm->codec, + substream); + substream->runtime->delay = delay; + } + trace_azx_get_position(chip, azx_dev, pos, delay); return pos; } -- 1.8.1.4 _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel