mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
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> Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
This commit is contained in:
@@ -115,6 +115,10 @@ properties:
|
||||
Phandle to a regulator that provides power to VBUS.
|
||||
See ./phy-bindings.txt for details.
|
||||
|
||||
vbus-supply:
|
||||
description:
|
||||
Phandle to a fixed-regulator that provides power to VBUS.
|
||||
|
||||
rockchip,utmi-bypass-uart:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: when set, indicates that support usb to bypass uart
|
||||
|
||||
@@ -198,6 +198,7 @@ struct rockchip_usb2phy_cfg {
|
||||
* false - 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.
|
||||
* @ls_irq: IRQ number assigned for linestate detection.
|
||||
@@ -209,6 +210,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.
|
||||
* @port_cfg: port register configuration, assigned by driver data.
|
||||
* @event_nb: hold event notification callback.
|
||||
* @state: define OTG enumeration states before device reset.
|
||||
@@ -222,6 +224,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;
|
||||
@@ -232,6 +235,7 @@ struct rockchip_usb2phy_port {
|
||||
struct delayed_work chg_work;
|
||||
struct delayed_work otg_sm_work;
|
||||
struct delayed_work sm_work;
|
||||
struct regulator *vbus;
|
||||
const struct rockchip_usb2phy_port_cfg *port_cfg;
|
||||
struct notifier_block event_nb;
|
||||
enum usb_otg_state state;
|
||||
@@ -742,6 +746,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, int submode)
|
||||
{
|
||||
@@ -761,9 +788,21 @@ static int rockchip_usb2phy_set_mode(struct phy *phy,
|
||||
*/
|
||||
fallthrough;
|
||||
case PHY_MODE_USB_DEVICE:
|
||||
/* 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:
|
||||
/* 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:
|
||||
vbus_det_en = false;
|
||||
@@ -1419,6 +1458,7 @@ static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data)
|
||||
{
|
||||
struct rockchip_usb2phy_port *rport = data;
|
||||
struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
|
||||
bool cable_vbus_state = false;
|
||||
|
||||
if (!property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st) &&
|
||||
!property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st))
|
||||
@@ -1430,18 +1470,22 @@ static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data)
|
||||
if (property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st)) {
|
||||
property_enable(rphy->grf, &rport->port_cfg->idfall_det_clr,
|
||||
true);
|
||||
extcon_set_state(rphy->edev, EXTCON_USB_HOST, true);
|
||||
extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, true);
|
||||
cable_vbus_state = true;
|
||||
} else if (property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st)) {
|
||||
property_enable(rphy->grf, &rport->port_cfg->idrise_det_clr,
|
||||
true);
|
||||
extcon_set_state(rphy->edev, EXTCON_USB_HOST, false);
|
||||
extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, false);
|
||||
cable_vbus_state = false;
|
||||
}
|
||||
|
||||
|
||||
extcon_set_state(rphy->edev, EXTCON_USB_HOST, cable_vbus_state);
|
||||
extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, cable_vbus_state);
|
||||
|
||||
extcon_sync(rphy->edev, EXTCON_USB_HOST);
|
||||
extcon_sync(rphy->edev, EXTCON_USB_VBUS_EN);
|
||||
|
||||
rockchip_set_vbus_power(rport, cable_vbus_state);
|
||||
|
||||
mutex_unlock(&rport->mutex);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -1511,6 +1555,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);
|
||||
@@ -1523,14 +1568,35 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
|
||||
rport->utmi_avalid =
|
||||
of_property_read_bool(child_np, "rockchip,utmi-avalid");
|
||||
|
||||
/* 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);
|
||||
if (rport->mode == USB_DR_MODE_HOST ||
|
||||
rport->mode == USB_DR_MODE_UNKNOWN ||
|
||||
rport->vbus_always_on) {
|
||||
ret = 0;
|
||||
rport->mode == USB_DR_MODE_UNKNOWN) {
|
||||
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);
|
||||
ret = rockchip_set_vbus_power(rport, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (rport->vbus_always_on)
|
||||
goto out;
|
||||
|
||||
INIT_DELAYED_WORK(&rport->bypass_uart_work,
|
||||
rockchip_usb_bypass_uart_work);
|
||||
INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
|
||||
@@ -1610,9 +1676,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);
|
||||
} else {
|
||||
extcon_set_state(rphy->edev, EXTCON_USB_HOST, false);
|
||||
extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, false);
|
||||
/* Enable VBUS supply */
|
||||
ret = rockchip_set_vbus_power(rport, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1967,6 +2034,23 @@ static int rockchip_usb2phy_pm_resume(struct device *dev)
|
||||
"failed to enable id irq\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!property_enabled(rphy->grf,
|
||||
&rport->port_cfg->utmi_iddig) &&
|
||||
!extcon_get_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);
|
||||
ret = rockchip_set_vbus_power(rport, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user