diff options
| -rw-r--r-- | Documentation/devicetree/bindings/sound/tlv320aic32x4.txt | 4 | ||||
| -rw-r--r-- | sound/soc/codecs/tlv320aic32x4.c | 21 |
2 files changed, 25 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt index db0551088cc4..352be7b1f7e2 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt | |||
| @@ -8,6 +8,8 @@ Required properties: | |||
| 8 | 8 | ||
| 9 | Optional properties: | 9 | Optional properties: |
| 10 | - reset-gpios: Reset-GPIO phandle with args as described in gpio/gpio.txt | 10 | - reset-gpios: Reset-GPIO phandle with args as described in gpio/gpio.txt |
| 11 | - clocks/clock-names: Clock named 'mclk' for the master clock of the codec. | ||
| 12 | See clock/clock-bindings.txt for information about the detailed format. | ||
| 11 | 13 | ||
| 12 | 14 | ||
| 13 | Example: | 15 | Example: |
| @@ -15,4 +17,6 @@ Example: | |||
| 15 | codec: tlv320aic32x4@18 { | 17 | codec: tlv320aic32x4@18 { |
| 16 | compatible = "ti,tlv320aic32x4"; | 18 | compatible = "ti,tlv320aic32x4"; |
| 17 | reg = <0x18>; | 19 | reg = <0x18>; |
| 20 | clocks = <&clks 201>; | ||
| 21 | clock-names = "mclk"; | ||
| 18 | }; | 22 | }; |
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 1dd50e48934c..643fa53beaab 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
| 34 | #include <linux/cdev.h> | 34 | #include <linux/cdev.h> |
| 35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 36 | #include <linux/clk.h> | ||
| 36 | 37 | ||
| 37 | #include <sound/tlv320aic32x4.h> | 38 | #include <sound/tlv320aic32x4.h> |
| 38 | #include <sound/core.h> | 39 | #include <sound/core.h> |
| @@ -67,6 +68,7 @@ struct aic32x4_priv { | |||
| 67 | u32 micpga_routing; | 68 | u32 micpga_routing; |
| 68 | bool swapdacs; | 69 | bool swapdacs; |
| 69 | int rstn_gpio; | 70 | int rstn_gpio; |
| 71 | struct clk *mclk; | ||
| 70 | }; | 72 | }; |
| 71 | 73 | ||
| 72 | /* 0dB min, 0.5dB steps */ | 74 | /* 0dB min, 0.5dB steps */ |
| @@ -487,8 +489,18 @@ static int aic32x4_mute(struct snd_soc_dai *dai, int mute) | |||
| 487 | static int aic32x4_set_bias_level(struct snd_soc_codec *codec, | 489 | static int aic32x4_set_bias_level(struct snd_soc_codec *codec, |
| 488 | enum snd_soc_bias_level level) | 490 | enum snd_soc_bias_level level) |
| 489 | { | 491 | { |
| 492 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | ||
| 493 | int ret; | ||
| 494 | |||
| 490 | switch (level) { | 495 | switch (level) { |
| 491 | case SND_SOC_BIAS_ON: | 496 | case SND_SOC_BIAS_ON: |
| 497 | /* Switch on master clock */ | ||
| 498 | ret = clk_prepare_enable(aic32x4->mclk); | ||
| 499 | if (ret) { | ||
| 500 | dev_err(codec->dev, "Failed to enable master clock\n"); | ||
| 501 | return ret; | ||
| 502 | } | ||
| 503 | |||
| 492 | /* Switch on PLL */ | 504 | /* Switch on PLL */ |
| 493 | snd_soc_update_bits(codec, AIC32X4_PLLPR, | 505 | snd_soc_update_bits(codec, AIC32X4_PLLPR, |
| 494 | AIC32X4_PLLEN, AIC32X4_PLLEN); | 506 | AIC32X4_PLLEN, AIC32X4_PLLEN); |
| @@ -539,6 +551,9 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec, | |||
| 539 | /* Switch off BCLK_N Divider */ | 551 | /* Switch off BCLK_N Divider */ |
| 540 | snd_soc_update_bits(codec, AIC32X4_BCLKN, | 552 | snd_soc_update_bits(codec, AIC32X4_BCLKN, |
| 541 | AIC32X4_BCLKEN, 0); | 553 | AIC32X4_BCLKEN, 0); |
| 554 | |||
| 555 | /* Switch off master clock */ | ||
| 556 | clk_disable_unprepare(aic32x4->mclk); | ||
| 542 | break; | 557 | break; |
| 543 | case SND_SOC_BIAS_OFF: | 558 | case SND_SOC_BIAS_OFF: |
| 544 | break; | 559 | break; |
| @@ -717,6 +732,12 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, | |||
| 717 | aic32x4->rstn_gpio = -1; | 732 | aic32x4->rstn_gpio = -1; |
| 718 | } | 733 | } |
| 719 | 734 | ||
| 735 | aic32x4->mclk = devm_clk_get(&i2c->dev, "mclk"); | ||
| 736 | if (IS_ERR(aic32x4->mclk)) { | ||
| 737 | dev_err(&i2c->dev, "Failed getting the mclk. The current implementation does not support the usage of this codec without mclk\n"); | ||
| 738 | return PTR_ERR(aic32x4->mclk); | ||
| 739 | } | ||
| 740 | |||
| 720 | if (gpio_is_valid(aic32x4->rstn_gpio)) { | 741 | if (gpio_is_valid(aic32x4->rstn_gpio)) { |
| 721 | ret = devm_gpio_request_one(&i2c->dev, aic32x4->rstn_gpio, | 742 | ret = devm_gpio_request_one(&i2c->dev, aic32x4->rstn_gpio, |
| 722 | GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); | 743 | GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); |
