phy: rockchip-inno-usb2: use fixed-regulator for vbus power

This patch uses a fixed-regulator instead of GPIO pin for
usb vbus power. It doesn't fix any issue, but it makes more
sense to convert the GPIO code into a fixed-regulator.

Change-Id: I7196a9cd592dbb3fab3ef8b9e99babc613a42869
Signed-off-by: William Wu <william.wu@rock-chips.com>
This commit is contained in:
William Wu
2018-02-24 16:29:32 +08:00
committed by Tao Huang
parent da8675c309
commit a1ca1be8f6
2 changed files with 67 additions and 24 deletions

View File

@@ -21,8 +21,8 @@ Optional properties:
usb-phy output 480m and xin24m.
Refer to clk/clock-bindings.txt for generic clock
consumer properties.
- rockchip,u2phy-tuning; when set, tuning u2phy to improve usb2 SI.
- otg-vbus-gpios : assign the gpio to control vbus of otg port.
- rockchip,u2phy-tuning: when set, tuning u2phy to improve usb2 SI.
- vbus-supply: regulator phandle for vbus power source.
Required nodes : a sub-node is required for each port the phy provides.
The sub-node name is used to identify host or otg port,

View File

@@ -206,9 +206,9 @@ struct rockchip_usb2phy_cfg {
* flase - use bvalid to get vbus status
* @vbus_attached: otg device vbus status.
* @vbus_always_on: otg vbus is always powered on.
* @vbus_enabled: vbus regulator status.
* @bypass_uart_en: usb bypass uart enable, passed from DT.
* @bvalid_irq: IRQ number assigned for vbus valid rise detection.
* @vbus_drv_gpio: gpio description for vbus control.
* @ls_irq: IRQ number assigned for linestate detection.
* @id_irq: IRQ number assigned for id fall or rise detection.
* @mutex: for register updating in sm_work.
@@ -216,6 +216,7 @@ struct rockchip_usb2phy_cfg {
* @bypass_uart_work: usb bypass uart work.
* @otg_sm_work: OTG state machine work.
* @sm_work: HOST state machine work.
* @vbus: vbus regulator supply on few rockchip boards.
* @phy_cfg: port register configuration, assigned by driver data.
* @event_nb: hold event notification callback.
* @wakelock: wake lock struct to prevent system suspend
@@ -231,6 +232,7 @@ struct rockchip_usb2phy_port {
bool utmi_avalid;
bool vbus_attached;
bool vbus_always_on;
bool vbus_enabled;
bool bypass_uart_en;
int bvalid_irq;
int ls_irq;
@@ -240,7 +242,7 @@ struct rockchip_usb2phy_port {
struct delayed_work chg_work;
struct delayed_work otg_sm_work;
struct delayed_work sm_work;
struct gpio_desc *vbus_drv_gpio;
struct regulator *vbus;
const struct rockchip_usb2phy_port_cfg *port_cfg;
struct notifier_block event_nb;
struct wake_lock wakelock;
@@ -735,6 +737,29 @@ static int rockchip_usb2phy_exit(struct phy *phy)
return 0;
}
static int rockchip_set_vbus_power(struct rockchip_usb2phy_port *rport,
bool en)
{
int ret = 0;
if (!rport->vbus)
return 0;
if (en && !rport->vbus_enabled) {
ret = regulator_enable(rport->vbus);
if (ret)
dev_err(&rport->phy->dev,
"Failed to enable VBUS supply\n");
} else if (!en && rport->vbus_enabled) {
ret = regulator_disable(rport->vbus);
}
if (ret == 0)
rport->vbus_enabled = en;
return ret;
}
static int rockchip_usb2phy_set_mode(struct phy *phy, enum phy_mode mode)
{
struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
@@ -754,12 +779,20 @@ static int rockchip_usb2phy_set_mode(struct phy *phy, enum phy_mode mode)
* fallthrough
*/
case PHY_MODE_USB_DEVICE:
gpiod_set_value_cansleep(rport->vbus_drv_gpio, 0);
/* Disable VBUS supply */
rockchip_set_vbus_power(rport, false);
extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, false);
vbus_det_en = true;
break;
case PHY_MODE_USB_HOST:
gpiod_set_value_cansleep(rport->vbus_drv_gpio, 1);
/* Enable VBUS supply */
ret = rockchip_set_vbus_power(rport, true);
if (ret) {
dev_err(&rport->phy->dev,
"Failed to set host mode\n");
return ret;
}
extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, true);
/* fallthrough */
case PHY_MODE_INVALID:
@@ -1427,8 +1460,8 @@ static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data)
extcon_sync(rphy->edev, EXTCON_USB_HOST);
extcon_sync(rphy->edev, EXTCON_USB_VBUS_EN);
gpiod_set_value_cansleep(rport->vbus_drv_gpio,
cable_vbus_state ? 1 : 0);
rockchip_set_vbus_power(rport, cable_vbus_state);
mutex_unlock(&rport->mutex);
@@ -1497,6 +1530,7 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
rport->state = OTG_STATE_UNDEFINED;
rport->vbus_attached = false;
rport->vbus_enabled = false;
rport->perip_connected = false;
mutex_init(&rport->mutex);
@@ -1524,13 +1558,15 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
return ret;
}
rport->vbus_drv_gpio = devm_gpiod_get_optional(rphy->dev, "otg-vbus",
GPIOD_OUT_LOW);
if (!rport->vbus_drv_gpio) {
dev_warn(rphy->dev, "vbus_drv is not assigned\n");
} else if (IS_ERR(rport->vbus_drv_gpio)) {
dev_err(rphy->dev, "failed to get vbus_drv\n");
return PTR_ERR(rport->vbus_drv_gpio);
/* Get Vbus regulators */
rport->vbus = devm_regulator_get_optional(&rport->phy->dev, "vbus");
if (IS_ERR(rport->vbus)) {
ret = PTR_ERR(rport->vbus);
if (ret == -EPROBE_DEFER)
return ret;
dev_warn(&rport->phy->dev, "Failed to get VBUS supply regulator\n");
rport->vbus = NULL;
}
rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
@@ -1539,8 +1575,12 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
if (rphy->edev_self) {
extcon_set_state(rphy->edev, EXTCON_USB, false);
extcon_set_state(rphy->edev, EXTCON_USB_HOST, true);
/* Enable VBUS supply */
extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, true);
gpiod_set_value_cansleep(rport->vbus_drv_gpio, 1);
ret = rockchip_set_vbus_power(rport, true);
if (ret)
return ret;
}
goto out;
}
@@ -1590,11 +1630,10 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
extcon_set_state(rphy->edev, EXTCON_USB, false);
extcon_set_state(rphy->edev, EXTCON_USB_HOST, true);
extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, true);
gpiod_set_value_cansleep(rport->vbus_drv_gpio, 1);
} else {
extcon_set_state(rphy->edev, EXTCON_USB_HOST, false);
extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, false);
gpiod_set_value_cansleep(rport->vbus_drv_gpio, 0);
/* Enable VBUS supply */
ret = rockchip_set_vbus_power(rport, true);
if (ret)
return ret;
}
}
@@ -1960,17 +1999,21 @@ static int rockchip_usb2phy_pm_resume(struct device *dev)
}
if (!property_enabled(rphy,
&rport->port_cfg->utmi_iddig)) {
&rport->port_cfg->utmi_iddig) &&
!extcon_get_cable_state_(rphy->edev,
EXTCON_USB_HOST)) {
dev_dbg(&rport->phy->dev,
"port power on when resume\n");
extcon_set_state_sync(rphy->edev,
EXTCON_USB_HOST,
true);
/* Enable VBUS supply */
extcon_set_state_sync(rphy->edev,
EXTCON_USB_VBUS_EN,
true);
gpiod_set_value_cansleep(rport->vbus_drv_gpio,
1);
ret = rockchip_set_vbus_power(rport, true);
if (ret)
return ret;
}
}
}