1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
11 #include <dm/device_compat.h>
12 #include <linux/err.h>
13 #include <power/pmic.h>
14 #include <power/regulator.h>
16 #define STM32MP_PWR_CR3 0xc
17 #define STM32MP_PWR_CR3_USB33DEN BIT(24)
18 #define STM32MP_PWR_CR3_USB33RDY BIT(26)
19 #define STM32MP_PWR_CR3_REG18DEN BIT(28)
20 #define STM32MP_PWR_CR3_REG18RDY BIT(29)
21 #define STM32MP_PWR_CR3_REG11DEN BIT(30)
22 #define STM32MP_PWR_CR3_REG11RDY BIT(31)
24 struct stm32mp_pwr_reg_info {
30 struct stm32mp_pwr_priv {
31 struct regmap *regmap;
34 static int stm32mp_pwr_write(struct udevice *dev, uint reg,
35 const uint8_t *buff, int len)
37 struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
38 u32 val = *(u32 *)buff;
43 return regmap_write(priv->regmap, STM32MP_PWR_CR3, val);
46 static int stm32mp_pwr_read(struct udevice *dev, uint reg, uint8_t *buff,
49 struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
54 return regmap_read(priv->regmap, STM32MP_PWR_CR3, (u32 *)buff);
57 static int stm32mp_pwr_ofdata_to_platdata(struct udevice *dev)
59 struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
60 struct regmap *regmap;
62 regmap = syscon_get_regmap_by_driver_data(STM32MP_SYSCON_PWR);
64 pr_err("%s: unable to find regmap (%ld)\n", __func__,
66 return PTR_ERR(regmap);
68 priv->regmap = regmap;
73 static const struct pmic_child_info pwr_children_info[] = {
74 { .prefix = "reg", .driver = "stm32mp_pwr_regulator"},
75 { .prefix = "usb", .driver = "stm32mp_pwr_regulator"},
79 static int stm32mp_pwr_bind(struct udevice *dev)
83 children = pmic_bind_children(dev, dev->node, pwr_children_info);
85 dev_dbg(dev, "no child found\n");
90 static struct dm_pmic_ops stm32mp_pwr_ops = {
91 .read = stm32mp_pwr_read,
92 .write = stm32mp_pwr_write,
95 static const struct udevice_id stm32mp_pwr_ids[] = {
96 { .compatible = "st,stm32mp1,pwr-reg" },
100 U_BOOT_DRIVER(stm32mp_pwr_pmic) = {
101 .name = "stm32mp_pwr_pmic",
103 .of_match = stm32mp_pwr_ids,
104 .bind = stm32mp_pwr_bind,
105 .ops = &stm32mp_pwr_ops,
106 .ofdata_to_platdata = stm32mp_pwr_ofdata_to_platdata,
107 .priv_auto_alloc_size = sizeof(struct stm32mp_pwr_priv),
110 static const struct stm32mp_pwr_reg_info stm32mp_pwr_reg11 = {
111 .enable = STM32MP_PWR_CR3_REG11DEN,
112 .ready = STM32MP_PWR_CR3_REG11RDY,
116 static const struct stm32mp_pwr_reg_info stm32mp_pwr_reg18 = {
117 .enable = STM32MP_PWR_CR3_REG18DEN,
118 .ready = STM32MP_PWR_CR3_REG18RDY,
122 static const struct stm32mp_pwr_reg_info stm32mp_pwr_usb33 = {
123 .enable = STM32MP_PWR_CR3_USB33DEN,
124 .ready = STM32MP_PWR_CR3_USB33RDY,
128 static const struct stm32mp_pwr_reg_info *stm32mp_pwr_reg_infos[] = {
135 static int stm32mp_pwr_regulator_probe(struct udevice *dev)
137 const struct stm32mp_pwr_reg_info **p = stm32mp_pwr_reg_infos;
138 struct dm_regulator_uclass_platdata *uc_pdata;
140 uc_pdata = dev_get_uclass_platdata(dev);
145 rc = dev_read_stringlist_search(dev, "regulator-name",
148 dev_dbg(dev, "found regulator %s\n", (*p)->name);
150 } else if (rc != -ENODATA) {
159 dev_dbg(dev, "regulator ");
160 while (dev_read_string_index(dev, "regulator-name",
162 dev_dbg(dev, "%s'%s' ", (i > 1) ? ", " : "", s);
163 dev_dbg(dev, "%s not supported\n", (i > 2) ? "are" : "is");
167 uc_pdata->type = REGULATOR_TYPE_FIXED;
168 dev->priv = (void *)*p;
173 static int stm32mp_pwr_regulator_set_value(struct udevice *dev, int uV)
175 struct dm_regulator_uclass_platdata *uc_pdata;
177 uc_pdata = dev_get_uclass_platdata(dev);
181 if (uc_pdata->min_uV != uV) {
182 dev_dbg(dev, "Invalid uV=%d for: %s\n", uV, uc_pdata->name);
189 static int stm32mp_pwr_regulator_get_value(struct udevice *dev)
191 struct dm_regulator_uclass_platdata *uc_pdata;
193 uc_pdata = dev_get_uclass_platdata(dev);
197 if (uc_pdata->min_uV != uc_pdata->max_uV) {
198 dev_dbg(dev, "Invalid constraints for: %s\n", uc_pdata->name);
202 return uc_pdata->min_uV;
205 static int stm32mp_pwr_regulator_get_enable(struct udevice *dev)
207 const struct stm32mp_pwr_reg_info *p = dev_get_priv(dev);
211 rc = pmic_read(dev->parent, 0, (uint8_t *)®, sizeof(reg));
215 dev_dbg(dev, "%s id %s\n", p->name, (reg & p->enable) ? "on" : "off");
217 return (reg & p->enable) != 0;
220 static int stm32mp_pwr_regulator_set_enable(struct udevice *dev, bool enable)
222 const struct stm32mp_pwr_reg_info *p = dev_get_priv(dev);
227 dev_dbg(dev, "Turning %s %s\n", enable ? "on" : "off", p->name);
229 rc = pmic_read(dev->parent, 0, (uint8_t *)®, sizeof(reg));
233 /* if regulator is already in the wanted state, nothing to do */
234 if (!!(reg & p->enable) == enable)
241 rc = pmic_write(dev->parent, 0, (uint8_t *)®, sizeof(reg));
248 /* waiting ready for enable */
249 time_start = get_timer(0);
251 rc = pmic_read(dev->parent, 0, (uint8_t *)®, sizeof(reg));
256 if (get_timer(time_start) > CONFIG_SYS_HZ) {
257 dev_dbg(dev, "%s: timeout\n", p->name);
264 static const struct dm_regulator_ops stm32mp_pwr_regulator_ops = {
265 .set_value = stm32mp_pwr_regulator_set_value,
266 .get_value = stm32mp_pwr_regulator_get_value,
267 .get_enable = stm32mp_pwr_regulator_get_enable,
268 .set_enable = stm32mp_pwr_regulator_set_enable,
271 U_BOOT_DRIVER(stm32mp_pwr_regulator) = {
272 .name = "stm32mp_pwr_regulator",
273 .id = UCLASS_REGULATOR,
274 .ops = &stm32mp_pwr_regulator_ops,
275 .probe = stm32mp_pwr_regulator_probe,