Re: [PATCHi v6 1/7] usb: typec: Manage SVDM version

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Feb 05, 2021 at 11:34:09AM +0800, Kyle Tso wrote:
> 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.
> 
> Signed-off-by: Kyle Tso <kyletso@xxxxxxxxxx>

Reviewed-by: Guenter Roeck <linux@xxxxxxxxxxxx>

> ---
> Changes since v5
> - !! most changes are from Heikki
> - location of the negotiated SVDM version is changed. Now the variable
>   resides in typec_partner
> - The setter and getter functions were modified according to the above
>   changes
> - the default SVDM version is stored upon calling to
>   typec_register_partner
> 
>  drivers/usb/typec/class.c         | 43 +++++++++++++++++++++++++++++++
>  include/linux/usb/typec.h         | 12 +++++++++
>  include/linux/usb/typec_altmode.h | 10 +++++++
>  3 files changed, 65 insertions(+)
> 
> 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 {
> @@ -824,6 +825,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
> @@ -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) {
>  		/*
> @@ -1894,6 +1910,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
> @@ -132,6 +132,16 @@ typec_altmode_get_orientation(struct typec_altmode *altmode)
>  	return typec_get_orientation(typec_altmode2port(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
> -- 
> 2.30.0.365.g02bc693789-goog
> 



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux