diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 4a6a631b5a7f..ead7dea4bc2b 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -123,6 +123,11 @@ struct snd_pcm_ops { #define SNDRV_PCM_POS_XRUN ((snd_pcm_uframes_t)-1) +#define SNDRV_DMA_MODE (0) +#define SNDRV_NON_DMA_MODE (1 << 0) +#define SNDRV_RENDER_STOPPED (1 << 1) +#define SNDRV_RENDER_RUNNING (1 << 2) + /* If you change this don't forget to change rates[] table in pcm_native.c */ #define SNDRV_PCM_RATE_5512 (1<<0) /* 5512Hz */ #define SNDRV_PCM_RATE_8000 (1<<1) /* 8000Hz */ @@ -390,6 +395,7 @@ struct snd_pcm_runtime { unsigned int rate_num; unsigned int rate_den; unsigned int no_period_wakeup: 1; + unsigned int render_flag; /* -- SW params -- */ int tstamp_mode; /* mmap timestamp is updated */ diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index c049f639061f..47725555fe34 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -2728,6 +2728,7 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream, volatile struct snd_pcm_mmap_status *status; volatile struct snd_pcm_mmap_control *control; int err; + snd_pcm_uframes_t hw_avail; memset(&sync_ptr, 0, sizeof(sync_ptr)); if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags))) @@ -2756,6 +2757,16 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream, control->avail_min = sync_ptr.c.control.avail_min; else sync_ptr.c.control.avail_min = control->avail_min; + + if (runtime->render_flag & SNDRV_NON_DMA_MODE) { + hw_avail = snd_pcm_playback_hw_avail(runtime); + if ((hw_avail >= runtime->start_threshold) + && (runtime->render_flag & + SNDRV_RENDER_STOPPED)) { + if (substream->ops->restart) + substream->ops->restart(substream); + } + } sync_ptr.s.status.state = status->state; sync_ptr.s.status.hw_ptr = status->hw_ptr; sync_ptr.s.status.tstamp = status->tstamp;