Commit 21229613 authored by Takashi Iwai's avatar Takashi Iwai

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: default avatarTakashi Iwai <tiwai@suse.de>
parent 1dc669fe
...@@ -757,6 +757,9 @@ struct hda_pcm_ops { ...@@ -757,6 +757,9 @@ struct hda_pcm_ops {
struct snd_pcm_substream *substream); struct snd_pcm_substream *substream);
int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec, int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
struct snd_pcm_substream *substream); 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 */ /* PCM information for each substream */
......
...@@ -2349,8 +2349,11 @@ static unsigned int azx_get_position(struct azx *chip, ...@@ -2349,8 +2349,11 @@ static unsigned int azx_get_position(struct azx *chip,
struct azx_dev *azx_dev, struct azx_dev *azx_dev,
bool with_check) bool with_check)
{ {
struct snd_pcm_substream *substream = azx_dev->substream;
struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
unsigned int pos; unsigned int pos;
int stream = azx_dev->substream->stream; int stream = substream->stream;
struct hda_pcm_stream *hinfo = apcm->hinfo[stream];
int delay = 0; int delay = 0;
switch (chip->position_fix[stream]) { switch (chip->position_fix[stream]) {
...@@ -2381,7 +2384,7 @@ static unsigned int azx_get_position(struct azx *chip, ...@@ -2381,7 +2384,7 @@ static unsigned int azx_get_position(struct azx *chip,
pos = 0; pos = 0;
/* calculate runtime delay from LPIB */ /* calculate runtime delay from LPIB */
if (azx_dev->substream->runtime && if (substream->runtime &&
chip->position_fix[stream] == POS_FIX_POSBUF && chip->position_fix[stream] == POS_FIX_POSBUF &&
(chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) { (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB); unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB);
...@@ -2399,9 +2402,16 @@ static unsigned int azx_get_position(struct azx *chip, ...@@ -2399,9 +2402,16 @@ static unsigned int azx_get_position(struct azx *chip,
delay = 0; delay = 0;
chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY; chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
} }
azx_dev->substream->runtime->delay = delay = bytes_to_frames(substream->runtime, delay);
bytes_to_frames(azx_dev->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); trace_azx_get_position(chip, azx_dev, pos, delay);
return pos; return pos;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment