Skip to content

Commit

Permalink
ASoC: Fix handling of DAPM suspend work
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Brown authored and Mark Brown committed Oct 30, 2008
1 parent 12ef193 commit d45f621
Showing 1 changed file with 23 additions and 32 deletions.
55 changes: 23 additions & 32 deletions sound/soc/soc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,51 +429,42 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
}
}

/* we only want to start a DAPM playback stream if we are not waiting
* on an existing one stopping */
if (codec_dai->pop_wait) {
/* we are waiting for the delayed work to start */
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
snd_soc_dapm_stream_event(socdev->codec,
codec_dai->capture.stream_name,
SND_SOC_DAPM_STREAM_START);
else {
codec_dai->pop_wait = 0;
cancel_delayed_work(&socdev->delayed_work);
snd_soc_dai_digital_mute(codec_dai, 0);
}
} else {
/* no delayed work - do we need to power up codec */
if (codec->bias_level != SND_SOC_BIAS_ON) {
/* cancel any delayed stream shutdown that is pending */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
codec_dai->pop_wait) {
codec_dai->pop_wait = 0;
cancel_delayed_work(&socdev->delayed_work);
}

snd_soc_dapm_set_bias_level(socdev,
SND_SOC_BIAS_PREPARE);
/* do we need to power up codec */
if (codec->bias_level != SND_SOC_BIAS_ON) {
snd_soc_dapm_set_bias_level(socdev,
SND_SOC_BIAS_PREPARE);

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_soc_dapm_stream_event(codec,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_soc_dapm_stream_event(codec,
codec_dai->playback.stream_name,
SND_SOC_DAPM_STREAM_START);
else
snd_soc_dapm_stream_event(codec,
else
snd_soc_dapm_stream_event(codec,
codec_dai->capture.stream_name,
SND_SOC_DAPM_STREAM_START);

snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
snd_soc_dai_digital_mute(codec_dai, 0);
snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
snd_soc_dai_digital_mute(codec_dai, 0);

} else {
/* codec already powered - power on widgets */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_soc_dapm_stream_event(codec,
} else {
/* codec already powered - power on widgets */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_soc_dapm_stream_event(codec,
codec_dai->playback.stream_name,
SND_SOC_DAPM_STREAM_START);
else
snd_soc_dapm_stream_event(codec,
else
snd_soc_dapm_stream_event(codec,
codec_dai->capture.stream_name,
SND_SOC_DAPM_STREAM_START);

snd_soc_dai_digital_mute(codec_dai, 0);
}
snd_soc_dai_digital_mute(codec_dai, 0);
}

out:
Expand Down

0 comments on commit d45f621

Please sign in to comment.