diff options
-rw-r--r-- | drivers/usb/typec/class.c | 43 | ||||
-rw-r--r-- | include/linux/usb/typec.h | 12 | ||||
-rw-r--r-- | include/linux/usb/typec_altmode.h | 10 |
3 files changed, 65 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 */ diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index a94df82ab62f..91b4303ca305 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -217,12 +217,19 @@ struct typec_operations { enum typec_port_type type); }; +enum usb_pd_svdm_ver { + SVDM_VER_1_0 = 0, + SVDM_VER_2_0 = 1, + SVDM_VER_MAX = SVDM_VER_2_0, +}; + /* * struct typec_capability - USB Type-C Port Capabilities * @type: Supported power role of the port * @data: Supported data role of the port * @revision: USB Type-C Specification release. Binary coded decimal * @pd_revision: USB Power Delivery Specification revision if supported + * @svdm_version: USB PD Structured VDM version if supported * @prefer_role: Initial role preference (DRP ports). * @accessory: Supported Accessory Modes * @fwnode: Optional fwnode of the port @@ -236,6 +243,7 @@ struct typec_capability { enum typec_port_data data; u16 revision; /* 0120H = "1.2" */ u16 pd_revision; /* 0300H = "3.0" */ + enum usb_pd_svdm_ver svdm_version; int prefer_role; enum typec_accessory accessory[TYPEC_MAX_ACCESSORY]; unsigned int orientation_aware:1; @@ -286,4 +294,8 @@ int typec_find_orientation(const char *name); int typec_find_port_power_role(const char *name); int typec_find_power_role(const char *name); int typec_find_port_data_role(const char *name); + +void typec_partner_set_svdm_version(struct typec_partner *partner, + enum usb_pd_svdm_ver svdm_version); +int typec_get_negotiated_svdm_version(struct typec_port *port); #endif /* __LINUX_USB_TYPEC_H */ diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h index 5e0a7b7647c3..65933cbe9129 100644 --- a/include/linux/usb/typec_altmode.h +++ b/include/linux/usb/typec_altmode.h @@ -133,6 +133,16 @@ typec_altmode_get_orientation(struct typec_altmode *altmode) } /** + * typec_altmode_get_svdm_version - Get negotiated SVDM version + * @altmode: Handle to the alternate mode + */ +static inline int +typec_altmode_get_svdm_version(struct typec_altmode *altmode) +{ + return typec_get_negotiated_svdm_version(typec_altmode2port(altmode)); +} + +/** * struct typec_altmode_driver - USB Type-C alternate mode device driver * @id_table: Null terminated array of SVIDs * @probe: Callback for device binding |