diff options
author | Markus Pargmann <mpa@pengutronix.de> | 2014-02-20 12:22:59 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-02-22 22:59:31 -0500 |
commit | 239b669b2dedc46d5e6b07d87c3d1dedf8d9477c (patch) | |
tree | b150ff9d9af91974b7bff8ba8f24b454a9fc45e4 | |
parent | 98b664e2ceddd40120e8cd2aa56f7eb9a51870cf (diff) |
ASoC: tlv320aic32x4: Support for regulators
Support regulators to power up the codec. This patch also enables the
AVDD LDO if no AV regulator was found.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | Documentation/devicetree/bindings/sound/tlv320aic32x4.txt | 8 | ||||
-rw-r--r-- | sound/soc/codecs/tlv320aic32x4.c | 126 |
2 files changed, 133 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt index 352be7b1f7e2..5e2741af27be 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt | |||
@@ -5,6 +5,14 @@ The tlv320aic32x4 serial control bus communicates through I2C protocols | |||
5 | Required properties: | 5 | Required properties: |
6 | - compatible: Should be "ti,tlv320aic32x4" | 6 | - compatible: Should be "ti,tlv320aic32x4" |
7 | - reg: I2C slave address | 7 | - reg: I2C slave address |
8 | - supply-*: Required supply regulators are: | ||
9 | "iov" - digital IO power supply | ||
10 | "ldoin" - LDO power supply | ||
11 | "dv" - Digital core power supply | ||
12 | "av" - Analog core power supply | ||
13 | If you supply ldoin, dv and av are optional. Otherwise they are required | ||
14 | See regulator/regulator.txt for more information about the detailed binding | ||
15 | format. | ||
8 | 16 | ||
9 | Optional properties: | 17 | Optional properties: |
10 | - reset-gpios: Reset-GPIO phandle with args as described in gpio/gpio.txt | 18 | - reset-gpios: Reset-GPIO phandle with args as described in gpio/gpio.txt |
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 643fa53beaab..d69c61ffcda8 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -34,6 +34,7 @@ | |||
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 | #include <linux/clk.h> |
37 | #include <linux/regulator/consumer.h> | ||
37 | 38 | ||
38 | #include <sound/tlv320aic32x4.h> | 39 | #include <sound/tlv320aic32x4.h> |
39 | #include <sound/core.h> | 40 | #include <sound/core.h> |
@@ -69,6 +70,11 @@ struct aic32x4_priv { | |||
69 | bool swapdacs; | 70 | bool swapdacs; |
70 | int rstn_gpio; | 71 | int rstn_gpio; |
71 | struct clk *mclk; | 72 | struct clk *mclk; |
73 | |||
74 | struct regulator *supply_ldo; | ||
75 | struct regulator *supply_iov; | ||
76 | struct regulator *supply_dv; | ||
77 | struct regulator *supply_av; | ||
72 | }; | 78 | }; |
73 | 79 | ||
74 | /* 0dB min, 0.5dB steps */ | 80 | /* 0dB min, 0.5dB steps */ |
@@ -695,6 +701,106 @@ static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, | |||
695 | return 0; | 701 | return 0; |
696 | } | 702 | } |
697 | 703 | ||
704 | static void aic32x4_disable_regulators(struct aic32x4_priv *aic32x4) | ||
705 | { | ||
706 | regulator_disable(aic32x4->supply_iov); | ||
707 | |||
708 | if (!IS_ERR(aic32x4->supply_ldo)) | ||
709 | regulator_disable(aic32x4->supply_ldo); | ||
710 | |||
711 | if (!IS_ERR(aic32x4->supply_dv)) | ||
712 | regulator_disable(aic32x4->supply_dv); | ||
713 | |||
714 | if (!IS_ERR(aic32x4->supply_av)) | ||
715 | regulator_disable(aic32x4->supply_av); | ||
716 | } | ||
717 | |||
718 | static int aic32x4_setup_regulators(struct device *dev, | ||
719 | struct aic32x4_priv *aic32x4) | ||
720 | { | ||
721 | int ret = 0; | ||
722 | |||
723 | aic32x4->supply_ldo = devm_regulator_get_optional(dev, "ldoin"); | ||
724 | aic32x4->supply_iov = devm_regulator_get(dev, "iov"); | ||
725 | aic32x4->supply_dv = devm_regulator_get_optional(dev, "dv"); | ||
726 | aic32x4->supply_av = devm_regulator_get_optional(dev, "av"); | ||
727 | |||
728 | /* Check if the regulator requirements are fulfilled */ | ||
729 | |||
730 | if (IS_ERR(aic32x4->supply_iov)) { | ||
731 | dev_err(dev, "Missing supply 'iov'\n"); | ||
732 | return PTR_ERR(aic32x4->supply_iov); | ||
733 | } | ||
734 | |||
735 | if (IS_ERR(aic32x4->supply_ldo)) { | ||
736 | if (PTR_ERR(aic32x4->supply_ldo) == -EPROBE_DEFER) | ||
737 | return -EPROBE_DEFER; | ||
738 | |||
739 | if (IS_ERR(aic32x4->supply_dv)) { | ||
740 | dev_err(dev, "Missing supply 'dv' or 'ldoin'\n"); | ||
741 | return PTR_ERR(aic32x4->supply_dv); | ||
742 | } | ||
743 | if (IS_ERR(aic32x4->supply_av)) { | ||
744 | dev_err(dev, "Missing supply 'av' or 'ldoin'\n"); | ||
745 | return PTR_ERR(aic32x4->supply_av); | ||
746 | } | ||
747 | } else { | ||
748 | if (IS_ERR(aic32x4->supply_dv) && | ||
749 | PTR_ERR(aic32x4->supply_dv) == -EPROBE_DEFER) | ||
750 | return -EPROBE_DEFER; | ||
751 | if (IS_ERR(aic32x4->supply_av) && | ||
752 | PTR_ERR(aic32x4->supply_av) == -EPROBE_DEFER) | ||
753 | return -EPROBE_DEFER; | ||
754 | } | ||
755 | |||
756 | ret = regulator_enable(aic32x4->supply_iov); | ||
757 | if (ret) { | ||
758 | dev_err(dev, "Failed to enable regulator iov\n"); | ||
759 | return ret; | ||
760 | } | ||
761 | |||
762 | if (!IS_ERR(aic32x4->supply_ldo)) { | ||
763 | ret = regulator_enable(aic32x4->supply_ldo); | ||
764 | if (ret) { | ||
765 | dev_err(dev, "Failed to enable regulator ldo\n"); | ||
766 | goto error_ldo; | ||
767 | } | ||
768 | } | ||
769 | |||
770 | if (!IS_ERR(aic32x4->supply_dv)) { | ||
771 | ret = regulator_enable(aic32x4->supply_dv); | ||
772 | if (ret) { | ||
773 | dev_err(dev, "Failed to enable regulator dv\n"); | ||
774 | goto error_dv; | ||
775 | } | ||
776 | } | ||
777 | |||
778 | if (!IS_ERR(aic32x4->supply_av)) { | ||
779 | ret = regulator_enable(aic32x4->supply_av); | ||
780 | if (ret) { | ||
781 | dev_err(dev, "Failed to enable regulator av\n"); | ||
782 | goto error_av; | ||
783 | } | ||
784 | } | ||
785 | |||
786 | if (!IS_ERR(aic32x4->supply_ldo) && IS_ERR(aic32x4->supply_av)) | ||
787 | aic32x4->power_cfg |= AIC32X4_PWR_AIC32X4_LDO_ENABLE; | ||
788 | |||
789 | return 0; | ||
790 | |||
791 | error_av: | ||
792 | if (!IS_ERR(aic32x4->supply_dv)) | ||
793 | regulator_disable(aic32x4->supply_dv); | ||
794 | |||
795 | error_dv: | ||
796 | if (!IS_ERR(aic32x4->supply_ldo)) | ||
797 | regulator_disable(aic32x4->supply_ldo); | ||
798 | |||
799 | error_ldo: | ||
800 | regulator_disable(aic32x4->supply_iov); | ||
801 | return ret; | ||
802 | } | ||
803 | |||
698 | static int aic32x4_i2c_probe(struct i2c_client *i2c, | 804 | static int aic32x4_i2c_probe(struct i2c_client *i2c, |
699 | const struct i2c_device_id *id) | 805 | const struct i2c_device_id *id) |
700 | { | 806 | { |
@@ -745,13 +851,31 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c, | |||
745 | return ret; | 851 | return ret; |
746 | } | 852 | } |
747 | 853 | ||
854 | ret = aic32x4_setup_regulators(&i2c->dev, aic32x4); | ||
855 | if (ret) { | ||
856 | dev_err(&i2c->dev, "Failed to setup regulators\n"); | ||
857 | return ret; | ||
858 | } | ||
859 | |||
748 | ret = snd_soc_register_codec(&i2c->dev, | 860 | ret = snd_soc_register_codec(&i2c->dev, |
749 | &soc_codec_dev_aic32x4, &aic32x4_dai, 1); | 861 | &soc_codec_dev_aic32x4, &aic32x4_dai, 1); |
750 | return ret; | 862 | if (ret) { |
863 | dev_err(&i2c->dev, "Failed to register codec\n"); | ||
864 | aic32x4_disable_regulators(aic32x4); | ||
865 | return ret; | ||
866 | } | ||
867 | |||
868 | i2c_set_clientdata(i2c, aic32x4); | ||
869 | |||
870 | return 0; | ||
751 | } | 871 | } |
752 | 872 | ||
753 | static int aic32x4_i2c_remove(struct i2c_client *client) | 873 | static int aic32x4_i2c_remove(struct i2c_client *client) |
754 | { | 874 | { |
875 | struct aic32x4_priv *aic32x4 = i2c_get_clientdata(client); | ||
876 | |||
877 | aic32x4_disable_regulators(aic32x4); | ||
878 | |||
755 | snd_soc_unregister_codec(&client->dev); | 879 | snd_soc_unregister_codec(&client->dev); |
756 | return 0; | 880 | return 0; |
757 | } | 881 | } |