usb: typec: Separate the definitions for data and power roles
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. Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
fde0aa6c17
commit
ceeb162500
|
@ -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;
|
||||
|
|
|
@ -1219,6 +1219,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,
|
||||
};
|
||||
|
|
|
@ -345,7 +345,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;
|
||||
|
@ -2179,7 +2179,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;
|
||||
}
|
||||
|
||||
|
@ -3469,11 +3469,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);
|
||||
|
@ -3641,6 +3641,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;
|
||||
|
|
|
@ -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 */
|
||||
case TPS_PORTINFO_DRP_UFP:
|
||||
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_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.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);
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue