#include <sound/initval.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/regulator/consumer.h>
 
 #include "cs4270.h"
 
 #define CS4270_MUTE_DAC_A      0x01
 #define CS4270_MUTE_DAC_B      0x02
 
+static const char *supply_names[] = {
+       "va", "vd", "vlc"
+};
+
 /* Private data for the CS4270 */
 struct cs4270_private {
        struct snd_soc_codec codec;
        unsigned int mode; /* The mode (I2S or left-justified) */
        unsigned int slave_mode;
        unsigned int manual_mute;
+
+       /* power domain regulators */
+       struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
 };
 
 /**
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
        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. */
        socdev->card->codec = codec;
                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;
 
 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_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
 
        return 0;
 };
 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;
+       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)
 {
        struct snd_soc_codec *codec = cs4270_codec;
+       struct cs4270_private *cs4270 = codec->private_data;
        struct i2c_client *i2c_client = codec->control_data;
        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
         * wait 500ns here before any I2C communication. */
        ndelay(500);