[PATCH v3 5/9] regulator: renesas-usb-vbus-regulator: Add RZ/G3L VBUS regulator support
Biju <[email protected]>
| Newsgroups | org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Biju Das <[email protected]> Add dual USB VBUS regulator support for the RZ/G3L (r9a08g046) SoC, which has two OTG controllers (one per port), unlike RZ/G3S which has only one. Introduce a RZG3L_USB_VBUS_REG macro and a rzg3l_usb_vbus_regulators array with two descriptors: vbus0 (BIT(0)) and vbus1 (BIT(1)), both sourced from a regulators sub-node as defined in the binding. Add a dedicated rzg3l_usb_vbus_regulator_probe() that iterates over the array and registers both regulators using devm_regulator_register(). Register a separate rzg3l-usb-vbus-regulator platform driver backed by this probe function. The existing rzg2l_usb_vbus_regulator_probe() and its platform driver are unchanged and continue to handle the single regulator-vbus case for all other SoCs. Signed-off-by: Biju Das <[email protected]> --- v2->v3: * No change. v1->v2: * Passing pointer to an array of regulators to make it scalable. * Updated commit description. --- .../regulator/renesas-usb-vbus-regulator.c | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/regulator/renesas-usb-vbus-regulator.c b/drivers/regulator/renesas-usb-vbus-regulator.c index 9ba791bd72ec..902834000874 100644 --- a/drivers/regulator/renesas-usb-vbus-regulator.c +++ b/drivers/regulator/renesas-usb-vbus-regulator.c @@ -55,6 +55,50 @@ static int rzg2l_usb_vbus_regulator_probe(struct platform_device *pdev) return 0; } +#define RZG3L_USB_VBUS_REG(rname, en_mask) \ + { \ + .name = #rname, \ + .of_match = of_match_ptr(#rname), \ + .regulators_node = of_match_ptr("regulators"), \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .ops = &rzg2l_usb_vbus_reg_ops, \ + .enable_reg = 0, \ + .enable_mask = (en_mask), \ + .enable_is_inverted = true, \ + .fixed_uV = 5000000, \ + .n_voltages = 1, \ + } + +static const struct regulator_desc rzg3l_usb_vbus_regulators[] = { + RZG3L_USB_VBUS_REG(vbus0, BIT(0)), + RZG3L_USB_VBUS_REG(vbus1, BIT(1)), +}; + +static int rzg3l_usb_vbus_regulator_probe(struct platform_device *pdev) +{ + struct regulator_config config = { }; + struct device *dev = &pdev->dev; + struct regulator_dev *rdev; + + config.dev = pdev->dev.parent; + config.regmap = dev_get_regmap(dev->parent, NULL); + if (!config.regmap) + return dev_err_probe(dev, -ENOENT, "Failed to get regmap\n"); + + for (unsigned int i = 0; i < ARRAY_SIZE(rzg3l_usb_vbus_regulators); i++) { + rdev = devm_regulator_register(dev, &rzg3l_usb_vbus_regulators[i], + &config); + if (IS_ERR(rdev)) { + dev_err(dev, "failed to register %s regulator\n", + rzg3l_usb_vbus_regulators[i].name); + return PTR_ERR(rdev); + } + } + + return 0; +} + static struct platform_driver rzg2l_usb_vbus_regulator_driver = { .probe = rzg2l_usb_vbus_regulator_probe, .driver = { @@ -64,6 +108,15 @@ static struct platform_driver rzg2l_usb_vbus_regulator_driver = { }; module_platform_driver(rzg2l_usb_vbus_regulator_driver); +static struct platform_driver rzg3l_usb_vbus_regulator_driver = { + .probe = rzg3l_usb_vbus_regulator_probe, + .driver = { + .name = "rzg3l-usb-vbus-regulator", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, +}; +module_platform_driver(rzg3l_usb_vbus_regulator_driver); + MODULE_AUTHOR("Biju Das <[email protected]>"); MODULE_DESCRIPTION("Renesas RZ/G2L USB Vbus Regulator Driver"); MODULE_LICENSE("GPL"); -- 2.43.0