Skip to content

Commit 65d80db

Browse files
krzkbroonie
authored andcommitted
regulator: s2mps11: Add support for disabling S2MPS11 regulators in suspend
The driver supported turning off regulators in suspend only for S2MPS14 device. However this makes also sense for S2MPS11 and can reduce the power consumption during suspend to RAM. Signed-off-by: Krzysztof Kozlowski <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent df33799 commit 65d80db

File tree

2 files changed

+120
-95
lines changed

2 files changed

+120
-95
lines changed

drivers/regulator/s2mps11.c

Lines changed: 115 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct s2mps11_info {
3434
enum sec_device_type dev_type;
3535

3636
/*
37-
* One bit for each S2MPS13/S2MPS14/S2MPU02 regulator whether
37+
* One bit for each S2MPS11/S2MPS13/S2MPS14/S2MPU02 regulator whether
3838
* the suspend mode was enabled.
3939
*/
4040
DECLARE_BITMAP(suspend_state, S2MPS_REGULATOR_MAX);
@@ -225,27 +225,133 @@ static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
225225
1 << enable_shift, 0);
226226
}
227227

228+
static int s2mps11_regulator_enable(struct regulator_dev *rdev)
229+
{
230+
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
231+
int rdev_id = rdev_get_id(rdev);
232+
unsigned int val;
233+
234+
switch (s2mps11->dev_type) {
235+
case S2MPS11X:
236+
if (test_bit(rdev_id, s2mps11->suspend_state))
237+
val = S2MPS14_ENABLE_SUSPEND;
238+
else
239+
val = rdev->desc->enable_mask;
240+
break;
241+
case S2MPS13X:
242+
case S2MPS14X:
243+
if (test_bit(rdev_id, s2mps11->suspend_state))
244+
val = S2MPS14_ENABLE_SUSPEND;
245+
else if (s2mps11->ext_control_gpiod[rdev_id])
246+
val = S2MPS14_ENABLE_EXT_CONTROL;
247+
else
248+
val = rdev->desc->enable_mask;
249+
break;
250+
case S2MPU02:
251+
if (test_bit(rdev_id, s2mps11->suspend_state))
252+
val = S2MPU02_ENABLE_SUSPEND;
253+
else
254+
val = rdev->desc->enable_mask;
255+
break;
256+
default:
257+
return -EINVAL;
258+
}
259+
260+
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
261+
rdev->desc->enable_mask, val);
262+
}
263+
264+
static int s2mps11_regulator_set_suspend_disable(struct regulator_dev *rdev)
265+
{
266+
int ret;
267+
unsigned int val, state;
268+
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
269+
int rdev_id = rdev_get_id(rdev);
270+
271+
/* Below LDO should be always on or does not support suspend mode. */
272+
switch (s2mps11->dev_type) {
273+
case S2MPS11X:
274+
switch (rdev_id) {
275+
case S2MPS11_LDO2:
276+
case S2MPS11_LDO36:
277+
case S2MPS11_LDO37:
278+
case S2MPS11_LDO38:
279+
return 0;
280+
default:
281+
state = S2MPS14_ENABLE_SUSPEND;
282+
break;
283+
}
284+
break;
285+
case S2MPS13X:
286+
case S2MPS14X:
287+
switch (rdev_id) {
288+
case S2MPS14_LDO3:
289+
return 0;
290+
default:
291+
state = S2MPS14_ENABLE_SUSPEND;
292+
break;
293+
}
294+
break;
295+
case S2MPU02:
296+
switch (rdev_id) {
297+
case S2MPU02_LDO13:
298+
case S2MPU02_LDO14:
299+
case S2MPU02_LDO15:
300+
case S2MPU02_LDO17:
301+
case S2MPU02_BUCK7:
302+
state = S2MPU02_DISABLE_SUSPEND;
303+
break;
304+
default:
305+
state = S2MPU02_ENABLE_SUSPEND;
306+
break;
307+
}
308+
break;
309+
default:
310+
return -EINVAL;
311+
}
312+
313+
ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
314+
if (ret < 0)
315+
return ret;
316+
317+
set_bit(rdev_id, s2mps11->suspend_state);
318+
/*
319+
* Don't enable suspend mode if regulator is already disabled because
320+
* this would effectively for a short time turn on the regulator after
321+
* resuming.
322+
* However we still want to toggle the suspend_state bit for regulator
323+
* in case if it got enabled before suspending the system.
324+
*/
325+
if (!(val & rdev->desc->enable_mask))
326+
return 0;
327+
328+
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
329+
rdev->desc->enable_mask, state);
330+
}
331+
228332
static const struct regulator_ops s2mps11_ldo_ops = {
229333
.list_voltage = regulator_list_voltage_linear,
230334
.map_voltage = regulator_map_voltage_linear,
231335
.is_enabled = regulator_is_enabled_regmap,
232-
.enable = regulator_enable_regmap,
336+
.enable = s2mps11_regulator_enable,
233337
.disable = regulator_disable_regmap,
234338
.get_voltage_sel = regulator_get_voltage_sel_regmap,
235339
.set_voltage_sel = regulator_set_voltage_sel_regmap,
236340
.set_voltage_time_sel = regulator_set_voltage_time_sel,
341+
.set_suspend_disable = s2mps11_regulator_set_suspend_disable,
237342
};
238343

