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); > + > /* > * supported power states check > */ > diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h > index 23ca172..23bd1e7 100644 > --- a/sound/pci/hda/hda_codec.h > +++ b/sound/pci/hda/hda_codec.h > @@ -725,6 +725,8 @@ struct hda_codec_ops { > int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid); > #endif > void (*reboot_notify)(struct hda_codec *codec); > + unsigned int (*get_processing_delay)(struct hda_codec *codec, > + unsigned int stream); > }; > > /* record for amp information cache */ > @@ -1063,6 +1065,8 @@ void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); > void snd_hda_bus_reboot_notify(struct hda_bus *bus); > void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, > unsigned int power_state); > +unsigned int snd_hda_codec_processing_delay(struct hda_codec *codec, > + unsigned int stream); > > int snd_hda_lock_devices(struct hda_bus *bus); > void snd_hda_unlock_devices(struct hda_bus *bus); > diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c > index 418bfc0..422bfaf 100644 > --- a/sound/pci/hda/hda_intel.c > +++ b/sound/pci/hda/hda_intel.c > @@ -2349,6 +2349,7 @@ static unsigned int azx_get_position(struct azx *chip, > struct azx_dev *azx_dev, > bool with_check) > { > + struct azx_pcm *apcm = snd_pcm_substream_chip(azx_dev->substream); > unsigned int pos; > int stream = azx_dev->substream->stream; > int delay = 0; > @@ -2400,6 +2401,7 @@ static unsigned int azx_get_position(struct azx *chip, > chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY; > } > azx_dev->substream->runtime->delay = > + snd_hda_codec_processing_delay(apcm->codec, stream) + > bytes_to_frames(azx_dev->substream->runtime, delay); Isn't this a code path where CA0132 never takes? It's in the conditional block of AZX_DCAPS_COUNT_LPIB_DELAY. You need a patch like: index 418bfc0..5d53eea 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2399,9 +2399,12 @@ 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(azx_dev->substream->runtime, delay); } + + azx_dev->substream->runtime->delay = + delay + snd_hda_codec_processing_delay(apcm->codec, stream); + trace_azx_get_position(chip, azx_dev, pos, delay); return pos; } Takashi _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel