On 10/12/2025 12:57 AM, Dmitry Baryshkov wrote:

On Sat, Oct 11, 2025 at 11:32:28AM +0800, Chaoyi Chen wrote:
From: Chaoyi Chen <[email protected]>

This patch add support for Type-C Port Controller Manager. Each PHY
will register typec_mux and typec_switch when external Type-C
controller is present. Type-C events are handled by TCPM without
extcon.

The extcon device should still be supported.

Signed-off-by: Chaoyi Chen <[email protected]>
---

(no changes since v5)

Changes in v4:
- Remove notify DP HPD state by USB/DP PHY.

(no changes since v3)

Changes in v2:
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.

  drivers/phy/rockchip/phy-rockchip-typec.c | 365 +++++++++++++++++++++-
  1 file changed, 349 insertions(+), 16 deletions(-)

@@ -850,6 +998,72 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
        return mode;
  }
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_orien_sw_set(struct typec_switch_dev *sw,
+                             enum typec_orientation orien)
+{
+       struct rockchip_typec_phy *tcphy = typec_switch_get_drvdata(sw);
+
+       mutex_lock(&tcphy->lock);
+
+       if (orien == TYPEC_ORIENTATION_NONE) {
+               tcphy->new_mode = MODE_DISCONNECT;
+               goto unlock_ret;
+       }
+
+       tcphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false;
+       tcphy->new_mode = MODE_DFP_USB;
Carrying over unanswered(!) comment from the previous series:

I don't think it is correct. Orientation defines only the cable (plug)
orientation. You should be getting the mux events for the mode
selection.

Sorry for that, I forgot to modify this part. Will fix in v6.



+
+unlock_ret:
+       mutex_unlock(&tcphy->lock);
+       return 0;
+}
+
+static void udphy_orien_switch_unregister(void *data)
+{
+       struct rockchip_typec_phy *tcphy = data;
+
+       typec_switch_unregister(tcphy->sw);
+}
+
@@ -1037,6 +1251,89 @@ static const struct phy_ops rockchip_dp_phy_ops = {
        .owner          = THIS_MODULE,
  };
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_typec_mux_set(struct typec_mux_dev *mux, struct 
typec_mux_state *state)
+{
+       struct rockchip_typec_phy *tcphy = typec_mux_get_drvdata(mux);
+       struct typec_displayport_data *data;
+       int hpd = 0;
+
+       mutex_lock(&tcphy->lock);
+
+       switch (state->mode) {
+       case TYPEC_STATE_SAFE:
+               fallthrough;
+       case TYPEC_STATE_USB:
+               tcphy->new_mode = MODE_DFP_USB;
+               phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], 0);
+               break;
+       case TYPEC_DP_STATE_C:
+       case TYPEC_DP_STATE_E:
You need to check that altmode->svid is DP before checking for these
modes.

Okay, will fix in v6.



+               tcphy->new_mode = MODE_DFP_DP;
+               data = state->data;
+               hpd = !!(data->status & DP_STATUS_HPD_STATE);
+               phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 4 : 0);
+               break;
+       case TYPEC_DP_STATE_D:
+               tcphy->new_mode = MODE_DFP_DP | MODE_DFP_USB;
+               data = state->data;
+               hpd = !!(data->status & DP_STATUS_HPD_STATE);
+               phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 2 : 0);
+               break;
+       default:
+               break;
+       }
+
+       mutex_unlock(&tcphy->lock);
+
+       return 0;
+}
+

--
Best,
Chaoyi

Reply via email to