aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2009-05-05 19:26:01 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-05-07 04:00:27 -0400
commit5e7c03442574ed0376c0621bfb0c477d79c12c71 (patch)
tree25c02cdb08cd708d06a67e012e43cd916895f4e4 /sound/soc
parent80ab8817bf9b740df1f0778c41875e93151409bf (diff)
ASoC: cs4270: add power management support
Signed-off-by: Daniel Mack <daniel@caiaq.de> Acked-by: Timur Tabi <timur@freescale.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/cs4270.c58
1 files changed, 57 insertions, 1 deletions
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 153124b2e3b1..a32b8226c8a4 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -18,7 +18,7 @@
18 * - The machine driver's 'startup' function must call 18 * - The machine driver's 'startup' function must call
19 * cs4270_set_dai_sysclk() with the value of MCLK. 19 * cs4270_set_dai_sysclk() with the value of MCLK.
20 * - Only I2S and left-justified modes are supported 20 * - Only I2S and left-justified modes are supported
21 * - Power management is not supported 21 * - Power management is supported
22 */ 22 */
23 23
24#include <linux/module.h> 24#include <linux/module.h>
@@ -27,6 +27,7 @@
27#include <sound/soc.h> 27#include <sound/soc.h>
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 31
31#include "cs4270.h" 32#include "cs4270.h"
32 33
@@ -65,6 +66,8 @@
65#define CS4270_PWRCTL_PDN_ADC 0x20 66#define CS4270_PWRCTL_PDN_ADC 0x20
66#define CS4270_PWRCTL_PDN_DAC 0x02 67#define CS4270_PWRCTL_PDN_DAC 0x02
67#define CS4270_PWRCTL_PDN 0x01 68#define CS4270_PWRCTL_PDN 0x01
69#define CS4270_PWRCTL_PDN_ALL \
70 (CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN)
68#define CS4270_MODE_SPEED_MASK 0x30 71#define CS4270_MODE_SPEED_MASK 0x30
69#define CS4270_MODE_1X 0x00 72#define CS4270_MODE_1X 0x00
70#define CS4270_MODE_2X 0x10 73#define CS4270_MODE_2X 0x10
@@ -788,6 +791,57 @@ static struct i2c_device_id cs4270_id[] = {
788}; 791};
789MODULE_DEVICE_TABLE(i2c, cs4270_id); 792MODULE_DEVICE_TABLE(i2c, cs4270_id);
790 793
794#ifdef CONFIG_PM
795
796/* This suspend/resume implementation can handle both - a simple standby
797 * where the codec remains powered, and a full suspend, where the voltage
798 * domain the codec is connected to is teared down and/or any other hardware
799 * reset condition is asserted.
800 *
801 * The codec's own power saving features are enabled in the suspend callback,
802 * and all registers are written back to the hardware when resuming.
803 */
804
805static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
806{
807 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
808 struct snd_soc_codec *codec = &cs4270->codec;
809 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
810
811 return snd_soc_write(codec, CS4270_PWRCTL, reg);
812}
813
814static int cs4270_i2c_resume(struct i2c_client *client)
815{
816 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
817 struct snd_soc_codec *codec = &cs4270->codec;
818 int reg;
819
820 /* In case the device was put to hard reset during sleep, we need to
821 * wait 500ns here before any I2C communication. */
822 ndelay(500);
823
824 /* first restore the entire register cache ... */
825 for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
826 u8 val = snd_soc_read(codec, reg);
827
828 if (i2c_smbus_write_byte_data(client, reg, val)) {
829 dev_err(codec->dev, "i2c write failed\n");
830 return -EIO;
831 }
832 }
833
834 /* ... then disable the power-down bits */
835 reg = snd_soc_read(codec, CS4270_PWRCTL);
836 reg &= ~CS4270_PWRCTL_PDN_ALL;
837
838 return snd_soc_write(codec, CS4270_PWRCTL, reg);
839}
840#else
841#define cs4270_i2c_suspend NULL
842#define cs4270_i2c_resume NULL
843#endif /* CONFIG_PM */
844
791/* 845/*
792 * cs4270_i2c_driver - I2C device identification 846 * cs4270_i2c_driver - I2C device identification
793 * 847 *
@@ -802,6 +856,8 @@ static struct i2c_driver cs4270_i2c_driver = {
802 .id_table = cs4270_id, 856 .id_table = cs4270_id,
803 .probe = cs4270_i2c_probe, 857 .probe = cs4270_i2c_probe,
804 .remove = cs4270_i2c_remove, 858 .remove = cs4270_i2c_remove,
859 .suspend = cs4270_i2c_suspend,
860 .resume = cs4270_i2c_resume,
805}; 861};
806 862
807/* 863/*