From 32629e59b32e5a4697c48266006f7563a0a7aaa4 Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Mon, 6 Jul 2026 18:01:05 +0530 Subject: [PATCH 1/4] FROMLIST: dt-bindings: regulator: qcom,usb-vbus-regulator: add qcom,pm4125-vbus-reg The pm4125 PMIC uses a different USB VBUS register layout than pm8150b. It uses a 2-bit VBOOST voltage selector supporting output voltages of 4.25 V, 4.5 V, 4.75 V and 5.0 V, instead of a current-limit selector. Move qcom,pm4125-vbus-reg from the pm8150b fallback items list into the standalone enum since the driver handles it with its own match-data and register layout. Make regulator-min/max-microamp conditional so they are only required for current-limit variants (pm8150b, pm6150, pm7250b, pmi632). Add an if/then condition for qcom,pm4125-vbus-reg requiring regulator-min/ max-microvolt instead, and update the pm4125 example accordingly. Link: https://lore.kernel.org/all/20260706-add_pm4125-vbus-reg-v3-1-999d78a87b81@oss.qualcomm.com/ Reviewed-by: Krzysztof Kozlowski Signed-off-by: Rakesh Kota --- .../regulator/qcom,usb-vbus-regulator.yaml | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml index fcefc722ee2a4..024b34d0eb1a6 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml @@ -14,17 +14,21 @@ description: | regulator will be enabled in situations where the device is required to provide power to the connected peripheral. -allOf: - - $ref: regulator.yaml# + The pm8150b variant uses an OTG current-limit selector, supporting limits + of 500 mA, 1000 mA, 1500 mA, 2000 mA, 2500 mA and 3000 mA. + + The pm4125 variant uses a different register layout with a 2-bit VBOOST + voltage selector supporting output voltages of 4.25 V, 4.5 V, 4.75 V + and 5.0 V. properties: compatible: oneOf: - enum: - qcom,pm8150b-vbus-reg + - qcom,pm4125-vbus-reg - items: - enum: - - qcom,pm4125-vbus-reg - qcom,pm6150-vbus-reg - qcom,pm7250b-vbus-reg - qcom,pmi632-vbus-reg @@ -34,11 +38,35 @@ properties: maxItems: 1 description: VBUS output base address +allOf: + - $ref: regulator.yaml# + - if: + properties: + compatible: + contains: + enum: + - qcom,pm8150b-vbus-reg + - qcom,pm6150-vbus-reg + - qcom,pm7250b-vbus-reg + - qcom,pmi632-vbus-reg + then: + required: + - regulator-min-microamp + - regulator-max-microamp + + - if: + properties: + compatible: + contains: + const: qcom,pm4125-vbus-reg + then: + required: + - regulator-min-microvolt + - regulator-max-microvolt + required: - compatible - reg - - regulator-min-microamp - - regulator-max-microamp unevaluatedProperties: false @@ -55,4 +83,16 @@ examples: regulator-max-microamp = <3000000>; }; }; + - | + pmic { + #address-cells = <1>; + #size-cells = <0>; + + usb-vbus-regulator@1100 { + compatible = "qcom,pm4125-vbus-reg"; + reg = <0x1100>; + regulator-min-microvolt = <4250000>; + regulator-max-microvolt = <5000000>; + }; + }; ... From be842f04994bb893134cda67c2758cdcdb177965 Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Mon, 6 Jul 2026 18:01:06 +0530 Subject: [PATCH 2/4] FROMLIST: regulator: qcom_usb_vbus: add register abstraction and PM8150B support Introduce per-compatible regulator descriptor data via struct qcom_usb_vbus_reg_data to abstract register layout differences between PMICs. This allows the probe function to dynamically populate the regulator_desc fields rather than relying on compile-time constants. Refactor the existing PM8150B support to use this abstraction, wiring in its CMD_OTG, OTG_CFG, and current-limit registers through pm8150b_data. No functional change is intended for PM8150B. Link: https://lore.kernel.org/all/20260706-add_pm4125-vbus-reg-v3-2-999d78a87b81@oss.qualcomm.com/ Signed-off-by: Rakesh Kota Reviewed-by: Dmitry Baryshkov Reviewed-by: Bryan O'Donoghue --- drivers/regulator/qcom_usb_vbus-regulator.c | 71 +++++++++++++++++---- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c index cd94ed67621fe..0201a3983981e 100644 --- a/drivers/regulator/qcom_usb_vbus-regulator.c +++ b/drivers/regulator/qcom_usb_vbus-regulator.c @@ -20,6 +20,21 @@ #define OTG_CFG 0x53 #define OTG_EN_SRC_CFG BIT(1) +struct qcom_usb_vbus_reg_data { + u16 cmd_otg; + u16 otg_cfg; + u8 otg_en_src_cfg; + u16 csel_reg; + u8 csel_mask; + const unsigned int *curr_table; + unsigned int n_current_limits; + u16 vsel_reg; + u8 vsel_mask; + const unsigned int *volt_table; + unsigned int n_voltages; + const struct regulator_ops *ops; +}; + static const unsigned int curr_table[] = { 500000, 1000000, 1500000, 2000000, 2500000, 3000000, }; @@ -32,19 +47,23 @@ static const struct regulator_ops qcom_usb_vbus_reg_ops = { .set_current_limit = regulator_set_current_limit_regmap, }; -static struct regulator_desc qcom_usb_vbus_rdesc = { - .name = "usb_vbus", - .ops = &qcom_usb_vbus_reg_ops, - .owner = THIS_MODULE, - .type = REGULATOR_VOLTAGE, +static const struct qcom_usb_vbus_reg_data pm8150b_data = { + .cmd_otg = CMD_OTG, + .otg_cfg = OTG_CFG, + .otg_en_src_cfg = OTG_EN_SRC_CFG, + .csel_reg = OTG_CURRENT_LIMIT_CFG, + .csel_mask = OTG_CURRENT_LIMIT_MASK, .curr_table = curr_table, .n_current_limits = ARRAY_SIZE(curr_table), + .ops = &qcom_usb_vbus_reg_ops, }; static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + const struct qcom_usb_vbus_reg_data *data; struct regulator_dev *rdev; + struct regulator_desc *rdesc; struct regmap *regmap; struct regulator_config config = { }; struct regulator_init_data *init_data; @@ -57,27 +76,51 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) return ret; } + data = of_device_get_match_data(dev); + if (!data) + return -EINVAL; + regmap = dev_get_regmap(dev->parent, NULL); if (!regmap) { dev_err(dev, "Failed to get regmap\n"); return -ENOENT; } - init_data = of_get_regulator_init_data(dev, dev->of_node, - &qcom_usb_vbus_rdesc); + rdesc = devm_kzalloc(dev, sizeof(*rdesc), GFP_KERNEL); + if (!rdesc) + return -ENOMEM; + + rdesc->name = "usb_vbus"; + rdesc->ops = data->ops; + rdesc->owner = THIS_MODULE; + rdesc->type = REGULATOR_VOLTAGE; + rdesc->enable_reg = base + data->cmd_otg; + rdesc->enable_mask = OTG_EN; + + if (data->curr_table) { + rdesc->curr_table = data->curr_table; + rdesc->n_current_limits = data->n_current_limits; + rdesc->csel_reg = base + data->csel_reg; + rdesc->csel_mask = data->csel_mask; + } + + if (data->volt_table) { + rdesc->volt_table = data->volt_table; + rdesc->n_voltages = data->n_voltages; + rdesc->vsel_reg = base + data->vsel_reg; + rdesc->vsel_mask = data->vsel_mask; + } + + init_data = of_get_regulator_init_data(dev, dev->of_node, rdesc); if (!init_data) return -ENOMEM; - qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG; - qcom_usb_vbus_rdesc.enable_mask = OTG_EN; - qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG; - qcom_usb_vbus_rdesc.csel_mask = OTG_CURRENT_LIMIT_MASK; config.dev = dev; config.init_data = init_data; config.of_node = dev->of_node; config.regmap = regmap; - rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config); + rdev = devm_regulator_register(dev, rdesc, &config); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); dev_err(dev, "not able to register vbus reg %d\n", ret); @@ -85,13 +128,13 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) } /* Disable HW logic for VBUS enable */ - regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0); + regmap_update_bits(regmap, base + data->otg_cfg, data->otg_en_src_cfg, 0); return 0; } static const struct of_device_id qcom_usb_vbus_regulator_match[] = { - { .compatible = "qcom,pm8150b-vbus-reg" }, + { .compatible = "qcom,pm8150b-vbus-reg", .data = &pm8150b_data }, { } }; MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match); From c2d8572d2cf1e12227a1d2a62de042a6f130ffba Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Mon, 6 Jul 2026 18:01:07 +0530 Subject: [PATCH 3/4] FROMLIST: regulator: qcom_usb_vbus: add support for qcom,pm4125-vbus-reg The PM4125 PMIC uses a different register layout for USB VBUS control compared to PM8150B. On PM4125, CMD_OTG is at offset 0x50, OTG_CFG is at 0x56, and offset 0x52 is a 2-bit VBOOST voltage selector rather than a current-limit selector. Add pm4125_data using the abstraction introduced for PM8150B, along with dedicated voltage-selector ops and the pm4125_vboost_table covering the four supported boost voltages: 4.25 V, 4.5 V, 4.75 V, and 5.0 V. Link: https://lore.kernel.org/all/20260706-add_pm4125-vbus-reg-v3-3-999d78a87b81@oss.qualcomm.com/ Signed-off-by: Rakesh Kota Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Reviewed-by: Bryan O'Donoghue --- drivers/regulator/qcom_usb_vbus-regulator.c | 31 +++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c index 0201a3983981e..9aea68876284e 100644 --- a/drivers/regulator/qcom_usb_vbus-regulator.c +++ b/drivers/regulator/qcom_usb_vbus-regulator.c @@ -20,6 +20,12 @@ #define OTG_CFG 0x53 #define OTG_EN_SRC_CFG BIT(1) +#define PM4125_VBOOST_EN 0x50 +#define PM4125_VBOOST_SEL 0x52 +#define PM4125_VBOOST_CFG_MASK GENMASK(1, 0) +#define PM4125_VBOOST_CFG 0x56 +#define PM4125_VBOOST_EN_SRC_CFG BIT(0) + struct qcom_usb_vbus_reg_data { u16 cmd_otg; u16 otg_cfg; @@ -39,6 +45,10 @@ static const unsigned int curr_table[] = { 500000, 1000000, 1500000, 2000000, 2500000, 3000000, }; +static const unsigned int pm4125_vboost_table[] = { + 4250000, 4500000, 4750000, 5000000, +}; + static const struct regulator_ops qcom_usb_vbus_reg_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -58,6 +68,26 @@ static const struct qcom_usb_vbus_reg_data pm8150b_data = { .ops = &qcom_usb_vbus_reg_ops, }; +static const struct regulator_ops qcom_usb_vbus_pm4125_reg_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_table, +}; + +static const struct qcom_usb_vbus_reg_data pm4125_data = { + .cmd_otg = PM4125_VBOOST_EN, + .otg_cfg = PM4125_VBOOST_CFG, + .otg_en_src_cfg = PM4125_VBOOST_EN_SRC_CFG, + .vsel_reg = PM4125_VBOOST_SEL, + .vsel_mask = PM4125_VBOOST_CFG_MASK, + .volt_table = pm4125_vboost_table, + .n_voltages = ARRAY_SIZE(pm4125_vboost_table), + .ops = &qcom_usb_vbus_pm4125_reg_ops, +}; + static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -135,6 +165,7 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) static const struct of_device_id qcom_usb_vbus_regulator_match[] = { { .compatible = "qcom,pm8150b-vbus-reg", .data = &pm8150b_data }, + { .compatible = "qcom,pm4125-vbus-reg", .data = &pm4125_data }, { } }; MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match); From 6994ff9ddc0d3451ba92adea1ec7f6c5fb4b7ea9 Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Mon, 6 Jul 2026 18:01:08 +0530 Subject: [PATCH 4/4] FROMLIST: arm64: dts: qcom: Fix pm4125 vbus regulator compatible and constraints Remove pm8150b fallback compatible from pm4125_vbus and fix regulator constraints in qrb2210 DTS files to use microvolt instead of microamp. List: https://lore.kernel.org/all/20260706-add_pm4125-vbus-reg-v3-4-999d78a87b81@oss.qualcomm.com/ Signed-off-by: Rakesh Kota Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Reviewed-by: Bryan O'Donoghue Reviewed-by: Krzysztof Kozlowski --- arch/arm64/boot/dts/qcom/pm4125.dtsi | 2 +- arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts | 4 ++-- arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/pm4125.dtsi b/arch/arm64/boot/dts/qcom/pm4125.dtsi index 542e8fe030da4..3dc8d667d091c 100644 --- a/arch/arm64/boot/dts/qcom/pm4125.dtsi +++ b/arch/arm64/boot/dts/qcom/pm4125.dtsi @@ -37,7 +37,7 @@ }; pm4125_vbus: usb-vbus-regulator@1100 { - compatible = "qcom,pm4125-vbus-reg", "qcom,pm8150b-vbus-reg"; + compatible = "qcom,pm4125-vbus-reg"; reg = <0x1100>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts index 5266f89feaaf2..acc831e02044d 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts @@ -327,8 +327,8 @@ }; &pm4125_vbus { - regulator-min-microamp = <500000>; - regulator-max-microamp = <500000>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts index 4ace2d6c06cee..bf6fb12ad9906 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts @@ -433,8 +433,8 @@ }; &pm4125_vbus { - regulator-min-microamp = <500000>; - regulator-max-microamp = <500000>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; status = "okay"; };