diff options
-rw-r--r-- | sound/soc/soc-core.c | 3 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 53 |
2 files changed, 33 insertions, 23 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4079223203e..95739767ec4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -963,6 +963,9 @@ static void soc_resume_deferred(struct work_struct *work) | |||
963 | 963 | ||
964 | dev_dbg(socdev->dev, "starting resume work\n"); | 964 | dev_dbg(socdev->dev, "starting resume work\n"); |
965 | 965 | ||
966 | /* Bring us up into D2 so that DAPM starts enabling things */ | ||
967 | snd_power_change_state(codec->card, SNDRV_CTL_POWER_D2); | ||
968 | |||
966 | if (card->resume_pre) | 969 | if (card->resume_pre) |
967 | card->resume_pre(pdev); | 970 | card->resume_pre(pdev); |
968 | 971 | ||
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index b30b0a255cd..8c8b291320a 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -430,6 +430,23 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec) | |||
430 | p->walked = 0; | 430 | p->walked = 0; |
431 | } | 431 | } |
432 | 432 | ||
433 | /* We implement power down on suspend by checking the power state of | ||
434 | * the ALSA card - when we are suspending the ALSA state for the card | ||
435 | * is set to D3. | ||
436 | */ | ||
437 | static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) | ||
438 | { | ||
439 | struct snd_soc_codec *codec = widget->codec; | ||
440 | |||
441 | switch (snd_power_get_state(codec->card)) { | ||
442 | case SNDRV_CTL_POWER_D3hot: | ||
443 | case SNDRV_CTL_POWER_D3cold: | ||
444 | return 0; | ||
445 | default: | ||
446 | return 1; | ||
447 | } | ||
448 | } | ||
449 | |||
433 | /* | 450 | /* |
434 | * Recursively check for a completed path to an active or physically connected | 451 | * Recursively check for a completed path to an active or physically connected |
435 | * output widget. Returns number of complete paths. | 452 | * output widget. Returns number of complete paths. |
@@ -446,7 +463,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) | |||
446 | case snd_soc_dapm_adc: | 463 | case snd_soc_dapm_adc: |
447 | case snd_soc_dapm_aif_out: | 464 | case snd_soc_dapm_aif_out: |
448 | if (widget->active) | 465 | if (widget->active) |
449 | return 1; | 466 | return snd_soc_dapm_suspend_check(widget); |
450 | default: | 467 | default: |
451 | break; | 468 | break; |
452 | } | 469 | } |
@@ -454,12 +471,12 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) | |||
454 | if (widget->connected) { | 471 | if (widget->connected) { |
455 | /* connected pin ? */ | 472 | /* connected pin ? */ |
456 | if (widget->id == snd_soc_dapm_output && !widget->ext) | 473 | if (widget->id == snd_soc_dapm_output && !widget->ext) |
457 | return 1; | 474 | return snd_soc_dapm_suspend_check(widget); |
458 | 475 | ||
459 | /* connected jack or spk ? */ | 476 | /* connected jack or spk ? */ |
460 | if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || | 477 | if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || |
461 | (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) | 478 | (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) |
462 | return 1; | 479 | return snd_soc_dapm_suspend_check(widget); |
463 | } | 480 | } |
464 | 481 | ||
465 | list_for_each_entry(path, &widget->sinks, list_source) { | 482 | list_for_each_entry(path, &widget->sinks, list_source) { |
@@ -492,7 +509,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) | |||
492 | case snd_soc_dapm_dac: | 509 | case snd_soc_dapm_dac: |
493 | case snd_soc_dapm_aif_in: | 510 | case snd_soc_dapm_aif_in: |
494 | if (widget->active) | 511 | if (widget->active) |
495 | return 1; | 512 | return snd_soc_dapm_suspend_check(widget); |
496 | default: | 513 | default: |
497 | break; | 514 | break; |
498 | } | 515 | } |
@@ -500,16 +517,16 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) | |||
500 | if (widget->connected) { | 517 | if (widget->connected) { |
501 | /* connected pin ? */ | 518 | /* connected pin ? */ |
502 | if (widget->id == snd_soc_dapm_input && !widget->ext) | 519 | if (widget->id == snd_soc_dapm_input && !widget->ext) |
503 | return 1; | 520 | return snd_soc_dapm_suspend_check(widget); |
504 | 521 | ||
505 | /* connected VMID/Bias for lower pops */ | 522 | /* connected VMID/Bias for lower pops */ |
506 | if (widget->id == snd_soc_dapm_vmid) | 523 | if (widget->id == snd_soc_dapm_vmid) |
507 | return 1; | 524 | return snd_soc_dapm_suspend_check(widget); |
508 | 525 | ||
509 | /* connected jack ? */ | 526 | /* connected jack ? */ |
510 | if (widget->id == snd_soc_dapm_mic || | 527 | if (widget->id == snd_soc_dapm_mic || |
511 | (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks))) | 528 | (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks))) |
512 | return 1; | 529 | return snd_soc_dapm_suspend_check(widget); |
513 | } | 530 | } |
514 | 531 | ||
515 | list_for_each_entry(path, &widget->sources, list_sink) { | 532 | list_for_each_entry(path, &widget->sources, list_sink) { |
@@ -897,22 +914,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
897 | if (!w->power_check) | 914 | if (!w->power_check) |
898 | continue; | 915 | continue; |
899 | 916 | ||
900 | /* If we're suspending then pull down all the | 917 | if (!w->force) |
901 | * power. */ | 918 | power = w->power_check(w); |
902 | switch (event) { | 919 | else |
903 | case SND_SOC_DAPM_STREAM_SUSPEND: | 920 | power = 1; |
904 | power = 0; | 921 | if (power) |
905 | break; | 922 | sys_power = 1; |
906 | |||
907 | default: | ||
908 | if (!w->force) | ||
909 | power = w->power_check(w); | ||
910 | else | ||
911 | power = 1; | ||
912 | if (power) | ||
913 | sys_power = 1; | ||
914 | break; | ||
915 | } | ||
916 | 923 | ||
917 | if (w->power == power) | 924 | if (w->power == power) |
918 | continue; | 925 | continue; |