Lines Matching +full:regulator +full:- +full:uv +full:- +full:protection +full:- +full:microvolt

1 // SPDX-License-Identifier: GPL-2.0+
3 // Regulator driver for DA9063 PMIC series
18 #include <linux/regulator/driver.h>
19 #include <linux/regulator/machine.h>
20 #include <linux/regulator/of_regulator.h>
27 REG_FIELD(_reg, __builtin_ffs((int)_mask) - 1, \
28 sizeof(unsigned int) * 8 - __builtin_clz((_mask)) - 1)
30 /* DA9063 and DA9063L regulator IDs */
53 /* DA9063-only LDOs */
62 /* Old regulator platform data */
73 /* Regulator capabilities and registers description */
98 .desc.n_voltages = (((max_mV) - (min_mV))/(step_mV) + 1 \
118 .desc.n_voltages = ((max_mV) - (min_mV))/(step_mV) + 1, \
143 /* Single regulator settings */
161 struct da9063_regulator regulator[]; member
172 /* Regulator operations */
213 struct device *dev = regl->hw->dev; in da9063_set_xvp()
215 dev_dbg(dev, "%s: lim: %d, sev: %d, en: %d\n", regl->desc.name, lim_uV, severity, enable); in da9063_set_xvp()
223 return -EINVAL; in da9063_set_xvp()
225 return regmap_field_write(regl->vmon, enable ? 1 : 0); in da9063_set_xvp()
244 return -EINVAL; in da9063_buck_set_mode()
247 return regmap_field_write(regl->mode, val); in da9063_buck_set_mode()
262 ret = regmap_field_read(regl->mode, &val); in da9063_buck_get_mode()
279 ret = regmap_field_read(regl->sleep, &val); in da9063_buck_get_mode()
290 * LDOs use sleep flags - one for normal and one for suspend state.
307 return -EINVAL; in da9063_ldo_set_mode()
310 return regmap_field_write(regl->sleep, val); in da9063_ldo_set_mode()
318 ret = regmap_field_read(regl->sleep, &val); in da9063_ldo_get_mode()
339 ret = -EIO; in da9063_buck_get_status()
356 ret = -EIO; in da9063_ldo_get_status()
362 static int da9063_set_suspend_voltage(struct regulator_dev *rdev, int uV) in da9063_set_suspend_voltage() argument
365 const struct da9063_regulator_info *rinfo = regl->info; in da9063_set_suspend_voltage()
368 sel = regulator_map_voltage_linear(rdev, uV, uV); in da9063_set_suspend_voltage()
372 sel <<= ffs(rdev->desc->vsel_mask) - 1; in da9063_set_suspend_voltage()
374 ret = regmap_update_bits(regl->hw->regmap, rinfo->suspend_vsel_reg, in da9063_set_suspend_voltage()
375 rdev->desc->vsel_mask, sel); in da9063_set_suspend_voltage()
384 return regmap_field_write(regl->suspend, 1); in da9063_suspend_enable()
391 return regmap_field_write(regl->suspend, 0); in da9063_suspend_disable()
411 return -EINVAL; in da9063_buck_set_suspend_mode()
414 return regmap_field_write(regl->mode, val); in da9063_buck_set_suspend_mode()
431 return -EINVAL; in da9063_ldo_set_suspend_mode()
434 return regmap_field_write(regl->suspend_sleep, val); in da9063_ldo_set_suspend_mode()
439 switch (desc->id) { in da9063_get_overdrive_mask()
464 ret = regmap_read(regl->hw->regmap, DA9063_REG_CONFIG_H, in da9063_buck_set_limit_set_overdrive()
471 ret = regmap_set_bits(regl->hw->regmap, DA9063_REG_CONFIG_H, in da9063_buck_set_limit_set_overdrive()
482 * Attempt to restore original overdrive state, ignore failure- in da9063_buck_set_limit_set_overdrive()
483 * on-failure. in da9063_buck_set_limit_set_overdrive()
485 regmap_clear_bits(regl->hw->regmap, DA9063_REG_CONFIG_H, in da9063_buck_set_limit_set_overdrive()
502 ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &orig_limit); in da9063_buck_set_limit_clear_overdrive()
510 ret = regmap_clear_bits(regl->hw->regmap, DA9063_REG_CONFIG_H, in da9063_buck_set_limit_clear_overdrive()
514 * Attempt to restore original current limit, ignore failure- in da9063_buck_set_limit_clear_overdrive()
515 * on-failure. in da9063_buck_set_limit_clear_overdrive()
517 regmap_write(rdev->regmap, rdev->desc->csel_reg, orig_limit); in da9063_buck_set_limit_clear_overdrive()
527 overdrive_mask = da9063_get_overdrive_mask(rdev->desc); in da9063_buck_set_current_limit()
529 n_currents = rdev->desc->n_current_limits; in da9063_buck_set_current_limit()
531 return -EINVAL; in da9063_buck_set_current_limit()
533 if (max_uA > rdev->desc->curr_table[n_currents - 1]) in da9063_buck_set_current_limit()
554 mask = da9063_get_overdrive_mask(rdev->desc); in da9063_buck_get_current_limit()
556 ret = regmap_read(regl->hw->regmap, DA9063_REG_CONFIG_H, &val); in da9063_buck_get_current_limit()
726 .n_regulators = ARRAY_SIZE(da9063_regulator_info) - 6,
732 /* Regulator interrupt handlers */
736 struct da9063 *hw = regulators->regulator[0].hw; in da9063_ldo_lim_event()
740 ret = regmap_read(hw->regmap, DA9063_REG_STATUS_D, &bits); in da9063_ldo_lim_event()
744 for (i = regulators->n_regulators - 1; i >= 0; i--) { in da9063_ldo_lim_event()
745 regl = &regulators->regulator[i]; in da9063_ldo_lim_event()
746 if (regl->info->oc_event.reg != DA9063_REG_STATUS_D) in da9063_ldo_lim_event()
749 if (BIT(regl->info->oc_event.lsb) & bits) { in da9063_ldo_lim_event()
750 regulator_notifier_call_chain(regl->rdev, in da9063_ldo_lim_event()
766 for (i = 0; i < regl_pdata->n_regulators; i++) { in da9063_get_regulator_initdata()
767 if (id == regl_pdata->regulator_data[i].id) in da9063_get_regulator_initdata()
768 return regl_pdata->regulator_data[i].initdata; in da9063_get_regulator_initdata()
776 struct da9063_regulator *regl = config->driver_data; in da9063_check_xvp_constraints()
777 const struct regulation_constraints *constr = &config->init_data->constraints; in da9063_check_xvp_constraints()
778 const struct notification_limit *uv_l = &constr->under_voltage_limits; in da9063_check_xvp_constraints()
779 const struct notification_limit *ov_l = &constr->over_voltage_limits; in da9063_check_xvp_constraints()
782 if ((!!uv_l->prot + !!uv_l->err + !!uv_l->warn) > 1) { in da9063_check_xvp_constraints()
783 dev_err(config->dev, "%s: at most one voltage monitoring severity allowed!\n", in da9063_check_xvp_constraints()
784 regl->desc.name); in da9063_check_xvp_constraints()
785 return -EINVAL; in da9063_check_xvp_constraints()
788 /* make sure that UV and OV monitoring is set to the same severity and value */ in da9063_check_xvp_constraints()
789 if (uv_l->prot != ov_l->prot) { in da9063_check_xvp_constraints()
790 dev_err(config->dev, in da9063_check_xvp_constraints()
791 "%s: protection-microvolt: value must be equal for uv and ov!\n", in da9063_check_xvp_constraints()
792 regl->desc.name); in da9063_check_xvp_constraints()
793 return -EINVAL; in da9063_check_xvp_constraints()
795 if (uv_l->err != ov_l->err) { in da9063_check_xvp_constraints()
796 dev_err(config->dev, "%s: error-microvolt: value must be equal for uv and ov!\n", in da9063_check_xvp_constraints()
797 regl->desc.name); in da9063_check_xvp_constraints()
798 return -EINVAL; in da9063_check_xvp_constraints()
800 if (uv_l->warn != ov_l->warn) { in da9063_check_xvp_constraints()
801 dev_err(config->dev, "%s: warn-microvolt: value must be equal for uv and ov!\n", in da9063_check_xvp_constraints()
802 regl->desc.name); in da9063_check_xvp_constraints()
803 return -EINVAL; in da9063_check_xvp_constraints()
816 [DA9063_ID_BCORES_MERGED] = { .name = "bcores-merged" },
817 [DA9063_ID_BMEM_BIO_MERGED] = { .name = "bmem-bio-merged", },
836 struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); in da9063_parse_regulators_dt()
843 if (da9063->type == PMIC_TYPE_DA9063L) in da9063_parse_regulators_dt()
844 da9063_matches_len -= 6; in da9063_parse_regulators_dt()
846 node = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); in da9063_parse_regulators_dt()
848 dev_err(&pdev->dev, "Regulators device node not found\n"); in da9063_parse_regulators_dt()
849 return ERR_PTR(-ENODEV); in da9063_parse_regulators_dt()
852 num = of_regulator_match(&pdev->dev, node, da9063_matches, in da9063_parse_regulators_dt()
856 dev_err(&pdev->dev, "Failed to match regulators\n"); in da9063_parse_regulators_dt()
857 return ERR_PTR(-EINVAL); in da9063_parse_regulators_dt()
860 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); in da9063_parse_regulators_dt()
862 return ERR_PTR(-ENOMEM); in da9063_parse_regulators_dt()
864 pdata->regulator_data = devm_kcalloc(&pdev->dev, in da9063_parse_regulators_dt()
865 num, sizeof(*pdata->regulator_data), in da9063_parse_regulators_dt()
867 if (!pdata->regulator_data) in da9063_parse_regulators_dt()
868 return ERR_PTR(-ENOMEM); in da9063_parse_regulators_dt()
869 pdata->n_regulators = num; in da9063_parse_regulators_dt()
876 rdata = &pdata->regulator_data[n]; in da9063_parse_regulators_dt()
877 rdata->id = i; in da9063_parse_regulators_dt()
878 rdata->initdata = da9063_matches[i].init_data; in da9063_parse_regulators_dt()
889 struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); in da9063_regulator_probe()
901 if (IS_ERR(regl_pdata) || regl_pdata->n_regulators == 0) { in da9063_regulator_probe()
902 dev_err(&pdev->dev, in da9063_regulator_probe()
904 return -ENODEV; in da9063_regulator_probe()
908 for (model = regulators_models; model->regulator_info; model++) { in da9063_regulator_probe()
909 if (model->type == da9063->type) in da9063_regulator_probe()
912 if (!model->regulator_info) { in da9063_regulator_probe()
913 dev_err(&pdev->dev, "Chip model not recognised (%u)\n", in da9063_regulator_probe()
914 da9063->type); in da9063_regulator_probe()
915 return -ENODEV; in da9063_regulator_probe()
918 ret = regmap_read(da9063->regmap, DA9063_REG_CONFIG_H, &val); in da9063_regulator_probe()
920 dev_err(&pdev->dev, in da9063_regulator_probe()
927 n_regulators = model->n_regulators; in da9063_regulator_probe()
929 n_regulators -= 2; /* remove BCORE1, BCORE2 */ in da9063_regulator_probe()
931 n_regulators--; /* remove BCORES_MERGED */ in da9063_regulator_probe()
933 n_regulators -= 2; /* remove BMEM, BIO */ in da9063_regulator_probe()
935 n_regulators--; /* remove BMEM_BIO_MERGED */ in da9063_regulator_probe()
938 regulators = devm_kzalloc(&pdev->dev, struct_size(regulators, in da9063_regulator_probe()
939 regulator, n_regulators), GFP_KERNEL); in da9063_regulator_probe()
941 return -ENOMEM; in da9063_regulator_probe()
943 regulators->n_regulators = n_regulators; in da9063_regulator_probe()
949 while (n < regulators->n_regulators) { in da9063_regulator_probe()
950 /* Skip regulator IDs depending on merge mode configuration */ in da9063_regulator_probe()
980 /* Initialise regulator structure */ in da9063_regulator_probe()
981 regl = &regulators->regulator[n]; in da9063_regulator_probe()
982 regl->hw = da9063; in da9063_regulator_probe()
983 regl->info = &model->regulator_info[id]; in da9063_regulator_probe()
984 regl->desc = regl->info->desc; in da9063_regulator_probe()
985 regl->desc.type = REGULATOR_VOLTAGE; in da9063_regulator_probe()
986 regl->desc.owner = THIS_MODULE; in da9063_regulator_probe()
988 if (regl->info->mode.reg) { in da9063_regulator_probe()
989 regl->mode = devm_regmap_field_alloc(&pdev->dev, in da9063_regulator_probe()
990 da9063->regmap, regl->info->mode); in da9063_regulator_probe()
991 if (IS_ERR(regl->mode)) in da9063_regulator_probe()
992 return PTR_ERR(regl->mode); in da9063_regulator_probe()
995 if (regl->info->suspend.reg) { in da9063_regulator_probe()
996 regl->suspend = devm_regmap_field_alloc(&pdev->dev, in da9063_regulator_probe()
997 da9063->regmap, regl->info->suspend); in da9063_regulator_probe()
998 if (IS_ERR(regl->suspend)) in da9063_regulator_probe()
999 return PTR_ERR(regl->suspend); in da9063_regulator_probe()
1002 if (regl->info->sleep.reg) { in da9063_regulator_probe()
1003 regl->sleep = devm_regmap_field_alloc(&pdev->dev, in da9063_regulator_probe()
1004 da9063->regmap, regl->info->sleep); in da9063_regulator_probe()
1005 if (IS_ERR(regl->sleep)) in da9063_regulator_probe()
1006 return PTR_ERR(regl->sleep); in da9063_regulator_probe()
1009 if (regl->info->suspend_sleep.reg) { in da9063_regulator_probe()
1010 regl->suspend_sleep = devm_regmap_field_alloc(&pdev->dev, in da9063_regulator_probe()
1011 da9063->regmap, regl->info->suspend_sleep); in da9063_regulator_probe()
1012 if (IS_ERR(regl->suspend_sleep)) in da9063_regulator_probe()
1013 return PTR_ERR(regl->suspend_sleep); in da9063_regulator_probe()
1015 if (regl->info->vmon.reg) { in da9063_regulator_probe()
1016 regl->vmon = devm_regmap_field_alloc(&pdev->dev, in da9063_regulator_probe()
1017 da9063->regmap, regl->info->vmon); in da9063_regulator_probe()
1018 if (IS_ERR(regl->vmon)) in da9063_regulator_probe()
1019 return PTR_ERR(regl->vmon); in da9063_regulator_probe()
1022 /* Register regulator */ in da9063_regulator_probe()
1024 config.dev = &pdev->dev; in da9063_regulator_probe()
1029 config.regmap = da9063->regmap; in da9063_regulator_probe()
1038 regl->rdev = devm_regulator_register(&pdev->dev, &regl->desc, in da9063_regulator_probe()
1040 if (IS_ERR(regl->rdev)) { in da9063_regulator_probe()
1041 dev_err(&pdev->dev, in da9063_regulator_probe()
1042 "Failed to register %s regulator\n", in da9063_regulator_probe()
1043 regl->desc.name); in da9063_regulator_probe()
1044 return PTR_ERR(regl->rdev); in da9063_regulator_probe()
1055 ret = devm_request_threaded_irq(&pdev->dev, irq, in da9063_regulator_probe()
1060 dev_err(&pdev->dev, "Failed to request LDO_LIM IRQ.\n"); in da9063_regulator_probe()