From d9fc40639dc1b87915426d2ef489a591b0fd650b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 30 Nov 2016 06:22:36 +0000 Subject: ASoC: core: replace codec_dev_list to component_dev_list on Card Current Card has Codec list (= codec_dev_list), but Codec will be removed in the future. Because of this reason, this patch adds new Component list in Card, and replace Codec list. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'sound/soc/soc-core.c') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c0bbcd903261..d204bb772f00 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -626,7 +626,7 @@ static void codec2codec_close_delayed_work(struct work_struct *work) int snd_soc_suspend(struct device *dev) { struct snd_soc_card *card = dev_get_drvdata(dev); - struct snd_soc_codec *codec; + struct snd_soc_component *component; struct snd_soc_pcm_runtime *rtd; int i; @@ -703,8 +703,12 @@ int snd_soc_suspend(struct device *dev) snd_soc_dapm_sync(&card->dapm); /* suspend all CODECs */ - list_for_each_entry(codec, &card->codec_dev_list, card_list) { - struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); + list_for_each_entry(component, &card->component_dev_list, card_list) { + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + if (!codec) + continue; /* If there are paths active then the CODEC will be held with * bias _ON and should not be suspended. */ @@ -768,7 +772,7 @@ static void soc_resume_deferred(struct work_struct *work) struct snd_soc_card *card = container_of(work, struct snd_soc_card, deferred_resume_work); struct snd_soc_pcm_runtime *rtd; - struct snd_soc_codec *codec; + struct snd_soc_component *component; int i; /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time, @@ -794,7 +798,12 @@ static void soc_resume_deferred(struct work_struct *work) cpu_dai->driver->resume(cpu_dai); } - list_for_each_entry(codec, &card->codec_dev_list, card_list) { + list_for_each_entry(component, &card->component_dev_list, card_list) { + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + if (!codec) + continue; + if (codec->suspended) { if (codec->driver->resume) codec->driver->resume(codec); @@ -1072,9 +1081,7 @@ static void soc_remove_component(struct snd_soc_component *component) if (!component->card) return; - /* This is a HACK and will be removed soon */ - if (component->codec) - list_del(&component->codec->card_list); + list_del(&component->card_list); if (component->remove) component->remove(component); @@ -1443,10 +1450,7 @@ static int soc_probe_component(struct snd_soc_card *card, component->num_dapm_routes); list_add(&dapm->list, &card->dapm_list); - - /* This is a HACK and will be removed soon */ - if (component->codec) - list_add(&component->codec->card_list, &card->codec_dev_list); + list_add(&component->card_list, &card->component_dev_list); return 0; -- cgit v1.2.3 From 1a653aa44725668590b36bbe2d7fe4736a69f055 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 30 Nov 2016 06:22:55 +0000 Subject: ASoC: core: replace aux_comp_list to component_dev_list Now, Card has component_dev_list, we can replace aux_comp_list to component_dev_list with new auxiliary flags Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- include/sound/soc.h | 4 +--- sound/soc/soc-core.c | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'sound/soc/soc-core.c') diff --git a/include/sound/soc.h b/include/sound/soc.h index b5544e2287b8..0bd57b77d010 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -807,9 +807,9 @@ struct snd_soc_component { unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ unsigned int registered_as_component:1; + unsigned int auxiliary:1; /* for auxiliary component of the card */ struct list_head list; - struct list_head list_aux; /* for auxiliary component of the card */ struct list_head card_list; struct snd_soc_dai_driver *dai_drv; @@ -1148,7 +1148,6 @@ struct snd_soc_card { */ struct snd_soc_aux_dev *aux_dev; int num_aux_devs; - struct list_head aux_comp_list; const struct snd_kcontrol_new *controls; int num_controls; @@ -1543,7 +1542,6 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) INIT_LIST_HEAD(&card->widgets); INIT_LIST_HEAD(&card->paths); INIT_LIST_HEAD(&card->dapm_list); - INIT_LIST_HEAD(&card->aux_comp_list); INIT_LIST_HEAD(&card->component_dev_list); } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d204bb772f00..ba8e000faaf1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1710,7 +1710,8 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num) } component->init = aux_dev->init; - list_add(&component->list_aux, &card->aux_comp_list); + component->auxiliary = 1; + return 0; err_defer: @@ -1726,7 +1727,10 @@ static int soc_probe_aux_devices(struct snd_soc_card *card) for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; order++) { - list_for_each_entry(comp, &card->aux_comp_list, list_aux) { + list_for_each_entry(comp, &card->component_dev_list, card_list) { + if (!comp->auxiliary) + continue; + if (comp->driver->probe_order == order) { ret = soc_probe_component(card, comp); if (ret < 0) { @@ -1750,11 +1754,14 @@ static void soc_remove_aux_devices(struct snd_soc_card *card) for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; order++) { list_for_each_entry_safe(comp, _comp, - &card->aux_comp_list, list_aux) { + &card->component_dev_list, card_list) { + + if (!comp->auxiliary) + continue; + if (comp->driver->remove_order == order) { soc_remove_component(comp); - /* remove it from the card's aux_comp_list */ - list_del(&comp->list_aux); + comp->auxiliary = 0; } } } -- cgit v1.2.3 From 9178feb4538e055bf22be44c38b90cc31d2baf99 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 30 Nov 2016 06:23:13 +0000 Subject: ASoC: add Component level suspend/resume In current ALSA SoC, Codec only has suspend/resume feature, but it should be supported on Component level. This patch adds it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- include/sound/soc.h | 6 ++++- sound/soc/soc-core.c | 63 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 42 insertions(+), 27 deletions(-) (limited to 'sound/soc/soc-core.c') diff --git a/include/sound/soc.h b/include/sound/soc.h index 0bd57b77d010..13cc64e5bb77 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -782,6 +782,8 @@ struct snd_soc_component_driver { int (*probe)(struct snd_soc_component *); void (*remove)(struct snd_soc_component *); + int (*suspend)(struct snd_soc_component *); + int (*resume)(struct snd_soc_component *); /* DT */ int (*of_xlate_dai_name)(struct snd_soc_component *component, @@ -808,6 +810,7 @@ struct snd_soc_component { unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ unsigned int registered_as_component:1; unsigned int auxiliary:1; /* for auxiliary component of the card */ + unsigned int suspended:1; /* is in suspend PM state */ struct list_head list; struct list_head card_list; @@ -853,6 +856,8 @@ struct snd_soc_component { int (*probe)(struct snd_soc_component *); void (*remove)(struct snd_soc_component *); + int (*suspend)(struct snd_soc_component *); + int (*resume)(struct snd_soc_component *); /* machine specific init */ int (*init)(struct snd_soc_component *component); @@ -872,7 +877,6 @@ struct snd_soc_codec { /* runtime */ unsigned int cache_bypass:1; /* Suppress access to the cache */ - unsigned int suspended:1; /* Codec is in suspend PM state */ unsigned int cache_init:1; /* codec cache has been initialized */ /* codec IO */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ba8e000faaf1..f35ec5bf3b78 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -702,43 +702,39 @@ int snd_soc_suspend(struct device *dev) dapm_mark_endpoints_dirty(card); snd_soc_dapm_sync(&card->dapm); - /* suspend all CODECs */ + /* suspend all COMPONENTs */ list_for_each_entry(component, &card->component_dev_list, card_list) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - if (!codec) - continue; - - /* If there are paths active then the CODEC will be held with + /* If there are paths active then the COMPONENT will be held with * bias _ON and should not be suspended. */ - if (!codec->suspended) { + if (!component->suspended) { switch (snd_soc_dapm_get_bias_level(dapm)) { case SND_SOC_BIAS_STANDBY: /* - * If the CODEC is capable of idle + * If the COMPONENT is capable of idle * bias off then being in STANDBY * means it's doing something, * otherwise fall through. */ if (dapm->idle_bias_off) { - dev_dbg(codec->dev, + dev_dbg(component->dev, "ASoC: idle_bias_off CODEC on over suspend\n"); break; } case SND_SOC_BIAS_OFF: - if (codec->driver->suspend) - codec->driver->suspend(codec); - codec->suspended = 1; - if (codec->component.regmap) - regcache_mark_dirty(codec->component.regmap); + if (component->suspend) + component->suspend(component); + component->suspended = 1; + if (component->regmap) + regcache_mark_dirty(component->regmap); /* deactivate pins to sleep state */ - pinctrl_pm_select_sleep_state(codec->dev); + pinctrl_pm_select_sleep_state(component->dev); break; default: - dev_dbg(codec->dev, - "ASoC: CODEC is on over suspend\n"); + dev_dbg(component->dev, + "ASoC: COMPONENT is on over suspend\n"); break; } } @@ -799,15 +795,10 @@ static void soc_resume_deferred(struct work_struct *work) } list_for_each_entry(component, &card->component_dev_list, card_list) { - struct snd_soc_codec *codec = snd_soc_component_to_codec(component); - - if (!codec) - continue; - - if (codec->suspended) { - if (codec->driver->resume) - codec->driver->resume(codec); - codec->suspended = 0; + if (component->suspended) { + if (component->resume) + component->resume(component); + component->suspended = 0; } } @@ -2937,6 +2928,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, component->driver = driver; component->probe = component->driver->probe; component->remove = component->driver->remove; + component->suspend = component->driver->suspend; + component->resume = component->driver->resume; dapm = &component->dapm; dapm->dev = dev; @@ -3286,6 +3279,20 @@ static void snd_soc_codec_drv_remove(struct snd_soc_component *component) codec->driver->remove(codec); } +static int snd_soc_codec_drv_suspend(struct snd_soc_component *component) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return codec->driver->suspend(codec); +} + +static int snd_soc_codec_drv_resume(struct snd_soc_component *component) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return codec->driver->resume(codec); +} + static int snd_soc_codec_drv_write(struct snd_soc_component *component, unsigned int reg, unsigned int val) { @@ -3347,6 +3354,10 @@ int snd_soc_register_codec(struct device *dev, codec->component.probe = snd_soc_codec_drv_probe; if (codec_drv->remove) codec->component.remove = snd_soc_codec_drv_remove; + if (codec_drv->suspend) + codec->component.suspend = snd_soc_codec_drv_suspend; + if (codec_drv->resume) + codec->component.resume = snd_soc_codec_drv_resume; if (codec_drv->write) codec->component.write = snd_soc_codec_drv_write; if (codec_drv->read) -- cgit v1.2.3