* [PATCH v4 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery
@ 2024-03-05 2:58 Jameson Thies
2024-03-05 2:58 ` [PATCH v4 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: Jameson Thies @ 2024-03-05 2:58 UTC (permalink / raw)
To: heikki.krogerus, linux-usb
Cc: jthies, pmalani, bleung, abhishekpandit, andersson,
dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede,
neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel
Hi Heikki,
This patch series expands support for partner and cable discover in the
UCSI driver. There are a few pieces here.
1. Some cleanup of the GET_CABLE_PROP definitions in ucsi.h.
2. Cable discovery and registration with the USB Type-C connector class.
3. Partner/Cable identity registration with the USB Type-C connector
class.
4. SOP' alternate mode registration with the USB-C connector class using
a cable plug.
These have been tested on a the usb-testing branch merged with a
chromeOS 6.8-rc2 kernel. Let me know if you have any questions.
Thanks,
Jameson
Changes in v4:
- Cleaned up redundent ucsi_send_command calls for discovering identity.
Changes in v3:
- Fixed CC stable and email threading issue.
Changes in v2:
- Re-ordered memset call and null assignment when unregistering partners
and cables.
- Supports registering partner and cable identity with UCSI versions
before v2.0.
- Shortened lines to within 80 characters with the exception of two
error log lines with three indentations.
- Tested on usb-testing branch merged with chromeOS 6.8-rc2 kernel.
Jameson Thies (4):
usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros
usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses
usb: typec: ucsi: Register SOP' alternate modes with cable plug
drivers/usb/typec/ucsi/ucsi.c | 245 ++++++++++++++++++++++++++++++++++
drivers/usb/typec/ucsi/ucsi.h | 40 +++++-
2 files changed, 283 insertions(+), 2 deletions(-)
base-commit: a14e6fd1b67799da7da9cc344023bd16aaf0d17d
--
2.44.0.rc1.240.g4c46232300-goog
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v4 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros
2024-03-05 2:58 [PATCH v4 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies
@ 2024-03-05 2:58 ` Jameson Thies
2024-03-27 11:14 ` Heikki Krogerus
2024-03-05 2:58 ` [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: Jameson Thies @ 2024-03-05 2:58 UTC (permalink / raw)
To: heikki.krogerus, linux-usb
Cc: jthies, pmalani, bleung, abhishekpandit, andersson,
dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede,
neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel,
stable, Benson Leung
Clean up UCSI_CABLE_PROP macros by fixing a bitmask shifting error for
plug type and updating the modal support macro for consistent naming.
Fixes: 3cf657f07918 ("usb: typec: ucsi: Remove all bit-fields")
Cc: stable@vger.kernel.org
Reviewed-by: Benson Leung <bleung@chromium.org>
Reviewed-by: Prashant Malani <pmalani@chromium.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Jameson Thies <jthies@google.com>
---
Changes in v4:
- None.
Changes in v3:
- Fixed CC stable.
Changes in v2:
- Tested on usb-testing branch merged with chromeOS 6.8-rc2 kernel.
drivers/usb/typec/ucsi/ucsi.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 7e35ffbe0a6f2..469a2baf472e4 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -259,12 +259,12 @@ struct ucsi_cable_property {
#define UCSI_CABLE_PROP_FLAG_VBUS_IN_CABLE BIT(0)
#define UCSI_CABLE_PROP_FLAG_ACTIVE_CABLE BIT(1)
#define UCSI_CABLE_PROP_FLAG_DIRECTIONALITY BIT(2)
-#define UCSI_CABLE_PROP_FLAG_PLUG_TYPE(_f_) ((_f_) & GENMASK(3, 0))
+#define UCSI_CABLE_PROP_FLAG_PLUG_TYPE(_f_) (((_f_) & GENMASK(4, 3)) >> 3)
#define UCSI_CABLE_PROPERTY_PLUG_TYPE_A 0
#define UCSI_CABLE_PROPERTY_PLUG_TYPE_B 1
#define UCSI_CABLE_PROPERTY_PLUG_TYPE_C 2
#define UCSI_CABLE_PROPERTY_PLUG_OTHER 3
-#define UCSI_CABLE_PROP_MODE_SUPPORT BIT(5)
+#define UCSI_CABLE_PROP_FLAG_MODE_SUPPORT BIT(5)
u8 latency;
} __packed;
--
2.44.0.rc1.240.g4c46232300-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
2024-03-05 2:58 [PATCH v4 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies
2024-03-05 2:58 ` [PATCH v4 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies
@ 2024-03-05 2:58 ` Jameson Thies
2024-03-11 17:28 ` neil.armstrong
2024-03-05 2:58 ` [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies
2024-03-05 2:58 ` [PATCH v4 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug Jameson Thies
3 siblings, 1 reply; 13+ messages in thread
From: Jameson Thies @ 2024-03-05 2:58 UTC (permalink / raw)
To: heikki.krogerus, linux-usb
Cc: jthies, pmalani, bleung, abhishekpandit, andersson,
dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede,
neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel,
Benson Leung
Register cables with the Type-C Connector Class in the UCSI driver based
on the PPM response to GET_CABLE_PROPERTY. Registered cable properties
include plug type, cable type and major revision.
Reviewed-by: Benson Leung <bleung@chromium.org>
Reviewed-by: Prashant Malani <pmalani@chromium.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Jameson Thies <jthies@google.com>
---
Expected cable properties populate the USB Type-C connector class sysfs
paths:
nospike-rev4 /sys/class/typec # ls port0-cable
device identity plug_type port0-plug0 power subsystem type uevent
usb_power_delivery_revision
Changes in v4:
- None.
Changes in v3:
- None.
Changes in v2:
- Shortened lines to within 80 characters.
- Tested on usb-testing branch merged with chromeOS 6.8-rc2 kernel.
drivers/usb/typec/ucsi/ucsi.c | 73 +++++++++++++++++++++++++++++++++++
drivers/usb/typec/ucsi/ucsi.h | 5 +++
2 files changed, 78 insertions(+)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index ae105383e69e7..7c84687b5d1a3 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -734,6 +734,52 @@ static void ucsi_unregister_partner_pdos(struct ucsi_connector *con)
con->partner_pd = NULL;
}
+static int ucsi_register_cable(struct ucsi_connector *con)
+{
+ struct typec_cable *cable;
+ struct typec_cable_desc desc = {};
+
+ switch (UCSI_CABLE_PROP_FLAG_PLUG_TYPE(con->cable_prop.flags)) {
+ case UCSI_CABLE_PROPERTY_PLUG_TYPE_A:
+ desc.type = USB_PLUG_TYPE_A;
+ break;
+ case UCSI_CABLE_PROPERTY_PLUG_TYPE_B:
+ desc.type = USB_PLUG_TYPE_B;
+ break;
+ case UCSI_CABLE_PROPERTY_PLUG_TYPE_C:
+ desc.type = USB_PLUG_TYPE_C;
+ break;
+ default:
+ desc.type = USB_PLUG_NONE;
+ break;
+ }
+
+ desc.active = !!(UCSI_CABLE_PROP_FLAG_ACTIVE_CABLE &
+ con->cable_prop.flags);
+ desc.pd_revision = UCSI_CABLE_PROP_FLAG_PD_MAJOR_REV_AS_BCD(
+ con->cable_prop.flags);
+
+ cable = typec_register_cable(con->port, &desc);
+ if (IS_ERR(cable)) {
+ dev_err(con->ucsi->dev,
+ "con%d: failed to register cable (%ld)\n", con->num,
+ PTR_ERR(cable));
+ return PTR_ERR(cable);
+ }
+
+ con->cable = cable;
+ return 0;
+}
+
+static void ucsi_unregister_cable(struct ucsi_connector *con)
+{
+ if (!con->cable)
+ return;
+
+ typec_unregister_cable(con->cable);
+ con->cable = NULL;
+}
+
static void ucsi_pwr_opmode_change(struct ucsi_connector *con)
{
switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
@@ -807,6 +853,7 @@ static void ucsi_unregister_partner(struct ucsi_connector *con)
typec_partner_set_usb_power_delivery(con->partner, NULL);
ucsi_unregister_partner_pdos(con);
ucsi_unregister_altmodes(con, UCSI_RECIPIENT_SOP);
+ ucsi_unregister_cable(con);
typec_unregister_partner(con->partner);
con->partner = NULL;
}
@@ -907,6 +954,30 @@ static int ucsi_check_connection(struct ucsi_connector *con)
return 0;
}
+static int ucsi_check_cable(struct ucsi_connector *con)
+{
+ u64 command;
+ int ret;
+
+ if (con->cable)
+ return 0;
+
+ command = UCSI_GET_CABLE_PROPERTY | UCSI_CONNECTOR_NUMBER(con->num);
+ ret = ucsi_send_command(con->ucsi, command, &con->cable_prop,
+ sizeof(con->cable_prop));
+ if (ret < 0) {
+ dev_err(con->ucsi->dev, "GET_CABLE_PROPERTY failed (%d)\n",
+ ret);
+ return ret;
+ }
+
+ ret = ucsi_register_cable(con);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static void ucsi_handle_connector_change(struct work_struct *work)
{
struct ucsi_connector *con = container_of(work, struct ucsi_connector,
@@ -948,6 +1019,7 @@ static void ucsi_handle_connector_change(struct work_struct *work)
ucsi_register_partner(con);
ucsi_partner_task(con, ucsi_check_connection, 1, HZ);
ucsi_partner_task(con, ucsi_check_connector_capability, 1, HZ);
+ ucsi_partner_task(con, ucsi_check_cable, 1, HZ);
if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) ==
UCSI_CONSTAT_PWR_OPMODE_PD)
@@ -1346,6 +1418,7 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
ucsi_register_partner(con);
ucsi_pwr_opmode_change(con);
ucsi_port_psy_changed(con);
+ ucsi_check_cable(con);
}
/* Only notify USB controller if partner supports USB data */
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 469a2baf472e4..f0aabef0b7c64 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -265,6 +265,9 @@ struct ucsi_cable_property {
#define UCSI_CABLE_PROPERTY_PLUG_TYPE_C 2
#define UCSI_CABLE_PROPERTY_PLUG_OTHER 3
#define UCSI_CABLE_PROP_FLAG_MODE_SUPPORT BIT(5)
+#define UCSI_CABLE_PROP_FLAG_PD_MAJOR_REV(_f_) (((_f_) & GENMASK(7, 6)) >> 6)
+#define UCSI_CABLE_PROP_FLAG_PD_MAJOR_REV_AS_BCD(_f_) \
+ UCSI_SPEC_REVISION_TO_BCD(UCSI_CABLE_PROP_FLAG_PD_MAJOR_REV(_f_))
u8 latency;
} __packed;
@@ -400,6 +403,7 @@ struct ucsi_connector {
struct typec_port *port;
struct typec_partner *partner;
+ struct typec_cable *cable;
struct typec_altmode *port_altmode[UCSI_MAX_ALTMODES];
struct typec_altmode *partner_altmode[UCSI_MAX_ALTMODES];
@@ -408,6 +412,7 @@ struct ucsi_connector {
struct ucsi_connector_status status;
struct ucsi_connector_capability cap;
+ struct ucsi_cable_property cable_prop;
struct power_supply *psy;
struct power_supply_desc psy_desc;
u32 rdo;
--
2.44.0.rc1.240.g4c46232300-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses
2024-03-05 2:58 [PATCH v4 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies
2024-03-05 2:58 ` [PATCH v4 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies
2024-03-05 2:58 ` [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies
@ 2024-03-05 2:58 ` Jameson Thies
2024-03-05 3:06 ` Benson Leung
2024-03-05 18:54 ` Prashant Malani
2024-03-05 2:58 ` [PATCH v4 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug Jameson Thies
3 siblings, 2 replies; 13+ messages in thread
From: Jameson Thies @ 2024-03-05 2:58 UTC (permalink / raw)
To: heikki.krogerus, linux-usb
Cc: jthies, pmalani, bleung, abhishekpandit, andersson,
dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede,
neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel
Register SOP and SOP' Discover Identity responses with the USB Type-C
Connector Class as partner and cable identities, respectively. Discover
Identity responses are requested from the PPM using the GET_PD_MESSAGE
UCSI command.
Signed-off-by: Jameson Thies <jthies@google.com>
---
GET_PD_MESSAGE responses from the PPM populate partner and cable
identity in sysfs:
nospike-rev4 /sys/class/typec # ls port0-partner/identity/
cert_stat id_header product product_type_vdo1 product_type_vdo2
product_type_vdo3
nospike-rev4 /sys/class/typec # ls port0-cable/identity/
cert_stat id_header product product_type_vdo1 product_type_vdo2
product_type_vdo3
Changes in v4:
- Cleaned up redundent ucsi_send_command calls for discovering identity.
Changes in v3:
- None.
Changes in v2:
- Re-ordered memset call and null assignment when unregistering partners
and cables.
- Supports registering partner and cable identity with UCSI versions
before v2.0.
- Shortened lines to within 80 characters with the exception of two
error log lines with three indentations.
- Tested on usb-testing branch merged with chromeOS 6.8-rc2 kernel.
drivers/usb/typec/ucsi/ucsi.c | 112 ++++++++++++++++++++++++++++++++++
drivers/usb/typec/ucsi/ucsi.h | 29 +++++++++
2 files changed, 141 insertions(+)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 7c84687b5d1a3..3b64a0f51041c 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -646,6 +646,108 @@ static int ucsi_get_src_pdos(struct ucsi_connector *con)
return ret;
}
+static int ucsi_read_identity(struct ucsi_connector *con, u8 recipient,
+ u8 offset, u8 bytes, void *resp)
+{
+ struct ucsi *ucsi = con->ucsi;
+ u64 command;
+ int ret;
+
+ command = UCSI_COMMAND(UCSI_GET_PD_MESSAGE) |
+ UCSI_CONNECTOR_NUMBER(con->num);
+ command |= UCSI_GET_PD_MESSAGE_RECIPIENT(recipient);
+ command |= UCSI_GET_PD_MESSAGE_OFFSET(offset);
+ command |= UCSI_GET_PD_MESSAGE_BYTES(bytes);
+ command |= UCSI_GET_PD_MESSAGE_TYPE(UCSI_GET_PD_MESSAGE_TYPE_IDENTITY);
+
+ ret = ucsi_send_command(ucsi, command, resp, bytes);
+ if (ret < 0)
+ dev_err(ucsi->dev, "UCSI_GET_PD_MESSAGE failed (%d)\n", ret);
+
+ return ret;
+}
+
+static int ucsi_get_identity(struct ucsi_connector *con, u8 recipient,
+ struct usb_pd_identity *id)
+{
+ struct ucsi *ucsi = con->ucsi;
+ struct ucsi_pd_message_disc_id resp = {};
+ int ret;
+
+ if (ucsi->version < UCSI_VERSION_2_0) {
+ /*
+ * Before UCSI v2.0, MESSAGE_IN is 16 bytes which cannot fit
+ * the 28 byte identity response including the VDM header.
+ * First request the VDM header, ID Header VDO, Cert Stat VDO
+ * and Product VDO.
+ */
+ ret = ucsi_read_identity(con, recipient, 0, 0x10, &resp);
+ if (ret < 0)
+ return ret;
+
+
+ /* Then request Product Type VDO1 through Product Type VDO3. */
+ ret = ucsi_read_identity(con, recipient, 0x10, 0xc,
+ &resp.vdo[0]);
+ if (ret < 0)
+ return ret;
+
+ } else {
+ /*
+ * In UCSI v2.0 and after, MESSAGE_IN is large enough to request
+ * the large enough to request the full Discover Identity
+ * response at once.
+ */
+ ret = ucsi_read_identity(con, recipient, 0x0, 0x1c, &resp);
+ if (ret < 0)
+ return ret;
+ }
+
+ id->id_header = resp.id_header;
+ id->cert_stat = resp.cert_stat;
+ id->product = resp.product;
+ id->vdo[0] = resp.vdo[0];
+ id->vdo[1] = resp.vdo[1];
+ id->vdo[2] = resp.vdo[2];
+ return 0;
+}
+
+static int ucsi_get_partner_identity(struct ucsi_connector *con)
+{
+ int ret;
+
+ ret = ucsi_get_identity(con, UCSI_RECIPIENT_SOP,
+ &con->partner_identity);
+ if (ret < 0)
+ return ret;
+
+ ret = typec_partner_set_identity(con->partner);
+ if (ret < 0) {
+ dev_err(con->ucsi->dev, "Failed to set partner identity (%d)\n",
+ ret);
+ }
+
+ return ret;
+}
+
+static int ucsi_get_cable_identity(struct ucsi_connector *con)
+{
+ int ret;
+
+ ret = ucsi_get_identity(con, UCSI_RECIPIENT_SOP_P,
+ &con->cable_identity);
+ if (ret < 0)
+ return ret;
+
+ ret = typec_cable_set_identity(con->cable);
+ if (ret < 0) {
+ dev_err(con->ucsi->dev, "Failed to set cable identity (%d)\n",
+ ret);
+ }
+
+ return ret;
+}
+
static int ucsi_check_altmodes(struct ucsi_connector *con)
{
int ret, num_partner_am;
@@ -754,6 +856,7 @@ static int ucsi_register_cable(struct ucsi_connector *con)
break;
}
+ desc.identity = &con->cable_identity;
desc.active = !!(UCSI_CABLE_PROP_FLAG_ACTIVE_CABLE &
con->cable_prop.flags);
desc.pd_revision = UCSI_CABLE_PROP_FLAG_PD_MAJOR_REV_AS_BCD(
@@ -777,6 +880,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con)
return;
typec_unregister_cable(con->cable);
+ memset(&con->cable_identity, 0, sizeof(con->cable_identity));
con->cable = NULL;
}
@@ -827,6 +931,7 @@ static int ucsi_register_partner(struct ucsi_connector *con)
break;
}
+ desc.identity = &con->partner_identity;
desc.usb_pd = pwr_opmode == UCSI_CONSTAT_PWR_OPMODE_PD;
desc.pd_revision = UCSI_CONCAP_FLAG_PARTNER_PD_MAJOR_REV_AS_BCD(con->cap.flags);
@@ -855,6 +960,7 @@ static void ucsi_unregister_partner(struct ucsi_connector *con)
ucsi_unregister_altmodes(con, UCSI_RECIPIENT_SOP);
ucsi_unregister_cable(con);
typec_unregister_partner(con->partner);
+ memset(&con->partner_identity, 0, sizeof(con->partner_identity));
con->partner = NULL;
}
@@ -975,6 +1081,10 @@ static int ucsi_check_cable(struct ucsi_connector *con)
if (ret < 0)
return ret;
+ ret = ucsi_get_cable_identity(con);
+ if (ret < 0)
+ return ret;
+
return 0;
}
@@ -1019,6 +1129,7 @@ static void ucsi_handle_connector_change(struct work_struct *work)
ucsi_register_partner(con);
ucsi_partner_task(con, ucsi_check_connection, 1, HZ);
ucsi_partner_task(con, ucsi_check_connector_capability, 1, HZ);
+ ucsi_partner_task(con, ucsi_get_partner_identity, 1, HZ);
ucsi_partner_task(con, ucsi_check_cable, 1, HZ);
if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) ==
@@ -1418,6 +1529,7 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
ucsi_register_partner(con);
ucsi_pwr_opmode_change(con);
ucsi_port_psy_changed(con);
+ ucsi_get_partner_identity(con);
ucsi_check_cable(con);
}
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index f0aabef0b7c64..b89fae82e8ce7 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -106,6 +106,7 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
#define UCSI_GET_CABLE_PROPERTY 0x11
#define UCSI_GET_CONNECTOR_STATUS 0x12
#define UCSI_GET_ERROR_STATUS 0x13
+#define UCSI_GET_PD_MESSAGE 0x15
#define UCSI_CONNECTOR_NUMBER(_num_) ((u64)(_num_) << 16)
#define UCSI_COMMAND(_cmd_) ((_cmd_) & 0xff)
@@ -159,6 +160,18 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
#define UCSI_MAX_PDOS (4)
#define UCSI_GET_PDOS_SRC_PDOS ((u64)1 << 34)
+/* GET_PD_MESSAGE command bits */
+#define UCSI_GET_PD_MESSAGE_RECIPIENT(_r_) ((u64)(_r_) << 23)
+#define UCSI_GET_PD_MESSAGE_OFFSET(_r_) ((u64)(_r_) << 26)
+#define UCSI_GET_PD_MESSAGE_BYTES(_r_) ((u64)(_r_) << 34)
+#define UCSI_GET_PD_MESSAGE_TYPE(_r_) ((u64)(_r_) << 42)
+#define UCSI_GET_PD_MESSAGE_TYPE_SNK_CAP_EXT 0
+#define UCSI_GET_PD_MESSAGE_TYPE_SRC_CAP_EXT 1
+#define UCSI_GET_PD_MESSAGE_TYPE_BAT_CAP 2
+#define UCSI_GET_PD_MESSAGE_TYPE_BAT_STAT 3
+#define UCSI_GET_PD_MESSAGE_TYPE_IDENTITY 4
+#define UCSI_GET_PD_MESSAGE_TYPE_REVISION 5
+
/* -------------------------------------------------------------------------- */
/* Error information returned by PPM in response to GET_ERROR_STATUS command. */
@@ -338,6 +351,18 @@ struct ucsi_connector_status {
((get_unaligned_le32(&(_p_)[5]) & GENMASK(16, 1)) >> 1)
} __packed;
+/*
+ * Data structure filled by PPM in response to GET_PD_MESSAGE command with the
+ * Response Message Type set to Discover Identity Response.
+ */
+struct ucsi_pd_message_disc_id {
+ u32 vdm_header;
+ u32 id_header;
+ u32 cert_stat;
+ u32 product;
+ u32 vdo[3];
+} __packed;
+
/* -------------------------------------------------------------------------- */
struct ucsi_debugfs_entry {
@@ -428,6 +453,10 @@ struct ucsi_connector {
struct usb_power_delivery_capabilities *partner_sink_caps;
struct usb_role_switch *usb_role_sw;
+
+ /* USB PD identity */
+ struct usb_pd_identity partner_identity;
+ struct usb_pd_identity cable_identity;
};
int ucsi_send_command(struct ucsi *ucsi, u64 command,
--
2.44.0.rc1.240.g4c46232300-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug
2024-03-05 2:58 [PATCH v4 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies
` (2 preceding siblings ...)
2024-03-05 2:58 ` [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies
@ 2024-03-05 2:58 ` Jameson Thies
3 siblings, 0 replies; 13+ messages in thread
From: Jameson Thies @ 2024-03-05 2:58 UTC (permalink / raw)
To: heikki.krogerus, linux-usb
Cc: jthies, pmalani, bleung, abhishekpandit, andersson,
dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede,
neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel,
Benson Leung
Register SOP' alternate modes with a Type-C Connector Class cable plug.
Alternate modes are queried from the PPM using the GET_ALTERNATE_MODES
command with recipient set to SOP'.
Reviewed-by: Benson Leung <bleung@chromium.org>
Reviewed-by: Prashant Malani <pmalani@chromium.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Jameson Thies <jthies@google.com>
---
SOP' GET_ALTERNATE_MODE responses from the PPM are correctly registered
to the cable plug.
nospike-rev4 /sys/class/typec # ls port0-cable/port0-plug0/
device port0-plug0.0 port0-plug0.1 power subsystem uevent
Changes in v4:
- None.
Changes in v3:
- None.
Changes in v2:
- Shortened lines to within 80 characters.
- Tested on usb-testing branch merged with chromeOS 6.8-rc2 kernel.
drivers/usb/typec/ucsi/ucsi.c | 60 +++++++++++++++++++++++++++++++++++
drivers/usb/typec/ucsi/ucsi.h | 2 ++
2 files changed, 62 insertions(+)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 3b64a0f51041c..cf52cb34d2859 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -399,6 +399,27 @@ static int ucsi_register_altmode(struct ucsi_connector *con,
con->partner_altmode[i] = alt;
break;
+ case UCSI_RECIPIENT_SOP_P:
+ i = ucsi_next_altmode(con->plug_altmode);
+ if (i < 0) {
+ ret = i;
+ goto err;
+ }
+
+ ret = ucsi_altmode_next_mode(con->plug_altmode, desc->svid);
+ if (ret < 0)
+ return ret;
+
+ desc->mode = ret;
+
+ alt = typec_plug_register_altmode(con->plug, desc);
+ if (IS_ERR(alt)) {
+ ret = PTR_ERR(alt);
+ goto err;
+ }
+
+ con->plug_altmode[i] = alt;
+ break;
default:
return -EINVAL;
}
@@ -566,6 +587,9 @@ static void ucsi_unregister_altmodes(struct ucsi_connector *con, u8 recipient)
case UCSI_RECIPIENT_SOP:
adev = con->partner_altmode;
break;
+ case UCSI_RECIPIENT_SOP_P:
+ adev = con->plug_altmode;
+ break;
default:
return;
}
@@ -836,6 +860,33 @@ static void ucsi_unregister_partner_pdos(struct ucsi_connector *con)
con->partner_pd = NULL;
}
+static int ucsi_register_plug(struct ucsi_connector *con)
+{
+ struct typec_plug *plug;
+ struct typec_plug_desc desc = {.index = TYPEC_PLUG_SOP_P};
+
+ plug = typec_register_plug(con->cable, &desc);
+ if (IS_ERR(plug)) {
+ dev_err(con->ucsi->dev,
+ "con%d: failed to register plug (%ld)\n", con->num,
+ PTR_ERR(plug));
+ return PTR_ERR(plug);
+ }
+
+ con->plug = plug;
+ return 0;
+}
+
+static void ucsi_unregister_plug(struct ucsi_connector *con)
+{
+ if (!con->plug)
+ return;
+
+ ucsi_unregister_altmodes(con, UCSI_RECIPIENT_SOP_P);
+ typec_unregister_plug(con->plug);
+ con->plug = NULL;
+}
+
static int ucsi_register_cable(struct ucsi_connector *con)
{
struct typec_cable *cable;
@@ -879,6 +930,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con)
if (!con->cable)
return;
+ ucsi_unregister_plug(con);
typec_unregister_cable(con->cable);
memset(&con->cable_identity, 0, sizeof(con->cable_identity));
con->cable = NULL;
@@ -1085,6 +1137,14 @@ static int ucsi_check_cable(struct ucsi_connector *con)
if (ret < 0)
return ret;
+ ret = ucsi_register_plug(con);
+ if (ret < 0)
+ return ret;
+
+ ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP_P);
+ if (ret < 0)
+ return ret;
+
return 0;
}
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index b89fae82e8ce7..32daf5f586505 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -429,9 +429,11 @@ struct ucsi_connector {
struct typec_port *port;
struct typec_partner *partner;
struct typec_cable *cable;
+ struct typec_plug *plug;
struct typec_altmode *port_altmode[UCSI_MAX_ALTMODES];
struct typec_altmode *partner_altmode[UCSI_MAX_ALTMODES];
+ struct typec_altmode *plug_altmode[UCSI_MAX_ALTMODES];
struct typec_capability typec_cap;
--
2.44.0.rc1.240.g4c46232300-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses
2024-03-05 2:58 ` [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies
@ 2024-03-05 3:06 ` Benson Leung
2024-03-05 18:54 ` Prashant Malani
1 sibling, 0 replies; 13+ messages in thread
From: Benson Leung @ 2024-03-05 3:06 UTC (permalink / raw)
To: Jameson Thies
Cc: heikki.krogerus, linux-usb, pmalani, abhishekpandit, andersson,
dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede,
neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 9459 bytes --]
Hi Jameson,
On Tue, Mar 05, 2024 at 02:58:03AM +0000, Jameson Thies wrote:
> Register SOP and SOP' Discover Identity responses with the USB Type-C
> Connector Class as partner and cable identities, respectively. Discover
> Identity responses are requested from the PPM using the GET_PD_MESSAGE
> UCSI command.
>
> Signed-off-by: Jameson Thies <jthies@google.com>
Reviewed-by: Benson Leung <bleung@chromium.org>
> ---
> GET_PD_MESSAGE responses from the PPM populate partner and cable
> identity in sysfs:
> nospike-rev4 /sys/class/typec # ls port0-partner/identity/
> cert_stat id_header product product_type_vdo1 product_type_vdo2
> product_type_vdo3
> nospike-rev4 /sys/class/typec # ls port0-cable/identity/
> cert_stat id_header product product_type_vdo1 product_type_vdo2
> product_type_vdo3
>
> Changes in v4:
> - Cleaned up redundent ucsi_send_command calls for discovering identity.
>
> Changes in v3:
> - None.
>
> Changes in v2:
> - Re-ordered memset call and null assignment when unregistering partners
> and cables.
> - Supports registering partner and cable identity with UCSI versions
> before v2.0.
> - Shortened lines to within 80 characters with the exception of two
> error log lines with three indentations.
> - Tested on usb-testing branch merged with chromeOS 6.8-rc2 kernel.
>
> drivers/usb/typec/ucsi/ucsi.c | 112 ++++++++++++++++++++++++++++++++++
> drivers/usb/typec/ucsi/ucsi.h | 29 +++++++++
> 2 files changed, 141 insertions(+)
>
> diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
> index 7c84687b5d1a3..3b64a0f51041c 100644
> --- a/drivers/usb/typec/ucsi/ucsi.c
> +++ b/drivers/usb/typec/ucsi/ucsi.c
> @@ -646,6 +646,108 @@ static int ucsi_get_src_pdos(struct ucsi_connector *con)
> return ret;
> }
>
> +static int ucsi_read_identity(struct ucsi_connector *con, u8 recipient,
> + u8 offset, u8 bytes, void *resp)
> +{
> + struct ucsi *ucsi = con->ucsi;
> + u64 command;
> + int ret;
> +
> + command = UCSI_COMMAND(UCSI_GET_PD_MESSAGE) |
> + UCSI_CONNECTOR_NUMBER(con->num);
> + command |= UCSI_GET_PD_MESSAGE_RECIPIENT(recipient);
> + command |= UCSI_GET_PD_MESSAGE_OFFSET(offset);
> + command |= UCSI_GET_PD_MESSAGE_BYTES(bytes);
> + command |= UCSI_GET_PD_MESSAGE_TYPE(UCSI_GET_PD_MESSAGE_TYPE_IDENTITY);
> +
> + ret = ucsi_send_command(ucsi, command, resp, bytes);
> + if (ret < 0)
> + dev_err(ucsi->dev, "UCSI_GET_PD_MESSAGE failed (%d)\n", ret);
> +
> + return ret;
> +}
> +
> +static int ucsi_get_identity(struct ucsi_connector *con, u8 recipient,
> + struct usb_pd_identity *id)
> +{
> + struct ucsi *ucsi = con->ucsi;
> + struct ucsi_pd_message_disc_id resp = {};
> + int ret;
> +
> + if (ucsi->version < UCSI_VERSION_2_0) {
> + /*
> + * Before UCSI v2.0, MESSAGE_IN is 16 bytes which cannot fit
> + * the 28 byte identity response including the VDM header.
> + * First request the VDM header, ID Header VDO, Cert Stat VDO
> + * and Product VDO.
> + */
> + ret = ucsi_read_identity(con, recipient, 0, 0x10, &resp);
> + if (ret < 0)
> + return ret;
> +
> +
> + /* Then request Product Type VDO1 through Product Type VDO3. */
> + ret = ucsi_read_identity(con, recipient, 0x10, 0xc,
> + &resp.vdo[0]);
> + if (ret < 0)
> + return ret;
> +
> + } else {
> + /*
> + * In UCSI v2.0 and after, MESSAGE_IN is large enough to request
> + * the large enough to request the full Discover Identity
> + * response at once.
> + */
> + ret = ucsi_read_identity(con, recipient, 0x0, 0x1c, &resp);
> + if (ret < 0)
> + return ret;
> + }
> +
> + id->id_header = resp.id_header;
> + id->cert_stat = resp.cert_stat;
> + id->product = resp.product;
> + id->vdo[0] = resp.vdo[0];
> + id->vdo[1] = resp.vdo[1];
> + id->vdo[2] = resp.vdo[2];
> + return 0;
> +}
> +
> +static int ucsi_get_partner_identity(struct ucsi_connector *con)
> +{
> + int ret;
> +
> + ret = ucsi_get_identity(con, UCSI_RECIPIENT_SOP,
> + &con->partner_identity);
> + if (ret < 0)
> + return ret;
> +
> + ret = typec_partner_set_identity(con->partner);
> + if (ret < 0) {
> + dev_err(con->ucsi->dev, "Failed to set partner identity (%d)\n",
> + ret);
> + }
> +
> + return ret;
> +}
> +
> +static int ucsi_get_cable_identity(struct ucsi_connector *con)
> +{
> + int ret;
> +
> + ret = ucsi_get_identity(con, UCSI_RECIPIENT_SOP_P,
> + &con->cable_identity);
> + if (ret < 0)
> + return ret;
> +
> + ret = typec_cable_set_identity(con->cable);
> + if (ret < 0) {
> + dev_err(con->ucsi->dev, "Failed to set cable identity (%d)\n",
> + ret);
> + }
> +
> + return ret;
> +}
> +
> static int ucsi_check_altmodes(struct ucsi_connector *con)
> {
> int ret, num_partner_am;
> @@ -754,6 +856,7 @@ static int ucsi_register_cable(struct ucsi_connector *con)
> break;
> }
>
> + desc.identity = &con->cable_identity;
> desc.active = !!(UCSI_CABLE_PROP_FLAG_ACTIVE_CABLE &
> con->cable_prop.flags);
> desc.pd_revision = UCSI_CABLE_PROP_FLAG_PD_MAJOR_REV_AS_BCD(
> @@ -777,6 +880,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con)
> return;
>
> typec_unregister_cable(con->cable);
> + memset(&con->cable_identity, 0, sizeof(con->cable_identity));
> con->cable = NULL;
> }
>
> @@ -827,6 +931,7 @@ static int ucsi_register_partner(struct ucsi_connector *con)
> break;
> }
>
> + desc.identity = &con->partner_identity;
> desc.usb_pd = pwr_opmode == UCSI_CONSTAT_PWR_OPMODE_PD;
> desc.pd_revision = UCSI_CONCAP_FLAG_PARTNER_PD_MAJOR_REV_AS_BCD(con->cap.flags);
>
> @@ -855,6 +960,7 @@ static void ucsi_unregister_partner(struct ucsi_connector *con)
> ucsi_unregister_altmodes(con, UCSI_RECIPIENT_SOP);
> ucsi_unregister_cable(con);
> typec_unregister_partner(con->partner);
> + memset(&con->partner_identity, 0, sizeof(con->partner_identity));
> con->partner = NULL;
> }
>
> @@ -975,6 +1081,10 @@ static int ucsi_check_cable(struct ucsi_connector *con)
> if (ret < 0)
> return ret;
>
> + ret = ucsi_get_cable_identity(con);
> + if (ret < 0)
> + return ret;
> +
> return 0;
> }
>
> @@ -1019,6 +1129,7 @@ static void ucsi_handle_connector_change(struct work_struct *work)
> ucsi_register_partner(con);
> ucsi_partner_task(con, ucsi_check_connection, 1, HZ);
> ucsi_partner_task(con, ucsi_check_connector_capability, 1, HZ);
> + ucsi_partner_task(con, ucsi_get_partner_identity, 1, HZ);
> ucsi_partner_task(con, ucsi_check_cable, 1, HZ);
>
> if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) ==
> @@ -1418,6 +1529,7 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
> ucsi_register_partner(con);
> ucsi_pwr_opmode_change(con);
> ucsi_port_psy_changed(con);
> + ucsi_get_partner_identity(con);
> ucsi_check_cable(con);
> }
>
> diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
> index f0aabef0b7c64..b89fae82e8ce7 100644
> --- a/drivers/usb/typec/ucsi/ucsi.h
> +++ b/drivers/usb/typec/ucsi/ucsi.h
> @@ -106,6 +106,7 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
> #define UCSI_GET_CABLE_PROPERTY 0x11
> #define UCSI_GET_CONNECTOR_STATUS 0x12
> #define UCSI_GET_ERROR_STATUS 0x13
> +#define UCSI_GET_PD_MESSAGE 0x15
>
> #define UCSI_CONNECTOR_NUMBER(_num_) ((u64)(_num_) << 16)
> #define UCSI_COMMAND(_cmd_) ((_cmd_) & 0xff)
> @@ -159,6 +160,18 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
> #define UCSI_MAX_PDOS (4)
> #define UCSI_GET_PDOS_SRC_PDOS ((u64)1 << 34)
>
> +/* GET_PD_MESSAGE command bits */
> +#define UCSI_GET_PD_MESSAGE_RECIPIENT(_r_) ((u64)(_r_) << 23)
> +#define UCSI_GET_PD_MESSAGE_OFFSET(_r_) ((u64)(_r_) << 26)
> +#define UCSI_GET_PD_MESSAGE_BYTES(_r_) ((u64)(_r_) << 34)
> +#define UCSI_GET_PD_MESSAGE_TYPE(_r_) ((u64)(_r_) << 42)
> +#define UCSI_GET_PD_MESSAGE_TYPE_SNK_CAP_EXT 0
> +#define UCSI_GET_PD_MESSAGE_TYPE_SRC_CAP_EXT 1
> +#define UCSI_GET_PD_MESSAGE_TYPE_BAT_CAP 2
> +#define UCSI_GET_PD_MESSAGE_TYPE_BAT_STAT 3
> +#define UCSI_GET_PD_MESSAGE_TYPE_IDENTITY 4
> +#define UCSI_GET_PD_MESSAGE_TYPE_REVISION 5
> +
> /* -------------------------------------------------------------------------- */
>
> /* Error information returned by PPM in response to GET_ERROR_STATUS command. */
> @@ -338,6 +351,18 @@ struct ucsi_connector_status {
> ((get_unaligned_le32(&(_p_)[5]) & GENMASK(16, 1)) >> 1)
> } __packed;
>
> +/*
> + * Data structure filled by PPM in response to GET_PD_MESSAGE command with the
> + * Response Message Type set to Discover Identity Response.
> + */
> +struct ucsi_pd_message_disc_id {
> + u32 vdm_header;
> + u32 id_header;
> + u32 cert_stat;
> + u32 product;
> + u32 vdo[3];
> +} __packed;
> +
> /* -------------------------------------------------------------------------- */
>
> struct ucsi_debugfs_entry {
> @@ -428,6 +453,10 @@ struct ucsi_connector {
> struct usb_power_delivery_capabilities *partner_sink_caps;
>
> struct usb_role_switch *usb_role_sw;
> +
> + /* USB PD identity */
> + struct usb_pd_identity partner_identity;
> + struct usb_pd_identity cable_identity;
> };
>
> int ucsi_send_command(struct ucsi *ucsi, u64 command,
> --
> 2.44.0.rc1.240.g4c46232300-goog
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses
2024-03-05 2:58 ` [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies
2024-03-05 3:06 ` Benson Leung
@ 2024-03-05 18:54 ` Prashant Malani
2024-03-27 11:18 ` Heikki Krogerus
1 sibling, 1 reply; 13+ messages in thread
From: Prashant Malani @ 2024-03-05 18:54 UTC (permalink / raw)
To: Jameson Thies
Cc: heikki.krogerus, linux-usb, bleung, abhishekpandit, andersson,
dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede,
neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel
On Mar 05 02:58, Jameson Thies wrote:
> Register SOP and SOP' Discover Identity responses with the USB Type-C
> Connector Class as partner and cable identities, respectively. Discover
> Identity responses are requested from the PPM using the GET_PD_MESSAGE
> UCSI command.
>
> Signed-off-by: Jameson Thies <jthies@google.com>
Mostly line splitting nits (which I have listed below). Once those are
addressed, please feel free to add:
Reviewed-by: Prashant Malani <pmalani@chromium.org>
> diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
> index 7c84687b5d1a3..3b64a0f51041c 100644
> --- a/drivers/usb/typec/ucsi/ucsi.c
> +++ b/drivers/usb/typec/ucsi/ucsi.c
> @@ -646,6 +646,108 @@ static int ucsi_get_src_pdos(struct ucsi_connector *con)
> return ret;
> }
>
> +static int ucsi_read_identity(struct ucsi_connector *con, u8 recipient,
> + u8 offset, u8 bytes, void *resp)
> +{
> + struct ucsi *ucsi = con->ucsi;
> + u64 command;
> + int ret;
> +
> + command = UCSI_COMMAND(UCSI_GET_PD_MESSAGE) |
> + UCSI_CONNECTOR_NUMBER(con->num);
> + command |= UCSI_GET_PD_MESSAGE_RECIPIENT(recipient);
> + command |= UCSI_GET_PD_MESSAGE_OFFSET(offset);
> + command |= UCSI_GET_PD_MESSAGE_BYTES(bytes);
> + command |= UCSI_GET_PD_MESSAGE_TYPE(UCSI_GET_PD_MESSAGE_TYPE_IDENTITY);
> +
> + ret = ucsi_send_command(ucsi, command, resp, bytes);
> + if (ret < 0)
> + dev_err(ucsi->dev, "UCSI_GET_PD_MESSAGE failed (%d)\n", ret);
> +
> + return ret;
> +}
> +
> +static int ucsi_get_identity(struct ucsi_connector *con, u8 recipient,
> + struct usb_pd_identity *id)
nit: Line limits are 100 now [1], so this can fit on one line.
> +{
> + struct ucsi *ucsi = con->ucsi;
> + struct ucsi_pd_message_disc_id resp = {};
> + int ret;
> +
> + if (ucsi->version < UCSI_VERSION_2_0) {
> + /*
> + * Before UCSI v2.0, MESSAGE_IN is 16 bytes which cannot fit
> + * the 28 byte identity response including the VDM header.
> + * First request the VDM header, ID Header VDO, Cert Stat VDO
> + * and Product VDO.
> + */
> + ret = ucsi_read_identity(con, recipient, 0, 0x10, &resp);
> + if (ret < 0)
> + return ret;
> +
> +
> + /* Then request Product Type VDO1 through Product Type VDO3. */
> + ret = ucsi_read_identity(con, recipient, 0x10, 0xc,
> + &resp.vdo[0]);
nit: Can fit on one line.
> + if (ret < 0)
> + return ret;
> +
> + } else {
> + /*
> + * In UCSI v2.0 and after, MESSAGE_IN is large enough to request
> + * the large enough to request the full Discover Identity
> + * response at once.
> + */
> + ret = ucsi_read_identity(con, recipient, 0x0, 0x1c, &resp);
> + if (ret < 0)
> + return ret;
> + }
> +
> + id->id_header = resp.id_header;
> + id->cert_stat = resp.cert_stat;
> + id->product = resp.product;
> + id->vdo[0] = resp.vdo[0];
> + id->vdo[1] = resp.vdo[1];
> + id->vdo[2] = resp.vdo[2];
> + return 0;
> +}
> +
> +static int ucsi_get_partner_identity(struct ucsi_connector *con)
> +{
> + int ret;
> +
> + ret = ucsi_get_identity(con, UCSI_RECIPIENT_SOP,
> + &con->partner_identity);
nit: One line please.
> + if (ret < 0)
> + return ret;
> +
> + ret = typec_partner_set_identity(con->partner);
> + if (ret < 0) {
> + dev_err(con->ucsi->dev, "Failed to set partner identity (%d)\n",
> + ret);
nit: One line (100 is the limit now).
> + }
> +
> + return ret;
> +}
> +
> +static int ucsi_get_cable_identity(struct ucsi_connector *con)
> +{
> + int ret;
> +
> + ret = ucsi_get_identity(con, UCSI_RECIPIENT_SOP_P,
> + &con->cable_identity);
nit: One line.
> + if (ret < 0)
> + return ret;
> +
> + ret = typec_cable_set_identity(con->cable);
> + if (ret < 0) {
> + dev_err(con->ucsi->dev, "Failed to set cable identity (%d)\n",
> + ret);
nit: One line.
Best regards,
-Prashant
[1] https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl#L59
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
2024-03-05 2:58 ` [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies
@ 2024-03-11 17:28 ` neil.armstrong
2024-03-11 23:47 ` Jameson Thies
2024-03-26 22:09 ` Bjorn Andersson
0 siblings, 2 replies; 13+ messages in thread
From: neil.armstrong @ 2024-03-11 17:28 UTC (permalink / raw)
To: Jameson Thies, heikki.krogerus, linux-usb
Cc: pmalani, bleung, abhishekpandit, andersson, dmitry.baryshkov,
fabrice.gasnier, gregkh, hdegoede, rajaram.regupathy,
saranya.gopal, linux-kernel, Benson Leung,
Linux regressions mailing list
Hi,
On 05/03/2024 03:58, Jameson Thies wrote:
> Register cables with the Type-C Connector Class in the UCSI driver based
> on the PPM response to GET_CABLE_PROPERTY. Registered cable properties
> include plug type, cable type and major revision.
>
> Reviewed-by: Benson Leung <bleung@chromium.org>
> Reviewed-by: Prashant Malani <pmalani@chromium.org>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Signed-off-by: Jameson Thies <jthies@google.com>
> ---
> Expected cable properties populate the USB Type-C connector class sysfs
> paths:
> nospike-rev4 /sys/class/typec # ls port0-cable
> device identity plug_type port0-plug0 power subsystem type uevent
> usb_power_delivery_revision
>
> Changes in v4:
> - None.
>
> Changes in v3:
> - None.
>
> Changes in v2:
> - Shortened lines to within 80 characters.
> - Tested on usb-testing branch merged with chromeOS 6.8-rc2 kernel.
>
> drivers/usb/typec/ucsi/ucsi.c | 73 +++++++++++++++++++++++++++++++++++
> drivers/usb/typec/ucsi/ucsi.h | 5 +++
> 2 files changed, 78 insertions(+)
Since those were merged, I see the following errors on SM8550-QRD and SM8650-QRD running linux-next:
[ 8.668966] ucsi_glink.pmic_glink_ucsi pmic_glink.ucsi.0: UCSI_GET_PD_MESSAGE failed (-95)
[ 11.170560] ucsi_glink.pmic_glink_ucsi pmic_glink.ucsi.0: GET_CABLE_PROPERTY failed (-95)
[ 16.361678] ucsi_glink.pmic_glink_ucsi pmic_glink.ucsi.0: timeout waiting for UCSI sync write response
[ 21.409633] ucsi_glink.pmic_glink_ucsi pmic_glink.ucsi.0: error -ETIMEDOUT: PPM init failed
perhaps you should check the GET_CAPABILITY.bmOptionalFeatures bit 5 (Cable details supported) and 8 (GET_PD_MESSAGE supported)
before sending UCSI_GET_PD_MESSAGE and GET_CABLE_PROPERTY messages ?
With:
=================><====================================
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index cf52cb34d285..eec64a4c8cdd 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -1189,8 +1189,10 @@ static void ucsi_handle_connector_change(struct work_struct *work)
ucsi_register_partner(con);
ucsi_partner_task(con, ucsi_check_connection, 1, HZ);
ucsi_partner_task(con, ucsi_check_connector_capability, 1, HZ);
- ucsi_partner_task(con, ucsi_get_partner_identity, 1, HZ);
- ucsi_partner_task(con, ucsi_check_cable, 1, HZ);
+ if (con->ucsi->cap.features & UCSI_CAP_GET_PD_MESSAGE)
+ ucsi_partner_task(con, ucsi_get_partner_identity, 1, HZ);
+ if (con->ucsi->cap.features & UCSI_CAP_CABLE_DETAILS)
+ ucsi_partner_task(con, ucsi_check_cable, 1, HZ);
if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) ==
UCSI_CONSTAT_PWR_OPMODE_PD)
@@ -1589,8 +1591,10 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
ucsi_register_partner(con);
ucsi_pwr_opmode_change(con);
ucsi_port_psy_changed(con);
- ucsi_get_partner_identity(con);
- ucsi_check_cable(con);
+ if (con->ucsi->cap.features & UCSI_CAP_GET_PD_MESSAGE)
+ ucsi_get_partner_identity(con);
+ if (con->ucsi->cap.features & UCSI_CAP_CABLE_DETAILS)
+ ucsi_check_cable(con);
}
/* Only notify USB controller if partner supports USB data */
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 32daf5f58650..2e9c35a3af27 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -215,6 +215,7 @@ struct ucsi_capability {
#define UCSI_CAP_CABLE_DETAILS BIT(5)
#define UCSI_CAP_EXT_SUPPLY_NOTIFICATIONS BIT(6)
#define UCSI_CAP_PD_RESET BIT(7)
+#define UCSI_CAP_GET_PD_MESSAGE BIT(8)
u16 reserved_1;
u8 num_alt_modes;
u8 reserved_2;
=================><====================================
it works fine again.
#regzbot introduced: 38ca416597b0
Thanks,
Neil
>
> diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
> index ae105383e69e7..7c84687b5d1a3 100644
> --- a/drivers/usb/typec/ucsi/ucsi.c
> +++ b/drivers/usb/typec/ucsi/ucsi.c
> @@ -734,6 +734,52 @@ static void ucsi_unregister_partner_pdos(struct ucsi_connector *con)
> con->partner_pd = NULL;
> }
>
> +static int ucsi_register_cable(struct ucsi_connector *con)
> +{
> + struct typec_cable *cable;
> + struct typec_cable_desc desc = {};
> +
> + switch (UCSI_CABLE_PROP_FLAG_PLUG_TYPE(con->cable_prop.flags)) {
> + case UCSI_CABLE_PROPERTY_PLUG_TYPE_A:
> + desc.type = USB_PLUG_TYPE_A;
> + break;
> + case UCSI_CABLE_PROPERTY_PLUG_TYPE_B:
> + desc.type = USB_PLUG_TYPE_B;
> + break;
> + case UCSI_CABLE_PROPERTY_PLUG_TYPE_C:
> + desc.type = USB_PLUG_TYPE_C;
> + break;
> + default:
> + desc.type = USB_PLUG_NONE;
> + break;
> + }
> +
> + desc.active = !!(UCSI_CABLE_PROP_FLAG_ACTIVE_CABLE &
> + con->cable_prop.flags);
> + desc.pd_revision = UCSI_CABLE_PROP_FLAG_PD_MAJOR_REV_AS_BCD(
> + con->cable_prop.flags);
> +
> + cable = typec_register_cable(con->port, &desc);
> + if (IS_ERR(cable)) {
> + dev_err(con->ucsi->dev,
> + "con%d: failed to register cable (%ld)\n", con->num,
> + PTR_ERR(cable));
> + return PTR_ERR(cable);
> + }
> +
> + con->cable = cable;
> + return 0;
> +}
> +
> +static void ucsi_unregister_cable(struct ucsi_connector *con)
> +{
> + if (!con->cable)
> + return;
> +
> + typec_unregister_cable(con->cable);
> + con->cable = NULL;
> +}
> +
> static void ucsi_pwr_opmode_change(struct ucsi_connector *con)
> {
> switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
> @@ -807,6 +853,7 @@ static void ucsi_unregister_partner(struct ucsi_connector *con)
> typec_partner_set_usb_power_delivery(con->partner, NULL);
> ucsi_unregister_partner_pdos(con);
> ucsi_unregister_altmodes(con, UCSI_RECIPIENT_SOP);
> + ucsi_unregister_cable(con);
> typec_unregister_partner(con->partner);
> con->partner = NULL;
> }
> @@ -907,6 +954,30 @@ static int ucsi_check_connection(struct ucsi_connector *con)
> return 0;
> }
>
> +static int ucsi_check_cable(struct ucsi_connector *con)
> +{
> + u64 command;
> + int ret;
> +
> + if (con->cable)
> + return 0;
> +
> + command = UCSI_GET_CABLE_PROPERTY | UCSI_CONNECTOR_NUMBER(con->num);
> + ret = ucsi_send_command(con->ucsi, command, &con->cable_prop,
> + sizeof(con->cable_prop));
> + if (ret < 0) {
> + dev_err(con->ucsi->dev, "GET_CABLE_PROPERTY failed (%d)\n",
> + ret);
> + return ret;
> + }
> +
> + ret = ucsi_register_cable(con);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> static void ucsi_handle_connector_change(struct work_struct *work)
> {
> struct ucsi_connector *con = container_of(work, struct ucsi_connector,
> @@ -948,6 +1019,7 @@ static void ucsi_handle_connector_change(struct work_struct *work)
> ucsi_register_partner(con);
> ucsi_partner_task(con, ucsi_check_connection, 1, HZ);
> ucsi_partner_task(con, ucsi_check_connector_capability, 1, HZ);
> + ucsi_partner_task(con, ucsi_check_cable, 1, HZ);
>
> if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) ==
> UCSI_CONSTAT_PWR_OPMODE_PD)
> @@ -1346,6 +1418,7 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
> ucsi_register_partner(con);
> ucsi_pwr_opmode_change(con);
> ucsi_port_psy_changed(con);
> + ucsi_check_cable(con);
> }
>
> /* Only notify USB controller if partner supports USB data */
> diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
> index 469a2baf472e4..f0aabef0b7c64 100644
> --- a/drivers/usb/typec/ucsi/ucsi.h
> +++ b/drivers/usb/typec/ucsi/ucsi.h
> @@ -265,6 +265,9 @@ struct ucsi_cable_property {
> #define UCSI_CABLE_PROPERTY_PLUG_TYPE_C 2
> #define UCSI_CABLE_PROPERTY_PLUG_OTHER 3
> #define UCSI_CABLE_PROP_FLAG_MODE_SUPPORT BIT(5)
> +#define UCSI_CABLE_PROP_FLAG_PD_MAJOR_REV(_f_) (((_f_) & GENMASK(7, 6)) >> 6)
> +#define UCSI_CABLE_PROP_FLAG_PD_MAJOR_REV_AS_BCD(_f_) \
> + UCSI_SPEC_REVISION_TO_BCD(UCSI_CABLE_PROP_FLAG_PD_MAJOR_REV(_f_))
> u8 latency;
> } __packed;
>
> @@ -400,6 +403,7 @@ struct ucsi_connector {
>
> struct typec_port *port;
> struct typec_partner *partner;
> + struct typec_cable *cable;
>
> struct typec_altmode *port_altmode[UCSI_MAX_ALTMODES];
> struct typec_altmode *partner_altmode[UCSI_MAX_ALTMODES];
> @@ -408,6 +412,7 @@ struct ucsi_connector {
>
> struct ucsi_connector_status status;
> struct ucsi_connector_capability cap;
> + struct ucsi_cable_property cable_prop;
> struct power_supply *psy;
> struct power_supply_desc psy_desc;
> u32 rdo;
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
2024-03-11 17:28 ` neil.armstrong
@ 2024-03-11 23:47 ` Jameson Thies
2024-03-26 22:09 ` Bjorn Andersson
1 sibling, 0 replies; 13+ messages in thread
From: Jameson Thies @ 2024-03-11 23:47 UTC (permalink / raw)
To: neil.armstrong
Cc: heikki.krogerus, linux-usb, pmalani, bleung, abhishekpandit,
andersson, dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede,
rajaram.regupathy, saranya.gopal, linux-kernel, Benson Leung,
Linux regressions mailing list
Hi Neil,
thanks for catching this. You're right, the UCSI driver doesn't need
to be sending these commands when they are not supported. I'll post a
followup patch properly gating ucsi_get_partner_identity and
ucsi_check_cable.
Thanks,
Jameson
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
2024-03-11 17:28 ` neil.armstrong
2024-03-11 23:47 ` Jameson Thies
@ 2024-03-26 22:09 ` Bjorn Andersson
2024-03-26 23:19 ` Jameson Thies
1 sibling, 1 reply; 13+ messages in thread
From: Bjorn Andersson @ 2024-03-26 22:09 UTC (permalink / raw)
To: neil.armstrong
Cc: Jameson Thies, heikki.krogerus, linux-usb, pmalani, bleung,
abhishekpandit, andersson, dmitry.baryshkov, fabrice.gasnier,
gregkh, hdegoede, rajaram.regupathy, saranya.gopal, linux-kernel,
Benson Leung, Linux regressions mailing list
On Mon, Mar 11, 2024 at 06:28:41PM +0100, neil.armstrong@linaro.org wrote:
> On 05/03/2024 03:58, Jameson Thies wrote:
[..]
> With:
> =================><====================================
> diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
> index cf52cb34d285..eec64a4c8cdd 100644
> --- a/drivers/usb/typec/ucsi/ucsi.c
> +++ b/drivers/usb/typec/ucsi/ucsi.c
> @@ -1189,8 +1189,10 @@ static void ucsi_handle_connector_change(struct work_struct *work)
> ucsi_register_partner(con);
> ucsi_partner_task(con, ucsi_check_connection, 1, HZ);
> ucsi_partner_task(con, ucsi_check_connector_capability, 1, HZ);
> - ucsi_partner_task(con, ucsi_get_partner_identity, 1, HZ);
> - ucsi_partner_task(con, ucsi_check_cable, 1, HZ);
> + if (con->ucsi->cap.features & UCSI_CAP_GET_PD_MESSAGE)
> + ucsi_partner_task(con, ucsi_get_partner_identity, 1, HZ);
> + if (con->ucsi->cap.features & UCSI_CAP_CABLE_DETAILS)
> + ucsi_partner_task(con, ucsi_check_cable, 1, HZ);
>
> if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) ==
> UCSI_CONSTAT_PWR_OPMODE_PD)
> @@ -1589,8 +1591,10 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
> ucsi_register_partner(con);
> ucsi_pwr_opmode_change(con);
> ucsi_port_psy_changed(con);
> - ucsi_get_partner_identity(con);
> - ucsi_check_cable(con);
> + if (con->ucsi->cap.features & UCSI_CAP_GET_PD_MESSAGE)
> + ucsi_get_partner_identity(con);
> + if (con->ucsi->cap.features & UCSI_CAP_CABLE_DETAILS)
> + ucsi_check_cable(con);
> }
>
> /* Only notify USB controller if partner supports USB data */
> diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
> index 32daf5f58650..2e9c35a3af27 100644
> --- a/drivers/usb/typec/ucsi/ucsi.h
> +++ b/drivers/usb/typec/ucsi/ucsi.h
> @@ -215,6 +215,7 @@ struct ucsi_capability {
> #define UCSI_CAP_CABLE_DETAILS BIT(5)
> #define UCSI_CAP_EXT_SUPPLY_NOTIFICATIONS BIT(6)
> #define UCSI_CAP_PD_RESET BIT(7)
> +#define UCSI_CAP_GET_PD_MESSAGE BIT(8)
> u16 reserved_1;
> u8 num_alt_modes;
> u8 reserved_2;
> =================><====================================
> it works fine again.
>
The series broke role switching on qcs6490-rb3gen2 (next-20240326 is
broken). You're proposed addition brings it back, thank you.
Was this posted somewhere?
Regards,
Bjorn
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
2024-03-26 22:09 ` Bjorn Andersson
@ 2024-03-26 23:19 ` Jameson Thies
0 siblings, 0 replies; 13+ messages in thread
From: Jameson Thies @ 2024-03-26 23:19 UTC (permalink / raw)
To: Bjorn Andersson
Cc: neil.armstrong, heikki.krogerus, linux-usb, pmalani, bleung,
abhishekpandit, andersson, dmitry.baryshkov, fabrice.gasnier,
gregkh, hdegoede, rajaram.regupathy, saranya.gopal, linux-kernel,
Benson Leung, Linux regressions mailing list
Hi Bjorn,
posted at https://lore.kernel.org/lkml/20240315171836.343830-2-jthies@google.com/
Thanks,
Jameson
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros
2024-03-05 2:58 ` [PATCH v4 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies
@ 2024-03-27 11:14 ` Heikki Krogerus
0 siblings, 0 replies; 13+ messages in thread
From: Heikki Krogerus @ 2024-03-27 11:14 UTC (permalink / raw)
To: Jameson Thies
Cc: linux-usb, pmalani, bleung, abhishekpandit, andersson,
dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede,
neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel,
stable, Benson Leung
On Tue, Mar 05, 2024 at 02:58:01AM +0000, Jameson Thies wrote:
> Clean up UCSI_CABLE_PROP macros by fixing a bitmask shifting error for
> plug type and updating the modal support macro for consistent naming.
>
> Fixes: 3cf657f07918 ("usb: typec: ucsi: Remove all bit-fields")
> Cc: stable@vger.kernel.org
> Reviewed-by: Benson Leung <bleung@chromium.org>
> Reviewed-by: Prashant Malani <pmalani@chromium.org>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Signed-off-by: Jameson Thies <jthies@google.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> ---
> Changes in v4:
> - None.
>
> Changes in v3:
> - Fixed CC stable.
>
> Changes in v2:
> - Tested on usb-testing branch merged with chromeOS 6.8-rc2 kernel.
>
> drivers/usb/typec/ucsi/ucsi.h | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
> index 7e35ffbe0a6f2..469a2baf472e4 100644
> --- a/drivers/usb/typec/ucsi/ucsi.h
> +++ b/drivers/usb/typec/ucsi/ucsi.h
> @@ -259,12 +259,12 @@ struct ucsi_cable_property {
> #define UCSI_CABLE_PROP_FLAG_VBUS_IN_CABLE BIT(0)
> #define UCSI_CABLE_PROP_FLAG_ACTIVE_CABLE BIT(1)
> #define UCSI_CABLE_PROP_FLAG_DIRECTIONALITY BIT(2)
> -#define UCSI_CABLE_PROP_FLAG_PLUG_TYPE(_f_) ((_f_) & GENMASK(3, 0))
> +#define UCSI_CABLE_PROP_FLAG_PLUG_TYPE(_f_) (((_f_) & GENMASK(4, 3)) >> 3)
> #define UCSI_CABLE_PROPERTY_PLUG_TYPE_A 0
> #define UCSI_CABLE_PROPERTY_PLUG_TYPE_B 1
> #define UCSI_CABLE_PROPERTY_PLUG_TYPE_C 2
> #define UCSI_CABLE_PROPERTY_PLUG_OTHER 3
> -#define UCSI_CABLE_PROP_MODE_SUPPORT BIT(5)
> +#define UCSI_CABLE_PROP_FLAG_MODE_SUPPORT BIT(5)
> u8 latency;
> } __packed;
>
> --
> 2.44.0.rc1.240.g4c46232300-goog
--
heikki
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses
2024-03-05 18:54 ` Prashant Malani
@ 2024-03-27 11:18 ` Heikki Krogerus
0 siblings, 0 replies; 13+ messages in thread
From: Heikki Krogerus @ 2024-03-27 11:18 UTC (permalink / raw)
To: Prashant Malani
Cc: Jameson Thies, linux-usb, bleung, abhishekpandit, andersson,
dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede,
neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel
On Tue, Mar 05, 2024 at 06:54:39PM +0000, Prashant Malani wrote:
> On Mar 05 02:58, Jameson Thies wrote:
> > Register SOP and SOP' Discover Identity responses with the USB Type-C
> > Connector Class as partner and cable identities, respectively. Discover
> > Identity responses are requested from the PPM using the GET_PD_MESSAGE
> > UCSI command.
> >
> > Signed-off-by: Jameson Thies <jthies@google.com>
>
> Mostly line splitting nits (which I have listed below). Once those are
> addressed, please feel free to add:
> Reviewed-by: Prashant Malani <pmalani@chromium.org>
After you've fixed those add also my:
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
> > index 7c84687b5d1a3..3b64a0f51041c 100644
> > --- a/drivers/usb/typec/ucsi/ucsi.c
> > +++ b/drivers/usb/typec/ucsi/ucsi.c
> > @@ -646,6 +646,108 @@ static int ucsi_get_src_pdos(struct ucsi_connector *con)
> > return ret;
> > }
> >
> > +static int ucsi_read_identity(struct ucsi_connector *con, u8 recipient,
> > + u8 offset, u8 bytes, void *resp)
> > +{
> > + struct ucsi *ucsi = con->ucsi;
> > + u64 command;
> > + int ret;
> > +
> > + command = UCSI_COMMAND(UCSI_GET_PD_MESSAGE) |
> > + UCSI_CONNECTOR_NUMBER(con->num);
> > + command |= UCSI_GET_PD_MESSAGE_RECIPIENT(recipient);
> > + command |= UCSI_GET_PD_MESSAGE_OFFSET(offset);
> > + command |= UCSI_GET_PD_MESSAGE_BYTES(bytes);
> > + command |= UCSI_GET_PD_MESSAGE_TYPE(UCSI_GET_PD_MESSAGE_TYPE_IDENTITY);
> > +
> > + ret = ucsi_send_command(ucsi, command, resp, bytes);
> > + if (ret < 0)
> > + dev_err(ucsi->dev, "UCSI_GET_PD_MESSAGE failed (%d)\n", ret);
> > +
> > + return ret;
> > +}
> > +
> > +static int ucsi_get_identity(struct ucsi_connector *con, u8 recipient,
> > + struct usb_pd_identity *id)
>
> nit: Line limits are 100 now [1], so this can fit on one line.
>
> > +{
> > + struct ucsi *ucsi = con->ucsi;
> > + struct ucsi_pd_message_disc_id resp = {};
> > + int ret;
> > +
> > + if (ucsi->version < UCSI_VERSION_2_0) {
> > + /*
> > + * Before UCSI v2.0, MESSAGE_IN is 16 bytes which cannot fit
> > + * the 28 byte identity response including the VDM header.
> > + * First request the VDM header, ID Header VDO, Cert Stat VDO
> > + * and Product VDO.
> > + */
> > + ret = ucsi_read_identity(con, recipient, 0, 0x10, &resp);
> > + if (ret < 0)
> > + return ret;
> > +
> > +
> > + /* Then request Product Type VDO1 through Product Type VDO3. */
> > + ret = ucsi_read_identity(con, recipient, 0x10, 0xc,
> > + &resp.vdo[0]);
>
> nit: Can fit on one line.
>
> > + if (ret < 0)
> > + return ret;
> > +
> > + } else {
> > + /*
> > + * In UCSI v2.0 and after, MESSAGE_IN is large enough to request
> > + * the large enough to request the full Discover Identity
> > + * response at once.
> > + */
> > + ret = ucsi_read_identity(con, recipient, 0x0, 0x1c, &resp);
> > + if (ret < 0)
> > + return ret;
> > + }
> > +
> > + id->id_header = resp.id_header;
> > + id->cert_stat = resp.cert_stat;
> > + id->product = resp.product;
> > + id->vdo[0] = resp.vdo[0];
> > + id->vdo[1] = resp.vdo[1];
> > + id->vdo[2] = resp.vdo[2];
> > + return 0;
> > +}
> > +
> > +static int ucsi_get_partner_identity(struct ucsi_connector *con)
> > +{
> > + int ret;
> > +
> > + ret = ucsi_get_identity(con, UCSI_RECIPIENT_SOP,
> > + &con->partner_identity);
>
> nit: One line please.
>
> > + if (ret < 0)
> > + return ret;
> > +
> > + ret = typec_partner_set_identity(con->partner);
> > + if (ret < 0) {
> > + dev_err(con->ucsi->dev, "Failed to set partner identity (%d)\n",
> > + ret);
>
> nit: One line (100 is the limit now).
>
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static int ucsi_get_cable_identity(struct ucsi_connector *con)
> > +{
> > + int ret;
> > +
> > + ret = ucsi_get_identity(con, UCSI_RECIPIENT_SOP_P,
> > + &con->cable_identity);
>
> nit: One line.
>
> > + if (ret < 0)
> > + return ret;
> > +
> > + ret = typec_cable_set_identity(con->cable);
> > + if (ret < 0) {
> > + dev_err(con->ucsi->dev, "Failed to set cable identity (%d)\n",
> > + ret);
>
> nit: One line.
>
> Best regards,
>
> -Prashant
>
> [1] https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl#L59
--
heikki
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2024-03-27 11:18 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-05 2:58 [PATCH v4 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies
2024-03-05 2:58 ` [PATCH v4 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies
2024-03-27 11:14 ` Heikki Krogerus
2024-03-05 2:58 ` [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies
2024-03-11 17:28 ` neil.armstrong
2024-03-11 23:47 ` Jameson Thies
2024-03-26 22:09 ` Bjorn Andersson
2024-03-26 23:19 ` Jameson Thies
2024-03-05 2:58 ` [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies
2024-03-05 3:06 ` Benson Leung
2024-03-05 18:54 ` Prashant Malani
2024-03-27 11:18 ` Heikki Krogerus
2024-03-05 2:58 ` [PATCH v4 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug Jameson Thies
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).