summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorKyle Tso <kyletso@google.com>2021-02-05 11:34:09 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-02-09 11:48:54 +0100
commit3c5960c0559c44c6628341a82167ee0d3e40ee50 (patch)
tree5926695eb67f8ab5b3ec5e92b28ce3a0893506e7 /drivers/usb
parent4b049f55ed95cd889bcdb3034fd75e1f01852b38 (diff)
downloadlwn-3c5960c0559c44c6628341a82167ee0d3e40ee50.tar.gz
lwn-3c5960c0559c44c6628341a82167ee0d3e40ee50.zip
usb: typec: Manage SVDM version
PD Spec Revision 3.0 Version 2.0 + ECNs 2020-12-10 6.4.4.2.3 Structured VDM Version "The Structured VDM Version field of the Discover Identity Command sent and received during VDM discovery Shall be used to determine the lowest common Structured VDM Version supported by the Port Partners or Cable Plug and Shall continue to operate using this Specification Revision until they are Detached." Add a variable in typec_capability to specify the highest SVDM version supported by the port and another variable in typec_partner to cache the negotiated SVDM version between the port and the partner. Also add setter/getter functions for the negotiated SVDM version. Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Kyle Tso <kyletso@google.com> Link: https://lore.kernel.org/r/20210205033415.3320439-2-kyletso@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/typec/class.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index b4a5d9d4564f..45f0bf65e9ab 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -38,6 +38,7 @@ struct typec_partner {
struct ida mode_ids;
int num_altmodes;
u16 pd_revision; /* 0300H = "3.0" */
+ enum usb_pd_svdm_ver svdm_version;
};
struct typec_port {
@@ -825,6 +826,20 @@ typec_partner_register_altmode(struct typec_partner *partner,
EXPORT_SYMBOL_GPL(typec_partner_register_altmode);
/**
+ * typec_partner_set_svdm_version - Set negotiated Structured VDM (SVDM) Version
+ * @partner: USB Type-C Partner that supports SVDM
+ * @svdm_version: Negotiated SVDM Version
+ *
+ * This routine is used to save the negotiated SVDM Version.
+ */
+void typec_partner_set_svdm_version(struct typec_partner *partner,
+ enum usb_pd_svdm_ver svdm_version)
+{
+ partner->svdm_version = svdm_version;
+}
+EXPORT_SYMBOL_GPL(typec_partner_set_svdm_version);
+
+/**
* typec_register_partner - Register a USB Type-C Partner
* @port: The USB Type-C Port the partner is connected to
* @desc: Description of the partner
@@ -848,6 +863,7 @@ struct typec_partner *typec_register_partner(struct typec_port *port,
partner->accessory = desc->accessory;
partner->num_altmodes = -1;
partner->pd_revision = desc->pd_revision;
+ partner->svdm_version = port->cap->svdm_version;
if (desc->identity) {
/*
@@ -1895,6 +1911,33 @@ EXPORT_SYMBOL_GPL(typec_set_mode);
/* --------------------------------------- */
/**
+ * typec_get_negotiated_svdm_version - Get negotiated SVDM Version
+ * @port: USB Type-C Port.
+ *
+ * Get the negotiated SVDM Version. The Version is set to the port default
+ * value stored in typec_capability on partner registration, and updated after
+ * a successful Discover Identity if the negotiated value is less than the
+ * default value.
+ *
+ * Returns usb_pd_svdm_ver if the partner has been registered otherwise -ENODEV.
+ */
+int typec_get_negotiated_svdm_version(struct typec_port *port)
+{
+ enum usb_pd_svdm_ver svdm_version;
+ struct device *partner_dev;
+
+ partner_dev = device_find_child(&port->dev, NULL, partner_match);
+ if (!partner_dev)
+ return -ENODEV;
+
+ svdm_version = to_typec_partner(partner_dev)->svdm_version;
+ put_device(partner_dev);
+
+ return svdm_version;
+}
+EXPORT_SYMBOL_GPL(typec_get_negotiated_svdm_version);
+
+/**
* typec_get_drvdata - Return private driver data pointer
* @port: USB Type-C port
*/