* [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery
@ 2024-02-23 1:03 Jameson Thies
2024-02-23 1:03 ` [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies
` (4 more replies)
0 siblings, 5 replies; 25+ messages in thread
From: Jameson Thies @ 2024-02-23 1:03 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 v6.6 kernel build running a usermode ppm
with a Realtek EVB. Let me know if you have any questions.
Thanks,
Jameson
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 | 206 ++++++++++++++++++++++++++++++++++
drivers/usb/typec/ucsi/ucsi.h | 40 ++++++-
2 files changed, 244 insertions(+), 2 deletions(-)
base-commit: 3bf0514dc6f36f81ee11b1becd977cb87b4c90c6
--
2.44.0.rc0.258.g7320e95886-goog
^ permalink raw reply [flat|nested] 25+ messages in thread* [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros 2024-02-23 1:03 [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies @ 2024-02-23 1:03 ` Jameson Thies 2024-02-23 1:24 ` Benson Leung ` (3 more replies) 2024-02-23 1:03 ` [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies ` (3 subsequent siblings) 4 siblings, 4 replies; 25+ messages in thread From: Jameson Thies @ 2024-02-23 1:03 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 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") Signed-off-by: Jameson Thies <jthies@google.com> --- Tested by building v6.6 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 7e35ffbe0a6f..469a2baf472e 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.rc0.258.g7320e95886-goog ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros 2024-02-23 1:03 ` [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies @ 2024-02-23 1:24 ` Benson Leung 2024-02-23 1:43 ` Prashant Malani ` (2 subsequent siblings) 3 siblings, 0 replies; 25+ messages in thread From: Benson Leung @ 2024-02-23 1:24 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: 1490 bytes --] Hi Jameson, On Fri, Feb 23, 2024 at 01:03:25AM +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") > Signed-off-by: Jameson Thies <jthies@google.com> Reviewed-by: Benson Leung <bleung@chromium.org> > --- > Tested by building v6.6 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 7e35ffbe0a6f..469a2baf472e 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.rc0.258.g7320e95886-goog > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros 2024-02-23 1:03 ` [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies 2024-02-23 1:24 ` Benson Leung @ 2024-02-23 1:43 ` Prashant Malani 2024-02-23 5:37 ` Dmitry Baryshkov 2024-02-26 8:48 ` Heikki Krogerus 3 siblings, 0 replies; 25+ messages in thread From: Prashant Malani @ 2024-02-23 1:43 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 Thu, Feb 22, 2024 at 5:04 PM Jameson Thies <jthies@google.com> 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") > Signed-off-by: Jameson Thies <jthies@google.com> I think you should CC stable@ for this patch. That apart: Reviewed-by: Prashant Malani <pmalani@chromium.org> ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros 2024-02-23 1:03 ` [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies 2024-02-23 1:24 ` Benson Leung 2024-02-23 1:43 ` Prashant Malani @ 2024-02-23 5:37 ` Dmitry Baryshkov 2024-02-26 8:48 ` Heikki Krogerus 3 siblings, 0 replies; 25+ messages in thread From: Dmitry Baryshkov @ 2024-02-23 5:37 UTC (permalink / raw) To: Jameson Thies Cc: heikki.krogerus, linux-usb, pmalani, bleung, abhishekpandit, andersson, fabrice.gasnier, gregkh, hdegoede, neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel On Fri, 23 Feb 2024 at 03:04, Jameson Thies <jthies@google.com> 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") > Signed-off-by: Jameson Thies <jthies@google.com> > --- > Tested by building v6.6 kernel. > > drivers/usb/typec/ucsi/ucsi.h | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros 2024-02-23 1:03 ` [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies ` (2 preceding siblings ...) 2024-02-23 5:37 ` Dmitry Baryshkov @ 2024-02-26 8:48 ` Heikki Krogerus 2024-02-27 0:29 ` Jameson Thies 3 siblings, 1 reply; 25+ messages in thread From: Heikki Krogerus @ 2024-02-26 8:48 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 On Fri, Feb 23, 2024 at 01:03:25AM +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") > Signed-off-by: Jameson Thies <jthies@google.com> This is missing CC stable. > --- > Tested by building v6.6 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 7e35ffbe0a6f..469a2baf472e 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.rc0.258.g7320e95886-goog -- heikki ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros 2024-02-26 8:48 ` Heikki Krogerus @ 2024-02-27 0:29 ` Jameson Thies 0 siblings, 0 replies; 25+ messages in thread From: Jameson Thies @ 2024-02-27 0:29 UTC (permalink / raw) To: Heikki Krogerus Cc: linux-usb, pmalani, bleung, abhishekpandit, andersson, dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede, neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel > This is missing CC stable. Ack. I'm planning a v2 version of this series to address the other comments and will CC stable there. ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY 2024-02-23 1:03 [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies 2024-02-23 1:03 ` [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies @ 2024-02-23 1:03 ` Jameson Thies 2024-02-23 1:29 ` Benson Leung ` (3 more replies) 2024-02-23 1:03 ` [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies ` (2 subsequent siblings) 4 siblings, 4 replies; 25+ messages in thread From: Jameson Thies @ 2024-02-23 1:03 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 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. Signed-off-by: Jameson Thies <jthies@google.com> --- Tested on v6.6 kernel. Expected cable properties populate the USB Type-C connector class sysfs paths: redrix-rev3 /sys/class/typec # ls port2-cable device identity plug_type port2-plug0 power subsystem type uevent usb_power_delivery_revision drivers/usb/typec/ucsi/ucsi.c | 69 +++++++++++++++++++++++++++++++++++ drivers/usb/typec/ucsi/ucsi.h | 5 +++ 2 files changed, 74 insertions(+) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index ae105383e69e..15e82f5fab37 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -734,6 +734,50 @@ 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 +851,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 +952,28 @@ 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 +1015,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 +1414,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 469a2baf472e..f0aabef0b7c6 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.rc0.258.g7320e95886-goog ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY 2024-02-23 1:03 ` [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies @ 2024-02-23 1:29 ` Benson Leung 2024-02-23 1:45 ` Prashant Malani ` (2 subsequent siblings) 3 siblings, 0 replies; 25+ messages in thread From: Benson Leung @ 2024-02-23 1:29 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: 5627 bytes --] Hi Jameson, On Fri, Feb 23, 2024 at 01:03:26AM +0000, 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. > > Signed-off-by: Jameson Thies <jthies@google.com> Reviewed-by: Benson Leung <bleung@chromium.org> > --- > Tested on v6.6 kernel. Expected cable properties populate the USB Type-C > connector class sysfs paths: > redrix-rev3 /sys/class/typec # ls port2-cable > device identity plug_type port2-plug0 power subsystem type uevent > usb_power_delivery_revision > > drivers/usb/typec/ucsi/ucsi.c | 69 +++++++++++++++++++++++++++++++++++ > drivers/usb/typec/ucsi/ucsi.h | 5 +++ > 2 files changed, 74 insertions(+) > > diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c > index ae105383e69e..15e82f5fab37 100644 > --- a/drivers/usb/typec/ucsi/ucsi.c > +++ b/drivers/usb/typec/ucsi/ucsi.c > @@ -734,6 +734,50 @@ 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 +851,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 +952,28 @@ 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 +1015,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 +1414,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 469a2baf472e..f0aabef0b7c6 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.rc0.258.g7320e95886-goog > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY 2024-02-23 1:03 ` [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies 2024-02-23 1:29 ` Benson Leung @ 2024-02-23 1:45 ` Prashant Malani 2024-02-23 5:42 ` Dmitry Baryshkov 2024-02-26 9:05 ` Heikki Krogerus 3 siblings, 0 replies; 25+ messages in thread From: Prashant Malani @ 2024-02-23 1:45 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 Thu, Feb 22, 2024 at 5:04 PM Jameson Thies <jthies@google.com> 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. > > Signed-off-by: Jameson Thies <jthies@google.com> Reviewed-by: Prashant Malani <pmalani@chromium.org> ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY 2024-02-23 1:03 ` [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies 2024-02-23 1:29 ` Benson Leung 2024-02-23 1:45 ` Prashant Malani @ 2024-02-23 5:42 ` Dmitry Baryshkov 2024-02-26 9:05 ` Heikki Krogerus 3 siblings, 0 replies; 25+ messages in thread From: Dmitry Baryshkov @ 2024-02-23 5:42 UTC (permalink / raw) To: Jameson Thies Cc: heikki.krogerus, linux-usb, pmalani, bleung, abhishekpandit, andersson, fabrice.gasnier, gregkh, hdegoede, neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel On Fri, 23 Feb 2024 at 03:04, Jameson Thies <jthies@google.com> 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. > > Signed-off-by: Jameson Thies <jthies@google.com> > --- > Tested on v6.6 kernel. Expected cable properties populate the USB Type-C > connector class sysfs paths: > redrix-rev3 /sys/class/typec # ls port2-cable > device identity plug_type port2-plug0 power subsystem type uevent > usb_power_delivery_revision > > drivers/usb/typec/ucsi/ucsi.c | 69 +++++++++++++++++++++++++++++++++++ > drivers/usb/typec/ucsi/ucsi.h | 5 +++ > 2 files changed, 74 insertions(+) Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> > > -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY 2024-02-23 1:03 ` [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies ` (2 preceding siblings ...) 2024-02-23 5:42 ` Dmitry Baryshkov @ 2024-02-26 9:05 ` Heikki Krogerus 3 siblings, 0 replies; 25+ messages in thread From: Heikki Krogerus @ 2024-02-26 9:05 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 On Fri, Feb 23, 2024 at 01:03:26AM +0000, 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. > > Signed-off-by: Jameson Thies <jthies@google.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > --- > Tested on v6.6 kernel. Expected cable properties populate the USB Type-C > connector class sysfs paths: > redrix-rev3 /sys/class/typec # ls port2-cable > device identity plug_type port2-plug0 power subsystem type uevent > usb_power_delivery_revision > > drivers/usb/typec/ucsi/ucsi.c | 69 +++++++++++++++++++++++++++++++++++ > drivers/usb/typec/ucsi/ucsi.h | 5 +++ > 2 files changed, 74 insertions(+) > > diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c > index ae105383e69e..15e82f5fab37 100644 > --- a/drivers/usb/typec/ucsi/ucsi.c > +++ b/drivers/usb/typec/ucsi/ucsi.c > @@ -734,6 +734,50 @@ 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 +851,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 +952,28 @@ 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 +1015,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 +1414,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 469a2baf472e..f0aabef0b7c6 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.rc0.258.g7320e95886-goog -- heikki ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses 2024-02-23 1:03 [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies 2024-02-23 1:03 ` [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies 2024-02-23 1:03 ` [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies @ 2024-02-23 1:03 ` Jameson Thies 2024-02-23 1:34 ` Benson Leung ` (3 more replies) 2024-02-23 1:03 ` [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug Jameson Thies 2024-02-23 5:34 ` [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Dmitry Baryshkov 4 siblings, 4 replies; 25+ messages in thread From: Jameson Thies @ 2024-02-23 1:03 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> --- Tested on v6.6 kernel. GET_PD_MESSAGE responses from the PPM populate partner and cable identity in sysfs. redrix-rev3 /sys/class/typec # ls port2-partner/identity/ cert_stat id_header product product_type_vdo1 product_type_vdo2 product_type_vdo3 redrix-rev3 /sys/class/typec # ls port2-cable/identity/ cert_stat id_header product product_type_vdo1 product_type_vdo2 product_type_vdo3 drivers/usb/typec/ucsi/ucsi.c | 77 +++++++++++++++++++++++++++++++++++ drivers/usb/typec/ucsi/ucsi.h | 29 +++++++++++++ 2 files changed, 106 insertions(+) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 15e82f5fab37..6d6443e61faa 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -646,6 +646,73 @@ static int ucsi_get_src_pdos(struct ucsi_connector *con) return ret; } +static int ucsi_read_identity(struct ucsi_connector *con, u8 recipient, struct usb_pd_identity *id) +{ + struct ucsi *ucsi = con->ucsi; + struct ucsi_pd_message_disc_id resp = {}; + u64 command; + int ret; + + /* + * Skip identity discovery and registration if UCSI version is less than + * v2.0. Before v2.0 MESSAGE_IN is 16 bytes which cannot fit a complete + * 24 byte identity response. + */ + if (ucsi->version < UCSI_VERSION_2_0) + return -EPROTO; + + command = UCSI_COMMAND(UCSI_GET_PD_MESSAGE) | UCSI_CONNECTOR_NUMBER(con->num); + command |= UCSI_GET_PD_MESSAGE_RECIPIENT(recipient); + /* VDM Header + 6 VDOs (0x1c bytes) without an offset */ + command |= UCSI_GET_PD_MESSAGE_OFFSET(0); + command |= UCSI_GET_PD_MESSAGE_BYTES(0x1c); + command |= UCSI_GET_PD_MESSAGE_TYPE(UCSI_GET_PD_MESSAGE_TYPE_IDENTITY); + + ret = ucsi_send_command(ucsi, command, &resp, sizeof(resp)); + if (ret < 0) { + dev_err(ucsi->dev, "UCSI_GET_PD_MESSAGE failed (%d)\n", ret); + 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_read_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_read_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 +821,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(con->cable_prop.flags); @@ -776,6 +844,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con) typec_unregister_cable(con->cable); con->cable = NULL; + memset(&con->cable_identity, 0, sizeof(con->cable_identity)); } static void ucsi_pwr_opmode_change(struct ucsi_connector *con) @@ -825,6 +894,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); @@ -854,6 +924,7 @@ static void ucsi_unregister_partner(struct ucsi_connector *con) ucsi_unregister_cable(con); typec_unregister_partner(con->partner); con->partner = NULL; + memset(&con->partner_identity, 0, sizeof(con->partner_identity)); } static void ucsi_partner_change(struct ucsi_connector *con) @@ -971,6 +1042,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; } @@ -1015,6 +1090,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) == @@ -1414,6 +1490,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 f0aabef0b7c6..b89fae82e8ce 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.rc0.258.g7320e95886-goog ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses 2024-02-23 1:03 ` [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies @ 2024-02-23 1:34 ` Benson Leung 2024-02-23 5:52 ` Dmitry Baryshkov ` (2 subsequent siblings) 3 siblings, 0 replies; 25+ messages in thread From: Benson Leung @ 2024-02-23 1:34 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: 8219 bytes --] Hi Jameson, On Fri, Feb 23, 2024 at 01:03:27AM +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> > --- > Tested on v6.6 kernel. GET_PD_MESSAGE responses from the PPM populate > partner and cable identity in sysfs. > redrix-rev3 /sys/class/typec # ls port2-partner/identity/ > cert_stat id_header product product_type_vdo1 product_type_vdo2 > product_type_vdo3 > redrix-rev3 /sys/class/typec # ls port2-cable/identity/ > cert_stat id_header product product_type_vdo1 product_type_vdo2 > product_type_vdo3 > > drivers/usb/typec/ucsi/ucsi.c | 77 +++++++++++++++++++++++++++++++++++ > drivers/usb/typec/ucsi/ucsi.h | 29 +++++++++++++ > 2 files changed, 106 insertions(+) > > diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c > index 15e82f5fab37..6d6443e61faa 100644 > --- a/drivers/usb/typec/ucsi/ucsi.c > +++ b/drivers/usb/typec/ucsi/ucsi.c > @@ -646,6 +646,73 @@ static int ucsi_get_src_pdos(struct ucsi_connector *con) > return ret; > } > > +static int ucsi_read_identity(struct ucsi_connector *con, u8 recipient, struct usb_pd_identity *id) > +{ > + struct ucsi *ucsi = con->ucsi; > + struct ucsi_pd_message_disc_id resp = {}; > + u64 command; > + int ret; > + > + /* > + * Skip identity discovery and registration if UCSI version is less than > + * v2.0. Before v2.0 MESSAGE_IN is 16 bytes which cannot fit a complete > + * 24 byte identity response. > + */ > + if (ucsi->version < UCSI_VERSION_2_0) > + return -EPROTO; > + > + command = UCSI_COMMAND(UCSI_GET_PD_MESSAGE) | UCSI_CONNECTOR_NUMBER(con->num); > + command |= UCSI_GET_PD_MESSAGE_RECIPIENT(recipient); > + /* VDM Header + 6 VDOs (0x1c bytes) without an offset */ > + command |= UCSI_GET_PD_MESSAGE_OFFSET(0); > + command |= UCSI_GET_PD_MESSAGE_BYTES(0x1c); > + command |= UCSI_GET_PD_MESSAGE_TYPE(UCSI_GET_PD_MESSAGE_TYPE_IDENTITY); > + > + ret = ucsi_send_command(ucsi, command, &resp, sizeof(resp)); > + if (ret < 0) { > + dev_err(ucsi->dev, "UCSI_GET_PD_MESSAGE failed (%d)\n", ret); > + 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_read_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_read_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 +821,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(con->cable_prop.flags); > > @@ -776,6 +844,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con) > > typec_unregister_cable(con->cable); > con->cable = NULL; > + memset(&con->cable_identity, 0, sizeof(con->cable_identity)); > } > > static void ucsi_pwr_opmode_change(struct ucsi_connector *con) > @@ -825,6 +894,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); > > @@ -854,6 +924,7 @@ static void ucsi_unregister_partner(struct ucsi_connector *con) > ucsi_unregister_cable(con); > typec_unregister_partner(con->partner); > con->partner = NULL; > + memset(&con->partner_identity, 0, sizeof(con->partner_identity)); > } > > static void ucsi_partner_change(struct ucsi_connector *con) > @@ -971,6 +1042,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; > } > > @@ -1015,6 +1090,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) == > @@ -1414,6 +1490,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 f0aabef0b7c6..b89fae82e8ce 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.rc0.258.g7320e95886-goog > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses 2024-02-23 1:03 ` [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies 2024-02-23 1:34 ` Benson Leung @ 2024-02-23 5:52 ` Dmitry Baryshkov 2024-02-26 9:06 ` Heikki Krogerus 2024-02-26 18:02 ` Prashant Malani 3 siblings, 0 replies; 25+ messages in thread From: Dmitry Baryshkov @ 2024-02-23 5:52 UTC (permalink / raw) To: Jameson Thies Cc: heikki.krogerus, linux-usb, pmalani, bleung, abhishekpandit, andersson, fabrice.gasnier, gregkh, hdegoede, neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel On Fri, 23 Feb 2024 at 03:04, Jameson Thies <jthies@google.com> 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> > --- > Tested on v6.6 kernel. GET_PD_MESSAGE responses from the PPM populate > partner and cable identity in sysfs. > redrix-rev3 /sys/class/typec # ls port2-partner/identity/ > cert_stat id_header product product_type_vdo1 product_type_vdo2 > product_type_vdo3 > redrix-rev3 /sys/class/typec # ls port2-cable/identity/ > cert_stat id_header product product_type_vdo1 product_type_vdo2 > product_type_vdo3 > > drivers/usb/typec/ucsi/ucsi.c | 77 +++++++++++++++++++++++++++++++++++ > drivers/usb/typec/ucsi/ucsi.h | 29 +++++++++++++ > 2 files changed, 106 insertions(+) > > diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c > index 15e82f5fab37..6d6443e61faa 100644 > --- a/drivers/usb/typec/ucsi/ucsi.c > +++ b/drivers/usb/typec/ucsi/ucsi.c > @@ -646,6 +646,73 @@ static int ucsi_get_src_pdos(struct ucsi_connector *con) > return ret; > } > > +static int ucsi_read_identity(struct ucsi_connector *con, u8 recipient, struct usb_pd_identity *id) > +{ > + struct ucsi *ucsi = con->ucsi; > + struct ucsi_pd_message_disc_id resp = {}; > + u64 command; > + int ret; > + > + /* > + * Skip identity discovery and registration if UCSI version is less than > + * v2.0. Before v2.0 MESSAGE_IN is 16 bytes which cannot fit a complete > + * 24 byte identity response. Please consider using two commands to retrieve the data. This will allow you to support UCSI 1.x too. > + */ > + if (ucsi->version < UCSI_VERSION_2_0) > + return -EPROTO; > + > + command = UCSI_COMMAND(UCSI_GET_PD_MESSAGE) | UCSI_CONNECTOR_NUMBER(con->num); > + command |= UCSI_GET_PD_MESSAGE_RECIPIENT(recipient); > + /* VDM Header + 6 VDOs (0x1c bytes) without an offset */ > + command |= UCSI_GET_PD_MESSAGE_OFFSET(0); > + command |= UCSI_GET_PD_MESSAGE_BYTES(0x1c); > + command |= UCSI_GET_PD_MESSAGE_TYPE(UCSI_GET_PD_MESSAGE_TYPE_IDENTITY); > + > + ret = ucsi_send_command(ucsi, command, &resp, sizeof(resp)); > + if (ret < 0) { > + dev_err(ucsi->dev, "UCSI_GET_PD_MESSAGE failed (%d)\n", ret); > + 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_read_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_read_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 +821,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(con->cable_prop.flags); > > @@ -776,6 +844,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con) > > typec_unregister_cable(con->cable); > con->cable = NULL; > + memset(&con->cable_identity, 0, sizeof(con->cable_identity)); Nit: I'd probably call memset before setting con->cable to NULL. > } > > static void ucsi_pwr_opmode_change(struct ucsi_connector *con) > @@ -825,6 +894,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); > > @@ -854,6 +924,7 @@ static void ucsi_unregister_partner(struct ucsi_connector *con) > ucsi_unregister_cable(con); > typec_unregister_partner(con->partner); > con->partner = NULL; > + memset(&con->partner_identity, 0, sizeof(con->partner_identity)); And the same here. > } > > static void ucsi_partner_change(struct ucsi_connector *con) > @@ -971,6 +1042,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; > } > > @@ -1015,6 +1090,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) == > @@ -1414,6 +1490,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 f0aabef0b7c6..b89fae82e8ce 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.rc0.258.g7320e95886-goog > -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses 2024-02-23 1:03 ` [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies 2024-02-23 1:34 ` Benson Leung 2024-02-23 5:52 ` Dmitry Baryshkov @ 2024-02-26 9:06 ` Heikki Krogerus 2024-02-26 18:02 ` Prashant Malani 3 siblings, 0 replies; 25+ messages in thread From: Heikki Krogerus @ 2024-02-26 9:06 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 On Fri, Feb 23, 2024 at 01:03:27AM +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: Heikki Krogerus <heikki.krogerus@linux.intel.com> > --- > Tested on v6.6 kernel. GET_PD_MESSAGE responses from the PPM populate > partner and cable identity in sysfs. > redrix-rev3 /sys/class/typec # ls port2-partner/identity/ > cert_stat id_header product product_type_vdo1 product_type_vdo2 > product_type_vdo3 > redrix-rev3 /sys/class/typec # ls port2-cable/identity/ > cert_stat id_header product product_type_vdo1 product_type_vdo2 > product_type_vdo3 > > drivers/usb/typec/ucsi/ucsi.c | 77 +++++++++++++++++++++++++++++++++++ > drivers/usb/typec/ucsi/ucsi.h | 29 +++++++++++++ > 2 files changed, 106 insertions(+) > > diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c > index 15e82f5fab37..6d6443e61faa 100644 > --- a/drivers/usb/typec/ucsi/ucsi.c > +++ b/drivers/usb/typec/ucsi/ucsi.c > @@ -646,6 +646,73 @@ static int ucsi_get_src_pdos(struct ucsi_connector *con) > return ret; > } > > +static int ucsi_read_identity(struct ucsi_connector *con, u8 recipient, struct usb_pd_identity *id) > +{ > + struct ucsi *ucsi = con->ucsi; > + struct ucsi_pd_message_disc_id resp = {}; > + u64 command; > + int ret; > + > + /* > + * Skip identity discovery and registration if UCSI version is less than > + * v2.0. Before v2.0 MESSAGE_IN is 16 bytes which cannot fit a complete > + * 24 byte identity response. > + */ > + if (ucsi->version < UCSI_VERSION_2_0) > + return -EPROTO; > + > + command = UCSI_COMMAND(UCSI_GET_PD_MESSAGE) | UCSI_CONNECTOR_NUMBER(con->num); > + command |= UCSI_GET_PD_MESSAGE_RECIPIENT(recipient); > + /* VDM Header + 6 VDOs (0x1c bytes) without an offset */ > + command |= UCSI_GET_PD_MESSAGE_OFFSET(0); > + command |= UCSI_GET_PD_MESSAGE_BYTES(0x1c); > + command |= UCSI_GET_PD_MESSAGE_TYPE(UCSI_GET_PD_MESSAGE_TYPE_IDENTITY); > + > + ret = ucsi_send_command(ucsi, command, &resp, sizeof(resp)); > + if (ret < 0) { > + dev_err(ucsi->dev, "UCSI_GET_PD_MESSAGE failed (%d)\n", ret); > + 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_read_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_read_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 +821,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(con->cable_prop.flags); > > @@ -776,6 +844,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con) > > typec_unregister_cable(con->cable); > con->cable = NULL; > + memset(&con->cable_identity, 0, sizeof(con->cable_identity)); > } > > static void ucsi_pwr_opmode_change(struct ucsi_connector *con) > @@ -825,6 +894,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); > > @@ -854,6 +924,7 @@ static void ucsi_unregister_partner(struct ucsi_connector *con) > ucsi_unregister_cable(con); > typec_unregister_partner(con->partner); > con->partner = NULL; > + memset(&con->partner_identity, 0, sizeof(con->partner_identity)); > } > > static void ucsi_partner_change(struct ucsi_connector *con) > @@ -971,6 +1042,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; > } > > @@ -1015,6 +1090,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) == > @@ -1414,6 +1490,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 f0aabef0b7c6..b89fae82e8ce 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.rc0.258.g7320e95886-goog -- heikki ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses 2024-02-23 1:03 ` [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies ` (2 preceding siblings ...) 2024-02-26 9:06 ` Heikki Krogerus @ 2024-02-26 18:02 ` Prashant Malani 2024-02-27 0:38 ` Jameson Thies 3 siblings, 1 reply; 25+ messages in thread From: Prashant Malani @ 2024-02-26 18:02 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 Thu, Feb 22, 2024 at 5:04 PM Jameson Thies <jthies@google.com> 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> I've reviewed this internally already [1], and it looks good to me: Reviewed-by: Prashant Malani <pmalani@chromium.org> [1] https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5260256 ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses 2024-02-26 18:02 ` Prashant Malani @ 2024-02-27 0:38 ` Jameson Thies 0 siblings, 0 replies; 25+ messages in thread From: Jameson Thies @ 2024-02-27 0:38 UTC (permalink / raw) To: Prashant Malani Cc: heikki.krogerus, linux-usb, bleung, abhishekpandit, andersson, dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede, neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel > Please consider using two commands to retrieve the data. This will > allow you to support UCSI 1.x too. > Nit: I'd probably call memset before setting con->cable to NULL. > And the same here. Thanks for your feedback. I'll apply these changes in a v2 version of this series. ^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug 2024-02-23 1:03 [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies ` (2 preceding siblings ...) 2024-02-23 1:03 ` [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies @ 2024-02-23 1:03 ` Jameson Thies 2024-02-23 1:47 ` Benson Leung ` (2 more replies) 2024-02-23 5:34 ` [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Dmitry Baryshkov 4 siblings, 3 replies; 25+ messages in thread From: Jameson Thies @ 2024-02-23 1:03 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' 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'. Signed-off-by: Jameson Thies <jthies@google.com> --- Tested on v6.6 kernel. SOP' GET_ALTERNATE_MODE responses from the PPM are correctly registered as to the cable plug. redrix-rev3 /sys/class/typec # ls port2-cable/port2-plug0/ device port2-plug0.0 port2-plug0.1 power subsystem uevent 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 6d6443e61faa..9b541547917b 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; } @@ -801,6 +825,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; @@ -842,6 +893,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con) if (!con->cable) return; + ucsi_unregister_plug(con); typec_unregister_cable(con->cable); con->cable = NULL; memset(&con->cable_identity, 0, sizeof(con->cable_identity)); @@ -1046,6 +1098,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 b89fae82e8ce..32daf5f58650 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.rc0.258.g7320e95886-goog ^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug 2024-02-23 1:03 ` [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug Jameson Thies @ 2024-02-23 1:47 ` Benson Leung 2024-02-23 18:40 ` Prashant Malani 2024-02-26 9:07 ` Heikki Krogerus 2 siblings, 0 replies; 25+ messages in thread From: Benson Leung @ 2024-02-23 1:47 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: 4275 bytes --] Hi Jameson, On Fri, Feb 23, 2024 at 01:03:28AM +0000, Jameson Thies wrote: > 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'. > Is there a plan to do the same for the SOP Double Prime for advanced active cables with two plugs? > Signed-off-by: Jameson Thies <jthies@google.com> Other than that question, Reviewed-by: Benson Leung <bleung@chromium.org> > --- > Tested on v6.6 kernel. SOP' GET_ALTERNATE_MODE responses from the PPM > are correctly registered as to the cable plug. > redrix-rev3 /sys/class/typec # ls port2-cable/port2-plug0/ > device port2-plug0.0 port2-plug0.1 power subsystem uevent > > 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 6d6443e61faa..9b541547917b 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; > } > @@ -801,6 +825,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; > @@ -842,6 +893,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con) > if (!con->cable) > return; > > + ucsi_unregister_plug(con); > typec_unregister_cable(con->cable); > con->cable = NULL; > memset(&con->cable_identity, 0, sizeof(con->cable_identity)); > @@ -1046,6 +1098,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 b89fae82e8ce..32daf5f58650 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.rc0.258.g7320e95886-goog > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug 2024-02-23 1:03 ` [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug Jameson Thies 2024-02-23 1:47 ` Benson Leung @ 2024-02-23 18:40 ` Prashant Malani 2024-02-26 9:07 ` Heikki Krogerus 2 siblings, 0 replies; 25+ messages in thread From: Prashant Malani @ 2024-02-23 18:40 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 Thu, Feb 22, 2024 at 5:05 PM Jameson Thies <jthies@google.com> wrote: > > 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'. > > Signed-off-by: Jameson Thies <jthies@google.com> Reviewed-by: Prashant Malani <pmalani@chromium.org> ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug 2024-02-23 1:03 ` [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug Jameson Thies 2024-02-23 1:47 ` Benson Leung 2024-02-23 18:40 ` Prashant Malani @ 2024-02-26 9:07 ` Heikki Krogerus 2024-02-27 0:44 ` Jameson Thies 2 siblings, 1 reply; 25+ messages in thread From: Heikki Krogerus @ 2024-02-26 9:07 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 On Fri, Feb 23, 2024 at 01:03:28AM +0000, Jameson Thies wrote: > 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'. > > Signed-off-by: Jameson Thies <jthies@google.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > --- > Tested on v6.6 kernel. SOP' GET_ALTERNATE_MODE responses from the PPM > are correctly registered as to the cable plug. > redrix-rev3 /sys/class/typec # ls port2-cable/port2-plug0/ > device port2-plug0.0 port2-plug0.1 power subsystem uevent > > 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 6d6443e61faa..9b541547917b 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; > } > @@ -801,6 +825,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; > @@ -842,6 +893,7 @@ static void ucsi_unregister_cable(struct ucsi_connector *con) > if (!con->cable) > return; > > + ucsi_unregister_plug(con); > typec_unregister_cable(con->cable); > con->cable = NULL; > memset(&con->cable_identity, 0, sizeof(con->cable_identity)); > @@ -1046,6 +1098,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 b89fae82e8ce..32daf5f58650 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.rc0.258.g7320e95886-goog -- heikki ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug 2024-02-26 9:07 ` Heikki Krogerus @ 2024-02-27 0:44 ` Jameson Thies 0 siblings, 0 replies; 25+ messages in thread From: Jameson Thies @ 2024-02-27 0:44 UTC (permalink / raw) To: Heikki Krogerus Cc: linux-usb, pmalani, bleung, abhishekpandit, andersson, dmitry.baryshkov, fabrice.gasnier, gregkh, hdegoede, neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel > Is there a plan to do the same for the SOP Double Prime for advanced active > cables with two plugs? Hey Benson, I am not currently planning to add support for SOP double prime discovery. I currently don't see how information about the second plug would impact mode entry decisions. But, we could always follow up and add that if we find a reason to. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery 2024-02-23 1:03 [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies ` (3 preceding siblings ...) 2024-02-23 1:03 ` [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug Jameson Thies @ 2024-02-23 5:34 ` Dmitry Baryshkov 2024-02-27 0:28 ` Jameson Thies 4 siblings, 1 reply; 25+ messages in thread From: Dmitry Baryshkov @ 2024-02-23 5:34 UTC (permalink / raw) To: Jameson Thies Cc: heikki.krogerus, linux-usb, pmalani, bleung, abhishekpandit, andersson, fabrice.gasnier, gregkh, hdegoede, neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel Hi Jameson, On Fri, 23 Feb 2024 at 03:04, Jameson Thies <jthies@google.com> wrote: > > 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 v6.6 kernel build running a usermode ppm > with a Realtek EVB. Let me know if you have any questions. First and the most obvious comment: 6.6 is four months old. I see that your base commit is the usb-testing tip, however you declare that you tested only on 6.6. Now I'm confused. Did you test your patches on top of usb-testing before sending them? -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery 2024-02-23 5:34 ` [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Dmitry Baryshkov @ 2024-02-27 0:28 ` Jameson Thies 0 siblings, 0 replies; 25+ messages in thread From: Jameson Thies @ 2024-02-27 0:28 UTC (permalink / raw) To: Dmitry Baryshkov Cc: heikki.krogerus, linux-usb, pmalani, bleung, abhishekpandit, andersson, fabrice.gasnier, gregkh, hdegoede, neil.armstrong, rajaram.regupathy, saranya.gopal, linux-kernel > First and the most obvious comment: 6.6 is four months old. I see that > your base commit is the usb-testing tip, however you declare that you > tested only on 6.6. Now I'm confused. Did you test your patches on top > of usb-testing before sending them? Hi Dmitry, sorry for the confusion. I tested this on a v6.6 kernel build with a few dependent commits cherry-picked to it. I'll re-validate the series on top of usb-testing. ^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2024-02-27 0:44 UTC | newest] Thread overview: 25+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-02-23 1:03 [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Jameson Thies 2024-02-23 1:03 ` [PATCH 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros Jameson Thies 2024-02-23 1:24 ` Benson Leung 2024-02-23 1:43 ` Prashant Malani 2024-02-23 5:37 ` Dmitry Baryshkov 2024-02-26 8:48 ` Heikki Krogerus 2024-02-27 0:29 ` Jameson Thies 2024-02-23 1:03 ` [PATCH 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY Jameson Thies 2024-02-23 1:29 ` Benson Leung 2024-02-23 1:45 ` Prashant Malani 2024-02-23 5:42 ` Dmitry Baryshkov 2024-02-26 9:05 ` Heikki Krogerus 2024-02-23 1:03 ` [PATCH 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses Jameson Thies 2024-02-23 1:34 ` Benson Leung 2024-02-23 5:52 ` Dmitry Baryshkov 2024-02-26 9:06 ` Heikki Krogerus 2024-02-26 18:02 ` Prashant Malani 2024-02-27 0:38 ` Jameson Thies 2024-02-23 1:03 ` [PATCH 4/4] usb: typec: ucsi: Register SOP' alternate modes with cable plug Jameson Thies 2024-02-23 1:47 ` Benson Leung 2024-02-23 18:40 ` Prashant Malani 2024-02-26 9:07 ` Heikki Krogerus 2024-02-27 0:44 ` Jameson Thies 2024-02-23 5:34 ` [PATCH 0/4] usb: typec: ucsi: Expand SOP/SOP' Discovery Dmitry Baryshkov 2024-02-27 0:28 ` Jameson Thies
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox