1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2020 ROHM Semiconductors
4 #include <linux/errno.h>
5 #include <linux/mfd/rohm-generic.h>
6 #include <linux/module.h>
8 #include <linux/regmap.h>
9 #include <linux/regulator/driver.h>
11 static int set_dvs_level(const struct regulator_desc *desc,
12 struct device_node *np, struct regmap *regmap,
13 char *prop, unsigned int reg, unsigned int mask,
14 unsigned int omask, unsigned int oreg)
19 ret = of_property_read_u32(np, prop, &uv);
25 /* If voltage is set to 0 => disable */
28 return regmap_update_bits(regmap, oreg, omask, 0);
30 /* Some setups don't allow setting own voltage but do allow enabling */
33 return regmap_update_bits(regmap, oreg, omask, omask);
37 for (i = 0; i < desc->n_voltages; i++) {
38 /* NOTE to next hacker - Does not support pickable ranges */
39 if (desc->linear_range_selectors_bitfield)
41 if (desc->n_linear_ranges)
42 ret = regulator_desc_list_voltage_linear_range(desc, i);
44 ret = regulator_desc_list_voltage_linear(desc, i);
48 i <<= ffs(desc->vsel_mask) - 1;
50 ret = regmap_update_bits(regmap, reg, mask, i);
52 ret = regmap_update_bits(regmap, oreg, omask,
57 if (i == desc->n_voltages)
58 pr_warn("Unsupported %s voltage %u\n", prop, uv);
63 int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,
64 struct device_node *np,
65 const struct regulator_desc *desc,
66 struct regmap *regmap)
70 unsigned int reg, mask, omask, oreg = desc->enable_reg;
72 for (i = 0; i < ROHM_DVS_LEVEL_VALID_AMOUNT && !ret; i++) {
76 if (dvs->level_map & bit) {
78 case ROHM_DVS_LEVEL_RUN:
79 prop = "rohm,dvs-run-voltage";
82 omask = dvs->run_on_mask;
84 case ROHM_DVS_LEVEL_IDLE:
85 prop = "rohm,dvs-idle-voltage";
87 mask = dvs->idle_mask;
88 omask = dvs->idle_on_mask;
90 case ROHM_DVS_LEVEL_SUSPEND:
91 prop = "rohm,dvs-suspend-voltage";
92 reg = dvs->suspend_reg;
93 mask = dvs->suspend_mask;
94 omask = dvs->suspend_on_mask;
96 case ROHM_DVS_LEVEL_LPSR:
97 prop = "rohm,dvs-lpsr-voltage";
99 mask = dvs->lpsr_mask;
100 omask = dvs->lpsr_on_mask;
102 case ROHM_DVS_LEVEL_SNVS:
103 prop = "rohm,dvs-snvs-voltage";
105 mask = dvs->snvs_mask;
106 omask = dvs->snvs_on_mask;
111 ret = set_dvs_level(desc, np, regmap, prop, reg, mask,
117 EXPORT_SYMBOL(rohm_regulator_set_dvs_levels);
120 * Few ROHM PMIC ICs have constrains on voltage changing:
121 * BD71837 - only buck 1-4 voltages can be changed when they are enabled.
122 * Other bucks and all LDOs must be disabled when voltage is changed.
123 * BD96801 - LDO voltage levels can be changed when LDOs are disabled.
125 int rohm_regulator_set_voltage_sel_restricted(struct regulator_dev *rdev,
128 if (rdev->desc->ops->is_enabled(rdev))
131 return regulator_set_voltage_sel_regmap(rdev, sel);
133 EXPORT_SYMBOL_GPL(rohm_regulator_set_voltage_sel_restricted);
135 MODULE_LICENSE("GPL v2");
137 MODULE_DESCRIPTION("Generic helpers for ROHM PMIC regulator drivers");