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");
136 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
137 MODULE_DESCRIPTION("Generic helpers for ROHM PMIC regulator drivers");