mfd: rk806: Support power-supply grouping to enter sleep mode

In order to support the suspend/resume power supply sequence,
the power supplies are grouped and controlled in stages to enter sleep mode.

Change-Id: I16cb53b01b86a8b221de91a62c5ffddfa34e0f33
Signed-off-by: Shengfei Xu <xsf@rock-chips.com>
This commit is contained in:
Shengfei Xu 2024-11-12 16:43:49 +08:00 committed by Tao Huang
parent 2c35da87a4
commit b711dfd7ef
3 changed files with 52 additions and 4 deletions

View file

@ -214,7 +214,7 @@ static const struct reg_field rk806_reg_fields[] = {
[NLDO3_VSEL_CTR_SEL] = REG_FIELD(0x6a, 0, 1),
/* SLEEP_VSEL_CTR_SEL4 */
[PLDO4_VSEL_CTR_SEL] = REG_FIELD(0x6d, 4, 5),
[PLDO3_VSEL_CTR_SEL] = REG_FIELD(0x6d, 0, 0),
[PLDO3_VSEL_CTR_SEL] = REG_FIELD(0x6d, 0, 1),
[PLDO2_VSEL_CTR_SEL] = REG_FIELD(0x6c, 4, 5),
[PLDO1_VSEL_CTR_SEL] = REG_FIELD(0x6c, 0, 1),
/* SLEEP_VSEL_CTR_SEL5 */
@ -820,6 +820,22 @@ static int rk806_parse_dt(struct rk806 *rk806)
dev_info(dev, "vb-shutdown-sequence missing!\n");
}
pdata->dvs_control_suspend = devm_kzalloc(dev,
RK806_ID_END * sizeof(int),
GFP_KERNEL);
if (!pdata->dvs_control_suspend)
return -EINVAL;
pdata->support_dvs_control_suspend = 1;
ret = device_property_read_u32_array(dev,
"dvs-suspend-control-by",
pdata->dvs_control_suspend,
RK806_ID_END);
if (ret) {
pdata->support_dvs_control_suspend = 0;
dev_info(dev, "dvs-suspend-control-by missing!\n");
}
return 0;
}

View file

@ -1178,6 +1178,8 @@ static int rk806_regulator_probe(struct platform_device *pdev)
static int __maybe_unused rk806_suspend(struct device *dev)
{
struct rk806 *rk806 = dev_get_drvdata(dev->parent);
struct rk806_platform_data *pdata = rk806->pdata;
int value;
int i;
rk806_field_write(rk806, RST_FUN, 0x00);
@ -1186,10 +1188,35 @@ static int __maybe_unused rk806_suspend(struct device *dev)
for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++)
rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_NO_EFFECT);
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_DVS_FUN);
if (!pdata->dvs_control_suspend || !pdata->support_dvs_control_suspend) {
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_DVS_FUN);
for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++)
rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_PWRCTRL1);
for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++)
rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_PWRCTRL1);
} else {
for (i = 0; i <= RK806_ID_PLDO6 - RK806_ID_PLDO1; i++) {
value = rk806_field_read(rk806, PLDO1_ON_VSEL + i);
rk806_field_write(rk806, PLDO1_SLP_VSEL + i, value);
}
for (i = RK806_ID_DCDC1; i <= RK806_ID_NLDO5; i++)
rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i,
pdata->dvs_control_suspend[i]);
rk806_field_write(rk806, PLDO1_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO6]);
rk806_field_write(rk806, PLDO2_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO1]);
rk806_field_write(rk806, PLDO3_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO2]);
rk806_field_write(rk806, PLDO4_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO3]);
rk806_field_write(rk806, PLDO5_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO4]);
rk806_field_write(rk806, PLDO6_VSEL_CTR_SEL, pdata->dvs_control_suspend[RK806_ID_PLDO5]);
for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++) {
if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL2)
rk806_field_write(rk806, PWRCTRL2_FUN, PWRCTRL_DVS_FUN);
if (pdata->dvs_control_suspend[i] == CTR_BY_PWRCTRL3)
rk806_field_write(rk806, PWRCTRL3_FUN, PWRCTRL_DVS_FUN);
}
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_SLP_FUN);
}
return 0;
}
@ -1203,6 +1230,9 @@ static int __maybe_unused rk806_resume(struct device *dev)
rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_NO_EFFECT);
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_NULL_FUN);
rk806_field_write(rk806, PWRCTRL2_FUN, PWRCTRL_NULL_FUN);
rk806_field_write(rk806, PWRCTRL3_FUN, PWRCTRL_NULL_FUN);
rk806_field_write(rk806, RST_FUN, 0x01);
return 0;

View file

@ -505,9 +505,11 @@ struct rk806_platform_data {
int *shutdown_sequence;
int *vb_shutdown_sequence;
int *dvs_control_suspend;
int support_shutdown_sequence;
int support_vb_sequence;
int support_dvs_control_suspend;
};
struct rk806_pin_info {