]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - sound/soc/soc-core.c
[ALSA] ASoC: Clarify API for bias configuration
[karo-tx-linux.git] / sound / soc / soc-core.c
index 7d51be8ee069c6e1779f20f150afdf3482a5c170..a05b3450aee86bf75f552de50ac79c25caf90541 100644 (file)
  *  Free Software Foundation;  either version 2 of the  License, or (at your
  *  option) any later version.
  *
- *  Revision history
- *    12th Aug 2005   Initial version.
- *    25th Oct 2005   Working Codec, Interface and Platform registration.
- *
  *  TODO:
  *   o Add hw rules to enforce rates, etc.
  *   o More testing with other codecs/machines.
@@ -287,12 +283,12 @@ static void close_delayed_work(struct work_struct *work)
                /* are we waiting on this codec DAI stream */
                if (codec_dai->pop_wait == 1) {
 
-                       /* power down the codec to D1 if no longer active */
+                       /* Reduce power if no longer active */
                        if (codec->active == 0) {
                                dbg("pop wq D1 %s %s\n", codec->name,
                                        codec_dai->playback.stream_name);
-                               snd_soc_dapm_device_event(socdev,
-                                       SNDRV_CTL_POWER_D1);
+                               snd_soc_dapm_set_bias_level(socdev,
+                                       SND_SOC_BIAS_PREPARE);
                        }
 
                        codec_dai->pop_wait = 0;
@@ -300,12 +296,12 @@ static void close_delayed_work(struct work_struct *work)
                                codec_dai->playback.stream_name,
                                SND_SOC_DAPM_STREAM_STOP);
 
-                       /* power down the codec power domain if no longer active */
+                       /* Fall into standby if no longer active */
                        if (codec->active == 0) {
                                dbg("pop wq D3 %s %s\n", codec->name,
                                        codec_dai->playback.stream_name);
-                               snd_soc_dapm_device_event(socdev,
-                                       SNDRV_CTL_POWER_D3hot);
+                               snd_soc_dapm_set_bias_level(socdev,
+                                       SND_SOC_BIAS_STANDBY);
                        }
                }
        }
@@ -365,8 +361,8 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
                        SND_SOC_DAPM_STREAM_STOP);
 
                if (codec->active == 0 && codec_dai->pop_wait == 0)
-                       snd_soc_dapm_device_event(socdev,
-                                               SNDRV_CTL_POWER_D3hot);
+                       snd_soc_dapm_set_bias_level(socdev,
+                                               SND_SOC_BIAS_STANDBY);
        }
 
        mutex_unlock(&pcm_mutex);
@@ -439,9 +435,10 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
                }
        } else {
                /* no delayed work - do we need to power up codec */
-               if (codec->dapm_state != SNDRV_CTL_POWER_D0) {
+               if (codec->bias_level != SND_SOC_BIAS_ON) {
 
-                       snd_soc_dapm_device_event(socdev,  SNDRV_CTL_POWER_D1);
+                       snd_soc_dapm_set_bias_level(socdev,
+                                                   SND_SOC_BIAS_PREPARE);
 
                        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                                snd_soc_dapm_stream_event(codec,
@@ -452,7 +449,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
                                        codec_dai->capture.stream_name,
                                        SND_SOC_DAPM_STREAM_START);
 
-                       snd_soc_dapm_device_event(socdev, SNDRV_CTL_POWER_D0);
+                       snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
                        if (codec_dai->dai_ops.digital_mute)
                                codec_dai->dai_ops.digital_mute(codec_dai, 0);
 
@@ -645,6 +642,10 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
                        dai->dai_ops.digital_mute(dai, 1);
        }
 
+       /* suspend all pcms */
+       for (i = 0; i < machine->num_links; i++)
+               snd_pcm_suspend_all(machine->dai_link[i].pcm);
+
        if (machine->suspend_pre)
                machine->suspend_pre(pdev, state);
 
@@ -658,7 +659,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
 
        /* close any waiting streams and save state */
        run_delayed_work(&socdev->delayed_work);
-       codec->suspend_dapm_state = codec->dapm_state;
+       codec->suspend_bias_level = codec->bias_level;
 
        for(i = 0; i < codec->num_dai; i++) {
                char *stream = codec->dai[i].playback.stream_name;
@@ -835,6 +836,7 @@ static int soc_remove(struct platform_device *pdev)
 static struct platform_driver soc_driver = {
        .driver         = {
                .name           = "soc-audio",
+               .owner          = THIS_MODULE,
        },
        .probe          = soc_probe,
        .remove         = soc_remove,
@@ -879,6 +881,7 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
                return ret;
        }
 
+       dai_link->pcm = pcm;
        pcm->private_data = rtd;
        soc_pcm_ops.mmap = socdev->platform->pcm_ops->mmap;
        soc_pcm_ops.pointer = socdev->platform->pcm_ops->pointer;
@@ -1096,7 +1099,6 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
        struct snd_soc_machine *machine = socdev->machine;
        int ret = 0, i, ac97 = 0, err = 0;
 
-       mutex_lock(&codec->mutex);
        for(i = 0; i < machine->num_links; i++) {
                if (socdev->machine->dai_link[i].init) {
                        err = socdev->machine->dai_link[i].init(codec);
@@ -1122,12 +1124,14 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
                goto out;
        }
 
+       mutex_lock(&codec->mutex);
 #ifdef CONFIG_SND_SOC_AC97_BUS
        if (ac97) {
                ret = soc_ac97_dev_register(codec);
                if (ret < 0) {
                        printk(KERN_ERR "asoc: AC97 device register failed\n");
                        snd_card_free(codec->card);
+                       mutex_unlock(&codec->mutex);
                        goto out;
                }
        }
@@ -1140,8 +1144,10 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
        err = device_create_file(socdev->dev, &dev_attr_codec_reg);
        if (err < 0)
                printk(KERN_WARNING "asoc: failed to add codec sysfs entries\n");
-out:
+
        mutex_unlock(&codec->mutex);
+
+out:
        return ret;
 }
 EXPORT_SYMBOL_GPL(snd_soc_register_card);
@@ -1593,3 +1599,4 @@ module_exit(snd_soc_exit);
 MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
 MODULE_DESCRIPTION("ALSA SoC Core");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:soc-audio");