Commit ffbfd336 authored by Daniel Mack's avatar Daniel Mack Committed by Mark Brown

ASoC: Add regulator support to CS4270 codec driver

Signed-off-by: default avatarDaniel Mack <daniel@caiaq.de>
Acked-by: default avatarTimur Tabi <timur@freescale.com>
Cc: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent a91eb199
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <sound/initval.h> #include <sound/initval.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include "cs4270.h" #include "cs4270.h"
...@@ -106,6 +107,10 @@ ...@@ -106,6 +107,10 @@
#define CS4270_MUTE_DAC_A 0x01 #define CS4270_MUTE_DAC_A 0x01
#define CS4270_MUTE_DAC_B 0x02 #define CS4270_MUTE_DAC_B 0x02
static const char *supply_names[] = {
"va", "vd", "vlc"
};
/* Private data for the CS4270 */ /* Private data for the CS4270 */
struct cs4270_private { struct cs4270_private {
struct snd_soc_codec codec; struct snd_soc_codec codec;
...@@ -114,6 +119,9 @@ struct cs4270_private { ...@@ -114,6 +119,9 @@ struct cs4270_private {
unsigned int mode; /* The mode (I2S or left-justified) */ unsigned int mode; /* The mode (I2S or left-justified) */
unsigned int slave_mode; unsigned int slave_mode;
unsigned int manual_mute; unsigned int manual_mute;
/* power domain regulators */
struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
}; };
/** /**
...@@ -579,7 +587,8 @@ static int cs4270_probe(struct platform_device *pdev) ...@@ -579,7 +587,8 @@ static int cs4270_probe(struct platform_device *pdev)
{ {
struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = cs4270_codec; struct snd_soc_codec *codec = cs4270_codec;
int ret; struct cs4270_private *cs4270 = codec->private_data;
int i, ret;
/* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
socdev->card->codec = codec; socdev->card->codec = codec;
...@@ -599,6 +608,15 @@ static int cs4270_probe(struct platform_device *pdev) ...@@ -599,6 +608,15 @@ static int cs4270_probe(struct platform_device *pdev)
goto error_free_pcms; goto error_free_pcms;
} }
/* get the power supply regulators */
for (i = 0; i < ARRAY_SIZE(supply_names); i++)
cs4270->supplies[i].supply = supply_names[i];
ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
cs4270->supplies);
if (ret < 0)
goto error_free_pcms;
return 0; return 0;
error_free_pcms: error_free_pcms:
...@@ -616,8 +634,11 @@ static int cs4270_probe(struct platform_device *pdev) ...@@ -616,8 +634,11 @@ static int cs4270_probe(struct platform_device *pdev)
static int cs4270_remove(struct platform_device *pdev) static int cs4270_remove(struct platform_device *pdev)
{ {
struct snd_soc_device *socdev = platform_get_drvdata(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); snd_soc_free_pcms(socdev);
regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
return 0; return 0;
}; };
...@@ -799,17 +820,33 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id); ...@@ -799,17 +820,33 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
{ {
struct snd_soc_codec *codec = cs4270_codec; struct snd_soc_codec *codec = cs4270_codec;
int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; struct cs4270_private *cs4270 = codec->private_data;
int reg, ret;
return snd_soc_write(codec, CS4270_PWRCTL, reg); reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
if (reg < 0)
return reg;
ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
if (ret < 0)
return ret;
regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
cs4270->supplies);
return 0;
} }
static int cs4270_soc_resume(struct platform_device *pdev) static int cs4270_soc_resume(struct platform_device *pdev)
{ {
struct snd_soc_codec *codec = cs4270_codec; struct snd_soc_codec *codec = cs4270_codec;
struct cs4270_private *cs4270 = codec->private_data;
struct i2c_client *i2c_client = codec->control_data; struct i2c_client *i2c_client = codec->control_data;
int reg; int reg;
regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
cs4270->supplies);
/* In case the device was put to hard reset during sleep, we need to /* In case the device was put to hard reset during sleep, we need to
* wait 500ns here before any I2C communication. */ * wait 500ns here before any I2C communication. */
ndelay(500); ndelay(500);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment