Skip to content

Commit b2dcf7a

Browse files
power-xsfrkhuangtao
authored andcommitted
mfd: rk806: config the power off sequence
Configure the power-off timing of each power supply of the PMIC during normal shutdown through the "shutdown-sequence". Configure the power-off timing of each power supply of PMIC during low power forced shutdown through "vb-shutdown-sequence". Press the RESET button in sleep mode, and the PMIC will power down and then power on. The PMIC's power on sequence follows the power on sequence. Change-Id: Iebd0ea604fe5419dcead8fa75ade1402cabf7461 Signed-off-by: Shengfei Xu <[email protected]>
1 parent a3f03c7 commit b2dcf7a

File tree

3 files changed

+141
-4
lines changed

3 files changed

+141
-4
lines changed

drivers/mfd/rk806-core.c

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,43 @@ static const struct reg_field rk806_reg_fields[] = {
280280
[INT_FUNCTION] = REG_FIELD(0x7b, 2, 2),
281281
[INT_POL] = REG_FIELD(0x7b, 1, 1),
282282
[INT_FC_EN] = REG_FIELD(0x7b, 0, 0),
283+
284+
[BUCK1_SEQ] = REG_FIELD(0xB2, 0, 5),
285+
[BUCK2_SEQ] = REG_FIELD(0xB3, 0, 5),
286+
[BUCK3_SEQ] = REG_FIELD(0xB4, 0, 5),
287+
[BUCK4_SEQ] = REG_FIELD(0xB5, 0, 5),
288+
[BUCK5_SEQ] = REG_FIELD(0xB6, 0, 5),
289+
[BUCK6_SEQ] = REG_FIELD(0xB7, 0, 5),
290+
[BUCK7_SEQ] = REG_FIELD(0xB8, 0, 5),
291+
[BUCK8_SEQ] = REG_FIELD(0xB9, 0, 5),
292+
[BUCK9_SEQ] = REG_FIELD(0xBA, 0, 5),
293+
[BUCK10_SEQ] = REG_FIELD(0xBB, 0, 5),
294+
295+
[NLDO1_SEQ] = REG_FIELD(0xBC, 0, 5),
296+
[NLDO2_SEQ] = REG_FIELD(0xBD, 0, 5),
297+
[NLDO3_SEQ] = REG_FIELD(0xBE, 0, 5),
298+
[NLDO4_SEQ] = REG_FIELD(0xBF, 0, 5),
299+
[NLDO5_SEQ] = REG_FIELD(0xC0, 0, 5),
300+
301+
[PLDO6_45_SEQ] = REG_FIELD(0xB5, 6, 7),
302+
[PLDO6_23_SEQ] = REG_FIELD(0xB6, 6, 7),
303+
[PLDO6_01_SEQ] = REG_FIELD(0xB7, 6, 7),
304+
305+
[PLDO1_45_SEQ] = REG_FIELD(0xB8, 6, 7),
306+
[PLDO1_23_SEQ] = REG_FIELD(0xB9, 6, 7),
307+
[PLDO1_01_SEQ] = REG_FIELD(0xBA, 6, 7),
308+
309+
[PLDO2_45_SEQ] = REG_FIELD(0xBB, 6, 7),
310+
[PLDO2_23_SEQ] = REG_FIELD(0xBC, 6, 7),
311+
[PLDO2_01_SEQ] = REG_FIELD(0xBD, 6, 7),
312+
313+
[PLDO3_45_SEQ] = REG_FIELD(0xBE, 6, 7),
314+
[PLDO3_23_SEQ] = REG_FIELD(0xBF, 6, 7),
315+
[PLDO3_01_SEQ] = REG_FIELD(0xC0, 6, 7),
316+
317+
[PLDO4_SEQ] = REG_FIELD(0xC1, 0, 5),
318+
[PLDO5_SEQ] = REG_FIELD(0xC2, 0, 5),
319+
283320
[BUCK9_RATE2] = REG_FIELD(0xEA, 0, 0),
284321
[BUCK10_RATE2] = REG_FIELD(0xEA, 1, 1),
285322
[LDO_RATE] = REG_FIELD(0xEA, 3, 5),
@@ -512,6 +549,55 @@ int rk806_field_write(struct rk806 *rk806,
512549
}
513550
EXPORT_SYMBOL_GPL(rk806_field_write);
514551

552+
static void rk806_vb_requence_config(struct rk806 *rk806)
553+
{
554+
struct rk806_platform_data *pdata = rk806->pdata;
555+
int i;
556+
557+
if (!pdata->support_vb_sequence || !pdata->vb_shutdown_sequence)
558+
return;
559+
560+
for (i = RK806_ID_DCDC1; i <= RK806_ID_DCDC10; i++)
561+
rk806_field_write(rk806, BUCK1_SEQ + i, pdata->vb_shutdown_sequence[i]);
562+
563+
for (i = RK806_ID_NLDO1; i <= RK806_ID_NLDO5; i++)
564+
rk806_field_write(rk806,
565+
NLDO1_SEQ + (i - RK806_ID_NLDO1),
566+
pdata->vb_shutdown_sequence[i]);
567+
568+
rk806_field_write(rk806, PLDO1_01_SEQ, pdata->vb_shutdown_sequence[RK806_ID_PLDO1]);
569+
rk806_field_write(rk806, PLDO2_01_SEQ, pdata->vb_shutdown_sequence[RK806_ID_PLDO2]);
570+
rk806_field_write(rk806, PLDO3_01_SEQ, pdata->vb_shutdown_sequence[RK806_ID_PLDO3]);
571+
rk806_field_write(rk806, PLDO4_SEQ, pdata->vb_shutdown_sequence[RK806_ID_PLDO4]);
572+
rk806_field_write(rk806, PLDO5_SEQ, pdata->vb_shutdown_sequence[RK806_ID_PLDO5]);
573+
rk806_field_write(rk806, PLDO6_01_SEQ, pdata->vb_shutdown_sequence[RK806_ID_PLDO6]);
574+
}
575+
576+
void rk806_shutdown_requence_config(struct rk806 *rk806)
577+
{
578+
struct rk806_platform_data *pdata = rk806->pdata;
579+
int i;
580+
581+
if (!pdata->support_shutdown_sequence || !pdata->shutdown_sequence)
582+
return;
583+
584+
for (i = RK806_ID_DCDC1; i <= RK806_ID_DCDC10; i++)
585+
rk806_field_write(rk806, BUCK1_SEQ + i, pdata->shutdown_sequence[i]);
586+
587+
for (i = RK806_ID_NLDO1; i <= RK806_ID_NLDO5; i++)
588+
rk806_field_write(rk806,
589+
NLDO1_SEQ + (i - RK806_ID_NLDO1),
590+
pdata->shutdown_sequence[i]);
591+
592+
rk806_field_write(rk806, PLDO1_01_SEQ, pdata->shutdown_sequence[RK806_ID_PLDO1]);
593+
rk806_field_write(rk806, PLDO2_01_SEQ, pdata->shutdown_sequence[RK806_ID_PLDO2]);
594+
rk806_field_write(rk806, PLDO3_01_SEQ, pdata->shutdown_sequence[RK806_ID_PLDO3]);
595+
rk806_field_write(rk806, PLDO4_SEQ, pdata->shutdown_sequence[RK806_ID_PLDO4]);
596+
rk806_field_write(rk806, PLDO5_SEQ, pdata->shutdown_sequence[RK806_ID_PLDO5]);
597+
rk806_field_write(rk806, PLDO6_01_SEQ, pdata->shutdown_sequence[RK806_ID_PLDO6]);
598+
}
599+
EXPORT_SYMBOL_GPL(rk806_shutdown_requence_config);
600+
515601
static void rk806_irq_init(struct rk806 *rk806)
516602
{
517603
/* INT pin polarity active low */
@@ -576,6 +662,7 @@ static void rk806_vb_force_shutdown_init(struct rk806 *rk806)
576662
{
577663
struct rk806_platform_data *pdata = rk806->pdata;
578664

665+
rk806_vb_requence_config(rk806);
579666
rk806_field_write(rk806, VB_LO_ACT, VB_LO_ACT_SD);
580667
rk806_field_write(rk806, VB_LO_SEL,
581668
(pdata->low_voltage_threshold - 2800) / 100);
@@ -701,6 +788,38 @@ static int rk806_parse_dt(struct rk806 *rk806)
701788
if (device_property_read_bool(dev, "vdc-wakeup-enable"))
702789
pdata->vdc_wakeup_enable = 1;
703790

791+
pdata->shutdown_sequence = devm_kzalloc(dev,
792+
RK806_ID_END * sizeof(int),
793+
GFP_KERNEL);
794+
if (!pdata->shutdown_sequence)
795+
return -EINVAL;
796+
797+
pdata->support_shutdown_sequence = 1;
798+
ret = device_property_read_u32_array(dev,
799+
"shutdown-sequence",
800+
pdata->shutdown_sequence,
801+
RK806_ID_END);
802+
if (ret) {
803+
dev_info(dev, "shutdown-sequence missing!\n");
804+
pdata->support_shutdown_sequence = 0;
805+
}
806+
807+
pdata->vb_shutdown_sequence = devm_kzalloc(dev,
808+
RK806_ID_END * sizeof(int),
809+
GFP_KERNEL);
810+
if (!pdata->vb_shutdown_sequence)
811+
return -EINVAL;
812+
813+
pdata->support_vb_sequence = 1;
814+
ret = device_property_read_u32_array(dev,
815+
"vb-shutdown-sequence",
816+
pdata->vb_shutdown_sequence,
817+
RK806_ID_END);
818+
if (ret) {
819+
pdata->support_vb_sequence = 0;
820+
dev_info(dev, "vb-shutdown-sequence missing!\n");
821+
}
822+
704823
return 0;
705824
}
706825

drivers/regulator/rk806-regulator.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,7 @@ static int __maybe_unused rk806_suspend(struct device *dev)
11801180
struct rk806 *rk806 = dev_get_drvdata(dev->parent);
11811181
int i;
11821182

1183+
rk806_field_write(rk806, RST_FUN, 0x00);
11831184
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_NULL_FUN);
11841185

11851186
for (i = RK806_ID_DCDC1; i < RK806_ID_END; i++)
@@ -1202,6 +1203,7 @@ static int __maybe_unused rk806_resume(struct device *dev)
12021203
rk806_field_write(rk806, BUCK1_VSEL_CTR_SEL + i, CTR_BY_NO_EFFECT);
12031204

12041205
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_NULL_FUN);
1206+
rk806_field_write(rk806, RST_FUN, 0x01);
12051207

