diff options
author | Songjun Wu <songjun.wu@atmel.com> | 2015-03-11 22:17:11 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-03-16 11:00:39 -0400 |
commit | 99d422341376443a98ef22d0f0003b3381f32186 (patch) | |
tree | bae29847615ff7f83c1385dd274054e688a3b4e0 /sound | |
parent | c517d838eb7d07bbe9507871fab3931deccff539 (diff) |
ASoC: wm8731: let codec to manage clock by itself
Enable WM8731 to support common clock framework.
Signed-off-by: Songjun Wu <songjun.wu@atmel.com>
Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/wm8731.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 098c143f44d6..8df1550f74b5 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
26 | #include <linux/of_device.h> | 26 | #include <linux/of_device.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/clk.h> | ||
28 | #include <sound/core.h> | 29 | #include <sound/core.h> |
29 | #include <sound/pcm.h> | 30 | #include <sound/pcm.h> |
30 | #include <sound/pcm_params.h> | 31 | #include <sound/pcm_params.h> |
@@ -45,6 +46,7 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { | |||
45 | /* codec private data */ | 46 | /* codec private data */ |
46 | struct wm8731_priv { | 47 | struct wm8731_priv { |
47 | struct regmap *regmap; | 48 | struct regmap *regmap; |
49 | struct clk *mclk; | ||
48 | struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; | 50 | struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; |
49 | const struct snd_pcm_hw_constraint_list *constraints; | 51 | const struct snd_pcm_hw_constraint_list *constraints; |
50 | unsigned int sysclk; | 52 | unsigned int sysclk; |
@@ -390,6 +392,8 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
390 | switch (clk_id) { | 392 | switch (clk_id) { |
391 | case WM8731_SYSCLK_XTAL: | 393 | case WM8731_SYSCLK_XTAL: |
392 | case WM8731_SYSCLK_MCLK: | 394 | case WM8731_SYSCLK_MCLK: |
395 | if (wm8731->mclk && clk_set_rate(wm8731->mclk, freq)) | ||
396 | return -EINVAL; | ||
393 | wm8731->sysclk_type = clk_id; | 397 | wm8731->sysclk_type = clk_id; |
394 | break; | 398 | break; |
395 | default: | 399 | default: |
@@ -491,6 +495,8 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, | |||
491 | 495 | ||
492 | switch (level) { | 496 | switch (level) { |
493 | case SND_SOC_BIAS_ON: | 497 | case SND_SOC_BIAS_ON: |
498 | if (wm8731->mclk) | ||
499 | clk_prepare_enable(wm8731->mclk); | ||
494 | break; | 500 | break; |
495 | case SND_SOC_BIAS_PREPARE: | 501 | case SND_SOC_BIAS_PREPARE: |
496 | break; | 502 | break; |
@@ -509,6 +515,8 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, | |||
509 | snd_soc_write(codec, WM8731_PWR, reg | 0x0040); | 515 | snd_soc_write(codec, WM8731_PWR, reg | 0x0040); |
510 | break; | 516 | break; |
511 | case SND_SOC_BIAS_OFF: | 517 | case SND_SOC_BIAS_OFF: |
518 | if (wm8731->mclk) | ||
519 | clk_disable_unprepare(wm8731->mclk); | ||
512 | snd_soc_write(codec, WM8731_PWR, 0xffff); | 520 | snd_soc_write(codec, WM8731_PWR, 0xffff); |
513 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), | 521 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), |
514 | wm8731->supplies); | 522 | wm8731->supplies); |
@@ -667,6 +675,19 @@ static int wm8731_spi_probe(struct spi_device *spi) | |||
667 | if (wm8731 == NULL) | 675 | if (wm8731 == NULL) |
668 | return -ENOMEM; | 676 | return -ENOMEM; |
669 | 677 | ||
678 | wm8731->mclk = devm_clk_get(&spi->dev, "mclk"); | ||
679 | if (IS_ERR(wm8731->mclk)) { | ||
680 | ret = PTR_ERR(wm8731->mclk); | ||
681 | if (ret == -ENOENT) { | ||
682 | wm8731->mclk = NULL; | ||
683 | dev_warn(&spi->dev, "Assuming static MCLK\n"); | ||
684 | } else { | ||
685 | dev_err(&spi->dev, "Failed to get MCLK: %d\n", | ||
686 | ret); | ||
687 | return ret; | ||
688 | } | ||
689 | } | ||
690 | |||
670 | mutex_init(&wm8731->lock); | 691 | mutex_init(&wm8731->lock); |
671 | 692 | ||
672 | wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap); | 693 | wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap); |
@@ -718,6 +739,19 @@ static int wm8731_i2c_probe(struct i2c_client *i2c, | |||
718 | if (wm8731 == NULL) | 739 | if (wm8731 == NULL) |
719 | return -ENOMEM; | 740 | return -ENOMEM; |
720 | 741 | ||
742 | wm8731->mclk = devm_clk_get(&i2c->dev, "mclk"); | ||
743 | if (IS_ERR(wm8731->mclk)) { | ||
744 | ret = PTR_ERR(wm8731->mclk); | ||
745 | if (ret == -ENOENT) { | ||
746 | wm8731->mclk = NULL; | ||
747 | dev_warn(&i2c->dev, "Assuming static MCLK\n"); | ||
748 | } else { | ||
749 | dev_err(&i2c->dev, "Failed to get MCLK: %d\n", | ||
750 | ret); | ||
751 | return ret; | ||
752 | } | ||
753 | } | ||
754 | |||
721 | mutex_init(&wm8731->lock); | 755 | mutex_init(&wm8731->lock); |
722 | 756 | ||
723 | wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap); | 757 | wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap); |