[ALSA] soc - Add device level DAPM event
authorLiam Girdwood <lg@opensource.wolfsonmicro.com>
Thu, 10 Jan 2008 13:36:20 +0000 (14:36 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 31 Jan 2008 16:29:50 +0000 (17:29 +0100)
Added a device level dapm event so that both the machine and codec are informed
when dapm events occur.

Signed-off-by: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
include/sound/soc-dapm.h
include/sound/soc.h
sound/soc/soc-core.c
sound/soc/soc-dapm.c

index b9d5864425181d98577f8c145dd7c0b98220f967..4158cbaa0f25dcb15e2c4477dc62402944d19a48 100644 (file)
@@ -199,6 +199,7 @@ void snd_soc_dapm_free(struct snd_soc_device *socdev);
 /* dapm events */
 int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream,
        int event);
+int snd_soc_dapm_device_event(struct snd_soc_device *socdev, int event);
 
 /* dapm sys fs - used by the core */
 int snd_soc_dapm_sys_add(struct device *dev);
index c22c65650405351f5241b2f13eba7d303cb8ac4c..add5f948e38318e6387cdce808d7b8b63b37ecfc 100644 (file)
@@ -425,6 +425,9 @@ struct snd_soc_machine {
        int (*resume_pre)(struct platform_device *pdev);
        int (*resume_post)(struct platform_device *pdev);
 
+       /* callbacks */
+       int (*dapm_event)(struct snd_soc_machine *, int event);
+
        /* CPU <--> Codec DAI links  */
        struct snd_soc_dai_link *dai_link;
        int num_links;
index 94075256638cbe0080843abd5865d23c02c137a6..bd656db347eeffaec849f9efbf6fc69268f13bee 100644 (file)
@@ -288,15 +288,16 @@ static void close_delayed_work(struct work_struct *work)
                if (codec_dai->pop_wait == 1) {
 
                        codec_dai->pop_wait = 0;
-                       snd_soc_dapm_stream_event(codec, codec_dai->playback.stream_name,
+                       snd_soc_dapm_stream_event(codec,
+                               codec_dai->playback.stream_name,
                                SND_SOC_DAPM_STREAM_STOP);
 
                        /* power down the codec power domain if no longer active */
                        if (codec->active == 0) {
                                dbg("pop wq D3 %s %s\n", codec->name,
                                        codec_dai->playback.stream_name);
-                               if (codec->dapm_event)
-                                       codec->dapm_event(codec, SNDRV_CTL_POWER_D3hot);
+                               snd_soc_dapm_device_event(socdev,
+                                       SNDRV_CTL_POWER_D3hot);
                        }
                }
        }
@@ -352,12 +353,12 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
        } else {
                /* capture streams can be powered down now */
                snd_soc_dapm_stream_event(codec,
-                       codec_dai->capture.stream_name, SND_SOC_DAPM_STREAM_STOP);
+                       codec_dai->capture.stream_name,
+                       SND_SOC_DAPM_STREAM_STOP);
 
-               if (codec->active == 0 && codec_dai->pop_wait == 0){
-                       if (codec->dapm_event)
-                               codec->dapm_event(codec, SNDRV_CTL_POWER_D3hot);
-               }
+               if (codec->active == 0 && codec_dai->pop_wait == 0)
+                       snd_soc_dapm_device_event(socdev,
+                                               SNDRV_CTL_POWER_D3hot);
        }
 
        mutex_unlock(&pcm_mutex);
@@ -432,8 +433,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
                /* no delayed work - do we need to power up codec */
                if (codec->dapm_state != SNDRV_CTL_POWER_D0) {
 
-                       if (codec->dapm_event)
-                               codec->dapm_event(codec, SNDRV_CTL_POWER_D1);
+                       snd_soc_dapm_device_event(socdev,  SNDRV_CTL_POWER_D1);
 
                        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                                snd_soc_dapm_stream_event(codec,
@@ -444,8 +444,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
                                        codec_dai->capture.stream_name,
                                        SND_SOC_DAPM_STREAM_START);
 
-                       if (codec->dapm_event)
-                               codec->dapm_event(codec, SNDRV_CTL_POWER_D0);
+                       snd_soc_dapm_device_event(socdev, SNDRV_CTL_POWER_D0);
                        if (codec_dai->dai_ops.digital_mute)
                                codec_dai->dai_ops.digital_mute(codec_dai, 0);
 
index 3b8f94af7e27c330684c948134e3d2ab4bb614a0..16ebb60ed3d4dc629f8cf7a30642bdaf5e417d61 100644 (file)
@@ -1278,6 +1278,29 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
 
+/**
+ * snd_soc_dapm_device_event - send a device event to the dapm core
+ * @socdev: audio device
+ * @event: device event
+ *
+ * Sends a device event to the dapm core. The core then makes any
+ * necessary machine or codec power changes..
+ *
+ * Returns 0 for success else error.
+ */
+int snd_soc_dapm_device_event(struct snd_soc_device *socdev, int event)
+{
+       struct snd_soc_codec *codec = socdev->codec;
+       struct snd_soc_machine *machine = socdev->machine;
+
+       if (machine->dapm_event)
+                               machine->dapm_event(machine, event);
+       if (codec->dapm_event)
+                               codec->dapm_event(codec, event);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dapm_device_event);
+
 /**
  * snd_soc_dapm_set_endpoint - set audio endpoint status
  * @codec: audio codec