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>
This commit is contained in:
Родитель
1dc669fed6
Коммит
21229613ef
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче