All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Mack <daniel@caiaq.de>
To: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: alsa-devel@alsa-project.org, Timur Tabi <timur@freescale.com>,
	Liam Girdwood <lrg@slimlogic.co.uk>
Subject: Re: [PATCH] ALSA: ASoc: Add regulator support to CS4270 codec driver
Date: Thu, 26 Nov 2009 18:42:45 +0100	[thread overview]
Message-ID: <20091126174245.GJ14091@buzzloop.caiaq.de> (raw)
In-Reply-To: <20091126160351.GB10674@rakim.wolfsonmicro.main>

On Thu, Nov 26, 2009 at 04:03:51PM +0000, Mark Brown wrote:
> On Thu, Nov 26, 2009 at 04:48:07PM +0100, Daniel Mack wrote:
> 
> > - I only added VA for now because when VD is disabled, we need to
> >   restore all codec information, and I can't test that here. We can
> >   still add that later, right?
> 
> I'd suggest just adding it blind.  The code is very simple and it's much
> easier to fix if there's a problem than it is to go through retrofit the
> additional regulator hookups to boards if the other supplies are added
> later.
> 
> You can test the flow by defining a fixed voltage regulator with no soft
> control, obviously it won't actually turn the power on or off but the
> code will run.

Ok. I couldn't find a dummy framework for such cases, and registering a
full regulator just to satisfy the codec code seems a litte cumbersome.
Is there anything like that? Or should there be?

> Just fail if you can't get the supply.  If you can't get the regulator
> then you've no analogue supply and the CODEC isn't going to work
> terribly well.  Currently the assumption is that if you've built in the
> regulator API you intend to use it, otherwise it's very hard to tell if
> the operation failed and broke something or failed because the API isn't
> in use.

Hmm - that will break all existing platforms that use this codec and
need regulators for other drivers. But ok, I'm fine with forcing
everyone to innovation :)

> >  	struct cs4270_private *cs4270 = i2c_get_clientdata(client);
> >  	struct snd_soc_codec *codec = &cs4270->codec;
> >  
> > +	cs4270_set_bias_level(codec, SND_SOC_BIAS_OFF);
> > +
> >  	return snd_soc_suspend_device(codec->dev);
> >  }
> 
> This patch isn't against current for-2.6.33 - those functions have been
> removed.  Better to do the bias management in the ASoC suspend/resume
> callbacks anyway so that it's joined up with the register save/restore.
> Until we get the pm_link stuff in the next merge window there's no link
> between the I2C bus suspend and the platform bus suspend for the ASoC
> core.

Ok, done - see the new patch below. I did use the regulator_bulk
functions in the first place, but due to the VA special case, I had to
extract the single regulators again from the bulk struct which turned
out to mess the code quite a bit. Looks better this way.

Thanks,
Daniel


>From dedbbb7ee101f635e9682559d31e48b4c57722a3 Mon Sep 17 00:00:00 2001
From: Daniel Mack <daniel@caiaq.de>
Date: Wed, 25 Nov 2009 15:31:25 +0100
Subject: [PATCH] ALSA: ASoc: Add regulator support to CS4270 codec driver

Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Timur Tabi <timur@freescale.com>
Cc: Liam Girdwood <lrg@slimlogic.co.uk>
---
 sound/soc/codecs/cs4270.c |   90 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 8069023..e79d30d 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -28,6 +28,7 @@
 #include <sound/initval.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/regulator/consumer.h>
 
 #include "cs4270.h"
 
@@ -114,6 +115,11 @@ struct cs4270_private {
 	unsigned int mode; /* The mode (I2S or left-justified) */
 	unsigned int slave_mode;
 	unsigned int manual_mute;
+
+	/* power domain regulators (optional) */
+	struct regulator *va_reg;
+	struct regulator *vd_reg;
+	struct regulator *vlc_reg;
 };
 
 /**
@@ -458,6 +464,56 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
 }
 
 /**
+ * cs4270_set_bias_level - catches BIAS level changes
+ * @dai: the SOC DAI
+ * @level: the new BIAS level
+ *
+ * This function controls the voltage regulators to properly
+ * power up/down the voltage regulator domains
+ */
+
+static int cs4270_set_bias_level(struct snd_soc_codec *codec,
+				 enum snd_soc_bias_level level)
+{
+	int ret;
+	struct cs4270_private *cs4270 = codec->private_data;
+
+	switch (level) {
+	case SND_SOC_BIAS_ON:
+		ret = regulator_enable(cs4270->vd_reg);
+		if (ret < 0)
+			return ret;
+
+		ret = regulator_enable(cs4270->vlc_reg);
+		if (ret < 0)
+			return ret;
+		/* fall thru */
+	case SND_SOC_BIAS_PREPARE:
+		ret = regulator_enable(cs4270->va_reg);
+		if (ret < 0)
+			return ret;
+		break;
+	case SND_SOC_BIAS_STANDBY:
+		if (codec->bias_level == SND_SOC_BIAS_OFF) {
+			/* OFF -> STANDBY */
+			ret = regulator_enable(cs4270->va_reg);
+			if (ret < 0)
+				return ret;
+		} else
+			regulator_disable(cs4270->va_reg);
+		break;
+	case SND_SOC_BIAS_OFF:
+		regulator_disable(cs4270->va_reg);
+		regulator_disable(cs4270->vd_reg);
+		regulator_disable(cs4270->vlc_reg);
+		break;
+	}
+
+	codec->bias_level = level;
+	return 0;
+}
+
+/**
  * cs4270_dai_mute - enable/disable the CS4270 external mute
  * @dai: the SOC DAI
  * @mute: 0 = disable mute, 1 = enable mute
@@ -579,6 +635,7 @@ static int cs4270_probe(struct platform_device *pdev)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
 	struct snd_soc_codec *codec = cs4270_codec;
+	struct cs4270_private *cs4270 = codec->private_data;
 	int ret;
 
 	/* Connect the codec to the socdev.  snd_soc_new_pcms() needs this. */
