hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/drivers/regulator/pfuze100-regulator.c
....@@ -31,11 +31,17 @@
3131
3232 #define PFUZE100_COINVOL 0x1a
3333 #define PFUZE100_SW1ABVOL 0x20
34
+#define PFUZE100_SW1ABMODE 0x23
3435 #define PFUZE100_SW1CVOL 0x2e
36
+#define PFUZE100_SW1CMODE 0x31
3537 #define PFUZE100_SW2VOL 0x35
38
+#define PFUZE100_SW2MODE 0x38
3639 #define PFUZE100_SW3AVOL 0x3c
40
+#define PFUZE100_SW3AMODE 0x3f
3741 #define PFUZE100_SW3BVOL 0x43
42
+#define PFUZE100_SW3BMODE 0x46
3843 #define PFUZE100_SW4VOL 0x4a
44
+#define PFUZE100_SW4MODE 0x4d
3945 #define PFUZE100_SWBSTCON1 0x66
4046 #define PFUZE100_VREFDDRCON 0x6a
4147 #define PFUZE100_VSNVSVOL 0x6b
....@@ -45,6 +51,13 @@
4551 #define PFUZE100_VGEN4VOL 0x6f
4652 #define PFUZE100_VGEN5VOL 0x70
4753 #define PFUZE100_VGEN6VOL 0x71
54
+
55
+#define PFUZE100_SWxMODE_MASK 0xf
56
+#define PFUZE100_SWxMODE_APS_APS 0x8
57
+#define PFUZE100_SWxMODE_APS_OFF 0x4
58
+
59
+#define PFUZE100_VGENxLPWR BIT(6)
60
+#define PFUZE100_VGENxSTBY BIT(5)
4861
4962 enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3, PFUZE3001 = 0x31, };
5063
....@@ -115,7 +128,7 @@
115128 struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev);
116129 int id = rdev_get_id(rdev);
117130 bool reg_has_ramp_delay;
118
- unsigned int ramp_bits;
131
+ unsigned int ramp_bits = 0;
119132 int ret;
120133
121134 switch (pfuze100->chip_id) {
....@@ -136,8 +149,11 @@
136149 }
137150
138151 if (reg_has_ramp_delay) {
139
- ramp_delay = 12500 / ramp_delay;
140
- ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3);
152
+ if (ramp_delay > 0) {
153
+ ramp_delay = 12500 / ramp_delay;
154
+ ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3);
155
+ }
156
+
141157 ret = regmap_update_bits(pfuze100->regmap,
142158 rdev->desc->vsel_reg + 4,
143159 0xc0, ramp_bits << 6);
....@@ -375,6 +391,7 @@
375391 PFUZE100_VGEN_REG(PFUZE100, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
376392 PFUZE100_VGEN_REG(PFUZE100, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
377393 PFUZE100_VGEN_REG(PFUZE100, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
394
+ PFUZE100_COIN_REG(PFUZE100, COIN, PFUZE100_COINVOL, 0x7, pfuze100_coin),
378395 };
379396
380397 static struct pfuze_regulator pfuze200_regulators[] = {
....@@ -441,6 +458,7 @@
441458 { .name = "vgen4", },
442459 { .name = "vgen5", },
443460 { .name = "vgen6", },
461
+ { .name = "coin", },
444462 };
445463
446464 /* PFUZE200 */
....@@ -513,6 +531,7 @@
513531 parent = of_get_child_by_name(np, "regulators");
514532 if (!parent) {
515533 dev_err(dev, "regulators node not found\n");
534
+ of_node_put(np);
516535 return -EINVAL;
517536 }
518537
....@@ -542,6 +561,7 @@
542561 }
543562
544563 of_node_put(parent);
564
+ of_node_put(np);
545565 if (ret < 0) {
546566 dev_err(dev, "Error parsing regulator init data: %d\n",
547567 ret);
....@@ -576,6 +596,69 @@
576596 return NULL;
577597 }
578598 #endif
599
+
600
+static struct pfuze_chip *syspm_pfuze_chip;
601
+
602
+static void pfuze_power_off_prepare(void)
603
+{
604
+ dev_info(syspm_pfuze_chip->dev, "Configure standby mode for power off");
605
+
606
+ /* Switch from default mode: APS/APS to APS/Off */
607
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW1ABMODE,
608
+ PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
609
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW1CMODE,
610
+ PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
611
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW2MODE,
612
+ PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
613
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW3AMODE,
614
+ PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
615
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW3BMODE,
616
+ PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
617
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW4MODE,
618
+ PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF);
619
+
620
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN1VOL,
621
+ PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
622
+ PFUZE100_VGENxSTBY);
623
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN2VOL,
624
+ PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
625
+ PFUZE100_VGENxSTBY);
626
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN3VOL,
627
+ PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
628
+ PFUZE100_VGENxSTBY);
629
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN4VOL,
630
+ PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
631
+ PFUZE100_VGENxSTBY);
632
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN5VOL,
633
+ PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
634
+ PFUZE100_VGENxSTBY);
635
+ regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN6VOL,
636
+ PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY,
637
+ PFUZE100_VGENxSTBY);
638
+}
639
+
640
+static int pfuze_power_off_prepare_init(struct pfuze_chip *pfuze_chip)
641
+{
642
+ if (pfuze_chip->chip_id != PFUZE100) {
643
+ dev_warn(pfuze_chip->dev, "Requested pm_power_off_prepare handler for not supported chip\n");
644
+ return -ENODEV;
645
+ }
646
+
647
+ if (pm_power_off_prepare) {
648
+ dev_warn(pfuze_chip->dev, "pm_power_off_prepare is already registered.\n");
649
+ return -EBUSY;
650
+ }
651
+
652
+ if (syspm_pfuze_chip) {
653
+ dev_warn(pfuze_chip->dev, "syspm_pfuze_chip is already set.\n");
654
+ return -EBUSY;
655
+ }
656
+
657
+ syspm_pfuze_chip = pfuze_chip;
658
+ pm_power_off_prepare = pfuze_power_off_prepare;
659
+
660
+ return 0;
661
+}
579662
580663 static int pfuze_identify(struct pfuze_chip *pfuze_chip)
581664 {
....@@ -708,7 +791,7 @@
708791 ((pfuze_chip->chip_id == PFUZE3000) ? "3000" : "3001"))));
709792
710793 memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators,
711
- sizeof(pfuze_chip->regulator_descs));
794
+ regulator_num * sizeof(struct pfuze_regulator));
712795
713796 ret = pfuze_parse_regulators_dt(pfuze_chip);
714797 if (ret)
....@@ -780,6 +863,20 @@
780863 }
781864 }
782865
866
+ if (of_property_read_bool(client->dev.of_node,
867
+ "fsl,pmic-stby-poweroff"))
868
+ return pfuze_power_off_prepare_init(pfuze_chip);
869
+
870
+ return 0;
871
+}
872
+
873
+static int pfuze100_regulator_remove(struct i2c_client *client)
874
+{
875
+ if (syspm_pfuze_chip) {
876
+ syspm_pfuze_chip = NULL;
877
+ pm_power_off_prepare = NULL;
878
+ }
879
+
783880 return 0;
784881 }
785882
....@@ -790,6 +887,7 @@
790887 .of_match_table = pfuze_dt_ids,
791888 },
792889 .probe = pfuze100_regulator_probe,
890
+ .remove = pfuze100_regulator_remove,
793891 };
794892 module_i2c_driver(pfuze_driver);
795893