diff mbox

[2/3,v2] ASoC: ak4104: add regulator consumer support

Message ID 1395952936-10670-2-git-send-email-zonque@gmail.com (mailing list archive)
State Accepted
Commit b38d10ed604a1adaafa82512867d0eb7e219d491
Headers show

Commit Message

Daniel Mack March 27, 2014, 8:42 p.m. UTC
The AK4104 has only one power supply, called VDD. Enable it as long as
the codec is in use.

Signed-off-by: Daniel Mack <zonque@gmail.com>
---
 sound/soc/codecs/ak4104.c | 62 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 55 insertions(+), 7 deletions(-)

Comments

Mark Brown March 28, 2014, 11:23 a.m. UTC | #1
On Thu, Mar 27, 2014 at 09:42:15PM +0100, Daniel Mack wrote:
> The AK4104 has only one power supply, called VDD. Enable it as long as
> the codec is in use.

This should update the DT binding too.  Also it seems we still have a
machine driver for Raumfeld using this which doesn't set full
constraints and isn't being updated here so would be broken as far as I
can tell.
Daniel Mack March 28, 2014, 11:27 a.m. UTC | #2
On 03/28/2014 12:23 PM, Mark Brown wrote:
> On Thu, Mar 27, 2014 at 09:42:15PM +0100, Daniel Mack wrote:
>> The AK4104 has only one power supply, called VDD. Enable it as long as
>> the codec is in use.
> 
> This should update the DT binding too.  Also it seems we still have a
> machine driver for Raumfeld using this which doesn't set full
> constraints and isn't being updated here so would be broken as far as I
> can tell.

Yeah, I noticed this one is unfortunately broken since a while already
due to other changes in ASoC. I'm working on fixing this in parallel,
but it's legacy hardware which get less attention than it should. I'll
fix up the constraints along with that.

Want me to resend with a DT bindings fix, or can we do that in 2nd step?


Daniel
Mark Brown March 28, 2014, 11:53 a.m. UTC | #3
On Fri, Mar 28, 2014 at 12:27:14PM +0100, Daniel Mack wrote:

> Yeah, I noticed this one is unfortunately broken since a while already
> due to other changes in ASoC. I'm working on fixing this in parallel,
> but it's legacy hardware which get less attention than it should. I'll
> fix up the constraints along with that.

> Want me to resend with a DT bindings fix, or can we do that in 2nd step?

Do it in a second step if Raumfeld is already broken anyway, I'll go
ahead and apply.
diff mbox

Patch

diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 10adf25..1fd7f72 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -11,13 +11,14 @@ 
 
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
 #include <linux/spi/spi.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
 #include <sound/asoundef.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
 
 /* AK4104 registers addresses */
 #define AK4104_REG_CONTROL1		0x00
@@ -47,6 +48,7 @@ 
 
 struct ak4104_private {
 	struct regmap *regmap;
+	struct regulator *regulator;
 };
 
 static const struct snd_soc_dapm_widget ak4104_dapm_widgets[] = {
@@ -174,20 +176,30 @@  static int ak4104_probe(struct snd_soc_codec *codec)
 	struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
+	ret = regulator_enable(ak4104->regulator);
+	if (ret < 0) {
+		dev_err(codec->dev, "Unable to enable regulator: %d\n", ret);
+		return ret;
+	}
+
 	/* set power-up and non-reset bits */
 	ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,
 				 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN,
 				 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
 	if (ret < 0)
-		return ret;
+		goto exit_disable_regulator;
 
 	/* enable transmitter */
 	ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX,
 				 AK4104_TX_TXE, AK4104_TX_TXE);
 	if (ret < 0)
-		return ret;
+		goto exit_disable_regulator;
 
 	return 0;
+
+exit_disable_regulator:
+	regulator_disable(ak4104->regulator);
+	return ret;
 }
 
 static int ak4104_remove(struct snd_soc_codec *codec)
@@ -196,13 +208,42 @@  static int ak4104_remove(struct snd_soc_codec *codec)
 
 	regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,
 			   AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
+	regulator_disable(ak4104->regulator);
 
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int ak4104_soc_suspend(struct snd_soc_codec *codec)
+{
+	struct ak4104_private *priv = snd_soc_codec_get_drvdata(codec);
+
+	regulator_disable(priv->regulator);
+
+	return 0;
+}
+
+static int ak4104_soc_resume(struct snd_soc_codec *codec)
+{
+	struct ak4104_private *priv = snd_soc_codec_get_drvdata(codec);
+	int ret;
+
+	ret = regulator_enable(priv->regulator);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+#else
+#define ak4104_soc_suspend	NULL
+#define ak4104_soc_resume	NULL
+#endif /* CONFIG_PM */
+
 static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
-	.probe =	ak4104_probe,
-	.remove =	ak4104_remove,
+	.probe = ak4104_probe,
+	.remove = ak4104_remove,
+	.suspend = ak4104_soc_suspend,
+	.resume = ak4104_soc_resume,
 
 	.dapm_widgets = ak4104_dapm_widgets,
 	.num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets),
@@ -239,6 +280,13 @@  static int ak4104_spi_probe(struct spi_device *spi)
 	if (ak4104 == NULL)
 		return -ENOMEM;
 
+	ak4104->regulator = devm_regulator_get(&spi->dev, "vdd");
+	if (IS_ERR(ak4104->regulator)) {
+		ret = PTR_ERR(ak4104->regulator);
+		dev_err(&spi->dev, "Unable to get Vdd regulator: %d\n", ret);
+		return ret;
+	}
+
 	ak4104->regmap = devm_regmap_init_spi(spi, &ak4104_regmap);
 	if (IS_ERR(ak4104->regmap)) {
 		ret = PTR_ERR(ak4104->regmap);