aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/cs4270.c
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2009-11-30 11:56:11 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-12-07 08:11:56 -0500
commitffbfd336f9eac361e1630cfcb17a70607551daf2 (patch)
tree23304b522d850dcf1e52940324c32f70ff7aa071 /sound/soc/codecs/cs4270.c
parenta91eb199e4dc8a2ab3fb7a53f1a23ce82b29fc04 (diff)
ASoC: Add regulator support to CS4270 codec driver
Signed-off-by: Daniel Mack <daniel@caiaq.de> Acked-by: Timur Tabi <timur@freescale.com> Cc: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/cs4270.c')
-rw-r--r--sound/soc/codecs/cs4270.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index ffe122d1cd76..8b5457542a0e 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -28,6 +28,7 @@
28#include <sound/initval.h> 28#include <sound/initval.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/regulator/consumer.h>
31 32
32#include "cs4270.h" 33#include "cs4270.h"
33 34
@@ -106,6 +107,10 @@
106#define CS4270_MUTE_DAC_A 0x01 107#define CS4270_MUTE_DAC_A 0x01
107#define CS4270_MUTE_DAC_B 0x02 108#define CS4270_MUTE_DAC_B 0x02
108 109
110static const char *supply_names[] = {
111 "va", "vd", "vlc"
112};
113
109/* Private data for the CS4270 */ 114/* Private data for the CS4270 */
110struct cs4270_private { 115struct cs4270_private {
111 struct snd_soc_codec codec; 116 struct snd_soc_codec codec;
@@ -114,6 +119,9 @@ struct cs4270_private {
114 unsigned int mode; /* The mode (I2S or left-justified) */ 119 unsigned int mode; /* The mode (I2S or left-justified) */
115 unsigned int slave_mode; 120 unsigned int slave_mode;
116 unsigned int manual_mute; 121 unsigned int manual_mute;
122
123 /* power domain regulators */
124 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
117}; 125};
118 126
119/** 127/**
@@ -579,7 +587,8 @@ static int cs4270_probe(struct platform_device *pdev)
579{ 587{
580 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 588 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
581 struct snd_soc_codec *codec = cs4270_codec; 589 struct snd_soc_codec *codec = cs4270_codec;
582 int ret; 590 struct cs4270_private *cs4270 = codec->private_data;
591 int i, ret;
583 592
584 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 593 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
585 socdev->card->codec = codec; 594 socdev->card->codec = codec;
@@ -599,6 +608,15 @@ static int cs4270_probe(struct platform_device *pdev)
599 goto error_free_pcms; 608 goto error_free_pcms;
600 } 609 }
601 610
611 /* get the power supply regulators */
612 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
613 cs4270->supplies[i].supply = supply_names[i];
614
615 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
616 cs4270->supplies);
617 if (ret < 0)
618 goto error_free_pcms;
619
602 return 0; 620 return 0;
603 621
604error_free_pcms: 622error_free_pcms:
@@ -616,8 +634,11 @@ error_free_pcms:
616static int cs4270_remove(struct platform_device *pdev) 634static int cs4270_remove(struct platform_device *pdev)
617{ 635{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 636 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
637 struct snd_soc_codec *codec = cs4270_codec;
638 struct cs4270_private *cs4270 = codec->private_data;
619 639
620 snd_soc_free_pcms(socdev); 640 snd_soc_free_pcms(socdev);
641 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
621 642
622 return 0; 643 return 0;
623}; 644};
@@ -799,17 +820,33 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
799static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 820static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
800{ 821{
801 struct snd_soc_codec *codec = cs4270_codec; 822 struct snd_soc_codec *codec = cs4270_codec;
802 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; 823 struct cs4270_private *cs4270 = codec->private_data;
824 int reg, ret;
803 825
804 return snd_soc_write(codec, CS4270_PWRCTL, reg); 826 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
827 if (reg < 0)
828 return reg;
829
830 ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
831 if (ret < 0)
832 return ret;
833
834 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
835 cs4270->supplies);
836
837 return 0;
805} 838}
806 839
807static int cs4270_soc_resume(struct platform_device *pdev) 840static int cs4270_soc_resume(struct platform_device *pdev)
808{ 841{
809 struct snd_soc_codec *codec = cs4270_codec; 842 struct snd_soc_codec *codec = cs4270_codec;
843 struct cs4270_private *cs4270 = codec->private_data;
810 struct i2c_client *i2c_client = codec->control_data; 844 struct i2c_client *i2c_client = codec->control_data;
811 int reg; 845 int reg;
812 846
847 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
848 cs4270->supplies);
849
813 /* In case the device was put to hard reset during sleep, we need to 850 /* In case the device was put to hard reset during sleep, we need to
814 * wait 500ns here before any I2C communication. */ 851 * wait 500ns here before any I2C communication. */
815 ndelay(500); 852 ndelay(500);