12061208
return 0;
12071209
}
@@ -1211,14 +1213,14 @@ static void rk806_regulator_shutdown(struct platform_device *pdev)
12111213
{
12121214
struct rk806 *rk806 = dev_get_drvdata(pdev->dev.parent);
12131215

1214-
if (system_state == SYSTEM_POWER_OFF)
1216+
if (system_state == SYSTEM_POWER_OFF) {
1217+
rk806_shutdown_requence_config(rk806);
12151218
if ((rk806->pins->p) && (rk806->pins->power_off))
12161219
pinctrl_select_state(rk806->pins->p, rk806->pins->power_off);
1217-
1220+
}
12181221
if (system_state == SYSTEM_RESTART)
12191222
if ((rk806->pins->p) && (rk806->pins->reset))
12201223
pinctrl_select_state(rk806->pins->p, rk806->pins->reset);
1221-
12221224
}
12231225

12241226
static const struct platform_device_id rk806_regulator_id_table[] = {

include/linux/mfd/rk806.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,16 @@ enum rk806_fields {
482482
LDO_RATE, BUCK1_RATE2, BUCK2_RATE2, BUCK3_RATE2, BUCK4_RATE2,
483483
BUCK5_RATE2, BUCK6_RATE2, BUCK7_RATE2, BUCK8_RATE2, BUCK9_RATE2,
484484
BUCK10_RATE2,
485+
486+
BUCK1_SEQ, BUCK2_SEQ, BUCK3_SEQ, BUCK4_SEQ, BUCK5_SEQ,
487+
BUCK6_SEQ, BUCK7_SEQ, BUCK8_SEQ, BUCK9_SEQ, BUCK10_SEQ,
488+
PLDO1_01_SEQ, PLDO1_23_SEQ, PLDO1_45_SEQ,
489+
PLDO2_01_SEQ, PLDO2_23_SEQ, PLDO2_45_SEQ,
490+
PLDO3_01_SEQ, PLDO3_23_SEQ, PLDO3_45_SEQ,
491+
PLDO4_SEQ, PLDO5_SEQ,
492+
PLDO6_01_SEQ, PLDO6_23_SEQ, PLDO6_45_SEQ,
493+
NLDO1_SEQ, NLDO2_SEQ, NLDO3_SEQ, NLDO4_SEQ, NLDO5_SEQ,
494+
485495
F_MAX_FIELDS
486496
};
487497

@@ -492,6 +502,12 @@ struct rk806_platform_data {
492502
int shutdown_temperture_threshold;
493503
int hotdie_temperture_threshold;
494504
int vdc_wakeup_enable;
505+
506+
int *shutdown_sequence;
507+
int *vb_shutdown_sequence;
508+
509+
int support_shutdown_sequence;
510+
int support_vb_sequence;
495511
};
496512

497513
struct rk806_pin_info {
@@ -517,7 +533,6 @@ struct rk806 {
517533
struct regmap_irq_chip_data *irq_data;
518534
struct rk806_platform_data *pdata;
519535
struct rk806_pin_info *pins;
520-
int vb_lo_irq;
521536
};
522537

523538
extern const struct regmap_config rk806_regmap_config;
@@ -529,4 +544,5 @@ int rk806_field_write(struct rk806 *rk806,
529544
unsigned int val);
530545
int rk806_field_read(struct rk806 *rk806,
531546
enum rk806_fields field_id);
547+
void rk806_shutdown_requence_config(struct rk806 *rk806);
532548
#endif /* __LINUX_REGULATOR_RK806_H */

0 commit comments

Comments
 (0)