Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21229613 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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 */
+14 −4
Original line number Diff line number Diff line
@@ -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;
}