@@ -83,6 +83,9 @@ struct da9063_regulator_info {
8383
8484 /* DA9063 event detection bit */
8585 struct reg_field oc_event ;
86+
87+ /* DA9063 voltage monitor bit */
88+ struct reg_field vmon ;
8689};
8790
8891/* Macros for LDO */
@@ -148,6 +151,7 @@ struct da9063_regulator {
148151 struct regmap_field * suspend ;
149152 struct regmap_field * sleep ;
150153 struct regmap_field * suspend_sleep ;
154+ struct regmap_field * vmon ;
151155};
152156
153157/* Encapsulates all information for the regulators driver */
@@ -203,6 +207,24 @@ static const unsigned int da9063_bmem_bio_merged_limits[] = {
203207 4600000 , 4800000 , 5000000 , 5200000 , 5400000 , 5600000 , 5800000 , 6000000
204208};
205209
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+
206228static int da9063_buck_set_mode (struct regulator_dev * rdev , unsigned int mode )
207229{
208230 struct da9063_regulator * regl = rdev_get_drvdata (rdev );
@@ -541,37 +563,41 @@ static int da9063_buck_get_current_limit(struct regulator_dev *rdev)
541563}
542564
543565static 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 ,
559583};
560584
561585static 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 ,
575601};
576602
577603/* Info of regulators for DA9063 */
@@ -581,91 +607,110 @@ static const struct da9063_regulator_info da9063_regulator_info[] = {
581607 da9063_buck_a_limits ,
582608 DA9063_REG_BUCK_ILIM_C , DA9063_BCORE1_ILIM_MASK ),
583609 DA9063_BUCK_COMMON_FIELDS (BCORE1 ),
610+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BCORE1_MON_EN ),
584611 },
585612 {
586613 DA9063_BUCK (DA9063 , BCORE2 , 300 , 10 , 1570 ,
587614 da9063_buck_a_limits ,
588615 DA9063_REG_BUCK_ILIM_C , DA9063_BCORE2_ILIM_MASK ),
589616 DA9063_BUCK_COMMON_FIELDS (BCORE2 ),
617+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BCORE2_MON_EN ),
590618 },
591619 {
592620 DA9063_BUCK (DA9063 , BPRO , 530 , 10 , 1800 ,
593621 da9063_buck_a_limits ,
594622 DA9063_REG_BUCK_ILIM_B , DA9063_BPRO_ILIM_MASK ),
595623 DA9063_BUCK_COMMON_FIELDS (BPRO ),
624+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BPRO_MON_EN ),
596625 },
597626 {
598627 DA9063_BUCK (DA9063 , BMEM , 800 , 20 , 3340 ,
599628 da9063_buck_b_limits ,
600629 DA9063_REG_BUCK_ILIM_A , DA9063_BMEM_ILIM_MASK ),
601630 DA9063_BUCK_COMMON_FIELDS (BMEM ),
631+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BMEM_MON_EN ),
602632 },
603633 {
604634 DA9063_BUCK (DA9063 , BIO , 800 , 20 , 3340 ,
605635 da9063_buck_b_limits ,
606636 DA9063_REG_BUCK_ILIM_A , DA9063_BIO_ILIM_MASK ),
607637 DA9063_BUCK_COMMON_FIELDS (BIO ),
638+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BIO_MON_EN ),
608639 },
609640 {
610641 DA9063_BUCK (DA9063 , BPERI , 800 , 20 , 3340 ,
611642 da9063_buck_b_limits ,
612643 DA9063_REG_BUCK_ILIM_B , DA9063_BPERI_ILIM_MASK ),
613644 DA9063_BUCK_COMMON_FIELDS (BPERI ),
645+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BPERI_MON_EN ),
614646 },
615647 {
616648 DA9063_BUCK (DA9063 , BCORES_MERGED , 300 , 10 , 1570 ,
617649 da9063_bcores_merged_limits ,
618650 DA9063_REG_BUCK_ILIM_C , DA9063_BCORE1_ILIM_MASK ),
619651 /* BCORES_MERGED uses the same register fields as BCORE1 */
620652 DA9063_BUCK_COMMON_FIELDS (BCORE1 ),
653+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BCORE1_MON_EN ),
621654 },
622655 {
623656 DA9063_BUCK (DA9063 , BMEM_BIO_MERGED , 800 , 20 , 3340 ,
624657 da9063_bmem_bio_merged_limits ,
625658 DA9063_REG_BUCK_ILIM_A , DA9063_BMEM_ILIM_MASK ),
626659 /* BMEM_BIO_MERGED uses the same register fields as BMEM */
627660 DA9063_BUCK_COMMON_FIELDS (BMEM ),
661+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_4 , DA9063_BMEM_MON_EN ),
628662 },
629663 {
630664 DA9063_LDO (DA9063 , LDO3 , 900 , 20 , 3440 ),
631665 .oc_event = BFIELD (DA9063_REG_STATUS_D , DA9063_LDO3_LIM ),
666+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO3_MON_EN ),
632667 },
633668 {
634669 DA9063_LDO (DA9063 , LDO7 , 900 , 50 , 3600 ),
635670 .oc_event = BFIELD (DA9063_REG_STATUS_D , DA9063_LDO7_LIM ),
671+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO7_MON_EN ),
636672 },
637673 {
638674 DA9063_LDO (DA9063 , LDO8 , 900 , 50 , 3600 ),
639675 .oc_event = BFIELD (DA9063_REG_STATUS_D , DA9063_LDO8_LIM ),
676+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO8_MON_EN ),
640677 },
641678 {
642679 DA9063_LDO (DA9063 , LDO9 , 950 , 50 , 3600 ),
680+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_3 , DA9063_LDO9_MON_EN ),
643681 },
644682 {
645683 DA9063_LDO (DA9063 , LDO11 , 900 , 50 , 3600 ),
646684 .oc_event = BFIELD (DA9063_REG_STATUS_D , DA9063_LDO11_LIM ),
685+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_3 , DA9063_LDO11_MON_EN ),
647686 },
648687
649688 /* The following LDOs are present only on DA9063, not on DA9063L */
650689 {
651690 DA9063_LDO (DA9063 , LDO1 , 600 , 20 , 1860 ),
691+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO1_MON_EN ),
652692 },
653693 {
654694 DA9063_LDO (DA9063 , LDO2 , 600 , 20 , 1860 ),
695+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO2_MON_EN ),
655696 },
656697 {
657698 DA9063_LDO (DA9063 , LDO4 , 900 , 20 , 3440 ),
658699 .oc_event = BFIELD (DA9063_REG_STATUS_D , DA9063_LDO4_LIM ),
700+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO4_MON_EN ),
659701 },
660702 {
661703 DA9063_LDO (DA9063 , LDO5 , 900 , 50 , 3600 ),
704+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO5_MON_EN ),
662705 },
663706 {
664707 DA9063_LDO (DA9063 , LDO6 , 900 , 50 , 3600 ),
708+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_2 , DA9063_LDO6_MON_EN ),
665709 },
666710
667711 {
668712 DA9063_LDO (DA9063 , LDO10 , 900 , 50 , 3600 ),
713+ .vmon = BFIELD (DA9063_BB_REG_MON_REG_3 , DA9063_LDO10_MON_EN ),
669714 },
670715};
671716
@@ -726,6 +771,41 @@ static const struct regulator_init_data *da9063_get_regulator_initdata(
726771 return NULL ;
727772}
728773
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+
729809static struct of_regulator_match da9063_matches [] = {
730810 [DA9063_ID_BCORE1 ] = { .name = "bcore1" },
731811 [DA9063_ID_BCORE2 ] = { .name = "bcore2" },
@@ -932,6 +1012,12 @@ static int da9063_regulator_probe(struct platform_device *pdev)
9321012 if (IS_ERR (regl -> suspend_sleep ))
9331013 return PTR_ERR (regl -> suspend_sleep );
9341014 }
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+ }
9351021
9361022 /* Register regulator */
9371023 memset (& config , 0 , sizeof (config ));
@@ -941,6 +1027,11 @@ static int da9063_regulator_probe(struct platform_device *pdev)
9411027 if (da9063_reg_matches )
9421028 config .of_node = da9063_reg_matches [id ].of_node ;
9431029 config .regmap = da9063 -> regmap ;
1030+
1031+ ret = da9063_check_xvp_constraints (& config );
1032+ if (ret )
1033+ return ret ;
1034+
9441035 regl -> rdev = devm_regulator_register (& pdev -> dev , & regl -> desc ,
9451036 & config );
9461037 if (IS_ERR (regl -> rdev )) {
0 commit comments