Skip to content

Commit

Permalink
ASoC: dapm: Treat DAI widgets like AIF widgets for power
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Brown committed Jun 7, 2013
1 parent 0567909 commit 4616274
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 25 deletions.
3 changes: 2 additions & 1 deletion include/sound/soc-dapm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
};

Expand Down
49 changes: 26 additions & 23 deletions sound/soc/soc-dapm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion sound/soc/soc-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 4616274

Please sign in to comment.