Hey Caleb, On Thu Mar 20, 2025 at 5:34 PM WET, Caleb Connolly wrote: > > Jaehoon: do you mind if I just take these both through the Qualcomm tree? > > If not then feel free to pick this one up > > Acked-by: Caleb Connolly <caleb.conno...@linaro.org>
Maybe it is easier/faster for you to pick this ones, one month passed. Thanks in advance. Cheers, Rui > > On 2/27/25 09:45, Rui Miguel Silva wrote: >> Add regulator driver that allow some Qualcomm PMIC to >> feed VBUS output to peripherals that are connected. >> >> Signed-off-by: Rui Miguel Silva <rui.si...@linaro.org> >> --- >> drivers/power/regulator/Kconfig | 7 ++ >> drivers/power/regulator/Makefile | 1 + >> .../power/regulator/qcom_usb_vbus_regulator.c | 111 ++++++++++++++++++ >> 3 files changed, 119 insertions(+) >> create mode 100644 drivers/power/regulator/qcom_usb_vbus_regulator.c >> >> diff --git a/drivers/power/regulator/Kconfig >> b/drivers/power/regulator/Kconfig >> index 958f337c7e73..558133e09bf8 100644 >> --- a/drivers/power/regulator/Kconfig >> +++ b/drivers/power/regulator/Kconfig >> @@ -224,6 +224,13 @@ config DM_REGULATOR_QCOM_RPMH >> implements get/set api for a limited set of regulators used >> by u-boot. >> >> +config DM_REGULATOR_QCOM_USB_VBUS >> + bool "Enable driver model for Qualcomm USB vbus regulator" >> + depends on DM_REGULATOR >> + ---help--- >> + Enable support for the Qualcomm USB Vbus regulator. The driver >> + implements get/set api for the regulator to be used by u-boot. >> + >> config SPL_DM_REGULATOR_GPIO >> bool "Enable Driver Model for GPIO REGULATOR in SPL" >> depends on DM_REGULATOR_GPIO && SPL_GPIO >> diff --git a/drivers/power/regulator/Makefile >> b/drivers/power/regulator/Makefile >> index ca6c89d13b5c..a4191b9302b1 100644 >> --- a/drivers/power/regulator/Makefile >> +++ b/drivers/power/regulator/Makefile >> @@ -22,6 +22,7 @@ obj-$(CONFIG_$(XPL_)DM_REGULATOR_COMMON) += >> regulator_common.o >> obj-$(CONFIG_$(XPL_)DM_REGULATOR_FIXED) += fixed.o >> obj-$(CONFIG_$(XPL_)DM_REGULATOR_GPIO) += gpio-regulator.o >> obj-$(CONFIG_DM_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o >> +obj-$(CONFIG_DM_REGULATOR_QCOM_USB_VBUS) += qcom_usb_vbus_regulator.o >> obj-$(CONFIG_$(PHASE_)REGULATOR_RK8XX) += rk8xx.o >> obj-$(CONFIG_DM_REGULATOR_S2MPS11) += s2mps11_regulator.o >> obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o >> diff --git a/drivers/power/regulator/qcom_usb_vbus_regulator.c >> b/drivers/power/regulator/qcom_usb_vbus_regulator.c >> new file mode 100644 >> index 000000000000..2d58ef5e111e >> --- /dev/null >> +++ b/drivers/power/regulator/qcom_usb_vbus_regulator.c >> @@ -0,0 +1,111 @@ >> +// SPDX-License-Identifier: BSD-3-Clause >> +/* >> + * Copyright (c) 2025, Linaro Limited >> + */ >> +#define pr_fmt(fmt) "qcom_usb_vbus: " fmt >> + >> +#include <bitfield.h> >> +#include <errno.h> >> +#include <dm.h> >> +#include <fdtdec.h> >> +#include <log.h> >> +#include <asm/gpio.h> >> +#include <linux/bitops.h> >> +#include <linux/printk.h> >> +#include <power/pmic.h> >> +#include <power/regulator.h> >> + >> +#define CMD_OTG 0x50 >> +#define OTG_EN BIT(0) >> +// The 0 bit in this register's bit field is undocumented >> +#define OTG_CFG 0x56 >> +#define OTG_EN_SRC_CFG BIT(1) >> + >> +struct qcom_usb_vbus_priv { >> + phys_addr_t base; >> +}; >> + >> +static int qcom_usb_vbus_regulator_of_to_plat(struct udevice *dev) >> +{ >> + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); >> + >> + priv->base = dev_read_addr(dev); >> + if (priv->base == FDT_ADDR_T_NONE) >> + return -EINVAL; >> + >> + return 0; >> +} >> + >> +static int qcom_usb_vbus_regulator_get_enable(struct udevice *dev) >> +{ >> + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); >> + int otg_en_reg = priv->base + CMD_OTG; >> + int ret; >> + >> + ret = pmic_reg_read(dev->parent, otg_en_reg); >> + if (ret < 0) >> + log_err("failed to read usb vbus: %d\n", ret); >> + else >> + ret &= OTG_EN; >> + >> + return ret; >> +} >> + >> +static int qcom_usb_vbus_regulator_set_enable(struct udevice *dev, bool >> enable) >> +{ >> + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); >> + int otg_en_reg = priv->base + CMD_OTG; >> + int ret; >> + >> + if (enable) { >> + ret = pmic_clrsetbits(dev->parent, otg_en_reg, 0, OTG_EN); >> + if (ret < 0) { >> + log_err("error enabling: %d\n", ret); >> + return ret; >> + } >> + } else { >> + ret = pmic_clrsetbits(dev->parent, otg_en_reg, OTG_EN, 0); >> + if (ret < 0) { >> + log_err("error disabling: %d\n", ret); >> + return ret; >> + } >> + } >> + >> + return 0; >> +} >> + >> +static int qcom_usb_vbus_regulator_probe(struct udevice *dev) >> +{ >> + struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); >> + int otg_cfg_reg = priv->base + OTG_CFG; >> + int ret; >> + >> + /* Disable HW logic for VBUS enable */ >> + ret = pmic_clrsetbits(dev->parent, otg_cfg_reg, OTG_EN_SRC_CFG, 0); >> + if (ret < 0) { >> + log_err("error setting EN_SRC_CFG: %d\n", ret); >> + return ret; >> + } >> + >> + return 0; >> +} >> + >> +static const struct dm_regulator_ops qcom_usb_vbus_regulator_ops = { >> + .get_enable = qcom_usb_vbus_regulator_get_enable, >> + .set_enable = qcom_usb_vbus_regulator_set_enable, >> +}; >> + >> +static const struct udevice_id qcom_usb_vbus_regulator_ids[] = { >> + { .compatible = "qcom,pm8150b-vbus-reg"}, >> + { }, >> +}; >> + >> +U_BOOT_DRIVER(qcom_usb_vbus_regulator) = { >> + .name = "qcom-usb-vbus-regulator", >> + .id = UCLASS_REGULATOR, >> + .of_match = qcom_usb_vbus_regulator_ids, >> + .of_to_plat = qcom_usb_vbus_regulator_of_to_plat, >> + .ops = &qcom_usb_vbus_regulator_ops, >> + .probe = qcom_usb_vbus_regulator_probe, >> + .priv_auto = sizeof(struct qcom_usb_vbus_priv), >> +}; > > -- > Caleb (they/them)