[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251201122604.1268071-7-akuchynski@chromium.org>
Date: Mon, 1 Dec 2025 12:26:02 +0000
From: Andrei Kuchynski <akuchynski@...omium.org>
To: Heikki Krogerus <heikki.krogerus@...ux.intel.com>,
Abhishek Pandit-Subedi <abhishekpandit@...omium.org>,
Benson Leung <bleung@...omium.org>,
Jameson Thies <jthies@...gle.com>,
Tzung-Bi Shih <tzungbi@...nel.org>,
linux-usb@...r.kernel.org,
chrome-platform@...ts.linux.dev
Cc: Guenter Roeck <groeck@...omium.org>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Dmitry Baryshkov <dmitry.baryshkov@....qualcomm.com>,
"Christian A. Ehrhardt" <lk@...e.de>,
Abel Vesa <abel.vesa@...aro.org>,
Pooja Katiyar <pooja.katiyar@...el.com>,
Pavan Holla <pholla@...omium.org>,
Madhu M <madhu.m@...el.com>,
Venkat Jayaraman <venkat.jayaraman@...el.com>,
linux-kernel@...r.kernel.org,
Andrei Kuchynski <akuchynski@...omium.org>
Subject: [PATCH RFC 6/8] usb: typec: ucsi: Implement enter_usb_mode operation
`enter_usb_mode` uses the SET_USB UCSI command to manage USB modes such as
USB3, and USB4 for current and future connections.
It allows port drivers and user-space applications (via the "usb_mode"
partner attribute) to enable and disable USB modes on a connector.
Signed-off-by: Andrei Kuchynski <akuchynski@...omium.org>
---
drivers/usb/typec/ucsi/ucsi.c | 22 ++++++++++++++++++++++
drivers/usb/typec/ucsi/ucsi.h | 3 +++
2 files changed, 25 insertions(+)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index ee96c42e9e27..3d4c277bcd49 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -1624,7 +1624,29 @@ static int ucsi_pr_swap(struct typec_port *port, enum typec_role role)
return ret;
}
+static int ucsi_enter_usb_mode(struct typec_port *port, enum usb_mode mode)
+{
+ struct ucsi_connector *con = typec_get_drvdata(port);
+ u64 command;
+ int ret;
+
+ command = UCSI_SET_USB | UCSI_CONNECTOR_NUMBER(con->num);
+ if (mode == USB_MODE_USB3)
+ command |= UCSI_USB3_ENABLE;
+ else if (mode == USB_MODE_USB4)
+ command |= UCSI_USB4_ENABLE;
+
+ if (!ucsi_con_mutex_lock(con))
+ return -ENOTCONN;
+ con->ucsi->message_in_size = 0;
+ ret = ucsi_send_command(con->ucsi, command);
+ ucsi_con_mutex_unlock(con);
+
+ return ret;
+}
+
static const struct typec_operations ucsi_ops = {
+ .enter_usb_mode = ucsi_enter_usb_mode,
.dr_set = ucsi_dr_swap,
.pr_set = ucsi_pr_swap
};
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 6e77bdbdaeae..a5ef35d9dce5 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -219,6 +219,9 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
#define UCSI_GET_PD_MESSAGE_TYPE_IDENTITY 4
#define UCSI_GET_PD_MESSAGE_TYPE_REVISION 5
+/* SET_USB command bits */
+#define UCSI_USB3_ENABLE ((u64)1 << 23)
+#define UCSI_USB4_ENABLE ((u64)1 << 24)
/* -------------------------------------------------------------------------- */
/* Error information returned by PPM in response to GET_ERROR_STATUS command. */
--
2.52.0.158.g65b55ccf14-goog
Powered by blists - more mailing lists