Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 230385
b: refs/heads/master
c: 7be31be
h: refs/heads/master
i:
  230383: fc46540
v: v3
  • Loading branch information
Jarkko Nikula authored and Mark Brown committed Dec 15, 2010
1 parent 4f95de7 commit e8c00fc
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 47 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 97c866defc0fc6e18b49603ac19f732f53e79c46
refs/heads/master: 7be31be880ee00c6f8d38184368e8a834923b469
5 changes: 5 additions & 0 deletions trunk/include/sound/soc-dapm.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,11 @@ struct snd_soc_dapm_context {
struct device *dev; /* from parent - for debug */
struct snd_soc_codec *codec; /* parent codec */
struct snd_soc_card *card; /* parent card */

/* used during DAPM updates */
int dev_power;
struct list_head list;

#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_dapm;
#endif
Expand Down
1 change: 1 addition & 0 deletions trunk/include/sound/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ struct snd_soc_card {

struct list_head widgets;
struct list_head paths;
struct list_head dapm_list;

#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_card_root;
Expand Down
2 changes: 2 additions & 0 deletions trunk/sound/soc/soc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
/* mark codec as probed and add to card codec list */
codec->probed = 1;
list_add(&codec->card_list, &card->codec_dev_list);
list_add(&codec->dapm.list, &card->dapm_list);

return ret;
}
Expand Down Expand Up @@ -1881,6 +1882,7 @@ static int soc_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&card->platform_dev_list);
INIT_LIST_HEAD(&card->widgets);
INIT_LIST_HEAD(&card->paths);
INIT_LIST_HEAD(&card->dapm_list);

soc_init_card_debugfs(card);

Expand Down
109 changes: 63 additions & 46 deletions trunk/sound/soc/soc-dapm.c
Original file line number Diff line number Diff line change
Expand Up @@ -847,19 +847,22 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
LIST_HEAD(pending);
int cur_sort = -1;
int cur_reg = SND_SOC_NOPM;
struct snd_soc_dapm_context *cur_dapm = NULL;
int ret;

