aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
authorMark Brown <broonie@sirena.org.uk>2008-10-14 08:58:36 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2008-10-30 10:34:03 -0400
commitd45f6219d256b4e02f9ebee2e3911f4ea80bac70 (patch)
treef738eaaf5dc222743682e5f8f98a1ec6a3c84b40 /sound/soc/soc-core.c
parent12ef193d5817504621e503e78d641265f6a86ac4 (diff)
ASoC: Fix handling of DAPM suspend work
Since we can query the playback stream power state directly we do not need to infer if it is powered up from the timer being scheduled. Doing this avoids problems that previously existed with streams being incorrectly determined to be powered up caused when the timer is scheduled when streams are closed after being partially set up. Reported-by: Nobin Mathew <nobin.mathew@gmail.com> Reported-by: Jukka Hynninen <ext-jukka.hynninen@vaisala.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c55
1 files changed, 23 insertions, 32 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4707042b3dad..411fd3bcf44f 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -429,51 +429,42 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
429 } 429 }
430 } 430 }
431 431
432 /* we only want to start a DAPM playback stream if we are not waiting 432 /* cancel any delayed stream shutdown that is pending */
433 * on an existing one stopping */ 433 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
434 if (codec_dai->pop_wait) { 434 codec_dai->pop_wait) {
435 /* we are waiting for the delayed work to start */ 435 codec_dai->pop_wait = 0;
436 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 436 cancel_delayed_work(&socdev->delayed_work);
437 snd_soc_dapm_stream_event(socdev->codec, 437 }
438 codec_dai->capture.stream_name,
439 SND_SOC_DAPM_STREAM_START);
440 else {
441 codec_dai->pop_wait = 0;
442 cancel_delayed_work(&socdev->delayed_work);
443 snd_soc_dai_digital_mute(codec_dai, 0);
444 }
445 } else {
446 /* no delayed work - do we need to power up codec */
447 if (codec->bias_level != SND_SOC_BIAS_ON) {
448 438
449 snd_soc_dapm_set_bias_level(socdev, 439 /* do we need to power up codec */
450 SND_SOC_BIAS_PREPARE); 440 if (codec->bias_level != SND_SOC_BIAS_ON) {
441 snd_soc_dapm_set_bias_level(socdev,
442 SND_SOC_BIAS_PREPARE);
451 443
452 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 444 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
453 snd_soc_dapm_stream_event(codec, 445 snd_soc_dapm_stream_event(codec,
454 codec_dai->playback.stream_name, 446 codec_dai->playback.stream_name,
455 SND_SOC_DAPM_STREAM_START); 447 SND_SOC_DAPM_STREAM_START);
456 else 448 else
457 snd_soc_dapm_stream_event(codec, 449 snd_soc_dapm_stream_event(codec,
458 codec_dai->capture.stream_name, 450 codec_dai->capture.stream_name,
459 SND_SOC_DAPM_STREAM_START); 451 SND_SOC_DAPM_STREAM_START);
460 452
461 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON); 453 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
462 snd_soc_dai_digital_mute(codec_dai, 0); 454 snd_soc_dai_digital_mute(codec_dai, 0);
463 455
464 } else { 456 } else {
465 /* codec already powered - power on widgets */ 457 /* codec already powered - power on widgets */
466 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 458 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
467 snd_soc_dapm_stream_event(codec, 459 snd_soc_dapm_stream_event(codec,
468 codec_dai->playback.stream_name, 460 codec_dai->playback.stream_name,
469 SND_SOC_DAPM_STREAM_START); 461 SND_SOC_DAPM_STREAM_START);
470 else 462 else
471 snd_soc_dapm_stream_event(codec, 463 snd_soc_dapm_stream_event(codec,
472 codec_dai->capture.stream_name, 464 codec_dai->capture.stream_name,
473 SND_SOC_DAPM_STREAM_START); 465 SND_SOC_DAPM_STREAM_START);
474 466
475 snd_soc_dai_digital_mute(codec_dai, 0); 467 snd_soc_dai_digital_mute(codec_dai, 0);
476 }
477 } 468 }
478 469
479out: 470out: