#define SNDRV_PCM_INFO_MMAP_VALID      0x00000002      /* period data are valid during transfer */
 #define SNDRV_PCM_INFO_DOUBLE          0x00000004      /* Double buffering needed for PCM start/stop */
 #define SNDRV_PCM_INFO_BATCH           0x00000010      /* double buffering */
+#define SNDRV_PCM_INFO_SYNC_APPLPTR    0x00000020      /* need the explicit sync of appl_ptr update */
 #define SNDRV_PCM_INFO_INTERLEAVED     0x00000100      /* channels are interleaved */
 #define SNDRV_PCM_INFO_NONINTERLEAVED  0x00000200      /* channels are not interleaved */
 #define SNDRV_PCM_INFO_COMPLEX         0x00000400      /* complex frame organization (mmap only) */
 
        area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
        return 0;
 }
+
+static bool pcm_status_mmap_allowed(struct snd_pcm_file *pcm_file)
+{
+       if (pcm_file->no_compat_mmap)
+               return false;
+       /* Disallow the status/control mmap when SYNC_APPLPTR flag is set;
+        * it enforces the user-space to fall back to snd_pcm_sync_ptr(),
+        * thus it effectively assures the manual update of appl_ptr.
+        * In theory, it should be enough to disallow only PCM control mmap,
+        * but since the current alsa-lib implementation requires both status
+        * and control mmaps always paired, we have to disable both of them.
+        */
+       if (pcm_file->substream->runtime->hw.info & SNDRV_PCM_INFO_SYNC_APPLPTR)
+               return false;
+       return true;
+}
+
 #else /* ! coherent mmap */
 /*
  * don't support mmap for status and control records.
  */
+#define pcm_status_mmap_allowed(pcm_file)      false
+
 static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
                               struct vm_area_struct *area)
 {
        offset = area->vm_pgoff << PAGE_SHIFT;
        switch (offset) {
        case SNDRV_PCM_MMAP_OFFSET_STATUS:
-               if (pcm_file->no_compat_mmap)
+               if (!pcm_status_mmap_allowed(pcm_file))
                        return -ENXIO;
                return snd_pcm_mmap_status(substream, file, area);
        case SNDRV_PCM_MMAP_OFFSET_CONTROL:
-               if (pcm_file->no_compat_mmap)
+               if (!pcm_status_mmap_allowed(pcm_file))
                        return -ENXIO;
                return snd_pcm_mmap_control(substream, file, area);
        default: