diff options
Diffstat (limited to 'sound/soc/codecs/wm8731.c')
| -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 c6d10533e2bd..2245b6a32f3d 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); |
