ASoC: dapm: Treat DAI widgets like AIF widgets for power
Mark Brown [Wed, 5 Jun 2013 18:36:11 +0000 (19:36 +0100)]
Even though they are virtual widgets DAI widgets still get counted for the
DAPM context power management so we can't just use the active state to
check if they should be powered as they may not be part of a complete path.

Instead split them into input and output widgets and do the same power
checks as we perform on AIFs.

Reported-by: Stephen Warren <swarren@nvidia.com>
Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Mark Brown <broonie@linaro.org>

include/sound/soc-dapm.h
sound/soc/soc-dapm.c
sound/soc/soc-pcm.c

index d460902..385c632 100644 (file)
@@ -450,7 +450,8 @@ enum snd_soc_dapm_type {
        snd_soc_dapm_aif_in,            /* audio interface input */
        snd_soc_dapm_aif_out,           /* audio interface output */
        snd_soc_dapm_siggen,            /* signal generator */
-       snd_soc_dapm_dai,               /* link to DAI structure */
+       snd_soc_dapm_dai_in,            /* link to DAI structure */
+       snd_soc_dapm_dai_out,
        snd_soc_dapm_dai_link,          /* link between two DAI structures */
 };
 
index a80c883..c7051c4 100644 (file)
@@ -55,7 +55,8 @@ static int dapm_up_seq[] = {
        [snd_soc_dapm_clock_supply] = 1,
        [snd_soc_dapm_micbias] = 2,
        [snd_soc_dapm_dai_link] = 2,
-       [snd_soc_dapm_dai] = 3,
+       [snd_soc_dapm_dai_in] = 3,
+       [snd_soc_dapm_dai_out] = 3,
        [snd_soc_dapm_aif_in] = 3,
        [snd_soc_dapm_aif_out] = 3,
        [snd_soc_dapm_mic] = 4,
@@ -92,7 +93,8 @@ static int dapm_down_seq[] = {
        [snd_soc_dapm_value_mux] = 9,
        [snd_soc_dapm_aif_in] = 10,
        [snd_soc_dapm_aif_out] = 10,
-       [snd_soc_dapm_dai] = 10,
+       [snd_soc_dapm_dai_in] = 10,
+       [snd_soc_dapm_dai_out] = 10,
        [snd_soc_dapm_dai_link] = 11,
        [snd_soc_dapm_clock_supply] = 12,
        [snd_soc_dapm_regulator_supply] = 12,
@@ -419,7 +421,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
        case snd_soc_dapm_clock_supply:
        case snd_soc_dapm_aif_in:
        case snd_soc_dapm_aif_out:
-       case snd_soc_dapm_dai:
+       case snd_soc_dapm_dai_in:
+       case snd_soc_dapm_dai_out:
        case snd_soc_dapm_hp:
        case snd_soc_dapm_mic:
        case snd_soc_dapm_spk:
@@ -820,7 +823,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
        switch (widget->id) {
        case snd_soc_dapm_adc:
        case snd_soc_dapm_aif_out:
-       case snd_soc_dapm_dai:
+       case snd_soc_dapm_dai_out:
                if (widget->active) {
                        widget->outputs = snd_soc_dapm_suspend_check(widget);
                        return widget->outputs;
@@ -916,7 +919,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
        switch (widget->id) {
        case snd_soc_dapm_dac:
        case snd_soc_dapm_aif_in:
-       case snd_soc_dapm_dai:
+       case snd_soc_dapm_dai_in:
                if (widget->active) {
                        widget->inputs = snd_soc_dapm_suspend_check(widget);
                        return widget->inputs;
@@ -1135,16 +1138,6 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
        return out != 0 && in != 0;
 }
 
-static int dapm_dai_check_power(struct snd_soc_dapm_widget *w)
-{
-       DAPM_UPDATE_STAT(w, power_checks);
-
-       if (w->active)
-               return w->active;
-
-       return dapm_generic_check_power(w);
-}
-
 /* Check to see if an ADC has power */
 static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
 {
@@ -2318,7 +2311,8 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
        case snd_soc_dapm_clock_supply:
        case snd_soc_dapm_aif_in:
        case snd_soc_dapm_aif_out:
-       case snd_soc_dapm_dai:
+       case snd_soc_dapm_dai_in:
+       case snd_soc_dapm_dai_out:
        case snd_soc_dapm_dai_link:
                list_add(&path->list, &dapm->card->paths);
                list_add(&path->list_sink, &wsink->sources);
@@ -3129,10 +3123,12 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
                break;
        case snd_soc_dapm_adc:
        case snd_soc_dapm_aif_out:
+       case snd_soc_dapm_dai_out:
                w->power_check = dapm_adc_check_power;
                break;
        case snd_soc_dapm_dac:
        case snd_soc_dapm_aif_in:
+       case snd_soc_dapm_dai_in:
                w->power_check = dapm_dac_check_power;
                break;
        case snd_soc_dapm_pga:
@@ -3152,9 +3148,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
        case snd_soc_dapm_clock_supply:
                w->power_check = dapm_supply_check_power;
                break;
-       case snd_soc_dapm_dai:
-               w->power_check = dapm_dai_check_power;
-               break;
        default:
                w->power_check = dapm_always_on_check_power;
                break;
@@ -3375,7 +3368,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
        template.reg = SND_SOC_NOPM;
 
        if (dai->driver->playback.stream_name) {
-               template.id = snd_soc_dapm_dai;
+               template.id = snd_soc_dapm_dai_in;
                template.name = dai->driver->playback.stream_name;
                template.sname = dai->driver->playback.stream_name;
 
@@ -3393,7 +3386,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
        }
 
        if (dai->driver->capture.stream_name) {
-               template.id = snd_soc_dapm_dai;
+               template.id = snd_soc_dapm_dai_out;
                template.name = dai->driver->capture.stream_name;
                template.sname = dai->driver->capture.stream_name;
 
@@ -3423,8 +3416,13 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
 
        /* For each DAI widget... */
        list_for_each_entry(dai_w, &card->widgets, list) {
-               if (dai_w->id != snd_soc_dapm_dai)
+               switch (dai_w->id) {
+               case snd_soc_dapm_dai_in:
+               case snd_soc_dapm_dai_out:
+                       break;
+               default:
                        continue;
+               }
 
                dai = dai_w->priv;
 
@@ -3433,8 +3431,13 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
                        if (w->dapm != dai_w->dapm)
                                continue;
 
-                       if (w->id == snd_soc_dapm_dai)
+                       switch (w->id) {
+                       case snd_soc_dapm_dai_in:
+                       case snd_soc_dapm_dai_out:
                                continue;
+                       default:
+                               break;
+                       }
 
                        if (!w->sname)
                                continue;
index a9fddf0..ccb6be4 100644 (file)
@@ -928,8 +928,13 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
        /* Create any new FE <--> BE connections */
        for (i = 0; i < list->num_widgets; i++) {
 
-               if (list->widgets[i]->id != snd_soc_dapm_dai)
+               switch (list->widgets[i]->id) {
+               case snd_soc_dapm_dai_in:
+               case snd_soc_dapm_dai_out:
+                       break;
+               default:
                        continue;
+               }
 
                /* is there a valid BE rtd for this widget */
                be = dpcm_get_be(card, list->widgets[i], stream);