usb: typec: ucsi: Expand SOP/SOP' Discovery
Subsystems (4)
v4 cover usb: typec: ucsi: Expand SOP/SOP' Discovery
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
Signature · 1 line
2.44.0.rc1.240.g4c46232300-goog
PATCH v4 1/4 usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros
Clean up UCSI_CABLE_PROP macros by fixing a bitmask shifting error for plug type and updating the modal support macro for consistent naming.
---
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(-)
drivers/usb/typec/ucsi/ucsi.h +2 -2
@@ -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;
Signature · 1 line
2.44.0.rc1.240.g4c46232300-goog
Re: [PATCH v4 1/4] usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros
Quoted 9 lines · Jameson Thies
Clean up
UCSI_CABLE_PROPmacros 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")Reviewed-by Benson Leung <[email protected]>Reviewed-by Prashant Malani <[email protected]>Reviewed-by Dmitry Baryshkov <[email protected]>Signed-off-by Jameson Thies <[email protected]>
Quoted 34 lines
---
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(-)drivers/usb/typec/ucsi/ucsi.h +2
-2@@ -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;Signature · 1 line
2.44.0.rc1.240.g4c46232300-goog
Signature · 1 line
heikki
PATCH v4 2/4 usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
In reply to Jameson ThiesRegister 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.
---
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(+)
drivers/usb/typec/ucsi/ucsi.c +73 -0
@@ -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 */
drivers/usb/typec/ucsi/ucsi.h +5 -0
@@ -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;
Signature · 1 line
2.44.0.rc1.240.g4c46232300-goog
Re: [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
Hi,
Quoted 22 lines · Jameson Thies
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 <[email protected]>Reviewed-by Prashant Malani <[email protected]>Reviewed-by Dmitry Baryshkov <[email protected]>Reviewed-by Heikki Krogerus <[email protected]>Signed-off-by Jameson Thies <[email protected]>---
Expected cable properties populate the USB Type-C connector class sysfs paths:
nospike-rev4/sys/class/typec# ls port0-cable
device identityplug_typeport0-plug0 power subsystem type ueventusb_power_delivery_revisionChanges in v4:
- None.Changes in v3:
- None.
Quoted 7 lines
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:
=================><====================================
drivers/usb/typec/ucsi/ucsi.c +8 -4
@@ -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 */
drivers/usb/typec/ucsi/ucsi.h +1 -0
@@ -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
Quoted 143 lines
drivers/usb/typec/ucsi/ucsi.c +73
-0@@ -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 */ drivers/usb/typec/ucsi/ucsi.h +5
-0@@ -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;
Re: [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
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
Re: [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
In reply to [email protected]Quoted 1 line · On Mon, Mar 11, 2024 at 06:28:41PM +0100, [email protected] wrote:
On 05/03/2024 03:58, Jameson Thies wrote:
[..]
Quoted 44 lines
With:
=================><====================================drivers/usb/typec/ucsi/ucsi.c +8
-4@@ -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 */ drivers/usb/typec/ucsi/ucsi.h +1
-0@@ -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;
Quoted 3 lines
=================><==================================== 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
Re: [PATCH v4 2/4] usb: typec: ucsi: Register cables based on GET_CABLE_PROPERTY
Hi Bjorn,
posted at https://lore.kernel.org/lkml/[email protected]/
Thanks,
Jameson
PATCH v4 3/4 usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses
In reply to Jameson ThiesRegister 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.
---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(+)
drivers/usb/typec/ucsi/ucsi.c +112 -0
@@ -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); }
drivers/usb/typec/ucsi/ucsi.h +29 -0
@@ -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,
Signature · 1 line
2.44.0.rc1.240.g4c46232300-goog
Re: [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses
Hi Jameson,
Quoted 6 lines · Jameson Thies
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_MESSAGEUCSI command.Signed-off-by Jameson Thies <[email protected]>
Quoted 265 lines
---
GET_PD_MESSAGEresponses from the PPM populate partner and cable identity in sysfs:
nospike-rev4/sys/class/typec# ls port0-partner/identity/cert_statid_headerproductproduct_type_vdo1product_type_vdo2product_type_vdo3
nospike-rev4/sys/class/typec# ls port0-cable/identity/cert_statid_headerproductproduct_type_vdo1product_type_vdo2product_type_vdo3Changes in v4:
- Cleaned up redundentucsi_send_commandcalls 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(+)drivers/usb/typec/ucsi/ucsi.c +112
-0@@ -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); }drivers/usb/typec/ucsi/ucsi.h +29
-0@@ -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,Signature · 1 line
2.44.0.rc1.240.g4c46232300-goog
Re: [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses
In reply to Jameson ThiesQuoted 6 lines · Jameson Thies
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_MESSAGEUCSI command.Signed-off-by Jameson Thies <[email protected]>
Mostly line splitting nits (which I have listed below). Once those are addressed, please feel free to add:
Quoted 21 lines
drivers/usb/typec/ucsi/ucsi.c +13
-0@@ -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 );
drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 671
Quoted 10 lines
drivers/usb/typec/ucsi/ucsi.c +10
-0+ + 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.
Quoted 10 lines
drivers/usb/typec/ucsi/ucsi.c +10
-0+{ +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
drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 691
Quoted 10 lines
drivers/usb/typec/ucsi/ucsi.c +10
-0+* 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.
Quoted 19 lines
drivers/usb/typec/ucsi/ucsi.c +19
-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 ];
drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 720
Quoted 10 lines
drivers/usb/typec/ucsi/ucsi.c +10
-0+ 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.
drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 727
Quoted 7 lines
drivers/usb/typec/ucsi/ucsi.c +7
-0+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).
drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 738
Quoted 11 lines
drivers/usb/typec/ucsi/ucsi.c +11
-0+ } + +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.
drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 745
Quoted 7 lines
drivers/usb/typec/ucsi/ucsi.c +7
-0+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
Re: [PATCH v4 3/4] usb: typec: ucsi: Register SOP/SOP' Discover Identity Responses
Quoted 11 lines · Prashant Malani
Quoted 6 lines · Jameson Thies
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_MESSAGEUCSI command.Signed-off-by Jameson Thies <[email protected]>Mostly line splitting nits (which I have listed below). Once those are addressed, please feel free to add:
Reviewed-by Prashant Malani <[email protected]>
After you've fixed those add also my:
Quoted 128 lines
Quoted 21 lines
drivers/usb/typec/ucsi/ucsi.c +13
-0@@ -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 );drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 671
Quoted 10 lines
drivers/usb/typec/ucsi/ucsi.c +10
-0+ + 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.
Quoted 10 lines
drivers/usb/typec/ucsi/ucsi.c +10
-0+{ +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 drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 691
Quoted 10 lines
drivers/usb/typec/ucsi/ucsi.c +10
-0+* 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.
Quoted 19 lines
drivers/usb/typec/ucsi/ucsi.c +19
-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 ];drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 720
Quoted 10 lines
drivers/usb/typec/ucsi/ucsi.c +10
-0+ 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.
drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 727
Quoted 7 lines
drivers/usb/typec/ucsi/ucsi.c +7
-0+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).
drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 738
Quoted 11 lines
drivers/usb/typec/ucsi/ucsi.c +11
-0+ } + +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.
drivers/usb/typec/ucsi/ucsi.c static int ucsi_get_src_pdos(struct ucsi_connector *con) · line 745
Quoted 7 lines
drivers/usb/typec/ucsi/ucsi.c +7
-0+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
Signature · 1 line
heikki
PATCH v4 4/4 usb: typec: ucsi: Register SOP' alternate modes with cable plug
In reply to Jameson ThiesRegister 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'.
---
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(+)
drivers/usb/typec/ucsi/ucsi.c +60 -0
@@ -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 ; }
drivers/usb/typec/ucsi/ucsi.h +2 -0
@@ -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;
Signature · 1 line
2.44.0.rc1.240.g4c46232300-goog