phy: rockchip-inno-usb2: support otg vbus always powered on
authorWilliam Wu <wulf@rock-chips.com>
Tue, 13 Dec 2016 09:29:24 +0000 (17:29 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 14 Dec 2016 03:54:39 +0000 (11:54 +0800)
Some platforms (e.g. RK3399 BOX board) otg port connector
interface is not standard, that is a Type-A connector with
vbus always powered on, looks like to work as host mode,
however, the otg port still need to support DRD mode.

In the current code, if otg vbus is always powered on, it
will cause USB2 PHY to detect a floating charger in error
case and power off USB2 PHY. This patch adds a new property
"rockchip,vbus-always-on" to fix this issue. With this patch,
we handle this case as otg host only mode, and avoid to do
charger detection and power off USB2 PHY.

Change-Id: I69e5e87021f3f2d654793e547264aec55ac664ef
Signed-off-by: William Wu <wulf@rock-chips.com>
Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt
drivers/phy/phy-rockchip-inno-usb2.c

index 1155aaa853f6e008024d12cf066138aaf6b840dc..39939d2511d308dda0f942f8bde6099507d7b5f3 100644 (file)
@@ -32,6 +32,8 @@ Optional properties:
  - rockchip,utmi-avalid : when set, the usb2 phy will use avalid
                status bit to get vbus status. If not, it will use
                bvalid status bit to get vbus status by default.
  - rockchip,utmi-avalid : when set, the usb2 phy will use avalid
                status bit to get vbus status. If not, it will use
                bvalid status bit to get vbus status by default.
+ - rockchip,vbus-always-on: when set, indicates that the otg vbus
+               is always powered on.
 
 Example:
 
 
 Example:
 
index f5055f19b5574367768ee4933d211aeb25d29db7..df92a481402eb68294aec1ca8749dcc1b50e1a7f 100644 (file)
@@ -191,6 +191,7 @@ struct rockchip_usb2phy_cfg {
  *     true    - use avalid to get vbus status
  *     flase   - use bvalid to get vbus status
  * @vbus_attached: otg device vbus status.
  *     true    - use avalid to get vbus status
  *     flase   - use bvalid to get vbus status
  * @vbus_attached: otg device vbus status.
+ * @vbus_always_on: otg vbus is always powered on.
  * @bvalid_irq: IRQ number assigned for vbus valid rise detection.
  * @ls_irq: IRQ number assigned for linestate detection.
  * @id_irq: IRQ number assigned for id fall or rise detection.
  * @bvalid_irq: IRQ number assigned for vbus valid rise detection.
  * @ls_irq: IRQ number assigned for linestate detection.
  * @id_irq: IRQ number assigned for id fall or rise detection.
@@ -212,6 +213,7 @@ struct rockchip_usb2phy_port {
        bool            suspended;
        bool            utmi_avalid;
        bool            vbus_attached;
        bool            suspended;
        bool            utmi_avalid;
        bool            vbus_attached;
+       bool            vbus_always_on;
        int             bvalid_irq;
        int             ls_irq;
        int             id_irq;
        int             bvalid_irq;
        int             ls_irq;
        int             id_irq;
@@ -438,7 +440,8 @@ static int rockchip_usb2phy_init(struct phy *phy)
        mutex_lock(&rport->mutex);
 
        if (rport->port_id == USB2PHY_PORT_OTG) {
        mutex_lock(&rport->mutex);
 
        if (rport->port_id == USB2PHY_PORT_OTG) {
-               if (rport->mode != USB_DR_MODE_HOST) {
+               if (rport->mode != USB_DR_MODE_HOST &&
+                   !rport->vbus_always_on) {
                        /* clear bvalid status and enable bvalid detect irq */
                        ret = property_enable(rphy,
                                              &rport->port_cfg->
                        /* clear bvalid status and enable bvalid detect irq */
                        ret = property_enable(rphy,
                                              &rport->port_cfg->
@@ -557,7 +560,8 @@ static int rockchip_usb2phy_exit(struct phy *phy)
        struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
 
        if (rport->port_id == USB2PHY_PORT_OTG &&
        struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
 
        if (rport->port_id == USB2PHY_PORT_OTG &&
-           rport->mode != USB_DR_MODE_HOST)
+           rport->mode != USB_DR_MODE_HOST &&
+           !rport->vbus_always_on)
                cancel_delayed_work_sync(&rport->chg_work);
        else if (rport->port_id == USB2PHY_PORT_HOST)
                cancel_delayed_work_sync(&rport->sm_work);
                cancel_delayed_work_sync(&rport->chg_work);
        else if (rport->port_id == USB2PHY_PORT_HOST)
                cancel_delayed_work_sync(&rport->sm_work);
@@ -1095,8 +1099,11 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
 
        mutex_init(&rport->mutex);
 
 
        mutex_init(&rport->mutex);
 
+       rport->vbus_always_on =
+               of_property_read_bool(child_np, "rockchip,vbus-always-on");
+
        rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
        rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
-       if (rport->mode == USB_DR_MODE_HOST)
+       if (rport->mode == USB_DR_MODE_HOST || rport->vbus_always_on)
                return 0;
 
        wake_lock_init(&rport->wakelock, WAKE_LOCK_SUSPEND, "rockchip_otg");
                return 0;
 
        wake_lock_init(&rport->wakelock, WAKE_LOCK_SUSPEND, "rockchip_otg");