Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ceeb1625 authored by Heikki Krogerus's avatar Heikki Krogerus Committed by Greg Kroah-Hartman
Browse files

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: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarHeikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fde0aa6c
Loading
Loading
Loading
Loading
+34 −22
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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,
};
+5 −4
Original line number Diff line number Diff line
@@ -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;
+17 −9
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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,
};

Loading