@@ -599,6 +656,20 @@ static int cs4270_probe(struct platform_device *pdev)
 		goto error_free_pcms;
 	}
 
+	/* get the power supply regulators */
+	cs4270->va_reg = regulator_get(&pdev->dev, "va");
+	cs4270->vd_reg = regulator_get(&pdev->dev, "vd");
+	cs4270->vlc_reg = regulator_get(&pdev->dev, "vlc");
+
+	if (IS_ERR(cs4270->va_reg) ||
+	    IS_ERR(cs4270->vd_reg) ||
+	    IS_ERR(cs4270->vlc_reg)) {
+		dev_err(codec->dev, "failed to get supplies %s\n", dev_name(codec->dev));
+		goto error_free_pcms;
+	}
+
+	cs4270_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
 	/* And finally, register the socdev */
 	ret = snd_soc_init_card(socdev);
 	if (ret < 0) {
@@ -609,6 +680,10 @@ static int cs4270_probe(struct platform_device *pdev)
 	return 0;
 
 error_free_pcms:
+	regulator_put(cs4270->va_reg);
+	regulator_put(cs4270->vd_reg);
+	regulator_put(cs4270->vlc_reg);
+
 	snd_soc_free_pcms(socdev);
 
 	return ret;
@@ -623,9 +698,15 @@ error_free_pcms:
 static int cs4270_remove(struct platform_device *pdev)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+	struct snd_soc_codec *codec = cs4270_codec;
+	struct cs4270_private *cs4270 = codec->private_data;
 
 	snd_soc_free_pcms(socdev);
 
+	regulator_put(cs4270->va_reg);
+	regulator_put(cs4270->vd_reg);
+	regulator_put(cs4270->vlc_reg);
+
 	return 0;
 };
 
@@ -699,6 +780,8 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
 	codec->write = cs4270_i2c_write;
 	codec->reg_cache = cs4270->reg_cache;
 	codec->reg_cache_size = CS4270_NUMREGS;
+	codec->bias_level = SND_SOC_BIAS_OFF;
+	codec->set_bias_level = cs4270_set_bias_level;
 
 	/* The I2C interface is set up, so pre-fill our register cache */
 
@@ -824,6 +907,8 @@ static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
 	struct snd_soc_codec *codec = cs4270_codec;
 	int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
 
+	cs4270_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
 	return snd_soc_write(codec, CS4270_PWRCTL, reg);
 }
 
@@ -833,6 +918,11 @@ static int cs4270_soc_resume(struct platform_device *pdev)
 	struct i2c_client *i2c_client = codec->control_data;
 	int reg;
 
+	cs4270_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+	if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
+		cs4270_set_bias_level(codec, SND_SOC_BIAS_ON);
+
 	/* In case the device was put to hard reset during sleep, we need to
 	 * wait 500ns here before any I2C communication. */
 	ndelay(500);
-- 
1.6.5.2

  reply	other threads:[~2009-11-26 17:42 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-25 14:36 [PATCH] ALSA: ASoc: Add regulator support to CS4270 codec driver Daniel Mack
2009-11-25 15:01 ` Mark Brown
2009-11-25 15:20   ` Daniel Mack
2009-11-25 15:38     ` Mark Brown
2009-11-25 15:46       ` Daniel Mack
2009-11-26 15:48       ` Daniel Mack
2009-11-26 16:03         ` Mark Brown
2009-11-26 17:42           ` Daniel Mack [this message]
2009-11-27 11:25             ` Mark Brown
2009-11-27 12:41               ` Daniel Mack
2009-11-27 13:32                 ` Mark Brown
2009-11-28 20:23                   ` Timur Tabi
2009-11-28 20:31                     ` Mark Brown
2009-11-28 22:18                       ` Timur Tabi
2009-11-29  0:44                         ` Daniel Mack
2009-11-29  4:34                           ` Timur Tabi
2009-11-29  8:35                             ` Daniel Mack
2009-11-30 10:12                               ` Daniel Mack
     [not found]                           ` <5610599F537DD74A8D1F5CC946A7507303478C40@az33exm25.fsl.freescale.net>
2009-11-30 12:01                             ` Mark Brown
2009-11-30 12:36                               ` Daniel Mack
2009-11-30 15:57                                 ` Daniel Mack
2009-11-30 16:12                                   ` Mark Brown
2009-11-30 16:51                                     ` Daniel Mack
2009-11-30 16:56                                       ` Daniel Mack
2009-12-04 12:00                                         ` Daniel Mack
2009-12-04 12:07                                           ` Mark Brown
2009-12-05  2:54                                             ` Timur Tabi
2009-12-05  3:51                                               ` Mark Brown
2009-12-05 17:03                                         ` Timur Tabi
2009-12-07 13:16                                           ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091126174245.GJ14091@buzzloop.caiaq.de \
    --to=daniel@caiaq.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@opensource.wolfsonmicro.com \
    --cc=lrg@slimlogic.co.uk \
    --cc=timur@freescale.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.