]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: typec: ucsi: Add support for orientation
authorAbel Vesa <abel.vesa@linaro.org>
Tue, 28 Oct 2025 12:52:12 +0000 (14:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 28 Oct 2025 14:37:48 +0000 (15:37 +0100)
According to UCSI 2.0 specification, the orientation is
part of the connector status payload. So tie up the port
orientation.

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Link: https://patch.msgid.link/20251028-usb-typec-ucsi-orientation-v2-1-9330478bb6c1@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/typec/ucsi/ucsi.c
drivers/usb/typec/ucsi/ucsi.h

index ed23edab776354f08452c539d75d27132b8c44dd..ec6c8f928ddaf62074846f9145866ce5074e0965 100644 (file)
@@ -1008,6 +1008,28 @@ static int ucsi_check_connector_capability(struct ucsi_connector *con)
        return ret;
 }
 
+static void ucsi_orientation(struct ucsi_connector *con)
+{
+       if (con->ucsi->version < UCSI_VERSION_2_0)
+               return;
+
+       if (!UCSI_CONSTAT(con, CONNECTED)) {
+               typec_set_orientation(con->port, TYPEC_ORIENTATION_NONE);
+               return;
+       }
+
+       switch (UCSI_CONSTAT(con, ORIENTATION)) {
+       case UCSI_CONSTAT_ORIENTATION_NORMAL:
+               typec_set_orientation(con->port, TYPEC_ORIENTATION_NORMAL);
+               break;
+       case UCSI_CONSTAT_ORIENTATION_REVERSE:
+               typec_set_orientation(con->port, TYPEC_ORIENTATION_REVERSE);
+               break;
+       default:
+               break;
+       }
+}
+
 static void ucsi_pwr_opmode_change(struct ucsi_connector *con)
 {
        switch (UCSI_CONSTAT(con, PWR_OPMODE)) {
@@ -1261,6 +1283,7 @@ static void ucsi_handle_connector_change(struct work_struct *work)
                typec_set_pwr_role(con->port, role);
                ucsi_port_psy_changed(con);
                ucsi_partner_change(con);
+               ucsi_orientation(con);
 
                if (UCSI_CONSTAT(con, CONNECTED)) {
                        ucsi_register_partner(con);
@@ -1693,6 +1716,7 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
                typec_set_pwr_role(con->port, UCSI_CONSTAT(con, PWR_DIR));
                ucsi_register_partner(con);
                ucsi_pwr_opmode_change(con);
+               ucsi_orientation(con);
                ucsi_port_psy_changed(con);
                if (con->ucsi->cap.features & UCSI_CAP_GET_PD_MESSAGE)
                        ucsi_get_partner_identity(con);
index 700d353f9bb14d1144de5c623c5bb58f46bc4b5a..410389ef173ab9fd625d9446f792f630860cb7e5 100644 (file)
@@ -361,6 +361,9 @@ struct ucsi_cable_property {
 #define   UCSI_CONSTAT_BC_SLOW_CHARGING                2
 #define   UCSI_CONSTAT_BC_TRICKLE_CHARGING     3
 #define UCSI_CONSTAT_PD_VERSION_V1_2           UCSI_DECLARE_BITFIELD_V1_2(70, 16)
+#define UCSI_CONSTAT_ORIENTATION               UCSI_DECLARE_BITFIELD_V2_0(86, 1)
+#define   UCSI_CONSTAT_ORIENTATION_NORMAL      0
+#define   UCSI_CONSTAT_ORIENTATION_REVERSE     1
 #define UCSI_CONSTAT_SINK_PATH_STATUS_V2_0     UCSI_DECLARE_BITFIELD_V2_0(87, 1)
 #define   UCSI_CONSTAT_SINK_PATH_DISABLED   0
 #define   UCSI_CONSTAT_SINK_PATH_ENABLED    1