alsa/0012-pcm-dmix-resume-workaround-for-buggy-driver.patch
Ismail Dönmez d51e946615 Accepting request 400689 from home:tiwai:branches:multimedia:libs
- Backport upstream fixes: fixing PCM dmix & co suspend/resume,
  namehint parser fixes, stackable async handler:
  0007-namehint-Don-t-enumerate-as-duplex-if-only-a-single-.patch
  0008-pcm-Define-namehint-for-single-directional-PCM-types.patch
  0009-conf-Add-thread-safe-global-tree-reference.patch
  0010-pcm-Remove-resume-support-from-dmix-co.patch
  0011-pcm-Fix-secondary-retry-in-dsnoop-and-dshare.patch
  0012-pcm-dmix-resume-workaround-for-buggy-driver.patch
  0013-pcm-dmix-Prepare-slave-when-it-s-in-SETUP-too.patch
  0014-pcm-dmix-Return-error-when-slave-is-in-OPEN-or-DISCO.patch
  0015-async-Handle-previously-installed-signal-handler.patch

OBS-URL: https://build.opensuse.org/request/show/400689
OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=198
2016-06-08 17:12:10 +00:00

73 lines
2.5 KiB
Diff

From 6d1d620eadf32c6d963468ce56ff52cc3a2f32e2 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Wed, 25 May 2016 15:03:51 +0200
Subject: [PATCH 12/15] pcm: dmix: resume workaround for buggy driver
The previous commit removed the whole handling of resume in dmix, but
this seems causing another regression; some buggy drivers assume that
the device-resume needs to be triggered before transitioning to
PREPARED state. As an ugly workaround, in this patch, when the slave
PCM supports resume, snd_pcm_direct_resume() does resume of the slave
PCM but immediately drop the stream after that. In that way, the
device is brought to the sane active state, then the apps can prepare
and restart the stream properly.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/pcm/pcm_direct.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
index 53c49929cb1f..343fd3c6da3c 100644
--- a/src/pcm/pcm_direct.c
+++ b/src/pcm/pcm_direct.c
@@ -837,6 +837,27 @@ int snd_pcm_direct_prepare(snd_pcm_t *pcm)
int snd_pcm_direct_resume(snd_pcm_t *pcm)
{
+ snd_pcm_direct_t *dmix = pcm->private_data;
+ snd_pcm_t *spcm = dmix->spcm;
+
+ snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
+ /* some buggy drivers require the device resumed before prepared;
+ * when a device has RESUME flag and is in SUSPENDED state, resume
+ * here but immediately drop to bring it to a sane active state.
+ */
+ if ((spcm->info & SND_PCM_INFO_RESUME) &&
+ snd_pcm_state(spcm) == SND_PCM_STATE_SUSPENDED) {
+ snd_pcm_resume(spcm);
+ snd_pcm_drop(spcm);
+ snd_pcm_direct_timer_stop(dmix);
+ snd_pcm_direct_clear_timer_queue(dmix);
+ snd_pcm_areas_silence(snd_pcm_mmap_areas(spcm), 0,
+ spcm->channels, spcm->buffer_size,
+ spcm->format);
+ snd_pcm_prepare(spcm);
+ snd_pcm_start(spcm);
+ }
+ snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
return -ENOSYS;
}
@@ -845,7 +866,7 @@ int snd_pcm_direct_resume(snd_pcm_t *pcm)
/* copy the slave setting */
static void save_slave_setting(snd_pcm_direct_t *dmix, snd_pcm_t *spcm)
{
- spcm->info &= ~(SND_PCM_INFO_PAUSE | SND_PCM_INFO_RESUME);
+ spcm->info &= ~SND_PCM_INFO_PAUSE;
COPY_SLAVE(access);
COPY_SLAVE(format);
@@ -874,6 +895,8 @@ static void save_slave_setting(snd_pcm_direct_t *dmix, snd_pcm_t *spcm)
COPY_SLAVE(buffer_time);
COPY_SLAVE(sample_bits);
COPY_SLAVE(frame_bits);
+
+ dmix->shmptr->s.info &= ~SND_PCM_INFO_RESUME;
}
#undef COPY_SLAVE
--
2.8.3