Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 148255
b: refs/heads/master
c: 5e7c034
h: refs/heads/master
i:
  148253: 771b296
  148251: 2313bae
  148247: 4fb00fc
  148239: 1e55560
  148223: 0afa282
v: v3
  • Loading branch information
Daniel Mack authored and Mark Brown committed May 7, 2009
1 parent ee27cad commit 6298a94
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 80ab8817bf9b740df1f0778c41875e93151409bf
refs/heads/master: 5e7c03442574ed0376c0621bfb0c477d79c12c71
58 changes: 57 additions & 1 deletion trunk/sound/soc/codecs/cs4270.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* - The machine driver's 'startup' function must call
* cs4270_set_dai_sysclk() with the value of MCLK.
* - Only I2S and left-justified modes are supported
* - Power management is not supported
* - Power management is supported
*/

#include <linux/module.h>
Expand All @@ -27,6 +27,7 @@
#include <sound/soc.h>
#include <sound/initval.h>
#include <linux/i2c.h>
#include <linux/delay.h>

#include "cs4270.h"

Expand Down Expand Up @@ -65,6 +66,8 @@
#define CS4270_PWRCTL_PDN_ADC 0x20
#define CS4270_PWRCTL_PDN_DAC 0x02
#define CS4270_PWRCTL_PDN 0x01
#define CS4270_PWRCTL_PDN_ALL \
(CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN)
#define CS4270_MODE_SPEED_MASK 0x30
#define CS4270_MODE_1X 0x00
#define CS4270_MODE_2X 0x10
Expand Down Expand Up @@ -788,6 +791,57 @@ static struct i2c_device_id cs4270_id[] = {
};
MODULE_DEVICE_TABLE(i2c, cs4270_id);

#ifdef CONFIG_PM

/* This suspend/resume implementation can handle both - a simple standby
* where the codec remains powered, and a full suspend, where the voltage
* domain the codec is connected to is teared down and/or any other hardware
* reset condition is asserted.
*
* The codec's own power saving features are enabled in the suspend callback,
* and all registers are written back to the hardware when resuming.
*/

static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
{
struct cs4270_private *cs4270 = i2c_get_clientdata(client);
struct snd_soc_codec *codec = &cs4270->codec;
int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;

return snd_soc_write(codec, CS4270_PWRCTL, reg);
}

static int cs4270_i2c_resume(struct i2c_client *client)
{
struct cs4270_private *cs4270 = i2c_get_clientdata(client);
struct snd_soc_codec *codec = &cs4270->codec;
int reg;

/* In case the device was put to hard reset during sleep, we need to
* wait 500ns here before any I2C communication. */
ndelay(500);

/* first restore the entire register cache ... */
for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
u8 val = snd_soc_read(codec, reg);

if (i2c_smbus_write_byte_data(client, reg, val)) {
dev_err(codec->dev, "i2c write failed\n");
return -EIO;
}
}

/* ... then disable the power-down bits */
reg = snd_soc_read(codec, CS4270_PWRCTL);
reg &= ~CS4270_PWRCTL_PDN_ALL;

return snd_soc_write(codec, CS4270_PWRCTL, reg);
}
#else
#define cs4270_i2c_suspend NULL
#define cs4270_i2c_resume NULL
#endif /* CONFIG_PM */

/*
* cs4270_i2c_driver - I2C device identification
*
Expand All @@ -802,6 +856,8 @@ static struct i2c_driver cs4270_i2c_driver = {
.id_table = cs4270_id,
.probe = cs4270_i2c_probe,
.remove = cs4270_i2c_remove,
.suspend = cs4270_i2c_suspend,
.resume = cs4270_i2c_resume,
};

/*
Expand Down

0 comments on commit 6298a94

Please sign in to comment.