summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/wm8962.h1
-rw-r--r--sound/soc/codecs/wm8962.c19
2 files changed, 20 insertions, 0 deletions
diff --git a/include/sound/wm8962.h b/include/sound/wm8962.h
index 79e6d427b858..0af7c1674cbf 100644
--- a/include/sound/wm8962.h
+++ b/include/sound/wm8962.h
@@ -37,6 +37,7 @@
#define WM8962_GPIO_FN_MICSCD 22
struct wm8962_pdata {
+ struct clk *mclk;
int gpio_base;
u32 gpio_init[WM8962_MAX_GPIO];
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index ca2fda9d72be..eac29031ae26 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/gcd.h>
@@ -3541,6 +3542,8 @@ static int wm8962_set_pdata_from_of(struct i2c_client *i2c,
pdata->gpio_init[i] = 0x0;
}
+ pdata->mclk = devm_clk_get(&i2c->dev, NULL);
+
return 0;
}
@@ -3572,6 +3575,14 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
return ret;
}
+ /* Mark the mclk pointer to NULL if no mclk assigned */
+ if (IS_ERR(wm8962->pdata.mclk)) {
+ /* But do not ignore the request for probe defer */
+ if (PTR_ERR(wm8962->pdata.mclk) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ wm8962->pdata.mclk = NULL;
+ }
+
for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
wm8962->supplies[i].supply = wm8962_supply_names[i];
@@ -3780,6 +3791,12 @@ static int wm8962_runtime_resume(struct device *dev)
struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
int ret;
+ ret = clk_prepare_enable(wm8962->pdata.mclk);
+ if (ret) {
+ dev_err(dev, "Failed to enable MCLK: %d\n", ret);
+ return ret;
+ }
+
ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
wm8962->supplies);
if (ret != 0) {
@@ -3839,6 +3856,8 @@ static int wm8962_runtime_suspend(struct device *dev)
regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
wm8962->supplies);
+ clk_disable_unprepare(wm8962->pdata.mclk);
+
return 0;
}
#endif