aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/soc-core.c3
-rw-r--r--sound/soc/soc-dapm.c53
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 */
437static 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;