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

Commit 51b4e24f authored by Liam Girdwood's avatar Liam Girdwood Committed by Mark Brown
Browse files

ASoC: Intel: Fix stream position pointer.



Read the stream offset and presentation position from DSP memory rather
than using the old estimated position. This fixes timing issues with
pulseaudio.

Signed-off-by: default avatarLiam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 916152c4
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -1547,10 +1547,28 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
}

/* Stream pointer positions */
int sst_hsw_get_dsp_position(struct sst_hsw *hsw,
u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw,
	struct sst_hsw_stream *stream)
{
	return stream->rpos.position;
	u32 rpos;

	sst_dsp_read(hsw->dsp, &rpos,
		stream->reply.read_position_register_address, sizeof(rpos));

	return rpos;
}

/* Stream presentation (monotonic) positions */
u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
	struct sst_hsw_stream *stream)
{
	u64 ppos;

	sst_dsp_read(hsw->dsp, &ppos,
		stream->reply.presentation_position_register_address,
		sizeof(ppos));

	return ppos;
}

int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
+3 −1
Original line number Diff line number Diff line
@@ -464,7 +464,9 @@ int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw,
	struct sst_hsw_stream *stream, u32 *position);
int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
	struct sst_hsw_stream *stream, u32 stage_id, u32 position);
int sst_hsw_get_dsp_position(struct sst_hsw *hsw,
u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw,
	struct sst_hsw_stream *stream);
u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
	struct sst_hsw_stream *stream);

/* HW port config */
+6 −4
Original line number Diff line number Diff line
@@ -569,12 +569,14 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
	struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
	struct sst_hsw *hsw = pdata->hsw;
	snd_pcm_uframes_t offset;
	uint64_t ppos;
	u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);

	offset = bytes_to_frames(runtime,
		sst_hsw_get_dsp_position(hsw, pcm_data->stream));
	offset = bytes_to_frames(runtime, position);
	ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);

	dev_dbg(rtd->dev, "PCM: DMA pointer %zu bytes\n",
		frames_to_bytes(runtime, (u32)offset));
	dev_dbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n",
		position, ppos);
	return offset;
}