Skip to content

Commit

Permalink
ASoC: Add a shutdown callback
Browse files Browse the repository at this point in the history
Ensure that the audio subsystem is powered down cleanly when the system
shuts down by providing a shutdown operation. This ensures that all the
components have been returned to an off state cleanly which should avoid
audio issues from partially charged capacitors or noise on digital inputs
if the system is restarted quickly.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Tested-by: Ben Dooks <ben-linux@fluff.org>
  • Loading branch information
Mark Brown committed Jun 23, 2009
1 parent 30808ca commit 5173747
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/sound/soc-dapm.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
/* dapm events */
int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream,
int event);
void snd_soc_dapm_shutdown(struct snd_soc_device *socdev);

/* dapm sys fs - used by the core */
int snd_soc_dapm_sys_add(struct device *dev);
Expand Down
16 changes: 16 additions & 0 deletions sound/soc/soc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,21 @@ static int soc_remove(struct platform_device *pdev)
return 0;
}

static void soc_shutdown(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_card *card = socdev->card;

if (!card->instantiated)
return;

/* Flush out pmdown_time work - we actually do want to run it
* now, we're shutting down so no imminent restart. */
run_delayed_work(&card->delayed_work);

snd_soc_dapm_shutdown(socdev);
}

/* ASoC platform driver */
static struct platform_driver soc_driver = {
.driver = {
Expand All @@ -1030,6 +1045,7 @@ static struct platform_driver soc_driver = {
.remove = soc_remove,
.suspend = soc_suspend,
.resume = soc_resume,
.shutdown = soc_shutdown,
};

/* create a new pcm */
Expand Down
29 changes: 29 additions & 0 deletions sound/soc/soc-dapm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2032,6 +2032,35 @@ void snd_soc_dapm_free(struct snd_soc_device *socdev)
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_free);

/*
* snd_soc_dapm_shutdown - callback for system shutdown
*/
void snd_soc_dapm_shutdown(struct snd_soc_device *socdev)
{
struct snd_soc_codec *codec = socdev->card->codec;
struct snd_soc_dapm_widget *w;
LIST_HEAD(down_list);
int powerdown = 0;

list_for_each_entry(w, &codec->dapm_widgets, list) {
if (w->power) {
dapm_seq_insert(w, &down_list, dapm_down_seq);
powerdown = 1;
}
}

/* If there were no widgets to power down we're already in
* standby.
*/
if (powerdown) {
snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_PREPARE);
dapm_seq_run(codec, &down_list, 0, dapm_down_seq);
snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_STANDBY);
}

snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF);
}

/* Module information */
MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");
Expand Down

0 comments on commit 5173747

Please sign in to comment.