* [PATCH 1/3] ASoC: ak5386: add regulator consumer support @ 2014-03-26 10:22 Daniel Mack 2014-03-26 10:22 ` [PATCH 2/3] ASoC: ak4104: " Daniel Mack 2014-03-26 10:22 ` [PATCH 3/3] ASoC: tas5086: " Daniel Mack 0 siblings, 2 replies; 6+ messages in thread From: Daniel Mack @ 2014-03-26 10:22 UTC (permalink / raw) To: broonie; +Cc: alsa-devel, Daniel Mack The chip has two power supplies, VA and VDD. Register and enable them both. Signed-off-by: Daniel Mack <zonque@gmail.com> --- sound/soc/codecs/ak5386.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c index 72e953b..99fb5db 100644 --- a/sound/soc/codecs/ak5386.c +++ b/sound/soc/codecs/ak5386.c @@ -14,12 +14,18 @@ #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/of_device.h> +#include <linux/regulator/consumer.h> #include <sound/soc.h> #include <sound/pcm.h> #include <sound/initval.h> +static const char *supply_names[] = { + "va", "vd" +}; + struct ak5386_priv { int reset_gpio; + struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; }; static const struct snd_soc_dapm_widget ak5386_dapm_widgets[] = { @@ -122,6 +128,7 @@ static int ak5386_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ak5386_priv *priv; + int ret, i; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -130,6 +137,19 @@ static int ak5386_probe(struct platform_device *pdev) priv->reset_gpio = -EINVAL; dev_set_drvdata(dev, priv); + for (i = 0; i < ARRAY_SIZE(supply_names); i++) + priv->supplies[i].supply = supply_names[i]; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(priv->supplies), + priv->supplies); + if (ret < 0) + return ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), + priv->supplies); + if (ret < 0) + return ret; + if (of_match_device(of_match_ptr(ak5386_dt_ids), dev)) priv->reset_gpio = of_get_named_gpio(dev->of_node, "reset-gpio", 0); @@ -140,13 +160,22 @@ static int ak5386_probe(struct platform_device *pdev) "AK5386 Reset")) priv->reset_gpio = -EINVAL; - return snd_soc_register_codec(dev, &soc_codec_ak5386, - &ak5386_dai, 1); + ret = snd_soc_register_codec(dev, &soc_codec_ak5386, + &ak5386_dai, 1); + if (ret < 0) + regulator_bulk_disable(ARRAY_SIZE(priv->supplies), + priv->supplies); + return ret; } static int ak5386_remove(struct platform_device *pdev) { - snd_soc_unregister_codec(&pdev->dev); + struct device *dev = &pdev->dev; + struct ak5386_priv *priv = dev_get_drvdata(dev); + + snd_soc_unregister_codec(dev); + regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); + return 0; } -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] ASoC: ak4104: add regulator consumer support 2014-03-26 10:22 [PATCH 1/3] ASoC: ak5386: add regulator consumer support Daniel Mack @ 2014-03-26 10:22 ` Daniel Mack 2014-03-26 15:06 ` Daniel Mack 2014-03-26 10:22 ` [PATCH 3/3] ASoC: tas5086: " Daniel Mack 1 sibling, 1 reply; 6+ messages in thread From: Daniel Mack @ 2014-03-26 10:22 UTC (permalink / raw) To: broonie; +Cc: alsa-devel, Daniel Mack The AK4104 has only one power supply, called VDD. Make sure it is enabled during the life-time of the module. Signed-off-by: Daniel Mack <zonque@gmail.com> --- sound/soc/codecs/ak4104.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index b4819dc..c7a541d 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[] = { @@ -176,20 +178,30 @@ static int ak4104_probe(struct snd_soc_codec *codec) codec->control_data = ak4104->regmap; + 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) @@ -198,6 +210,7 @@ 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; } @@ -241,6 +254,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); -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] ASoC: ak4104: add regulator consumer support 2014-03-26 10:22 ` [PATCH 2/3] ASoC: ak4104: " Daniel Mack @ 2014-03-26 15:06 ` Daniel Mack 0 siblings, 0 replies; 6+ messages in thread From: Daniel Mack @ 2014-03-26 15:06 UTC (permalink / raw) To: broonie; +Cc: alsa-devel On 03/26/2014 11:22 AM, Daniel Mack wrote: > The AK4104 has only one power supply, called VDD. Make sure it is > enabled during the life-time of the module. Sorry, I just noticed there was an update for this driver in the ASoC for-next branch that causes a trivial conflict for this particular patch. If desired, I can resend a rebased version. The other two patches are unaffected. > > Signed-off-by: Daniel Mack <zonque@gmail.com> > --- > sound/soc/codecs/ak4104.c | 30 +++++++++++++++++++++++++----- > 1 file changed, 25 insertions(+), 5 deletions(-) > > diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c > index b4819dc..c7a541d 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[] = { > @@ -176,20 +178,30 @@ static int ak4104_probe(struct snd_soc_codec *codec) > > codec->control_data = ak4104->regmap; > > + 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) > @@ -198,6 +210,7 @@ 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; > } > @@ -241,6 +254,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); > ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/3] ASoC: tas5086: add regulator consumer support 2014-03-26 10:22 [PATCH 1/3] ASoC: ak5386: add regulator consumer support Daniel Mack 2014-03-26 10:22 ` [PATCH 2/3] ASoC: ak4104: " Daniel Mack @ 2014-03-26 10:22 ` Daniel Mack 2014-03-26 16:31 ` Daniel Mack 1 sibling, 1 reply; 6+ messages in thread From: Daniel Mack @ 2014-03-26 10:22 UTC (permalink / raw) To: broonie; +Cc: alsa-devel, Daniel Mack The TAS5086 has two power domains, DVDD and AVDD. Add support for regulators to the TAS5086 codec driver. Signed-off-by: Daniel Mack <zonque@gmail.com> --- sound/soc/codecs/tas5086.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index a895a5e..e87a577 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -36,6 +36,7 @@ #include <linux/gpio.h> #include <linux/i2c.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include <linux/spi/spi.h> #include <linux/of.h> #include <linux/of_device.h> @@ -240,6 +241,10 @@ static int tas5086_reg_read(void *context, unsigned int reg, return 0; } +static const char *supply_names[] = { + "dvdd", "avdd" +}; + struct tas5086_private { struct regmap *regmap; unsigned int mclk, sclk; @@ -251,6 +256,7 @@ struct tas5086_private { int rate; /* GPIO driving Reset pin, if any */ int gpio_nreset; + struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; }; static int tas5086_deemph[] = { 0, 32000, 44100, 48000 }; @@ -773,6 +779,8 @@ static int tas5086_soc_suspend(struct snd_soc_codec *codec) if (ret < 0) return ret; + regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); + return 0; } @@ -781,6 +789,10 @@ static int tas5086_soc_resume(struct snd_soc_codec *codec) struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); int ret; + ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); + if (ret < 0) + return ret; + tas5086_reset(priv); regcache_mark_dirty(priv->regmap); @@ -812,6 +824,12 @@ static int tas5086_probe(struct snd_soc_codec *codec) struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); int i, ret; + ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); + if (ret < 0) { + dev_err(codec->dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + priv->pwm_start_mid_z = 0; priv->charge_period = 1300000; /* hardware default is 1300 ms */ @@ -834,14 +852,19 @@ static int tas5086_probe(struct snd_soc_codec *codec) ret = tas5086_init(codec->dev, priv); if (ret < 0) - return ret; + goto exit_disable_regulators; /* set master volume to 0 dB */ ret = regmap_write(priv->regmap, TAS5086_MASTER_VOL, 0x30); if (ret < 0) - return ret; + goto exit_disable_regulators; return 0; + +exit_disable_regulators: + regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); + + return ret; } static int tas5086_remove(struct snd_soc_codec *codec) @@ -852,6 +875,8 @@ static int tas5086_remove(struct snd_soc_codec *codec) /* Set codec to the reset state */ gpio_set_value(priv->gpio_nreset, 0); + regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); + return 0; }; @@ -900,6 +925,16 @@ static int tas5086_i2c_probe(struct i2c_client *i2c, if (!priv) return -ENOMEM; + for (i = 0; i < ARRAY_SIZE(supply_names); i++) + priv->supplies[i].supply = supply_names[i]; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(priv->supplies), + priv->supplies); + if (ret < 0) { + dev_err(dev, "Failed to get regulators: %d\n", ret); + return ret; + } + priv->regmap = devm_regmap_init(dev, NULL, i2c, &tas5086_regmap); if (IS_ERR(priv->regmap)) { ret = PTR_ERR(priv->regmap); -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 3/3] ASoC: tas5086: add regulator consumer support 2014-03-26 10:22 ` [PATCH 3/3] ASoC: tas5086: " Daniel Mack @ 2014-03-26 16:31 ` Daniel Mack 2014-03-26 16:38 ` Mark Brown 0 siblings, 1 reply; 6+ messages in thread From: Daniel Mack @ 2014-03-26 16:31 UTC (permalink / raw) To: broonie; +Cc: alsa-devel On 03/26/2014 11:22 AM, Daniel Mack wrote: > The TAS5086 has two power domains, DVDD and AVDD. Add support for > regulators to the TAS5086 codec driver. Meh, this one needs more tweaking as well. Please ignore all patches in this series; I'll resend once things work as expected. Sorry for the noise. > > Signed-off-by: Daniel Mack <zonque@gmail.com> > --- > sound/soc/codecs/tas5086.c | 39 +++++++++++++++++++++++++++++++++++++-- > 1 file changed, 37 insertions(+), 2 deletions(-) > > diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c > index a895a5e..e87a577 100644 > --- a/sound/soc/codecs/tas5086.c > +++ b/sound/soc/codecs/tas5086.c > @@ -36,6 +36,7 @@ > #include <linux/gpio.h> > #include <linux/i2c.h> > #include <linux/regmap.h> > +#include <linux/regulator/consumer.h> > #include <linux/spi/spi.h> > #include <linux/of.h> > #include <linux/of_device.h> > @@ -240,6 +241,10 @@ static int tas5086_reg_read(void *context, unsigned int reg, > return 0; > } > > +static const char *supply_names[] = { > + "dvdd", "avdd" > +}; > + > struct tas5086_private { > struct regmap *regmap; > unsigned int mclk, sclk; > @@ -251,6 +256,7 @@ struct tas5086_private { > int rate; > /* GPIO driving Reset pin, if any */ > int gpio_nreset; > + struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; > }; > > static int tas5086_deemph[] = { 0, 32000, 44100, 48000 }; > @@ -773,6 +779,8 @@ static int tas5086_soc_suspend(struct snd_soc_codec *codec) > if (ret < 0) > return ret; > > + regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); > + > return 0; > } > > @@ -781,6 +789,10 @@ static int tas5086_soc_resume(struct snd_soc_codec *codec) > struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); > int ret; > > + ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); > + if (ret < 0) > + return ret; > + > tas5086_reset(priv); > regcache_mark_dirty(priv->regmap); > > @@ -812,6 +824,12 @@ static int tas5086_probe(struct snd_soc_codec *codec) > struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); > int i, ret; > > + ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); > + if (ret < 0) { > + dev_err(codec->dev, "Failed to enable regulators: %d\n", ret); > + return ret; > + } > + > priv->pwm_start_mid_z = 0; > priv->charge_period = 1300000; /* hardware default is 1300 ms */ > > @@ -834,14 +852,19 @@ static int tas5086_probe(struct snd_soc_codec *codec) > > ret = tas5086_init(codec->dev, priv); > if (ret < 0) > - return ret; > + goto exit_disable_regulators; > > /* set master volume to 0 dB */ > ret = regmap_write(priv->regmap, TAS5086_MASTER_VOL, 0x30); > if (ret < 0) > - return ret; > + goto exit_disable_regulators; > > return 0; > + > +exit_disable_regulators: > + regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); > + > + return ret; > } > > static int tas5086_remove(struct snd_soc_codec *codec) > @@ -852,6 +875,8 @@ static int tas5086_remove(struct snd_soc_codec *codec) > /* Set codec to the reset state */ > gpio_set_value(priv->gpio_nreset, 0); > > + regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); > + > return 0; > }; > > @@ -900,6 +925,16 @@ static int tas5086_i2c_probe(struct i2c_client *i2c, > if (!priv) > return -ENOMEM; > > + for (i = 0; i < ARRAY_SIZE(supply_names); i++) > + priv->supplies[i].supply = supply_names[i]; > + > + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(priv->supplies), > + priv->supplies); > + if (ret < 0) { > + dev_err(dev, "Failed to get regulators: %d\n", ret); > + return ret; > + } > + > priv->regmap = devm_regmap_init(dev, NULL, i2c, &tas5086_regmap); > if (IS_ERR(priv->regmap)) { > ret = PTR_ERR(priv->regmap); > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 3/3] ASoC: tas5086: add regulator consumer support 2014-03-26 16:31 ` Daniel Mack @ 2014-03-26 16:38 ` Mark Brown 0 siblings, 0 replies; 6+ messages in thread From: Mark Brown @ 2014-03-26 16:38 UTC (permalink / raw) To: Daniel Mack; +Cc: alsa-devel [-- Attachment #1.1: Type: text/plain, Size: 386 bytes --] On Wed, Mar 26, 2014 at 05:31:18PM +0100, Daniel Mack wrote: > On 03/26/2014 11:22 AM, Daniel Mack wrote: > > The TAS5086 has two power domains, DVDD and AVDD. Add support for > > regulators to the TAS5086 codec driver. > Meh, this one needs more tweaking as well. Please ignore all patches in > this series; I'll resend once things work as expected. Sorry for the noise. No problem. [-- Attachment #1.2: Digital signature --] [-- Type: application/pgp-signature, Size: 836 bytes --] [-- Attachment #2: Type: text/plain, Size: 0 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-03-26 16:38 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-03-26 10:22 [PATCH 1/3] ASoC: ak5386: add regulator consumer support Daniel Mack 2014-03-26 10:22 ` [PATCH 2/3] ASoC: ak4104: " Daniel Mack 2014-03-26 15:06 ` Daniel Mack 2014-03-26 10:22 ` [PATCH 3/3] ASoC: tas5086: " Daniel Mack 2014-03-26 16:31 ` Daniel Mack 2014-03-26 16:38 ` Mark Brown
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.