|
@@ -726,8 +726,15 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
|
|
|
|
|
|
static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
|
|
static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
|
|
struct snd_soc_dapm_widget *b,
|
|
struct snd_soc_dapm_widget *b,
|
|
- int sort[])
|
|
|
|
|
|
+ bool power_up)
|
|
{
|
|
{
|
|
|
|
+ int *sort;
|
|
|
|
+
|
|
|
|
+ if (power_up)
|
|
|
|
+ sort = dapm_up_seq;
|
|
|
|
+ else
|
|
|
|
+ sort = dapm_down_seq;
|
|
|
|
+
|
|
if (sort[a->id] != sort[b->id])
|
|
if (sort[a->id] != sort[b->id])
|
|
return sort[a->id] - sort[b->id];
|
|
return sort[a->id] - sort[b->id];
|
|
if (a->reg != b->reg)
|
|
if (a->reg != b->reg)
|
|
@@ -741,12 +748,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
|
|
/* Insert a widget in order into a DAPM power sequence. */
|
|
/* Insert a widget in order into a DAPM power sequence. */
|
|
static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
|
|
static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
|
|
struct list_head *list,
|
|
struct list_head *list,
|
|
- int sort[])
|
|
|
|
|
|
+ bool power_up)
|
|
{
|
|
{
|
|
struct snd_soc_dapm_widget *w;
|
|
struct snd_soc_dapm_widget *w;
|
|
|
|
|
|
list_for_each_entry(w, list, power_list)
|
|
list_for_each_entry(w, list, power_list)
|
|
- if (dapm_seq_compare(new_widget, w, sort) < 0) {
|
|
|
|
|
|
+ if (dapm_seq_compare(new_widget, w, power_up) < 0) {
|
|
list_add_tail(&new_widget->power_list, &w->power_list);
|
|
list_add_tail(&new_widget->power_list, &w->power_list);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -857,7 +864,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
|
|
* handled.
|
|
* handled.
|
|
*/
|
|
*/
|
|
static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
|
|
static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
|
|
- struct list_head *list, int event, int sort[])
|
|
|
|
|
|
+ struct list_head *list, int event, bool power_up)
|
|
{
|
|
{
|
|
struct snd_soc_dapm_widget *w, *n;
|
|
struct snd_soc_dapm_widget *w, *n;
|
|
LIST_HEAD(pending);
|
|
LIST_HEAD(pending);
|
|
@@ -865,6 +872,12 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
|
|
int cur_reg = SND_SOC_NOPM;
|
|
int cur_reg = SND_SOC_NOPM;
|
|
struct snd_soc_dapm_context *cur_dapm = NULL;
|
|
struct snd_soc_dapm_context *cur_dapm = NULL;
|
|
int ret;
|
|
int ret;
|
|
|
|
+ int *sort;
|
|
|
|
+
|
|
|
|
+ if (power_up)
|
|
|
|
+ sort = dapm_up_seq;
|
|
|
|
+ else
|
|
|
|
+ sort = dapm_down_seq;
|
|
|
|
|
|
list_for_each_entry_safe(w, n, list, power_list) {
|
|
list_for_each_entry_safe(w, n, list, power_list) {
|
|
ret = 0;
|
|
ret = 0;
|
|
@@ -1002,10 +1015,10 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
|
|
list_for_each_entry(w, &card->widgets, list) {
|
|
list_for_each_entry(w, &card->widgets, list) {
|
|
switch (w->id) {
|
|
switch (w->id) {
|
|
case snd_soc_dapm_pre:
|
|
case snd_soc_dapm_pre:
|
|
- dapm_seq_insert(w, &down_list, dapm_down_seq);
|
|
|
|
|
|
+ dapm_seq_insert(w, &down_list, false);
|
|
break;
|
|
break;
|
|
case snd_soc_dapm_post:
|
|
case snd_soc_dapm_post:
|
|
- dapm_seq_insert(w, &up_list, dapm_up_seq);
|
|
|
|
|
|
+ dapm_seq_insert(w, &up_list, true);
|
|
break;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|
|
@@ -1025,9 +1038,9 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
|
|
trace_snd_soc_dapm_widget_power(w, power);
|
|
trace_snd_soc_dapm_widget_power(w, power);
|
|
|
|
|
|
if (power)
|
|
if (power)
|
|
- dapm_seq_insert(w, &up_list, dapm_up_seq);
|
|
|
|
|
|
+ dapm_seq_insert(w, &up_list, true);
|
|
else
|
|
else
|
|
- dapm_seq_insert(w, &down_list, dapm_down_seq);
|
|
|
|
|
|
+ dapm_seq_insert(w, &down_list, false);
|
|
|
|
|
|
w->power = power;
|
|
w->power = power;
|
|
break;
|
|
break;
|
|
@@ -1086,12 +1099,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
|
|
}
|
|
}
|
|
|
|
|
|
/* Power down widgets first; try to avoid amplifying pops. */
|
|
/* Power down widgets first; try to avoid amplifying pops. */
|
|
- dapm_seq_run(dapm, &down_list, event, dapm_down_seq);
|
|
|
|
|
|
+ dapm_seq_run(dapm, &down_list, event, false);
|
|
|
|
|
|
dapm_widget_update(dapm);
|
|
dapm_widget_update(dapm);
|
|
|
|
|
|
/* Now power up. */
|
|
/* Now power up. */
|
|
- dapm_seq_run(dapm, &up_list, event, dapm_up_seq);
|
|
|
|
|
|
+ dapm_seq_run(dapm, &up_list, event, true);
|
|
|
|
|
|
list_for_each_entry(d, &dapm->card->dapm_list, list) {
|
|
list_for_each_entry(d, &dapm->card->dapm_list, list) {
|
|
/* If we just powered the last thing off drop to standby bias */
|
|
/* If we just powered the last thing off drop to standby bias */
|
|
@@ -2372,7 +2385,7 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
|
|
if (w->dapm != dapm)
|
|
if (w->dapm != dapm)
|
|
continue;
|
|
continue;
|
|
if (w->power) {
|
|
if (w->power) {
|
|
- dapm_seq_insert(w, &down_list, dapm_down_seq);
|
|
|
|
|
|
+ dapm_seq_insert(w, &down_list, false);
|
|
w->power = 0;
|
|
w->power = 0;
|
|
powerdown = 1;
|
|
powerdown = 1;
|
|
}
|
|
}
|
|
@@ -2383,7 +2396,7 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
|
|
*/
|
|
*/
|
|
if (powerdown) {
|
|
if (powerdown) {
|
|
snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE);
|
|
snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE);
|
|
- dapm_seq_run(dapm, &down_list, 0, dapm_down_seq);
|
|
|
|
|
|
+ dapm_seq_run(dapm, &down_list, 0, false);
|
|
snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY);
|
|
snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY);
|
|
}
|
|
}
|
|
}
|
|
}
|