blob: c463de8786b373886d8df8961422bf01fbcdccee [file] [log] [blame]
Samuel Holland32dc5072023-10-31 01:39:51 -05001// SPDX-License-Identifier: GPL-2.0+
2
3#include <dm.h>
4#include <power/pmic.h>
5#include <power/regulator.h>
6
7#define AXP_VBUS_IPSOUT 0x30
8#define AXP_VBUS_IPSOUT_DRIVEBUS BIT(2)
9#define AXP_MISC_CTRL 0x8f
10#define AXP_MISC_CTRL_N_VBUSEN_FUNC BIT(4)
11
12static int axp_drivevbus_get_enable(struct udevice *dev)
13{
14 int ret;
15
16 ret = pmic_reg_read(dev->parent, AXP_VBUS_IPSOUT);
17 if (ret < 0)
18 return ret;
19
20 return !!(ret & AXP_VBUS_IPSOUT_DRIVEBUS);
21}
22
23static int axp_drivevbus_set_enable(struct udevice *dev, bool enable)
24{
25 return pmic_clrsetbits(dev->parent, AXP_VBUS_IPSOUT,
26 AXP_VBUS_IPSOUT_DRIVEBUS,
27 enable ? AXP_VBUS_IPSOUT_DRIVEBUS : 0);
28}
29
30static const struct dm_regulator_ops axp_drivevbus_ops = {
31 .get_enable = axp_drivevbus_get_enable,
32 .set_enable = axp_drivevbus_set_enable,
33};
34
35static int axp_drivevbus_probe(struct udevice *dev)
36{
37 struct dm_regulator_uclass_plat *uc_plat = dev_get_uclass_plat(dev);
38 int ret;
39
40 uc_plat->type = REGULATOR_TYPE_FIXED;
41
42 if (dev_read_bool(dev->parent, "x-powers,drive-vbus-en")) {
43 ret = pmic_clrsetbits(dev->parent, AXP_MISC_CTRL,
44 AXP_MISC_CTRL_N_VBUSEN_FUNC, 0);
45 if (ret)
46 return ret;
47 }
48
49 return 0;
50}
51
52U_BOOT_DRIVER(axp_drivevbus) = {
53 .name = "axp_drivevbus",
54 .id = UCLASS_REGULATOR,
55 .probe = axp_drivevbus_probe,
56 .ops = &axp_drivevbus_ops,
57};