From c3d7d6d952d5b94e216515f7302eb9bed7b7693f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Jirman?= Date: Fri, 4 Feb 2022 02:25:34 +0100 Subject: [PATCH 339/391] 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 --- 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 490cce6e1..ae448127d 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.35.3