[alsa-devel] [PATCH 1/4] ASoC:rt5670:Add runtime PM support
bardliao at realtek.com
bardliao at realtek.com
Thu Nov 6 05:23:51 CET 2014
From: Bard Liao <bardliao at realtek.com>
This patch adds runtime PM support on rt5670 codec. And will switch
sysclk to internal clock during runtime suspend.
Signed-off-by: Bard Liao <bardliao at realtek.com>
---
sound/soc/codecs/rt5670.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index da4b689..97359b3 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
+#include <linux/pm_runtime.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/firmware.h>
@@ -2666,6 +2667,13 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
/*Give sysclk a default value*/
rt5670->sysclk = 24576000;
+ /* The set initial power status to active, to be consist with ACPI power
+ * state D0. The codec will be suspended after probe and runtime status
+ * change will trigger ACPI D3 method for power saving.
+ */
+ pm_runtime_set_active(&i2c->dev);
+ pm_runtime_enable(&i2c->dev);
+
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670,
rt5670_dai, ARRAY_SIZE(rt5670_dai));
if (ret < 0)
@@ -2673,20 +2681,61 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
return 0;
err:
+ pm_runtime_disable(&i2c->dev);
+
return ret;
}
static int rt5670_i2c_remove(struct i2c_client *i2c)
{
+ pm_runtime_disable(&i2c->dev);
snd_soc_unregister_codec(&i2c->dev);
return 0;
}
+#ifdef CONFIG_PM_RUNTIME
+static void rt5670_use_internal_clk(struct rt5670_priv *rt5670)
+{
+ struct snd_soc_codec *codec = rt5670->codec;
+
+ if (!codec ||
+ (0 == rt5670->sysclk && RT5670_SCLK_S_RCCLK == rt5670->sysclk_src))
+ return;
+
+ snd_soc_update_bits(codec, RT5670_GLB_CLK,
+ RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK);
+
+ rt5670->sysclk = 0;
+ rt5670->sysclk_src = RT5670_SCLK_S_RCCLK;
+}
+
+static int rt5670_runtime_suspend(struct device *dev)
+{
+ struct rt5670_priv *rt5670 = dev_get_drvdata(dev);
+
+ rt5670_use_internal_clk(rt5670);
+ return 0;
+}
+
+static int rt5670_runtime_resume(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops rt5670_pm = {
+ SET_RUNTIME_PM_OPS(rt5670_runtime_suspend, rt5670_runtime_resume, NULL)
+};
+#define RT5670_PM_OPS rt5670_pm
+#else
+#define RT5670_PM_OPS NULL
+#endif /* CONFIG_PM_RUNTIME */
+
static struct i2c_driver rt5670_i2c_driver = {
.driver = {
.name = "rt5670",
.owner = THIS_MODULE,
+ .pm = &RT5670_PM_OPS,
},
.probe = rt5670_i2c_probe,
.remove = rt5670_i2c_remove,
--
1.8.1.1.439.g50a6b54
More information about the Alsa-devel
mailing list