aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorNicolin Chen <nicoleotsuka@gmail.com>2014-07-29 06:38:39 -0400
committerMark Brown <broonie@linaro.org>2014-07-31 15:51:26 -0400
commitd7821953cfe9803c593a682320468ce2de862803 (patch)
tree4919f011ce7e05397a6e40c5de782ada5269cd8d /sound
parent7171511eaec5bf23fb06078f59784a3a0626b38f (diff)
ASoC: wm8962: Let CODEC driver enable and disable its own MCLK
snd_soc_open() will trigger pm_runtime resume() which will then enable the regulator and initialization. So we should make sure the MCLK is enabled before this resume(). Previously we let the machine driver get the clock and enable it in its probe(). However, considering about power saving, it'll be better to enable it when it's going to be used and disable it after using. So this patch just simply adds clk_get() and clk_enable() to WM8962 driver. Meanwhile, it marks clock pointer to NULL if no clock assigned to it so it will not break any current function. Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/wm8962.c19
1 files changed, 19 insertions, 0 deletions
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 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/clk.h>
17#include <linux/delay.h> 18#include <linux/delay.h>
18#include <linux/pm.h> 19#include <linux/pm.h>
19#include <linux/gcd.h> 20#include <linux/gcd.h>
@@ -3541,6 +3542,8 @@ static int wm8962_set_pdata_from_of(struct i2c_client *i2c,
3541 pdata->gpio_init[i] = 0x0; 3542 pdata->gpio_init[i] = 0x0;
3542 } 3543 }
3543 3544
3545 pdata->mclk = devm_clk_get(&i2c->dev, NULL);
3546
3544 return 0; 3547 return 0;
3545} 3548}
3546 3549
@@ -3572,6 +3575,14 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
3572 return ret; 3575 return ret;
3573 } 3576 }
3574 3577
3578 /* Mark the mclk pointer to NULL if no mclk assigned */
3579 if (IS_ERR(wm8962->pdata.mclk)) {
3580 /* But do not ignore the request for probe defer */
3581 if (PTR_ERR(wm8962->pdata.mclk) == -EPROBE_DEFER)
3582 return -EPROBE_DEFER;
3583 wm8962->pdata.mclk = NULL;
3584 }
3585
3575 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) 3586 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
3576 wm8962->supplies[i].supply = wm8962_supply_names[i]; 3587 wm8962->supplies[i].supply = wm8962_supply_names[i];
3577 3588
@@ -3780,6 +3791,12 @@ static int wm8962_runtime_resume(struct device *dev)
3780 struct wm8962_priv *wm8962 = dev_get_drvdata(dev); 3791 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
3781 int ret; 3792 int ret;
3782 3793
3794 ret = clk_prepare_enable(wm8962->pdata.mclk);
3795 if (ret) {
3796 dev_err(dev, "Failed to enable MCLK: %d\n", ret);
3797 return ret;
3798 }
3799
3783 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), 3800 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
3784 wm8962->supplies); 3801 wm8962->supplies);
3785 if (ret != 0) { 3802 if (ret != 0) {
@@ -3839,6 +3856,8 @@ static int wm8962_runtime_suspend(struct device *dev)
3839 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), 3856 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
3840 wm8962->supplies); 3857 wm8962->supplies);
3841 3858
3859 clk_disable_unprepare(wm8962->pdata.mclk);
3860
3842 return 0; 3861 return 0;
3843} 3862}
3844#endif 3863#endif