diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-04-05 07:27:45 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-04-05 07:33:32 +0200 |
commit | 21229613eff5b6241d27e2588d10588d5656d500 (patch) | |
tree | 8caab8a0c5f8c70c52f21d05fb811a7fdf85b0e9 /sound/pci | |
parent | 1dc669fed61a4ec4270a89e5fb3535802cc45668 (diff) |
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@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_codec.h | 3 | ||||
-rw-r--r-- | 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 23ca1722aff..c93f9021f45 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 418bfc0eb0a..735567e86f7 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; } |