[alsa-devel] [PATCH 2/2] ASoC: rsnd: enable/disable ADG when suspend/resume timing
Kuninori Morimoto
kuninori.morimoto.gx at renesas.com
Wed Dec 7 01:29:02 CET 2016
From: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
Current rsnd driver enables ADG clock when .probe timing,
but it breaks sound after Suspend/Resume. These should be setups
every suspend/resume timing too.
This patch is tested on R-Car Gen3 Salvator-X board
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
Tested-by: Gaku Inami <gaku.inami.xw at bp.renesas.com>
---
sound/soc/sh/rcar/adg.c | 38 ++++++++++++++++++++++++--------------
sound/soc/sh/rcar/core.c | 24 ++++++++++++++++++++++++
sound/soc/sh/rcar/rsnd.h | 3 +++
3 files changed, 51 insertions(+), 14 deletions(-)
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index f1068170..85a33ac 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -380,6 +380,25 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
return 0;
}
+void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
+{
+ struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
+ struct device *dev = rsnd_priv_to_dev(priv);
+ struct clk *clk;
+ int i, ret;
+
+ for_each_rsnd_clk(clk, adg, i) {
+ ret = 0;
+ if (enable)
+ ret = clk_prepare_enable(clk);
+ else
+ clk_disable_unprepare(clk);
+
+ if (ret < 0)
+ dev_warn(dev, "can't use clk %d\n", i);
+ }
+}
+
static void rsnd_adg_get_clkin(struct rsnd_priv *priv,
struct rsnd_adg *adg)
{
@@ -391,20 +410,15 @@ static void rsnd_adg_get_clkin(struct rsnd_priv *priv,
[CLKC] = "clk_c",
[CLKI] = "clk_i",
};
- int i, ret;
+ int i;
for (i = 0; i < CLKMAX; i++) {
clk = devm_clk_get(dev, clk_name[i]);
adg->clk[i] = IS_ERR(clk) ? NULL : clk;
}
- for_each_rsnd_clk(clk, adg, i) {
- ret = clk_prepare_enable(clk);
- if (ret < 0)
- dev_warn(dev, "can't use clk %d\n", i);
-
+ for_each_rsnd_clk(clk, adg, i)
dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk));
- }
}
static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
@@ -568,16 +582,12 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
priv->adg = adg;
+ rsnd_adg_clk_enable(priv);
+
return 0;
}
void rsnd_adg_remove(struct rsnd_priv *priv)
{
- struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
- struct clk *clk;
- int i;
-
- for_each_rsnd_clk(clk, adg, i) {
- clk_disable_unprepare(clk);
- }
+ rsnd_adg_clk_disable(priv);
}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index a328bfe..b8de983 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1358,9 +1358,33 @@ static int rsnd_remove(struct platform_device *pdev)
return ret;
}
+static int rsnd_suspend(struct device *dev)
+{
+ struct rsnd_priv *priv = dev_get_drvdata(dev);
+
+ rsnd_adg_clk_disable(priv);
+
+ return 0;
+}
+
+static int rsnd_resume(struct device *dev)
+{
+ struct rsnd_priv *priv = dev_get_drvdata(dev);
+
+ rsnd_adg_clk_enable(priv);
+
+ return 0;
+}
+
+static struct dev_pm_ops rsnd_pm_ops = {
+ .suspend = rsnd_suspend,
+ .resume = rsnd_resume,
+};
+
static struct platform_driver rsnd_driver = {
.driver = {
.name = "rcar_sound",
+ .pm = &rsnd_pm_ops,
.of_match_table = rsnd_of_match,
},
.probe = rsnd_probe,
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index dc05152..f301130 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -501,6 +501,9 @@ int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod,
unsigned int out_rate);
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
struct rsnd_dai_stream *io);
+#define rsnd_adg_clk_enable(priv) rsnd_adg_clk_control(priv, 1)
+#define rsnd_adg_clk_disable(priv) rsnd_adg_clk_control(priv, 0)
+void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable);
/*
* R-Car sound priv
--
2.7.4
More information about the Alsa-devel
mailing list