[alsa-devel] [PATCH] ASoC: wm8994: codec driver should manage its own MCLK
Zidan Wang
zidan.wang at freescale.com
Thu Mar 3 07:45:35 CET 2016
codec driver should manage its own master clock, MCLK1 and MCLK2.
When bias_level change from standby to prepare, enable codec MCLK.
When bias_level change from prepare to standby, disable codec MCLK.
Signed-off-by: Zidan Wang <zidan.wang at freescale.com>
---
drivers/mfd/wm8994-core.c | 7 +++++++
include/linux/mfd/wm8994/pdata.h | 3 +++
sound/soc/codecs/wm8994.c | 17 +++++++++++++++--
3 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 7eec619..ace2cea 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/err.h>
@@ -270,6 +271,7 @@ static int wm8994_set_pdata_from_of(struct wm8994 *wm8994)
{
struct device_node *np = wm8994->dev->of_node;
struct wm8994_pdata *pdata = &wm8994->pdata;
+ char tmp[8];
int i;
if (!np)
@@ -310,6 +312,11 @@ static int wm8994_set_pdata_from_of(struct wm8994 *wm8994)
if (pdata->ldo[1].enable < 0)
pdata->ldo[1].enable = 0;
+ for (i = 0; i < WM8994_NUM_MCLK; i++) {
+ sprintf(tmp, "MCLK%d", i + 1);
+ pdata->mclk[i] = devm_clk_get(wm8994->dev, tmp);
+ }
+
return 0;
}
#else
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index 90c6052..657a828 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -18,6 +18,7 @@
#define WM8994_NUM_LDO 2
#define WM8994_NUM_GPIO 11
#define WM8994_NUM_AIF 3
+#define WM8994_NUM_MCLK 2
struct wm8994_ldo_pdata {
/** GPIOs to enable regulator, 0 or less if not available */
@@ -233,6 +234,8 @@ struct wm8994_pdata {
* GPIO for the IRQ pin if host only supports edge triggering
*/
int irq_gpio;
+
+ struct clk *mclk[WM8994_NUM_MCLK];
};
#endif
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 2ccbb32..7379eae 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/gcd.h>
+#include <linux/clk.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -2474,6 +2475,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994 *control = wm8994->wm8994;
+ struct wm8994_pdata *pdata = &control->pdata;
+ int i;
wm_hubs_set_bias_level(codec, level);
@@ -2495,8 +2498,13 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
break;
}
- if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY)
+ if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
active_reference(codec);
+
+ for (i = 0; i < WM8994_NUM_MCLK; i++)
+ if (!IS_ERR(pdata->mclk[i]))
+ clk_prepare_enable(pdata->mclk[i]);
+ }
break;
case SND_SOC_BIAS_STANDBY:
@@ -2524,8 +2532,13 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
WM8994_LINEOUT2_DISCH);
}
- if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE)
+ if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE) {
+ for (i = 0; i < WM8994_NUM_MCLK; i++)
+ if (!IS_ERR(pdata->mclk[i]))
+ clk_disable_unprepare(pdata->mclk[i]);
+
active_dereference(codec);
+ }
/* MICBIAS into bypass mode on newer devices */
switch (control->type) {
--
1.9.1
More information about the Alsa-devel
mailing list