summaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-05-17 22:41:23 +0200
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-05-18 16:53:16 +0200
commit452c5eaa0d5162e02ffee742ea17540887bc2904 (patch)
tree7dbac625d69e3ff01445d7f1b1fa321aa35fcae5 /sound/soc/soc-core.c
parentASoC: Make DAPM sysfs entries non-optional (diff)
downloadlinux-452c5eaa0d5162e02ffee742ea17540887bc2904.tar.xz
linux-452c5eaa0d5162e02ffee742ea17540887bc2904.zip
ASoC: Integrate bias management with DAPM power management
Rather than managing the bias level of the system based on if there is an active audio stream manage it based on there being an active DAPM widget. This simplifies the code a little, moving the power handling into one place, and improves audio performance for bypass paths when no playbacks or captures are active. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c61
1 files changed, 10 insertions, 51 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c0e706645ec4..4aa8e2d35061 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -299,7 +299,6 @@ static void close_delayed_work(struct work_struct *work)
{
struct snd_soc_card *card = container_of(work, struct snd_soc_card,
delayed_work.work);
- struct snd_soc_device *socdev = card->socdev;
struct snd_soc_codec *codec = card->codec;
struct snd_soc_dai *codec_dai;
int i;
@@ -315,27 +314,10 @@ static void close_delayed_work(struct work_struct *work)
/* are we waiting on this codec DAI stream */
if (codec_dai->pop_wait == 1) {
-
- /* Reduce power if no longer active */
- if (codec->active == 0) {
- pr_debug("pop wq D1 %s %s\n", codec->name,
- codec_dai->playback.stream_name);
- snd_soc_dapm_set_bias_level(socdev,
- SND_SOC_BIAS_PREPARE);
- }
-
codec_dai->pop_wait = 0;
snd_soc_dapm_stream_event(codec,
codec_dai->playback.stream_name,
SND_SOC_DAPM_STREAM_STOP);
-
- /* Fall into standby if no longer active */
- if (codec->active == 0) {
- pr_debug("pop wq D3 %s %s\n", codec->name,
- codec_dai->playback.stream_name);
- snd_soc_dapm_set_bias_level(socdev,
- SND_SOC_BIAS_STANDBY);
- }
}
}
mutex_unlock(&pcm_mutex);
@@ -399,10 +381,6 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
snd_soc_dapm_stream_event(codec,
codec_dai->capture.stream_name,
SND_SOC_DAPM_STREAM_STOP);
-
- if (codec->active == 0 && codec_dai->pop_wait == 0)
- snd_soc_dapm_set_bias_level(socdev,
- SND_SOC_BIAS_STANDBY);
}
mutex_unlock(&pcm_mutex);
@@ -467,36 +445,16 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
cancel_delayed_work(&card->delayed_work);
}
- /* 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,
- SND_SOC_DAPM_STREAM_START);
-
- 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,
- 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);
+ 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);
- }
+ snd_soc_dai_digital_mute(codec_dai, 0);
out:
mutex_unlock(&pcm_mutex);
@@ -1372,6 +1330,7 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
return ret;
}
+ codec->socdev = socdev;
codec->card->dev = socdev->dev;
codec->card->private_data = codec;
strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver));