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
)
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;
49 ret
= regmap_update_bits(regmap
, reg
, mask
, i
);
51 ret
= regmap_update_bits(regmap
, oreg
, omask
,
59 int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config
*dvs
,
60 struct device_node
*np
,
61 const struct regulator_desc
*desc
,
62 struct regmap
*regmap
)
66 unsigned int reg
, mask
, omask
, oreg
= desc
->enable_reg
;
68 for (i
= 0; i
< ROHM_DVS_LEVEL_VALID_AMOUNT
&& !ret
; i
++) {
72 if (dvs
->level_map
& bit
) {
74 case ROHM_DVS_LEVEL_RUN
:
75 prop
= "rohm,dvs-run-voltage";
78 omask
= dvs
->run_on_mask
;
80 case ROHM_DVS_LEVEL_IDLE
:
81 prop
= "rohm,dvs-idle-voltage";
83 mask
= dvs
->idle_mask
;
84 omask
= dvs
->idle_on_mask
;
86 case ROHM_DVS_LEVEL_SUSPEND
:
87 prop
= "rohm,dvs-suspend-voltage";
88 reg
= dvs
->suspend_reg
;
89 mask
= dvs
->suspend_mask
;
90 omask
= dvs
->suspend_on_mask
;
92 case ROHM_DVS_LEVEL_LPSR
:
93 prop
= "rohm,dvs-lpsr-voltage";
95 mask
= dvs
->lpsr_mask
;
96 omask
= dvs
->lpsr_on_mask
;
98 case ROHM_DVS_LEVEL_SNVS
:
99 prop
= "rohm,dvs-snvs-voltage";
101 mask
= dvs
->snvs_mask
;
102 omask
= dvs
->snvs_on_mask
;
107 ret
= set_dvs_level(desc
, np
, regmap
, prop
, reg
, mask
,
113 EXPORT_SYMBOL(rohm_regulator_set_dvs_levels
);
115 MODULE_LICENSE("GPL v2");
116 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
117 MODULE_DESCRIPTION("Generic helpers for ROHM PMIC regulator drivers");