summaryrefslogtreecommitdiff
path: root/drivers/regulator/max77802.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/max77802.c')
-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 6eabb95..dae2c1a 100644
--- a/drivers/regulator/max77802.c
+++ b/drivers/regulator/max77802.c
@@ -50,6 +50,7 @@
#define MAX77802_RAMP_RATE_SHIFT_4BIT 4
#define MAX77802_OFF_PWRREQ 0x1
+#define MAX77802_LP_PWRREQ 0x2
/* MAX77802 has two register formats: 2-bit and 4-bit */
static const unsigned int ramp_table_77802_2bit[] = {
@@ -148,71 +149,68 @@ static unsigned max77802_get_mode(struct regulator_dev *rdev)
return max77802_map_mode(max77802->opmode[id]);
}
-/*
- * Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state
- * (Enable Control Logic1 by PWRREQ)
+/**
+ * max77802_set_suspend_mode - set regulator opmode when the system is suspended
+ * @rdev: regulator to change mode
+ * @mode: operating mode to be set
+ *
+ * Will set the operating mode for the regulators during system suspend.
+ * This function is valid for the three different enable control logics:
*
- * LDOs 2, 4-19, 22-35.
+ * Enable Control Logic1 by PWRREQ (BUCK 2-4 and LDOs 2, 4-19, 22-35)
+ * Enable Control Logic2 by PWRREQ (LDOs 1, 20, 21)
+ * Enable Control Logic3 by PWRREQ (LDO 3)
*
+ * If setting the regulator mode fails, the function only warns but does
+ * not return an error code to avoid the regulator core to stop setting
+ * the operating mode for the remaining regulators.
*/
-static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev,
- unsigned int mode)
+static int max77802_set_suspend_mode(struct regulator_dev *rdev,
+ unsigned int mode)
{
struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
unsigned int val;
int shift = max77802_get_opmode_shift(id);
- switch (mode) {
- case REGULATOR_MODE_IDLE: /* ON in LP Mode */
- val = MAX77802_OPMODE_LP;
- break;
- case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
- val = MAX77802_OPMODE_NORMAL;
- break;
- case REGULATOR_MODE_STANDBY: /* ON/OFF by PWRREQ */
- val = MAX77802_OPMODE_STANDBY;
- break;
- default:
- dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
+ /*
+ * If the regulator has been disabled for suspend
+ * then is invalid to try setting a suspend mode.
+ */
+ if (!max77802->opmode[id] == MAX77802_OFF_PWRREQ) {
+ dev_warn(&rdev->dev, "%s: is disabled, mode: 0x%x not set\n",
rdev->desc->name, mode);
- return -EINVAL;
+ return 0;
}
- max77802->opmode[id] = val;
- return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
- rdev->desc->enable_mask, val << shift);
-}
-
-/*
- * Mode 1 (Output[ON/OFF] by PWRREQ) is not supported on some LDOs
- * (Enable Control Logic2 by PWRREQ)
- *
- * LDOs 1, 20, 21, and 3,
- *
- */
-static int max77802_ldo_set_suspend_mode_logic2(struct regulator_dev *rdev,
- unsigned int mode)
-{
- struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
- int id = rdev_get_id(rdev);
- unsigned int val;
- int shift = max77802_get_opmode_shift(id);
-
switch (mode) {
- case REGULATOR_MODE_IDLE: /* ON in LP Mode */
- val = MAX77802_OPMODE_LP;
- break;
- case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
- val = MAX77802_OPMODE_NORMAL;
+ case REGULATOR_MODE_STANDBY:
+ /*
+ * If the regulator opmode is normal then enable
+ * ON in Low Power Mode by PWRREQ. If the mode is
+ * already Low Power then no action is required.
+ */
+ if (max77802->opmode[id] == MAX77802_OPMODE_NORMAL)
+ val = MAX77802_LP_PWRREQ;
+ else
+ return 0;
break;
+ case REGULATOR_MODE_NORMAL:
+ /*
+ * If the regulator operating mode is Low Power then
+ * normal is not a valid opmode in suspend. If the
+ * mode is already normal then no action is required.
+ */
+ if (max77802->opmode[id] == MAX77802_OPMODE_LP)
+ dev_warn(&rdev->dev, "%s: in Low Power: 0x%x invalid\n",
+ rdev->desc->name, mode);
+ return 0;
default:
dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
rdev->desc->name, mode);
return -EINVAL;
}
- max77802->opmode[id] = val;
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, val << shift);
}
@@ -297,7 +295,7 @@ static struct regulator_ops max77802_ldo_ops_logic1 = {
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_suspend_enable = max77802_enable,
.set_suspend_disable = max77802_set_suspend_disable,
- .set_suspend_mode = max77802_ldo_set_suspend_mode_logic1,
+ .set_suspend_mode = max77802_set_suspend_mode,
};
/*
@@ -314,7 +312,7 @@ static struct regulator_ops max77802_ldo_ops_logic2 = {
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_mode = max77802_set_mode,
.get_mode = max77802_get_mode,
- .set_suspend_mode = max77802_ldo_set_suspend_mode_logic2,
+ .set_suspend_mode = max77802_set_suspend_mode,
};
/* BUCKS 1, 6 */
@@ -345,6 +343,7 @@ static struct regulator_ops max77802_buck_234_ops = {
.set_ramp_delay = max77802_set_ramp_delay_2bit,
.set_suspend_enable = max77802_enable,
.set_suspend_disable = max77802_set_suspend_disable,
+ .set_suspend_mode = max77802_set_suspend_mode,
};
/* BUCKs 5, 7-10 */