@@ -83,6 +83,9 @@ struct da9063_regulator_info {
83
83
84
84
/* DA9063 event detection bit */
85
85
struct reg_field oc_event ;
86
+
87
+ /* DA9063 voltage monitor bit */
88
+ struct reg_field vmon ;
86
89
};
87
90
88
91
/* Macros for LDO */
@@ -148,6 +151,7 @@ struct da9063_regulator {
148
151
struct regmap_field * suspend ;
149
152
struct regmap_field * sleep ;
150
153
struct regmap_field * suspend_sleep ;
154
+ struct regmap_field * vmon ;
151
155
};
152
156
153
157
/* Encapsulates all information for the regulators driver */
@@ -203,6 +207,24 @@ static const unsigned int da9063_bmem_bio_merged_limits[] = {
203
207
4600000 , 4800000 , 5000000 , 5200000 , 5400000 , 5600000 , 5800000 , 6000000
204
208
};
205
209
210
+ static int da9063_set_xvp (struct regulator_dev * rdev , int lim_uV , int severity , bool enable )
211
+ {
212
+ struct da9063_regulator * regl = rdev_get_drvdata (rdev );
213
+ struct device * dev = regl -> hw -> dev ;
214
+
215
+ dev_dbg (dev , "%s: lim: %d, sev: %d, en: %d\n" , regl -> desc .name , lim_uV , severity , enable );
216
+
217
+ /*
218
+ * only support enable and disable.
219
+ * the da9063 offers a GPIO (GP_FB2) which is unasserted if an XV happens.
220
+ * therefore ignore severity here, as there might be handlers in hardware.
221
+ */
222
+ if (lim_uV )
223
+ return - EINVAL ;
224
+
225
+ return regmap_field_write (regl -> vmon , enable ? 1 : 0 );
226
+ }
227
+
206
228
static int da9063_buck_set_mode (struct regulator_dev * rdev , unsigned int mode )
207
229
{
208
230
struct da9063_regulator * regl = rdev_get_drvdata (rdev );
@@ -541,37 +563,41 @@ static int da9063_buck_get_current_limit(struct regulator_dev *rdev)
541
563
}
542
564
543
565
static const struct regulator_ops da9063_buck_ops = {
544
- .enable = regulator_enable_regmap ,
545
- .disable = regulator_disable_regmap ,
546
- .is_enabled = regulator_is_enabled_regmap ,
547
- .get_voltage_sel = regulator_get_voltage_sel_regmap ,
548
- .set_voltage_sel = regulator_set_voltage_sel_regmap ,
549
- .list_voltage = regulator_list_voltage_linear ,
550
- .set_current_limit = da9063_buck_set_current_limit ,
551
- .get_current_limit = da9063_buck_get_current_limit ,
552
- .set_mode = da9063_buck_set_mode ,
553
- .get_mode = da9063_buck_get_mode ,
554
- .get_status = da9063_buck_get_status ,
555
- .set_suspend_voltage = da9063_set_suspend_voltage ,
556
- .set_suspend_enable = da9063_suspend_enable ,
557
- .set_suspend_disable = da9063_suspend_disable ,
558
- .set_suspend_mode = da9063_buck_set_suspend_mode ,
566
+ .enable = regulator_enable_regmap ,
567
+ .disable = regulator_disable_regmap ,
568
+ .is_enabled = regulator_is_enabled_regmap ,
569
+ .get_voltage_sel = regulator_get_voltage_sel_regmap ,
570
+ .set_voltage_sel = regulator_set_voltage_sel_regmap ,
571
+ .list_voltage = regulator_list_voltage_linear ,
572
+ .set_current_limit = da9063_buck_set_current_limit ,
573
+ .get_current_limit = da9063_buck_get_current_limit ,
574
+ .set_mode = da9063_buck_set_mode ,
575
+ .get_mode = da9063_buck_get_mode ,
576
+ .get_status = da9063_buck_get_status ,
577
+ .set_suspend_voltage = da9063_set_suspend_voltage ,
578
+ .set_suspend_enable = da9063_suspend_enable ,
579
+ .set_suspend_disable = da9063_suspend_disable ,
580
+ .set_suspend_mode = da9063_buck_set_suspend_mode ,
581
+ .set_over_voltage_protection = da9063_set_xvp ,
582
+ .set_under_voltage_protection = da9063_set_xvp ,
559
583
};
560
584
561
585
static const struct regulator_ops da9063_ldo_ops = {
562
- .enable = regulator_enable_regmap ,
563
- .disable = regulator_disable_regmap ,
564
- .is_enabled = regulator_is_enabled_regmap ,
565
- .get_voltage_sel = regulator_get_voltage_sel_regmap ,
566
- .set_voltage_sel = regulator_set_voltage_sel_regmap ,
567
- .list_voltage = regulator_list_voltage_linear ,
568
- .set_mode = da9063_ldo_set_mode ,
569
- .get_mode = da9063_ldo_get_mode ,
570
- .get_status = da9063_ldo_get_status ,
571
- .set_suspend_voltage = da9063_set_suspend_voltage ,
572
- .set_suspend_enable = da9063_suspend_enable ,
573
- .set_suspend_disable = da9063_suspend_disable ,
574
- .set_suspend_mode = da9063_ldo_set_suspend_mode ,
586
+ .enable = regulator_enable_regmap ,
587
+ .disable = regulator_disable_regmap ,
588
+ .is_enabled = regulator_is_enabled_regmap ,
589
+ .get_voltage_sel = regulator_get_voltage_sel_regmap ,
590
+ .set_voltage_sel = regulator_set_voltage_sel_regmap ,
591
+ .list_voltage = regulator_list_voltage_linear ,
592
+ .set_mode = da9063_ldo_set_mode ,
593
+ .get_mode = da9063_ldo_get_mode ,
594
+ .get_status = da9063_ldo_get_status ,
595
+ .set_suspend_voltage = da9063_set_suspend_voltage ,
596
+ .set_suspend_enable = da9063_suspend_enable ,
597
+ .set_suspend_disable = da9063_suspend_disable ,
598
+ .set_suspend_mode = da9063_ldo_set_suspend_mode ,
599
+ .set_over_voltage_protection = da9063_set_xvp ,
600
+ .set_under_voltage_protection = da9063_set_xvp ,
575
601
};
576
602
577
603
/* Info of regulators for DA9063 */
@@ -581,91 +607,110 @@ static const struct da9063_regulator_info da9063_regulator_info[] = {
581
607
da9063_buck_a_limits ,
582
608
DA9063_REG_BUCK_ILIM_C , DA9063_BCORE1_ILIM_MASK ),
583
609
DA9063_BUCK_COMMON_FIELDS (BCORE1 ),
610
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BCORE1_MON_EN ),
584
611
},
585
612
{
586
613
DA9063_BUCK (DA9063 , BCORE2 , 300 , 10 , 1570 ,
587
614
da9063_buck_a_limits ,
588
615
DA9063_REG_BUCK_ILIM_C , DA9063_BCORE2_ILIM_MASK ),
589
616
DA9063_BUCK_COMMON_FIELDS (BCORE2 ),
617
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BCORE2_MON_EN ),
590
618
},
591
619
{
592
620
DA9063_BUCK (DA9063 , BPRO , 530 , 10 , 1800 ,
593
621
da9063_buck_a_limits ,
594
622
DA9063_REG_BUCK_ILIM_B , DA9063_BPRO_ILIM_MASK ),
595
623
DA9063_BUCK_COMMON_FIELDS (BPRO ),
624
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BPRO_MON_EN ),
596
625
},
597
626
{
598
627
DA9063_BUCK (DA9063 , BMEM , 800 , 20 , 3340 ,
599
628
da9063_buck_b_limits ,
600
629
DA9063_REG_BUCK_ILIM_A , DA9063_BMEM_ILIM_MASK ),
601
630
DA9063_BUCK_COMMON_FIELDS (BMEM ),
631
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BMEM_MON_EN ),
602
632
},
603
633
{
604
634
DA9063_BUCK (DA9063 , BIO , 800 , 20 , 3340 ,
605
635
da9063_buck_b_limits ,
606
636
DA9063_REG_BUCK_ILIM_A , DA9063_BIO_ILIM_MASK ),
607
637
DA9063_BUCK_COMMON_FIELDS (BIO ),
638
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BIO_MON_EN ),
608
639
},
609
640
{
610
641
DA9063_BUCK (DA9063 , BPERI , 800 , 20 , 3340 ,
611
642
da9063_buck_b_limits ,
612
643
DA9063_REG_BUCK_ILIM_B , DA9063_BPERI_ILIM_MASK ),
613
644
DA9063_BUCK_COMMON_FIELDS (BPERI ),
645
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BPERI_MON_EN ),
614
646
},
615
647
{
616
648
DA9063_BUCK (DA9063 , BCORES_MERGED , 300 , 10 , 1570 ,
617
649
da9063_bcores_merged_limits ,
618
650
DA9063_REG_BUCK_ILIM_C , DA9063_BCORE1_ILIM_MASK ),
619
651
/* BCORES_MERGED uses the same register fields as BCORE1 */
620
652
DA9063_BUCK_COMMON_FIELDS (BCORE1 ),
653
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BCORE1_MON_EN ),
621
654
},
622
655
{
623
656
DA9063_BUCK (DA9063 , BMEM_BIO_MERGED , 800 , 20 , 3340 ,
624
657
da9063_bmem_bio_merged_limits ,
625
658
DA9063_REG_BUCK_ILIM_A , DA9063_BMEM_ILIM_MASK ),
626
659
/* BMEM_BIO_MERGED uses the same register fields as BMEM */
627
660
DA9063_BUCK_COMMON_FIELDS (BMEM ),
661
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BMEM_MON_EN ),
628
662
},
629
663
{
630
664
DA9063_LDO (DA9063 , LDO3 , 900 , 20 , 3440 ),
631
665
.oc_event = BFIELD (DA9063_REG_STATUS_D , DA9063_LDO3_LIM ),
666
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO3_MON_EN ),
632
667
},
633
668
{
634
669
DA9063_LDO (DA9063 , LDO7 , 900 , 50 , 3600 ),
635
670
.oc_event = BFIELD (DA9063_REG_STATUS_D , DA9063_LDO7_LIM ),
671
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO7_MON_EN ),
636
672
},
637
673
{
638
674
DA9063_LDO (DA9063 , LDO8 , 900 , 50 , 3600 ),
639
675
.oc_event = BFIELD (DA9063_REG_STATUS_D , DA9063_LDO8_LIM ),
676
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO8_MON_EN ),
640
677
},
641
678
{
642
679
DA9063_LDO (DA9063 , LDO9 , 950 , 50 , 3600 ),
680
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_3 , DA9063_LDO9_MON_EN ),
643
681
},
644
682
{
645
683
DA9063_LDO (DA9063 , LDO11 , 900 , 50 , 3600 ),
646
684
.oc_event = BFIELD (DA9063_REG_STATUS_D , DA9063_LDO11_LIM ),
685
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_3 , DA9063_LDO11_MON_EN ),
647
686
},
648
687
649
688
/* The following LDOs are present only on DA9063, not on DA9063L */
650
689
{
651
690
DA9063_LDO (DA9063 , LDO1 , 600 , 20 , 1860 ),
691
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO1_MON_EN ),
652
692
},
653
693
{
654
694
DA9063_LDO (DA9063 , LDO2 , 600 , 20 , 1860 ),
695
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO2_MON_EN ),
655
696
},
656
697
{
657
698
DA9063_LDO (DA9063 , LDO4 , 900 , 20 , 3440 ),
658
699
.oc_event = BFIELD (DA9063_REG_STATUS_D , DA9063_LDO4_LIM ),
700
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO4_MON_EN ),
659
701
},
660
702
{
661
703
DA9063_LDO (DA9063 , LDO5 , 900 , 50 , 3600 ),
704
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO5_MON_EN ),
662
705
},
663
706
{
664
707
DA9063_LDO (DA9063 , LDO6 , 900 , 50 , 3600 ),
708
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO6_MON_EN ),
665
709
},
666
710
667
711
{
668
712
DA9063_LDO (DA9063 , LDO10 , 900 , 50 , 3600 ),
713
+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_3 , DA9063_LDO10_MON_EN ),
669
714
},
670
715
};
671
716
@@ -726,6 +771,41 @@ static const struct regulator_init_data *da9063_get_regulator_initdata(
726
771
return NULL ;
727
772
}
728
773
774
+ static int da9063_check_xvp_constraints (struct regulator_config * config )
775
+ {
776
+ struct da9063_regulator * regl = config -> driver_data ;
777
+ const struct regulation_constraints * constr = & config -> init_data -> constraints ;
778
+ const struct notification_limit * uv_l = & constr -> under_voltage_limits ;
779
+ const struct notification_limit * ov_l = & constr -> over_voltage_limits ;
780
+
781
+ /* make sure that only one severity is used to clarify if unchanged, enabled or disabled */
782
+ if ((!!uv_l -> prot + !!uv_l -> err + !!uv_l -> warn ) > 1 ) {
783
+ dev_err (config -> dev , "%s: at most one voltage monitoring severity allowed!\n" ,
784
+ regl -> desc .name );
785
+ return - EINVAL ;
786
+ }
787
+
788
+ /* make sure that UV and OV monitoring is set to the same severity and value */
789
+ if (uv_l -> prot != ov_l -> prot ) {
790
+ dev_err (config -> dev ,
791
+ "%s: protection-microvolt: value must be equal for uv and ov!\n" ,
792
+ regl -> desc .name );
793
+ return - EINVAL ;
794
+ }
795
+ if (uv_l -> err != ov_l -> err ) {
796
+ dev_err (config -> dev , "%s: error-microvolt: value must be equal for uv and ov!\n" ,
797
+ regl -> desc .name );
798
+ return - EINVAL ;
799
+ }
800
+ if (uv_l -> warn != ov_l -> warn ) {
801
+ dev_err (config -> dev , "%s: warn-microvolt: value must be equal for uv and ov!\n" ,
802
+ regl -> desc .name );
803
+ return - EINVAL ;
804
+ }
805
+
806
+ return 0 ;
807
+ }
808
+
729
809
static struct of_regulator_match da9063_matches [] = {
730
810
[DA9063_ID_BCORE1 ] = { .name = "bcore1" },
731
811
[DA9063_ID_BCORE2 ] = { .name = "bcore2" },
@@ -932,6 +1012,12 @@ static int da9063_regulator_probe(struct platform_device *pdev)
932
1012
if (IS_ERR (regl -> suspend_sleep ))
933
1013
return PTR_ERR (regl -> suspend_sleep );
934
1014
}
1015
+ if (regl -> info -> vmon .reg ) {
1016
+ regl -> vmon = devm_regmap_field_alloc (& pdev -> dev ,
1017
+ da9063 -> regmap , regl -> info -> vmon );
1018
+ if (IS_ERR (regl -> vmon ))
1019
+ return PTR_ERR (regl -> vmon );
1020
+ }
935
1021
936
1022
/* Register regulator */
937
1023
memset (& config , 0 , sizeof (config ));
@@ -941,6 +1027,11 @@ static int da9063_regulator_probe(struct platform_device *pdev)
941
1027
if (da9063_reg_matches )
942
1028
config .of_node = da9063_reg_matches [id ].of_node ;
943
1029
config .regmap = da9063 -> regmap ;
1030
+
1031
+ ret = da9063_check_xvp_constraints (& config );
1032
+ if (ret )
1033
+ return ret ;
1034
+
944
1035
regl -> rdev = devm_regulator_register (& pdev -> dev , & regl -> desc ,
945
1036
& config );
946
1037
if (IS_ERR (regl -> rdev )) {
0 commit comments