aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-04-18 06:13:51 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-05-01 06:00:23 -0400
commit201cf052810d20814a77ca0e0045a2c1a3508a1f (patch)
tree6ba7526b1fd4e37dffb515b057aac16f9140b01a /drivers/mfd
parent58d114b669d2b86aa79eac6688590c808072579b (diff)
mfd: Add support for tps65910 device sleep
Adding support for device sleep through the external input control signal "SLEEP". Changing the SLEEP signal state can switch the device into SLEEP and ACTIVE state. Also adding sleep configuration for different resources so that they should be keep on during sleep state of device. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/tps65910.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index bf2b25ebf2ca..ae7f47b6e71b 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -90,6 +90,66 @@ static const struct regmap_config tps65910_regmap_config = {
90 .cache_type = REGCACHE_RBTREE, 90 .cache_type = REGCACHE_RBTREE,
91}; 91};
92 92
93static int __init tps65910_sleepinit(struct tps65910 *tps65910,
94 struct tps65910_board *pmic_pdata)
95{
96 struct device *dev = NULL;
97 int ret = 0;
98
99 dev = tps65910->dev;
100
101 if (!pmic_pdata->en_dev_slp)
102 return 0;
103
104 /* enabling SLEEP device state */
105 ret = tps65910_set_bits(tps65910, TPS65910_DEVCTRL,
106 DEVCTRL_DEV_SLP_MASK);
107 if (ret < 0) {
108 dev_err(dev, "set dev_slp failed: %d\n", ret);
109 goto err_sleep_init;
110 }
111
112 /* Return if there is no sleep keepon data. */
113 if (!pmic_pdata->slp_keepon)
114 return 0;
115
116 if (pmic_pdata->slp_keepon->therm_keepon) {
117 ret = tps65910_set_bits(tps65910, TPS65910_SLEEP_KEEP_RES_ON,
118 SLEEP_KEEP_RES_ON_THERM_KEEPON_MASK);
119 if (ret < 0) {
120 dev_err(dev, "set therm_keepon failed: %d\n", ret);
121 goto disable_dev_slp;
122 }
123 }
124
125 if (pmic_pdata->slp_keepon->clkout32k_keepon) {
126 ret = tps65910_set_bits(tps65910, TPS65910_SLEEP_KEEP_RES_ON,
127 SLEEP_KEEP_RES_ON_CLKOUT32K_KEEPON_MASK);
128 if (ret < 0) {
129 dev_err(dev, "set clkout32k_keepon failed: %d\n", ret);
130 goto disable_dev_slp;
131 }
132 }
133
134 if (pmic_pdata->slp_keepon->i2chs_keepon) {
135 ret = tps65910_set_bits(tps65910, TPS65910_SLEEP_KEEP_RES_ON,
136 SLEEP_KEEP_RES_ON_I2CHS_KEEPON_MASK);
137 if (ret < 0) {
138 dev_err(dev, "set i2chs_keepon failed: %d\n", ret);
139 goto disable_dev_slp;
140 }
141 }
142
143 return 0;
144
145disable_dev_slp:
146 tps65910_clear_bits(tps65910, TPS65910_DEVCTRL, DEVCTRL_DEV_SLP_MASK);
147
148err_sleep_init:
149 return ret;
150}
151
152
93static int tps65910_i2c_probe(struct i2c_client *i2c, 153static int tps65910_i2c_probe(struct i2c_client *i2c,
94 const struct i2c_device_id *id) 154 const struct i2c_device_id *id)
95{ 155{
@@ -140,6 +200,8 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
140 200
141 tps65910_irq_init(tps65910, init_data->irq, init_data); 201 tps65910_irq_init(tps65910, init_data->irq, init_data);
142 202
203 tps65910_sleepinit(tps65910, pmic_plat_data);
204
143 kfree(init_data); 205 kfree(init_data);
144 return ret; 206 return ret;
145 207