aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-12-13 03:29:00 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-12-24 10:42:33 -0500
commit514cfd6dd72508b79030c8504764a73a7261b713 (patch)
tree94bb3b9dc270b9acc979aa79cef4367c51ce0a41 /sound/soc/codecs
parenta49f0d1ea3ec94fc7cf33a7c36a16343b74bd565 (diff)
ASoC: wm2000: Integrate with clock API
Request MCLK as a clock and then enable it when carrying out a state transtion and while ANC is active, minimising system power consumption in idle modes. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/wm2000.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 1cbe88f01d63..0aba8ce424ca 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -26,6 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/firmware.h> 28#include <linux/firmware.h>
29#include <linux/clk.h>
29#include <linux/delay.h> 30#include <linux/delay.h>
30#include <linux/pm.h> 31#include <linux/pm.h>
31#include <linux/i2c.h> 32#include <linux/i2c.h>
@@ -62,6 +63,7 @@ enum wm2000_anc_mode {
62struct wm2000_priv { 63struct wm2000_priv {
63 struct i2c_client *i2c; 64 struct i2c_client *i2c;
64 struct regmap *regmap; 65 struct regmap *regmap;
66 struct clk *mclk;
65 67
66 struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES]; 68 struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES];
67 69
@@ -550,6 +552,15 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000,
550 return -EINVAL; 552 return -EINVAL;
551 } 553 }
552 554
555 /* Maintain clock while active */
556 if (anc_transitions[i].source == ANC_OFF) {
557 ret = clk_prepare_enable(wm2000->mclk);
558 if (ret != 0) {
559 dev_err(&i2c->dev, "Failed to enable MCLK: %d\n", ret);
560 return ret;
561 }
562 }
563
553 for (j = 0; j < ARRAY_SIZE(anc_transitions[j].step); j++) { 564 for (j = 0; j < ARRAY_SIZE(anc_transitions[j].step); j++) {
554 if (!anc_transitions[i].step[j]) 565 if (!anc_transitions[i].step[j])
555 break; 566 break;
@@ -559,7 +570,10 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000,
559 return ret; 570 return ret;
560 } 571 }
561 572
562 return 0; 573 if (anc_transitions[i].dest == ANC_OFF)
574 clk_disable_unprepare(wm2000->mclk);
575
576 return ret;
563} 577}
564 578
565static int wm2000_anc_set_mode(struct wm2000_priv *wm2000) 579static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
@@ -823,6 +837,13 @@ static int wm2000_i2c_probe(struct i2c_client *i2c,
823 reg = wm2000_read(i2c, WM2000_REG_REVISON); 837 reg = wm2000_read(i2c, WM2000_REG_REVISON);
824 dev_info(&i2c->dev, "revision %c\n", reg + 'A'); 838 dev_info(&i2c->dev, "revision %c\n", reg + 'A');
825 839
840 wm2000->mclk = devm_clk_get(&i2c->dev, "MCLK");
841 if (IS_ERR(wm2000->mclk)) {
842 ret = PTR_ERR(wm2000->mclk);
843 dev_err(&i2c->dev, "Failed to get MCLK: %d\n", ret);
844 goto err_supplies;
845 }
846
826 filename = "wm2000_anc.bin"; 847 filename = "wm2000_anc.bin";
827 pdata = dev_get_platdata(&i2c->dev); 848 pdata = dev_get_platdata(&i2c->dev);
828 if (pdata) { 849 if (pdata) {