Commit 6dcfd7c3 authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by Kishon Vijay Abraham I

phy: rcar-gen3-usb2: Add vbus-supply to handle VBUS on/off

To handle the VBUS on/off by a regulator driver, this patch adds
regulator APIs calling in the driver and description about vbus-supply
in the rcar-gen3-phy-usb2.txt.
Signed-off-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Acked-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parent 801a69c7
...@@ -21,6 +21,8 @@ To use a USB channel where USB 2.0 Host and HSUSB (USB 2.0 Peripheral) are ...@@ -21,6 +21,8 @@ To use a USB channel where USB 2.0 Host and HSUSB (USB 2.0 Peripheral) are
combined, the device tree node should set interrupt properties to use the combined, the device tree node should set interrupt properties to use the
channel as USB OTG: channel as USB OTG:
- interrupts: interrupt specifier for the PHY. - interrupts: interrupt specifier for the PHY.
- vbus-supply: Phandle to a regulator that provides power to the VBUS. This
regulator will be managed during the PHY power on/off sequence.
Example (R-Car H3): Example (R-Car H3):
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
/******* USB2.0 Host registers (original offset is +0x200) *******/ /******* USB2.0 Host registers (original offset is +0x200) *******/
#define USB2_INT_ENABLE 0x000 #define USB2_INT_ENABLE 0x000
...@@ -77,6 +78,7 @@ ...@@ -77,6 +78,7 @@
struct rcar_gen3_chan { struct rcar_gen3_chan {
void __iomem *base; void __iomem *base;
struct phy *phy; struct phy *phy;
struct regulator *vbus;
bool has_otg; bool has_otg;
}; };
...@@ -210,6 +212,13 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p) ...@@ -210,6 +212,13 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
struct rcar_gen3_chan *channel = phy_get_drvdata(p); struct rcar_gen3_chan *channel = phy_get_drvdata(p);
void __iomem *usb2_base = channel->base; void __iomem *usb2_base = channel->base;
u32 val; u32 val;
int ret;
if (channel->vbus) {
ret = regulator_enable(channel->vbus);
if (ret)
return ret;
}
val = readl(usb2_base + USB2_USBCTR); val = readl(usb2_base + USB2_USBCTR);
val |= USB2_USBCTR_PLL_RST; val |= USB2_USBCTR_PLL_RST;
...@@ -220,10 +229,22 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p) ...@@ -220,10 +229,22 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
return 0; return 0;
} }
static int rcar_gen3_phy_usb2_power_off(struct phy *p)
{
struct rcar_gen3_chan *channel = phy_get_drvdata(p);
int ret = 0;
if (channel->vbus)
ret = regulator_disable(channel->vbus);
return ret;
}
static struct phy_ops rcar_gen3_phy_usb2_ops = { static struct phy_ops rcar_gen3_phy_usb2_ops = {
.init = rcar_gen3_phy_usb2_init, .init = rcar_gen3_phy_usb2_init,
.exit = rcar_gen3_phy_usb2_exit, .exit = rcar_gen3_phy_usb2_exit,
.power_on = rcar_gen3_phy_usb2_power_on, .power_on = rcar_gen3_phy_usb2_power_on,
.power_off = rcar_gen3_phy_usb2_power_off,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -290,6 +311,13 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) ...@@ -290,6 +311,13 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
return PTR_ERR(channel->phy); return PTR_ERR(channel->phy);
} }
channel->vbus = devm_regulator_get_optional(dev, "vbus");
if (IS_ERR(channel->vbus)) {
if (PTR_ERR(channel->vbus) == -EPROBE_DEFER)
return PTR_ERR(channel->vbus);
channel->vbus = NULL;
}
phy_set_drvdata(channel->phy, channel); phy_set_drvdata(channel->phy, channel);
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment