diff options
author | Liam Girdwood <liam.r.girdwood@linux.intel.com> | 2014-05-02 11:56:33 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-05-02 12:54:05 -0400 |
commit | 51b4e24f383c84ed927fef348072b6dc65b9816d (patch) | |
tree | d0818cfe74582d6152c4b094d915bd53c8f36333 | |
parent | 916152c48848290a8aba5cf4dd16c2a8a888e11c (diff) |
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>
-rw-r--r-- | sound/soc/intel/sst-haswell-ipc.c | 22 | ||||
-rw-r--r-- | sound/soc/intel/sst-haswell-ipc.h | 4 | ||||
-rw-r--r-- | sound/soc/intel/sst-haswell-pcm.c | 10 |
3 files changed, 29 insertions, 7 deletions
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index 5bcf5963a0ba..e7996b39a484 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c | |||
@@ -1547,10 +1547,28 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | |||
1547 | } | 1547 | } |
1548 | 1548 | ||
1549 | /* Stream pointer positions */ | 1549 | /* Stream pointer positions */ |
1550 | int sst_hsw_get_dsp_position(struct sst_hsw *hsw, | 1550 | u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw, |
1551 | struct sst_hsw_stream *stream) | 1551 | struct sst_hsw_stream *stream) |
1552 | { | 1552 | { |
1553 | return stream->rpos.position; | 1553 | u32 rpos; |
1554 | |||
1555 | sst_dsp_read(hsw->dsp, &rpos, | ||
1556 | stream->reply.read_position_register_address, sizeof(rpos)); | ||
1557 | |||
1558 | return rpos; | ||
1559 | } | ||
1560 | |||
1561 | /* Stream presentation (monotonic) positions */ | ||
1562 | u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw, | ||
1563 | struct sst_hsw_stream *stream) | ||
1564 | { | ||
1565 | u64 ppos; | ||
1566 | |||
1567 | sst_dsp_read(hsw->dsp, &ppos, | ||
1568 | stream->reply.presentation_position_register_address, | ||
1569 | sizeof(ppos)); | ||
1570 | |||
1571 | return ppos; | ||
1554 | } | 1572 | } |
1555 | 1573 | ||
1556 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, | 1574 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, |
diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h index d517929ccc38..2ac194a6d04b 100644 --- a/sound/soc/intel/sst-haswell-ipc.h +++ b/sound/soc/intel/sst-haswell-ipc.h | |||
@@ -464,7 +464,9 @@ int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw, | |||
464 | struct sst_hsw_stream *stream, u32 *position); | 464 | struct sst_hsw_stream *stream, u32 *position); |
465 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, | 465 | int sst_hsw_stream_set_write_position(struct sst_hsw *hsw, |
466 | struct sst_hsw_stream *stream, u32 stage_id, u32 position); | 466 | struct sst_hsw_stream *stream, u32 stage_id, u32 position); |
467 | int sst_hsw_get_dsp_position(struct sst_hsw *hsw, | 467 | u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw, |
468 | struct sst_hsw_stream *stream); | ||
469 | u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw, | ||
468 | struct sst_hsw_stream *stream); | 470 | struct sst_hsw_stream *stream); |
469 | 471 | ||
470 | /* HW port config */ | 472 | /* HW port config */ |
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 50fea077898b..8c6bd33dd375 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c | |||
@@ -569,12 +569,14 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream) | |||
569 | struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 569 | struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); |
570 | struct sst_hsw *hsw = pdata->hsw; | 570 | struct sst_hsw *hsw = pdata->hsw; |
571 | snd_pcm_uframes_t offset; | 571 | snd_pcm_uframes_t offset; |
572 | uint64_t ppos; | ||
573 | u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream); | ||
572 | 574 | ||
573 | offset = bytes_to_frames(runtime, | 575 | offset = bytes_to_frames(runtime, position); |
574 | sst_hsw_get_dsp_position(hsw, pcm_data->stream)); | 576 | ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream); |
575 | 577 | ||
576 | dev_dbg(rtd->dev, "PCM: DMA pointer %zu bytes\n", | 578 | dev_dbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n", |
577 | frames_to_bytes(runtime, (u32)offset)); | 579 | position, ppos); |
578 | return offset; | 580 | return offset; |
579 | } | 581 | } |
580 | 582 | ||