On Fri, Mar 09, 2018 at 02:09:18PM +0300, Heikki Krogerus wrote:
> USB Type-C specification v1.2 separated the power and data
> roles more clearly. Dual-Role-Data term was introduced, and
> the meaning of DRP was changed from "Dual-Role-Port" to
> "Dual-Role-Power".
> 
> In order to allow the port drivers to describe the
> capabilities of the ports more clearly according to the
> newest specifications, introducing separate definitions for
> the data roles.
> 
> Signed-off-by: Heikki Krogerus <heikki.kroge...@linux.intel.com>

Reviewed-by: Guenter Roeck <li...@roeck-us.net>

> ---
>  drivers/usb/typec/class.c           | 56 
> ++++++++++++++++++++++---------------
>  drivers/usb/typec/fusb302/fusb302.c |  1 +
>  drivers/usb/typec/tcpm.c            |  9 +++---
>  drivers/usb/typec/tps6598x.c        | 26 +++++++++++------
>  drivers/usb/typec/typec_wcove.c     |  1 +
>  drivers/usb/typec/ucsi/ucsi.c       | 13 +++++++--
>  include/linux/usb/tcpm.h            |  1 +
>  include/linux/usb/typec.h           | 14 ++++++++--
>  8 files changed, 80 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
> index 2620a694704f..53df10df2f9d 100644
> --- a/drivers/usb/typec/class.c
> +++ b/drivers/usb/typec/class.c
> @@ -282,10 +282,10 @@ typec_altmode_roles_show(struct device *dev, struct 
> device_attribute *attr,
>       ssize_t ret;
>  
>       switch (mode->roles) {
> -     case TYPEC_PORT_DFP:
> +     case TYPEC_PORT_SRC:
>               ret = sprintf(buf, "source\n");
>               break;
> -     case TYPEC_PORT_UFP:
> +     case TYPEC_PORT_SNK:
>               ret = sprintf(buf, "sink\n");
>               break;
>       case TYPEC_PORT_DRP:
> @@ -797,14 +797,14 @@ static const char * const typec_data_roles[] = {
>  };
>  
>  static const char * const typec_port_types[] = {
> -     [TYPEC_PORT_DFP] = "source",
> -     [TYPEC_PORT_UFP] = "sink",
> +     [TYPEC_PORT_SRC] = "source",
> +     [TYPEC_PORT_SNK] = "sink",
>       [TYPEC_PORT_DRP] = "dual",
>  };
>  
>  static const char * const typec_port_types_drp[] = {
> -     [TYPEC_PORT_DFP] = "dual [source] sink",
> -     [TYPEC_PORT_UFP] = "dual source [sink]",
> +     [TYPEC_PORT_SRC] = "dual [source] sink",
> +     [TYPEC_PORT_SNK] = "dual source [sink]",
>       [TYPEC_PORT_DRP] = "[dual] source sink",
>  };
>  
> @@ -875,9 +875,7 @@ static ssize_t data_role_store(struct device *dev,
>               return ret;
>  
>       mutex_lock(&port->port_type_lock);
> -     if (port->port_type != TYPEC_PORT_DRP) {
> -             dev_dbg(dev, "port type fixed at \"%s\"",
> -                          typec_port_types[port->port_type]);
> +     if (port->cap->data != TYPEC_PORT_DRD) {
>               ret = -EOPNOTSUPP;
>               goto unlock_and_ret;
>       }
> @@ -897,7 +895,7 @@ static ssize_t data_role_show(struct device *dev,
>  {
>       struct typec_port *port = to_typec_port(dev);
>  
> -     if (port->cap->type == TYPEC_PORT_DRP)
> +     if (port->cap->data == TYPEC_PORT_DRD)
>               return sprintf(buf, "%s\n", port->data_role == TYPEC_HOST ?
>                              "[host] device" : "host [device]");
>  
> @@ -1328,7 +1326,6 @@ struct typec_port *typec_register_port(struct device 
> *parent,
>                                      const struct typec_capability *cap)
>  {
>       struct typec_port *port;
> -     int role;
>       int ret;
>       int id;
>  
> @@ -1354,21 +1351,36 @@ struct typec_port *typec_register_port(struct device 
> *parent,
>               goto err_mux;
>       }
>  
> -     if (cap->type == TYPEC_PORT_DFP)
> -             role = TYPEC_SOURCE;
> -     else if (cap->type == TYPEC_PORT_UFP)
> -             role = TYPEC_SINK;
> -     else
> -             role = cap->prefer_role;
> -
> -     if (role == TYPEC_SOURCE) {
> -             port->data_role = TYPEC_HOST;
> +     switch (cap->type) {
> +     case TYPEC_PORT_SRC:
>               port->pwr_role = TYPEC_SOURCE;
>               port->vconn_role = TYPEC_SOURCE;
> -     } else {
> -             port->data_role = TYPEC_DEVICE;
> +             break;
> +     case TYPEC_PORT_SNK:
>               port->pwr_role = TYPEC_SINK;
>               port->vconn_role = TYPEC_SINK;
> +             break;
> +     case TYPEC_PORT_DRP:
> +             if (cap->prefer_role != TYPEC_NO_PREFERRED_ROLE)
> +                     port->pwr_role = cap->prefer_role;
> +             else
> +                     port->pwr_role = TYPEC_SINK;
> +             break;
> +     }
> +
> +     switch (cap->data) {
> +     case TYPEC_PORT_DFP:
> +             port->data_role = TYPEC_HOST;
> +             break;
> +     case TYPEC_PORT_UFP:
> +             port->data_role = TYPEC_DEVICE;
> +             break;
> +     case TYPEC_PORT_DRD:
> +             if (cap->prefer_role == TYPEC_SOURCE)
> +                     port->data_role = TYPEC_HOST;
> +             else
> +                     port->data_role = TYPEC_DEVICE;
> +             break;
>       }
>  
>       port->id = id;
> diff --git a/drivers/usb/typec/fusb302/fusb302.c 
> b/drivers/usb/typec/fusb302/fusb302.c
> index b267b907bf24..76c9d955fa40 100644
> --- a/drivers/usb/typec/fusb302/fusb302.c
> +++ b/drivers/usb/typec/fusb302/fusb302.c
> @@ -1230,6 +1230,7 @@ static const struct tcpc_config fusb302_tcpc_config = {
>       .max_snk_mw = 15000,
>       .operating_snk_mw = 2500,
>       .type = TYPEC_PORT_DRP,
> +     .data = TYPEC_PORT_DRD,
>       .default_role = TYPEC_SINK,
>       .alt_modes = NULL,
>  };
> diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
> index 735a6dd74c20..4e447e1e9ec6 100644
> --- a/drivers/usb/typec/tcpm.c
> +++ b/drivers/usb/typec/tcpm.c
> @@ -347,7 +347,7 @@ static enum tcpm_state tcpm_default_state(struct 
> tcpm_port *port)
>               else if (port->tcpc->config->default_role == TYPEC_SINK)
>                       return SNK_UNATTACHED;
>               /* Fall through to return SRC_UNATTACHED */
> -     } else if (port->port_type == TYPEC_PORT_UFP) {
> +     } else if (port->port_type == TYPEC_PORT_SNK) {
>               return SNK_UNATTACHED;
>       }
>       return SRC_UNATTACHED;
> @@ -2207,7 +2207,7 @@ static inline enum tcpm_state unattached_state(struct 
> tcpm_port *port)
>                       return SRC_UNATTACHED;
>               else
>                       return SNK_UNATTACHED;
> -     } else if (port->port_type == TYPEC_PORT_DFP) {
> +     } else if (port->port_type == TYPEC_PORT_SRC) {
>               return SRC_UNATTACHED;
>       }
>  
> @@ -3497,11 +3497,11 @@ static int tcpm_port_type_set(const struct 
> typec_capability *cap,
>  
>       if (!port->connected) {
>               tcpm_set_state(port, PORT_RESET, 0);
> -     } else if (type == TYPEC_PORT_UFP) {
> +     } else if (type == TYPEC_PORT_SNK) {
>               if (!(port->pwr_role == TYPEC_SINK &&
>                     port->data_role == TYPEC_DEVICE))
>                       tcpm_set_state(port, PORT_RESET, 0);
> -     } else if (type == TYPEC_PORT_DFP) {
> +     } else if (type == TYPEC_PORT_SRC) {
>               if (!(port->pwr_role == TYPEC_SOURCE &&
>                     port->data_role == TYPEC_HOST))
>                       tcpm_set_state(port, PORT_RESET, 0);
> @@ -3669,6 +3669,7 @@ struct tcpm_port *tcpm_register_port(struct device 
> *dev, struct tcpc_dev *tcpc)
>  
>       port->typec_caps.prefer_role = tcpc->config->default_role;
>       port->typec_caps.type = tcpc->config->type;
> +     port->typec_caps.data = tcpc->config->data;
>       port->typec_caps.revision = 0x0120;     /* Type-C spec release 1.2 */
>       port->typec_caps.pd_revision = 0x0200;  /* USB-PD spec release 2.0 */
>       port->typec_caps.dr_set = tcpm_dr_set;
> diff --git a/drivers/usb/typec/tps6598x.c b/drivers/usb/typec/tps6598x.c
> index 37a15c14a6c6..8b8406867c02 100644
> --- a/drivers/usb/typec/tps6598x.c
> +++ b/drivers/usb/typec/tps6598x.c
> @@ -393,31 +393,39 @@ static int tps6598x_probe(struct i2c_client *client)
>       if (ret < 0)
>               return ret;
>  
> +     tps->typec_cap.revision = USB_TYPEC_REV_1_2;
> +     tps->typec_cap.pd_revision = 0x200;
> +     tps->typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
> +     tps->typec_cap.pr_set = tps6598x_pr_set;
> +     tps->typec_cap.dr_set = tps6598x_dr_set;
> +
>       switch (TPS_SYSCONF_PORTINFO(conf)) {
>       case TPS_PORTINFO_SINK_ACCESSORY:
>       case TPS_PORTINFO_SINK:
> -             tps->typec_cap.type = TYPEC_PORT_UFP;
> +             tps->typec_cap.type = TYPEC_PORT_SNK;
> +             tps->typec_cap.data = TYPEC_PORT_UFP;
>               break;
>       case TPS_PORTINFO_DRP_UFP_DRD:
>       case TPS_PORTINFO_DRP_DFP_DRD:
> -             tps->typec_cap.dr_set = tps6598x_dr_set;
> -             /* fall through */
> +             tps->typec_cap.type = TYPEC_PORT_DRP;
> +             tps->typec_cap.data = TYPEC_PORT_DRD;
> +             break;
>       case TPS_PORTINFO_DRP_UFP:
> +             tps->typec_cap.type = TYPEC_PORT_DRP;
> +             tps->typec_cap.data = TYPEC_PORT_UFP;
> +             break;
>       case TPS_PORTINFO_DRP_DFP:
> -             tps->typec_cap.pr_set = tps6598x_pr_set;
>               tps->typec_cap.type = TYPEC_PORT_DRP;
> +             tps->typec_cap.data = TYPEC_PORT_DFP;
>               break;
>       case TPS_PORTINFO_SOURCE:
> -             tps->typec_cap.type = TYPEC_PORT_DFP;
> +             tps->typec_cap.type = TYPEC_PORT_SRC;
> +             tps->typec_cap.data = TYPEC_PORT_DFP;
>               break;
>       default:
>               return -ENODEV;
>       }
>  
> -     tps->typec_cap.revision = USB_TYPEC_REV_1_2;
> -     tps->typec_cap.pd_revision = 0x200;
> -     tps->typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
> -
>       tps->port = typec_register_port(&client->dev, &tps->typec_cap);
>       if (IS_ERR(tps->port))
>               return PTR_ERR(tps->port);
> diff --git a/drivers/usb/typec/typec_wcove.c b/drivers/usb/typec/typec_wcove.c
> index 2e990e0d917d..19cca7f1b2c5 100644
> --- a/drivers/usb/typec/typec_wcove.c
> +++ b/drivers/usb/typec/typec_wcove.c
> @@ -572,6 +572,7 @@ static struct tcpc_config wcove_typec_config = {
>       .operating_snk_mw = 15000,
>  
>       .type = TYPEC_PORT_DRP,
> +     .data = TYPEC_PORT_DRD,
>       .default_role = TYPEC_SINK,
>  };
>  
> diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
> index 69d544cfcd45..bf0977fbd100 100644
> --- a/drivers/usb/typec/ucsi/ucsi.c
> +++ b/drivers/usb/typec/ucsi/ucsi.c
> @@ -592,11 +592,18 @@ static int ucsi_register_port(struct ucsi *ucsi, int 
> index)
>               return ret;
>  
>       if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DRP)
> -             cap->type = TYPEC_PORT_DRP;
> +             cap->data = TYPEC_PORT_DRD;
>       else if (con->cap.op_mode & UCSI_CONCAP_OPMODE_DFP)
> -             cap->type = TYPEC_PORT_DFP;
> +             cap->data = TYPEC_PORT_DFP;
>       else if (con->cap.op_mode & UCSI_CONCAP_OPMODE_UFP)
> -             cap->type = TYPEC_PORT_UFP;
> +             cap->data = TYPEC_PORT_UFP;
> +
> +     if (con->cap.provider && con->cap.consumer)
> +             cap->type = TYPEC_PORT_DRP;
> +     else if (con->cap.provider)
> +             cap->type = TYPEC_PORT_SRC;
> +     else if (con->cap.consumer)
> +             cap->type = TYPEC_PORT_SNK;
>  
>       cap->revision = ucsi->cap.typec_version;
>       cap->pd_revision = ucsi->cap.pd_version;
> diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h
> index fe3508e6e1df..f0d839daeaea 100644
> --- a/include/linux/usb/tcpm.h
> +++ b/include/linux/usb/tcpm.h
> @@ -91,6 +91,7 @@ struct tcpc_config {
>       unsigned int operating_snk_mw;
>  
>       enum typec_port_type type;
> +     enum typec_port_data data;
>       enum typec_role default_role;
>       bool try_role_hw;       /* try.{src,snk} implemented in hardware */
>  
> diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
> index 2408e5c2ed91..672b39bb0adc 100644
> --- a/include/linux/usb/typec.h
> +++ b/include/linux/usb/typec.h
> @@ -22,9 +22,15 @@ struct typec_port;
>  struct fwnode_handle;
>  
>  enum typec_port_type {
> +     TYPEC_PORT_SRC,
> +     TYPEC_PORT_SNK,
> +     TYPEC_PORT_DRP,
> +};
> +
> +enum typec_port_data {
>       TYPEC_PORT_DFP,
>       TYPEC_PORT_UFP,
> -     TYPEC_PORT_DRP,
> +     TYPEC_PORT_DRD,
>  };
>  
>  enum typec_plug_type {
> @@ -186,10 +192,11 @@ struct typec_partner_desc {
>  
>  /*
>   * struct typec_capability - USB Type-C Port Capabilities
> - * @role: DFP (Host-only), UFP (Device-only) or DRP (Dual Role)
> + * @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
> - * @prefer_role: Initial role preference
> + * @prefer_role: Initial role preference (DRP ports).
>   * @accessory: Supported Accessory Modes
>   * @sw: Cable plug orientation switch
>   * @mux: Multiplexer switch for Alternate/Accessory Modes
> @@ -205,6 +212,7 @@ struct typec_partner_desc {
>   */
>  struct typec_capability {
>       enum typec_port_type    type;
> +     enum typec_port_data    data;
>       u16                     revision; /* 0120H = "1.2" */
>       u16                     pd_revision; /* 0300H = "3.0" */
>       int                     prefer_role;
> -- 
> 2.16.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to