1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2023 Starfive, Inc.
4 * Author: keith.zhao<keith.zhao@statfivetech.com>
13 #include <power/pmic.h>
14 #include <power/regulator.h>
15 #include <power/lp873x.h>
17 static const char lp873x_ldo_ctrl[LP873X_LDO_NUM] = {0x8, 0x9};
18 static const char lp873x_ldo_volt[LP873X_LDO_NUM] = {0xA, 0xB};
21 static int lp873x_ldo_enable(struct udevice *dev, int op, bool *enable)
25 struct dm_regulator_uclass_plat *uc_pdata;
27 uc_pdata = dev_get_uclass_plat(dev);
28 adr = uc_pdata->ctrl_reg;
30 ret = pmic_reg_read(dev->parent, adr);
34 if (op == PMIC_OP_GET) {
35 ret &= LP873X_LDO_MODE_MASK;
43 } else if (op == PMIC_OP_SET) {
45 ret |= LP873X_LDO_MODE_MASK;
47 ret &= ~(LP873X_LDO_MODE_MASK);
49 ret = pmic_reg_write(dev->parent, adr, ret);
57 static int lp873x_ldo_volt2hex(int uV)
59 if (uV > LP873X_LDO_VOLT_MAX)
62 return (uV - 800000) / 100000;
65 static int lp873x_ldo_hex2volt(int hex)
67 if (hex > LP873X_LDO_VOLT_MAX_HEX)
73 return (hex * 100000) + 800000;
76 static int lp873x_ldo_val(struct udevice *dev, int op, int *uV)
78 unsigned int hex, adr;
81 struct dm_regulator_uclass_plat *uc_pdata;
83 if (op == PMIC_OP_GET)
86 uc_pdata = dev_get_uclass_plat(dev);
88 adr = uc_pdata->volt_reg;
90 ret = pmic_reg_read(dev->parent, adr);
94 if (op == PMIC_OP_GET) {
95 ret &= LP873X_LDO_VOLT_MASK;
96 ret = lp873x_ldo_hex2volt(ret);
103 hex = lp873x_ldo_volt2hex(*uV);
107 ret &= ~LP873X_LDO_VOLT_MASK;
111 ret = pmic_reg_write(dev->parent, adr, ret);
116 static int lp873x_ldo_probe(struct udevice *dev)
118 struct dm_regulator_uclass_plat *uc_pdata;
120 uc_pdata = dev_get_uclass_plat(dev);
121 uc_pdata->type = REGULATOR_TYPE_LDO;
123 int idx = dev->driver_data;
124 if (idx >= LP873X_LDO_NUM) {
128 uc_pdata->ctrl_reg = lp873x_ldo_ctrl[idx];
129 uc_pdata->volt_reg = lp873x_ldo_volt[idx];
134 static int ldo_get_value(struct udevice *dev)
139 ret = lp873x_ldo_val(dev, PMIC_OP_GET, &uV);
146 static int ldo_set_value(struct udevice *dev, int uV)
148 return lp873x_ldo_val(dev, PMIC_OP_SET, &uV);
151 static int ldo_get_enable(struct udevice *dev)
156 ret = lp873x_ldo_enable(dev, PMIC_OP_GET, &enable);
163 static int ldo_set_enable(struct udevice *dev, bool enable)
165 return lp873x_ldo_enable(dev, PMIC_OP_SET, &enable);
168 static const struct dm_regulator_ops lp873x_ldo_ops = {
169 .get_value = ldo_get_value,
170 .set_value = ldo_set_value,
171 .get_enable = ldo_get_enable,
172 .set_enable = ldo_set_enable,
175 U_BOOT_DRIVER(lp873x_ldo) = {
176 .name = LP873X_LDO_DRIVER,
177 .id = UCLASS_REGULATOR,
178 .ops = &lp873x_ldo_ops,
179 .probe = lp873x_ldo_probe,