build/patch/kernel/archive/sunxi-6.4/patches.megous/phy-rockchip-inno-usb2-More-robust-charger-detection-extcon-upd.patch

115 lines
4.0 KiB
Diff

From fc847faa60649c49892c838dc62f4b596f5a8a67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Jirman?= <megi@xff.cz>
Date: Fri, 4 Feb 2022 02:25:34 +0100
Subject: [PATCH 357/469] phy: rockchip-inno-usb2: More robust charger
detection extcon updates
Make sure we always clear the charger detection results. Allow to
disable updates of EXTCON_USB state via extcon,ignore-usb DT property.
The previous method was smart, but assumed !vbus_branch would
always be called.
Signed-off-by: Ondrej Jirman <megi@xff.cz>
---
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 39 +++++++++++--------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 490cce6e1d40..ae448127d31c 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -542,21 +542,27 @@ static const struct phy_ops rockchip_usb2phy_ops = {
.owner = THIS_MODULE,
};
+const int rockchip_usb2phy_cable_types[] = {
+ EXTCON_CHG_USB_SDP,
+ EXTCON_CHG_USB_DCP,
+ EXTCON_CHG_USB_CDP,
+ EXTCON_CHG_USB_ACA,
+};
+
static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
{
struct rockchip_usb2phy_port *rport =
container_of(work, struct rockchip_usb2phy_port,
otg_sm_work.work);
struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
- static unsigned int cable;
+ unsigned int cable = 0, i;
unsigned long delay;
- bool vbus_attach, sch_work, notify_charger;
+ bool vbus_attach, sch_work;
vbus_attach = property_enabled(rphy->grf,
&rport->port_cfg->utmi_bvalid);
sch_work = false;
- notify_charger = false;
delay = OTG_SCHEDULE_DELAY;
dev_dbg(&rport->phy->dev, "%s otg sm work\n",
usb_otg_state_string(rport->state));
@@ -585,14 +591,12 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
dev_dbg(&rport->phy->dev, "sdp cable is connected\n");
rockchip_usb2phy_power_on(rport->phy);
rport->state = OTG_STATE_B_PERIPHERAL;
- notify_charger = true;
sch_work = true;
cable = EXTCON_CHG_USB_SDP;
break;
case POWER_SUPPLY_TYPE_USB_DCP:
dev_dbg(&rport->phy->dev, "dcp cable is connected\n");
rockchip_usb2phy_power_off(rport->phy);
- notify_charger = true;
sch_work = true;
cable = EXTCON_CHG_USB_DCP;
break;
@@ -600,7 +604,6 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
dev_dbg(&rport->phy->dev, "cdp cable is connected\n");
rockchip_usb2phy_power_on(rport->phy);
rport->state = OTG_STATE_B_PERIPHERAL;
- notify_charger = true;
sch_work = true;
cable = EXTCON_CHG_USB_CDP;
break;
@@ -612,22 +615,26 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
break;
}
} else {
- notify_charger = true;
rphy->chg_state = USB_CHG_STATE_UNDEFINED;
rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
}
- if (rport->vbus_attached != vbus_attach) {
- rport->vbus_attached = vbus_attach;
+ if (rphy->edev && extcon_get_state(rphy->edev, cable) != vbus_attach) {
+ for (i = 0; i < ARRAY_SIZE(rockchip_usb2phy_cable_types); i++) {
+ int type = rockchip_usb2phy_cable_types[i];
- if (notify_charger && rphy->edev) {
- extcon_set_state_sync(rphy->edev,
- cable, vbus_attach);
- if (cable == EXTCON_CHG_USB_SDP)
- extcon_set_state_sync(rphy->edev,
- EXTCON_USB,
- vbus_attach);
+ if (extcon_get_state(rphy->edev, type))
+ extcon_set_state_sync(rphy->edev, type, 0);
}
+
+ if (vbus_attach)
+ extcon_set_state_sync(rphy->edev, cable, vbus_attach);
+
+ if ((cable == EXTCON_CHG_USB_SDP || cable == POWER_SUPPLY_TYPE_USB_CDP)
+ && extcon_get_state(rphy->edev, EXTCON_USB) != vbus_attach
+ && !of_property_read_bool(rphy->dev->of_node, "extcon,ignore-usb"))
+ extcon_set_state_sync(rphy->edev,
+ EXTCON_USB, vbus_attach);
}
break;
case OTG_STATE_B_PERIPHERAL:
--
2.34.1