239344
static const struct regulator_ops s2mps11_buck_ops = {
240345
.list_voltage = regulator_list_voltage_linear,
241346
.map_voltage = regulator_map_voltage_linear,
242347
.is_enabled = regulator_is_enabled_regmap,
243-
.enable = regulator_enable_regmap,
348+
.enable = s2mps11_regulator_enable,
244349
.disable = regulator_disable_regmap,
245350
.get_voltage_sel = regulator_get_voltage_sel_regmap,
246351
.set_voltage_sel = regulator_set_voltage_sel_regmap,
247352
.set_voltage_time_sel = s2mps11_regulator_set_voltage_time_sel,
248353
.set_ramp_delay = s2mps11_set_ramp_delay,
354+
.set_suspend_disable = s2mps11_regulator_set_suspend_disable,
249355
};
250356

251357
#define regulator_desc_s2mps11_ldo(num, step) { \
@@ -501,102 +607,16 @@ static const struct regulator_desc s2mps13_regulators[] = {
501607
regulator_desc_s2mps13_buck8_10(10, MIN_500_MV, STEP_6_25_MV, 0x10),
502608
};
503609

504-
static int s2mps14_regulator_enable(struct regulator_dev *rdev)
505-
{
506-
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
507-
int rdev_id = rdev_get_id(rdev);
508-
unsigned int val;
509-
510-
switch (s2mps11->dev_type) {
511-
case S2MPS13X:
512-
case S2MPS14X:
513-
if (test_bit(rdev_id, s2mps11->suspend_state))
514-
val = S2MPS14_ENABLE_SUSPEND;
515-
else if (s2mps11->ext_control_gpiod[rdev_id])
516-
val = S2MPS14_ENABLE_EXT_CONTROL;
517-
else
518-
val = rdev->desc->enable_mask;
519-
break;
520-
case S2MPU02:
521-
if (test_bit(rdev_id, s2mps11->suspend_state))
522-
val = S2MPU02_ENABLE_SUSPEND;
523-
else
524-
val = rdev->desc->enable_mask;
525-
break;
526-
default:
527-
return -EINVAL;
528-
}
529-
530-
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
531-
rdev->desc->enable_mask, val);
532-
}
533-
534-
static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
535-
{
536-
int ret;
537-
unsigned int val, state;
538-
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
539-
int rdev_id = rdev_get_id(rdev);
540-
541-
/* Below LDO should be always on or does not support suspend mode. */
542-
switch (s2mps11->dev_type) {
543-
case S2MPS13X:
544-
case S2MPS14X:
545-
switch (rdev_id) {
546-
case S2MPS14_LDO3:
547-
return 0;
548-
default:
549-
state = S2MPS14_ENABLE_SUSPEND;
550-
break;
551-
}
552-
break;
553-
case S2MPU02:
554-
switch (rdev_id) {
555-
case S2MPU02_LDO13:
556-
case S2MPU02_LDO14:
557-
case S2MPU02_LDO15:
558-
case S2MPU02_LDO17:
559-
case S2MPU02_BUCK7:
560-
state = S2MPU02_DISABLE_SUSPEND;
561-
break;
562-
default:
563-
state = S2MPU02_ENABLE_SUSPEND;
564-
break;
565-
}
566-
break;
567-
default:
568-
return -EINVAL;
569-
}
570-
571-
ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
572-
if (ret < 0)
573-
return ret;
574-
575-
set_bit(rdev_id, s2mps11->suspend_state);
576-
/*
577-
* Don't enable suspend mode if regulator is already disabled because
578-
* this would effectively for a short time turn on the regulator after
579-
* resuming.
580-
* However we still want to toggle the suspend_state bit for regulator
581-
* in case if it got enabled before suspending the system.
582-
*/
583-
if (!(val & rdev->desc->enable_mask))
584-
return 0;
585-
586-
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
587-
rdev->desc->enable_mask, state);
588-
}
589-
590610
static const struct regulator_ops s2mps14_reg_ops = {
591611
.list_voltage = regulator_list_voltage_linear,
592612
.map_voltage = regulator_map_voltage_linear,
593613
.is_enabled = regulator_is_enabled_regmap,
594-
.enable = s2mps14_regulator_enable,
614+
.enable = s2mps11_regulator_enable,
595615
.disable = regulator_disable_regmap,
596616
.get_voltage_sel = regulator_get_voltage_sel_regmap,
597617
.set_voltage_sel = regulator_set_voltage_sel_regmap,
598618
.set_voltage_time_sel = regulator_set_voltage_time_sel,
599-
.set_suspend_disable = s2mps14_regulator_set_suspend_disable,
619+
.set_suspend_disable = s2mps11_regulator_set_suspend_disable,
600620
};
601621

