mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
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>
This commit is contained in:
parent
12ef193d58
commit
d45f6219d2
1 changed files with 28 additions and 37 deletions
|
@ -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
|
/* cancel any delayed stream shutdown that is pending */
|
||||||
* on an existing one stopping */
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||||
if (codec_dai->pop_wait) {
|
codec_dai->pop_wait) {
|
||||||
/* we are waiting for the delayed work to start */
|
codec_dai->pop_wait = 0;
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
|
cancel_delayed_work(&socdev->delayed_work);
|
||||||
snd_soc_dapm_stream_event(socdev->codec,
|
}
|
||||||
|
|
||||||
|
/* 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,
|
||||||
|
codec_dai->playback.stream_name,
|
||||||
|
SND_SOC_DAPM_STREAM_START);
|
||||||
|
else
|
||||||
|
snd_soc_dapm_stream_event(codec,
|
||||||
codec_dai->capture.stream_name,
|
codec_dai->capture.stream_name,
|
||||||
SND_SOC_DAPM_STREAM_START);
|
SND_SOC_DAPM_STREAM_START);
|
||||||
else {
|
|
||||||
codec_dai->pop_wait = 0;
|
snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
|
||||||
cancel_delayed_work(&socdev->delayed_work);
|
snd_soc_dai_digital_mute(codec_dai, 0);
|
||||||
snd_soc_dai_digital_mute(codec_dai, 0);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* no delayed work - do we need to power up codec */
|
/* codec already powered - power on widgets */
|
||||||
if (codec->bias_level != SND_SOC_BIAS_ON) {
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||||
|
snd_soc_dapm_stream_event(codec,
|
||||||
snd_soc_dapm_set_bias_level(socdev,
|
|
||||||
SND_SOC_BIAS_PREPARE);
|
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
||||||
snd_soc_dapm_stream_event(codec,
|
|
||||||
codec_dai->playback.stream_name,
|
codec_dai->playback.stream_name,
|
||||||
SND_SOC_DAPM_STREAM_START);
|
SND_SOC_DAPM_STREAM_START);
|
||||||
else
|
else
|
||||||
snd_soc_dapm_stream_event(codec,
|
snd_soc_dapm_stream_event(codec,
|
||||||
codec_dai->capture.stream_name,
|
codec_dai->capture.stream_name,
|
||||||
SND_SOC_DAPM_STREAM_START);
|
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_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,
|
|
||||||
codec_dai->playback.stream_name,
|
|
||||||
SND_SOC_DAPM_STREAM_START);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Reference in a new issue