[alsa-devel] [PATCH v2] ASoC: Add pinctrl PM to components of active DAIs

Kyungmin Park kmpark at infradead.org
Tue Oct 29 04:35:06 CET 2013


On Tue, Oct 29, 2013 at 12:12 PM, Nicolin Chen <b42378 at freescale.com> wrote:
> It's quite popular that more drivers are using pinctrl PM, for example:
> (Documentation/devicetree/bindings/arm/primecell.txt). Just like what
> runtime PM does, it would de-active and en-active pin group depending
> on whether it's being used or not.
>
> And this pinctrl PM might be also beneficial to cpu dai drivers because
> they might have actual pinctrl so as to sleep their pins and wake them
> up as needed.
>
> To achieve this goal, this patch sets pins to the default state during
> resume or startup; While during suspend and shutdown, it would set pins
> to the sleep state.
>
> As pinctrl PM would return zero if there is no such pinctrl sleep state
> settings, this patch would not break current ASoC subsystem directly.
>
> [ However, there is still an exception that the patch can not handle,
> that is, when cpu dai driver does not have pinctrl property but another
> device has it. (The AUDMUX <-> SSI on Freescale i.MX6 series for example.
> SSI as a cpu dai doesn't contain pinctrl property while AUDMUX, an Audio
> Multiplexer, has it). In this case, this kind of cpu dai driver needs to
> find a way to obtain the pinctrl property as its own, by moving property
> from AUDMUX to SSI, or creating a pins link/dependency between these two
> devices, or using a more decent way after we figure it out. ]
>
> Signed-off-by: Nicolin Chen <b42378 at freescale.com>
> ---
> Changelog
> v1->v2:
>  * Use proper verbs in comments.
>  * Add 'dai->active' condition for resume case.
>
> ---
>  sound/soc/soc-core.c | 29 +++++++++++++++++++++++++++++
>  sound/soc/soc-pcm.c  |  3 +++
>  2 files changed, 32 insertions(+)
>
> diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
> index 4280c70..5c972ac 100644
> --- a/sound/soc/soc-core.c
> +++ b/sound/soc/soc-core.c
> @@ -684,6 +684,13 @@ int snd_soc_suspend(struct device *dev)
>         if (card->suspend_post)
>                 card->suspend_post(card);
>
> +       /* deactivate pins to sleep state */
> +       for (i = 0; i < card->num_rtd; i++) {
> +               struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
> +               struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
> +               pinctrl_pm_select_sleep_state(cpu_dai->dev);

I wonder doesn't check it's active or not? if codec is used during
suspend. it doesn't set sleep state?

Thank you,
Kyungmin Park
> +       }
> +
>         return 0;
>  }
>  EXPORT_SYMBOL_GPL(snd_soc_suspend);
> @@ -807,6 +814,14 @@ int snd_soc_resume(struct device *dev)
>         if (list_empty(&card->codec_dev_list))
>                 return 0;
>
> +       /* activate pins from sleep state */
> +       for (i = 0; i < card->num_rtd; i++) {
> +               struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
> +               struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
> +               if (cpu_dai->active)
> +                       pinctrl_pm_select_default_state(cpu_dai->dev);
> +       }
> +
>         /* AC97 devices might have other drivers hanging off them so
>          * need to resume immediately.  Other drivers don't have that
>          * problem and may take a substantial amount of time to resume
> @@ -1929,6 +1944,13 @@ int snd_soc_poweroff(struct device *dev)
>
>         snd_soc_dapm_shutdown(card);
>
> +       /* deactivate pins to sleep state */
> +       for (i = 0; i < card->num_rtd; i++) {
> +               struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
> +               struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
> +               pinctrl_pm_select_sleep_state(cpu_dai->dev);
> +       }
> +
>         return 0;
>  }
>  EXPORT_SYMBOL_GPL(snd_soc_poweroff);
> @@ -3766,6 +3788,13 @@ int snd_soc_register_card(struct snd_soc_card *card)
>         if (ret != 0)
>                 soc_cleanup_card_debugfs(card);
>
> +       /* deactivate pins to sleep state */
> +       for (i = 0; i < card->num_rtd; i++) {
> +               struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
> +               struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
> +               pinctrl_pm_select_sleep_state(cpu_dai->dev);
> +       }
> +
>         return ret;
>  }
>  EXPORT_SYMBOL_GPL(snd_soc_register_card);
> diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
> index 330c9a6..05bdba0 100644
> --- a/sound/soc/soc-pcm.c
> +++ b/sound/soc/soc-pcm.c
> @@ -183,6 +183,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
>         struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
>         int ret = 0;
>
> +       pinctrl_pm_select_default_state(cpu_dai->dev);
>         pm_runtime_get_sync(cpu_dai->dev);
>         pm_runtime_get_sync(codec_dai->dev);
>         pm_runtime_get_sync(platform->dev);
> @@ -317,6 +318,7 @@ out:
>         pm_runtime_put(platform->dev);
>         pm_runtime_put(codec_dai->dev);
>         pm_runtime_put(cpu_dai->dev);
> +       pinctrl_pm_select_sleep_state(cpu_dai->dev);
>
>         return ret;
>  }
> @@ -426,6 +428,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
>         pm_runtime_put(platform->dev);
>         pm_runtime_put(codec_dai->dev);
>         pm_runtime_put(cpu_dai->dev);
> +       pinctrl_pm_select_sleep_state(cpu_dai->dev);
>
>         return 0;
>  }
> --
> 1.8.4
>
>
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel


More information about the Alsa-devel mailing list