602622
#define regulator_desc_s2mps14_ldo(num, min, step) { \
@@ -888,24 +908,24 @@ static const struct regulator_ops s2mpu02_ldo_ops = {
888908
.list_voltage = regulator_list_voltage_linear,
889909
.map_voltage = regulator_map_voltage_linear,
890910
.is_enabled = regulator_is_enabled_regmap,
891-
.enable = s2mps14_regulator_enable,
911+
.enable = s2mps11_regulator_enable,
892912
.disable = regulator_disable_regmap,
893913
.get_voltage_sel = regulator_get_voltage_sel_regmap,
894914
.set_voltage_sel = regulator_set_voltage_sel_regmap,
895915
.set_voltage_time_sel = regulator_set_voltage_time_sel,
896-
.set_suspend_disable = s2mps14_regulator_set_suspend_disable,
916+
.set_suspend_disable = s2mps11_regulator_set_suspend_disable,
897917
};
898918

899919
static const struct regulator_ops s2mpu02_buck_ops = {
900920
.list_voltage = regulator_list_voltage_linear,
901921
.map_voltage = regulator_map_voltage_linear,
902922
.is_enabled = regulator_is_enabled_regmap,
903-
.enable = s2mps14_regulator_enable,
923+
.enable = s2mps11_regulator_enable,
904924
.disable = regulator_disable_regmap,
905925
.get_voltage_sel = regulator_get_voltage_sel_regmap,
906926
.set_voltage_sel = regulator_set_voltage_sel_regmap,
907927
.set_voltage_time_sel = regulator_set_voltage_time_sel,
908-
.set_suspend_disable = s2mps14_regulator_set_suspend_disable,
928+
.set_suspend_disable = s2mps11_regulator_set_suspend_disable,
909929
.set_ramp_delay = s2mpu02_set_ramp_delay,
910930
};
911931

include/linux/mfd/samsung/s2mps11.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,9 @@ enum s2mps11_regulators {
188188
#define S2MPS11_BUCK6_RAMP_EN_SHIFT 0
189189
#define S2MPS11_PMIC_EN_SHIFT 6
190190

191+
/*
192+
* Bits for "enable suspend" (On/Off controlled by PWREN)
193+
* are the same as in S2MPS14: S2MPS14_ENABLE_SUSPEND
194+
*/
195+
191196
#endif /* __LINUX_MFD_S2MPS11_H */

0 commit comments

Comments
 (0)