usb: musb: mediatek: add support for vbus-supply regulator
Add the ability to control a regulator for VBUS. The regulator
will be enabled only when we are in host mode.
Signed-off-by: Fabien Parent <fparent@baylibre.com>
Change-Id: Ief542dd0b95fcab572a422315d13d5ef391de062
diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c
index e218dc0..0582041 100644
--- a/drivers/usb/musb/mediatek.c
+++ b/drivers/usb/musb/mediatek.c
@@ -52,6 +52,7 @@
struct clk *univpll;
enum usb_role role;
struct usb_role_switch *role_sw;
+ struct regulator *vbus_supply;
};
static int mtk_musb_clks_get(struct mtk_glue *glue)
@@ -124,10 +125,14 @@
struct musb *musb = glue->musb;
u8 devctl = readb(musb->mregs + MUSB_DEVCTL);
enum usb_role new_role;
+ int ret;
if (role == glue->role)
return 0;
+ if (glue->vbus_supply && regulator_is_enabled(glue->vbus_supply))
+ regulator_disable(glue->vbus_supply);
+
switch (role) {
case USB_ROLE_HOST:
musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
@@ -138,6 +143,14 @@
devctl |= MUSB_DEVCTL_SESSION;
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+
+ if (glue->vbus_supply) {
+ ret = regulator_enable(glue->vbus_supply);
+ if (ret)
+ dev_warn(glue->dev,
+ "Failed to enable VBUS: %d\n", ret);
+ }
+
MUSB_HST_MODE(musb);
break;
case USB_ROLE_DEVICE:
@@ -526,6 +539,8 @@
goto err_unregister_usb_phy;
}
+ glue->vbus_supply = devm_regulator_get_optional(dev, "vbus");
+
platform_set_drvdata(pdev, glue);
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);