From 53d9214f5602ddc11794044f4f85cb5cd9589835 Mon Sep 17 00:00:00 2001 From: Frank Wang Date: Wed, 21 Jul 2021 11:33:51 +0800 Subject: [PATCH] phy: rockchip: typec: amend to support the tcpm framework This adds typec orientation switch to support the TCPM framework for Type-C feature. Signed-off-by: Frank Wang Change-Id: I14aa2bc6a4a377733bd5bfd1e2ff77820dbc2758 --- drivers/phy/rockchip/phy-rockchip-typec.c | 54 ++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c index 676c213ce177..2141dc2710a0 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -414,6 +415,7 @@ struct rockchip_typec_phy { struct device *dev; void __iomem *base; struct extcon_dev *extcon; + struct typec_switch *sw; struct regmap *grf_regs; struct clk *clk_core; struct clk *clk_ref; @@ -1380,6 +1382,48 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy) return mode; } +static int tcphy_orien_sw_set(struct typec_switch *sw, + enum typec_orientation orien) +{ + struct rockchip_typec_phy *tcphy = typec_switch_get_drvdata(sw); + + mutex_lock(&tcphy->lock); + + if (orien == TYPEC_ORIENTATION_NONE) + goto unlock_ret; + + tcphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false; + +unlock_ret: + mutex_unlock(&tcphy->lock); + return 0; +} + +static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy) +{ + struct typec_switch_desc sw_desc = { }; + + sw_desc.drvdata = tcphy; + sw_desc.fwnode = dev_fwnode(tcphy->dev); + sw_desc.set = tcphy_orien_sw_set; + + tcphy->sw = typec_switch_register(tcphy->dev, &sw_desc); + if (IS_ERR(tcphy->sw)) { + dev_err(tcphy->dev, "Error register typec orientation switch: %ld\n", + PTR_ERR(tcphy->sw)); + return PTR_ERR(tcphy->sw); + } + + return 0; +} + +static void udphy_orien_switch_unregister(void *data) +{ + struct rockchip_typec_phy *tcphy = data; + + typec_switch_unregister(tcphy->sw); +} + static int _rockchip_usb3_phy_power_on(struct rockchip_typec_phy *tcphy) { const struct rockchip_usb3phy_port_cfg *cfg = tcphy->port_cfgs; @@ -1415,7 +1459,6 @@ static int _rockchip_usb3_phy_power_on(struct rockchip_typec_phy *tcphy) regmap_read(tcphy->grf_regs, reg->offset, &val); if (!(val & BIT(reg->enable_bit))) { tcphy->mode |= new_mode & (MODE_DFP_USB | MODE_UFP_USB); - /* enable usb3 host */ tcphy_cfg_usb3_to_usb2_only(tcphy, false); goto unlock_ret; @@ -1702,6 +1745,15 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev) if (IS_ERR(tcphy->extcon)) { if (PTR_ERR(tcphy->extcon) == -ENODEV) { tcphy->extcon = NULL; + if (device_property_present(dev, "orientation-switch")) { + ret = tcphy_setup_orien_switch(tcphy); + if (ret) + return ret; + ret = devm_add_action_or_reset(dev, udphy_orien_switch_unregister, + tcphy); + if (ret) + return ret; + } } else { if (PTR_ERR(tcphy->extcon) != -EPROBE_DEFER) dev_err(dev, "Invalid or missing extcon\n");