aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorJavier Martinez Canillas <javier.martinez@collabora.co.uk>2014-10-16 12:48:48 -0400
committerMark Brown <broonie@kernel.org>2014-10-20 07:23:50 -0400
commit2e0eaa1aa0084ff1ee1af7cf388358b868143816 (patch)
treecd86597459b78d9803c6cfae2c6328501ab29812 /drivers/regulator
parentefbe519945746371f92f5c3796818bf3e24c80ad (diff)
regulator: max77802: Add set suspend mode for BUCKs and simplify code
The max77802 PMIC has a special enable pin (PWRREQ) that can be used by the Application Processor (AP) to power down and up voltage rails. The max77802 PMIC regulators have 3 different enable control logics. Some regulators support to be configured on different operational mode during normal operation while others only support to be put in a Low Power Mode while the system has entered in sleep mode. Some regulators don't even support that configuration. The logics are the following: Enable Control Logic1 by PWRREQ (BUCK 2-4, LDO2, LDO4-19, LDO22, LDO35) ------------------------------- 0: Output OFF 1: Output ON/OFF (Controlled by PWRREQ) PWRREQ = HIGH (1): Output ON in Normal Mode PWRREQ = LOW (0): Output OFF 2: Output On with Low Power Mode (Controlled by PWRREQ) PWRREQ = HIGH (1) : Output ON in Normal Mode PWRREQ = LOW (0): Output ON in Low Power Mode 3: Output ON in Normal Mode Enable Control Logic2 by PWRREQ (LDO1, LDO20, LDO21) ------------------------------- 0: Output ON/OFF by ENx 1: Output ON in Low Power Mode 2: Output ON in Low Power Mode (Controlled by PWRREQ) PWRREQ = HIGH (1): Output ON in Normal Mode PWRREQ = LOW (0): Output ON in Low Power Mode 3: Output ON in Normal Mode Enable Control Logic3 by PWRREQ (LDO3) ------------------------------- 0 or 3: Output ON in Normal Mode 1: Output ON in Low Power Mode 2: Output ON in Low Power Mode (Controlled by PWRREQ) PWRREQ = HIGH (1): Output ON in Normal Mode PWRREQ = LOW (0): Output ON in Low Power Mode The driver only implemented .set_suspend_mode for the LDOs regulators but some BUCKs also support to be put in Low Power Mode on system wide suspend so they should be supported as well. Two different functions were used for the logic 1 and 2 but this is not necessary. Only normal and Low Power Mode are valid operational modes, OFF is not an mode but is a regulator state that is handled by .set_suspend_enable ad .set_suspend_disable. So the same .set_suspend_mode function can be used by all the regulators that support Output On with Low Power Mode by PWRREQ, making much simpler the code to set the suspend mode. Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/max77802.c93
1 files changed, 46 insertions, 47 deletions
diff --git a/drivers/regulator/max77802.c b/drivers/regulator/max77802.c
index 6eabb954ec7c..dae2c1acd879 100644
--- a/drivers/regulator/max77802.c
+++ b/drivers/regulator/max77802.c
@@ -50,6 +50,7 @@
50#define MAX77802_RAMP_RATE_SHIFT_4BIT 4 50#define MAX77802_RAMP_RATE_SHIFT_4BIT 4
51 51
52#define MAX77802_OFF_PWRREQ 0x1 52#define MAX77802_OFF_PWRREQ 0x1
53#define MAX77802_LP_PWRREQ 0x2
53 54
54/* MAX77802 has two register formats: 2-bit and 4-bit */ 55/* MAX77802 has two register formats: 2-bit and 4-bit */
55static const unsigned int ramp_table_77802_2bit[] = { 56static const unsigned int ramp_table_77802_2bit[] = {
@@ -148,71 +149,68 @@ static unsigned max77802_get_mode(struct regulator_dev *rdev)
148 return max77802_map_mode(max77802->opmode[id]); 149 return max77802_map_mode(max77802->opmode[id]);
149} 150}
150 151
151/* 152/**
152 * Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state 153 * max77802_set_suspend_mode - set regulator opmode when the system is suspended
153 * (Enable Control Logic1 by PWRREQ) 154 * @rdev: regulator to change mode
155 * @mode: operating mode to be set
156 *
157 * Will set the operating mode for the regulators during system suspend.
158 * This function is valid for the three different enable control logics:
154 * 159 *
155 * LDOs 2, 4-19, 22-35. 160 * Enable Control Logic1 by PWRREQ (BUCK 2-4 and LDOs 2, 4-19, 22-35)
161 * Enable Control Logic2 by PWRREQ (LDOs 1, 20, 21)
162 * Enable Control Logic3 by PWRREQ (LDO 3)
156 * 163 *
164 * If setting the regulator mode fails, the function only warns but does
165 * not return an error code to avoid the regulator core to stop setting
166 * the operating mode for the remaining regulators.
157 */ 167 */
158static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev, 168static int max77802_set_suspend_mode(struct regulator_dev *rdev,
159 unsigned int mode) 169 unsigned int mode)
160{ 170{
161 struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); 171 struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
162 int id = rdev_get_id(rdev); 172 int id = rdev_get_id(rdev);
163 unsigned int val; 173 unsigned int val;
164 int shift = max77802_get_opmode_shift(id); 174 int shift = max77802_get_opmode_shift(id);
165 175
166 switch (mode) { 176 /*
167 case REGULATOR_MODE_IDLE: /* ON in LP Mode */ 177 * If the regulator has been disabled for suspend
168 val = MAX77802_OPMODE_LP; 178 * then is invalid to try setting a suspend mode.
169 break; 179 */
170 case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ 180 if (!max77802->opmode[id] == MAX77802_OFF_PWRREQ) {
171 val = MAX77802_OPMODE_NORMAL; 181 dev_warn(&rdev->dev, "%s: is disabled, mode: 0x%x not set\n",
172 break;
173 case REGULATOR_MODE_STANDBY: /* ON/OFF by PWRREQ */
174 val = MAX77802_OPMODE_STANDBY;
175 break;
176 default:
177 dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
178 rdev->desc->name, mode); 182 rdev->desc->name, mode);
179 return -EINVAL; 183 return 0;
180 } 184 }
181 185
182 max77802->opmode[id] = val;
183 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
184 rdev->desc->enable_mask, val << shift);
185}
186
187/*
188 * Mode 1 (Output[ON/OFF] by PWRREQ) is not supported on some LDOs
189 * (Enable Control Logic2 by PWRREQ)
190 *
191 * LDOs 1, 20, 21, and 3,
192 *
193 */
194static int max77802_ldo_set_suspend_mode_logic2(struct regulator_dev *rdev,
195 unsigned int mode)
196{
197 struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
198 int id = rdev_get_id(rdev);
199 unsigned int val;
200 int shift = max77802_get_opmode_shift(id);
201
202 switch (mode) { 186 switch (mode) {
203 case REGULATOR_MODE_IDLE: /* ON in LP Mode */ 187 case REGULATOR_MODE_STANDBY:
204 val = MAX77802_OPMODE_LP; 188 /*
205 break; 189 * If the regulator opmode is normal then enable
206 case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ 190 * ON in Low Power Mode by PWRREQ. If the mode is
207 val = MAX77802_OPMODE_NORMAL; 191 * already Low Power then no action is required.
192 */
193 if (max77802->opmode[id] == MAX77802_OPMODE_NORMAL)
194 val = MAX77802_LP_PWRREQ;
195 else
196 return 0;
208 break; 197 break;
198 case REGULATOR_MODE_NORMAL:
199 /*
200 * If the regulator operating mode is Low Power then
201 * normal is not a valid opmode in suspend. If the
202 * mode is already normal then no action is required.
203 */
204 if (max77802->opmode[id] == MAX77802_OPMODE_LP)
205 dev_warn(&rdev->dev, "%s: in Low Power: 0x%x invalid\n",
206 rdev->desc->name, mode);
207 return 0;
209 default: 208 default:
210 dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", 209 dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
211 rdev->desc->name, mode); 210 rdev->desc->name, mode);
212 return -EINVAL; 211 return -EINVAL;
213 } 212 }
214 213
215 max77802->opmode[id] = val;
216 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 214 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
217 rdev->desc->enable_mask, val << shift); 215 rdev->desc->enable_mask, val << shift);
218} 216}
@@ -297,7 +295,7 @@ static struct regulator_ops max77802_ldo_ops_logic1 = {
297 .set_voltage_time_sel = regulator_set_voltage_time_sel, 295 .set_voltage_time_sel = regulator_set_voltage_time_sel,
298 .set_suspend_enable = max77802_enable, 296 .set_suspend_enable = max77802_enable,
299 .set_suspend_disable = max77802_set_suspend_disable, 297 .set_suspend_disable = max77802_set_suspend_disable,
300 .set_suspend_mode = max77802_ldo_set_suspend_mode_logic1, 298 .set_suspend_mode = max77802_set_suspend_mode,
301}; 299};
302 300
303/* 301/*
@@ -314,7 +312,7 @@ static struct regulator_ops max77802_ldo_ops_logic2 = {
314 .set_voltage_time_sel = regulator_set_voltage_time_sel, 312 .set_voltage_time_sel = regulator_set_voltage_time_sel,
315 .set_mode = max77802_set_mode, 313 .set_mode = max77802_set_mode,
316 .get_mode = max77802_get_mode, 314 .get_mode = max77802_get_mode,
317 .set_suspend_mode = max77802_ldo_set_suspend_mode_logic2, 315 .set_suspend_mode = max77802_set_suspend_mode,
318}; 316};
319 317
320/* BUCKS 1, 6 */ 318/* BUCKS 1, 6 */
@@ -345,6 +343,7 @@ static struct regulator_ops max77802_buck_234_ops = {
345 .set_ramp_delay = max77802_set_ramp_delay_2bit, 343 .set_ramp_delay = max77802_set_ramp_delay_2bit,
346 .set_suspend_enable = max77802_enable, 344 .set_suspend_enable = max77802_enable,
347 .set_suspend_disable = max77802_set_suspend_disable, 345 .set_suspend_disable = max77802_set_suspend_disable,
346 .set_suspend_mode = max77802_set_suspend_mode,
348}; 347};
349 348
350/* BUCKs 5, 7-10 */ 349/* BUCKs 5, 7-10 */