list_for_each_entry_safe(w, n, list, power_list) {
ret = 0;

/* Do we need to apply any queued changes? */
if (sort[w->id] != cur_sort || w->reg != cur_reg) {
if (sort[w->id] != cur_sort || w->reg != cur_reg ||
w->dapm != cur_dapm) {
if (!list_empty(&pending))
dapm_seq_run_coalesced(dapm, &pending);
dapm_seq_run_coalesced(cur_dapm, &pending);

INIT_LIST_HEAD(&pending);
cur_sort = -1;
cur_reg = SND_SOC_NOPM;
cur_dapm = NULL;
}

switch (w->id) {
Expand Down Expand Up @@ -903,6 +906,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
/* Queue it up for application */
cur_sort = sort[w->id];
cur_reg = w->reg;
cur_dapm = w->dapm;
list_move(&w->power_list, &pending);
break;
}
Expand All @@ -929,20 +933,22 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
{
struct snd_soc_card *card = dapm->codec->card;
struct snd_soc_dapm_widget *w;
struct snd_soc_dapm_context *d;
LIST_HEAD(up_list);
LIST_HEAD(down_list);
int ret = 0;
int power;
int sys_power = 0;

trace_snd_soc_dapm_start(card);

list_for_each_entry(d, &card->dapm_list, list)
if (d->n_widgets)
d->dev_power = 0;

/* Check which widgets we need to power and store them in
* lists indicating if they should be powered up or down.
*/
list_for_each_entry(w, &card->widgets, list) {
if (w->dapm != dapm)
continue;
switch (w->id) {
case snd_soc_dapm_pre:
dapm_seq_insert(w, &down_list, dapm_down_seq);
Expand All @@ -960,7 +966,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
else
power = 1;
if (power)
sys_power = 1;
w->dapm->dev_power = 1;

if (w->power == power)
continue;
Expand All @@ -984,22 +990,22 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
switch (event) {
case SND_SOC_DAPM_STREAM_START:
case SND_SOC_DAPM_STREAM_RESUME:
sys_power = 1;
dapm->dev_power = 1;
break;
case SND_SOC_DAPM_STREAM_STOP:
sys_power = !!dapm->codec->active;
dapm->dev_power = !!dapm->codec->active;
break;
case SND_SOC_DAPM_STREAM_SUSPEND:
sys_power = 0;
dapm->dev_power = 0;
break;
case SND_SOC_DAPM_STREAM_NOP:
switch (dapm->bias_level) {
case SND_SOC_BIAS_STANDBY:
case SND_SOC_BIAS_OFF:
sys_power = 0;
dapm->dev_power = 0;
break;
default:
sys_power = 1;
dapm->dev_power = 1;
break;
}
break;
Expand All @@ -1008,21 +1014,24 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
}
}

if (sys_power && dapm->bias_level == SND_SOC_BIAS_OFF) {
ret = snd_soc_dapm_set_bias_level(card, dapm,
SND_SOC_BIAS_STANDBY);
if (ret != 0)
dev_err(dapm->dev,
"Failed to turn on bias: %d\n", ret);
}
list_for_each_entry(d, &dapm->card->dapm_list, list) {
if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) {
ret = snd_soc_dapm_set_bias_level(card, d,
SND_SOC_BIAS_STANDBY);
if (ret != 0)
dev_err(d->dev,
"Failed to turn on bias: %d\n", ret);
}

/* If we're changing to all on or all off then prepare */
if ((sys_power && dapm->bias_level == SND_SOC_BIAS_STANDBY) ||
(!sys_power && dapm->bias_level == SND_SOC_BIAS_ON)) {
ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_PREPARE);
if (ret != 0)
dev_err(dapm->dev,
"Failed to prepare bias: %d\n", ret);
/* If we're changing to all on or all off then prepare */
if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
(!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
ret = snd_soc_dapm_set_bias_level(card, d,
SND_SOC_BIAS_PREPARE);
if (ret != 0)
dev_err(d->dev,
"Failed to prepare bias: %d\n", ret);
}
}

/* Power down widgets first; try to avoid amplifying pops. */
Expand All @@ -1031,29 +1040,36 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
/* Now power up. */
dapm_seq_run(dapm, &up_list, event, dapm_up_seq);

/* If we just powered the last thing off drop to standby bias */
if (dapm->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) {
ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY);
if (ret != 0)
dev_err(dapm->dev,
"Failed to apply standby bias: %d\n", ret);
}
list_for_each_entry(d, &dapm->card->dapm_list, list) {
/* If we just powered the last thing off drop to standby bias */
if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
ret = snd_soc_dapm_set_bias_level(card, d,
SND_SOC_BIAS_STANDBY);
if (ret != 0)
dev_err(d->dev,
"Failed to apply standby bias: %d\n",
ret);
}

/* If we're in standby and can support bias off then do that */
if (dapm->bias_level == SND_SOC_BIAS_STANDBY &&
dapm->idle_bias_off) {
ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_OFF);
if (ret != 0)
dev_err(dapm->dev,
"Failed to turn off bias: %d\n", ret);
}
/* If we're in standby and can support bias off then do that */
if (d->bias_level == SND_SOC_BIAS_STANDBY &&
d->idle_bias_off) {
ret = snd_soc_dapm_set_bias_level(card, d,
SND_SOC_BIAS_OFF);
if (ret != 0)
dev_err(d->dev,
"Failed to turn off bias: %d\n", ret);
}

/* If we just powered up then move to active bias */
if (dapm->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_ON);
if (ret != 0)
dev_err(dapm->dev,
"Failed to apply active bias: %d\n", ret);
/* If we just powered up then move to active bias */
if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
ret = snd_soc_dapm_set_bias_level(card, d,
SND_SOC_BIAS_ON);
if (ret != 0)
dev_err(d->dev,
"Failed to apply active bias: %d\n",
ret);
}
}

pop_dbg(dapm->dev, card->pop_time,
Expand Down Expand Up @@ -2309,6 +2325,7 @@ void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
{
snd_soc_dapm_sys_remove(dapm->dev);
dapm_free_widgets(dapm);
list_del(&dapm->list);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_free);

Expand Down

0 comments on commit e8c00fc

Please sign in to comment.