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: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
Liam Girdwood 2014-05-02 16:56:33 +01:00 committed by Mark Brown
parent 916152c488
commit 51b4e24f38
3 changed files with 29 additions and 7 deletions

View File

@ -1547,10 +1547,28 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
} }
/* Stream pointer positions */ /* 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) 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, int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,

View File

@ -464,7 +464,9 @@ int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw,
struct sst_hsw_stream *stream, u32 *position); struct sst_hsw_stream *stream, u32 *position);
int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
struct sst_hsw_stream *stream, u32 stage_id, u32 position); 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); struct sst_hsw_stream *stream);
/* HW port config */ /* HW port config */

View File

@ -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 hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
struct sst_hsw *hsw = pdata->hsw; struct sst_hsw *hsw = pdata->hsw;
snd_pcm_uframes_t offset; snd_pcm_uframes_t offset;
uint64_t ppos;
u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);
offset = bytes_to_frames(runtime, offset = bytes_to_frames(runtime, position);
sst_hsw_get_dsp_position(hsw, pcm_data->stream)); ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);
dev_dbg(rtd->dev, "PCM: DMA pointer %zu bytes\n", dev_dbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n",
frames_to_bytes(runtime, (u32)offset)); position, ppos);
return offset; return offset;
} }