diff options
author | Prashant Malani <pmalani@chromium.org> | 2020-04-14 22:29:43 -0700 |
---|---|---|
committer | Enric Balletbo i Serra <enric.balletbo@collabora.com> | 2020-04-15 08:00:20 +0200 |
commit | 9d33ea331032332882d4cc1a38a9d0e237126bd0 (patch) | |
tree | 15ec2f0af7057017024b1493b5347894a64477cc /drivers/platform | |
parent | platform/chrome: cros_ec_typec: Add struct for port data (diff) | |
download | wireguard-linux-9d33ea331032332882d4cc1a38a9d0e237126bd0.tar.xz wireguard-linux-9d33ea331032332882d4cc1a38a9d0e237126bd0.zip |
platform/chrome: cros_ec_typec: Register port partner
Register (and unregister) the port partner when a connect (and
disconnect) is detected.
Co-developed-by: Jon Flatley <jflat@chromium.org>
Signed-off-by: Prashant Malani <pmalani@chromium.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/chrome/cros_ec_typec.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 56ded09a60ff..eda57db26f8d 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -22,6 +22,9 @@ struct cros_typec_port { struct typec_port *port; /* Initial capabilities for the port. */ struct typec_capability caps; + struct typec_partner *partner; + /* Port partner PD identity info. */ + struct usb_pd_identity p_identity; }; /* Platform-specific data for the Chrome OS EC Type C controller. */ @@ -190,6 +193,30 @@ static int cros_typec_ec_command(struct cros_typec_data *typec, return ret; } +static int cros_typec_add_partner(struct cros_typec_data *typec, int port_num, + bool pd_en) +{ + struct cros_typec_port *port = typec->ports[port_num]; + struct typec_partner_desc p_desc = { + .usb_pd = pd_en, + }; + int ret = 0; + + /* + * Fill an initial PD identity, which will then be updated with info + * from the EC. + */ + p_desc.identity = &port->p_identity; + + port->partner = typec_register_partner(port->port, &p_desc); + if (IS_ERR(port->partner)) { + ret = PTR_ERR(port->partner); + port->partner = NULL; + } + + return ret; +} + static void cros_typec_set_port_params_v0(struct cros_typec_data *typec, int port_num, struct ec_response_usb_pd_control *resp) { @@ -212,6 +239,8 @@ static void cros_typec_set_port_params_v1(struct cros_typec_data *typec, { struct typec_port *port = typec->ports[port_num]->port; enum typec_orientation polarity; + bool pd_en; + int ret; if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED)) polarity = TYPEC_ORIENTATION_NONE; @@ -226,6 +255,25 @@ static void cros_typec_set_port_params_v1(struct cros_typec_data *typec, TYPEC_SOURCE : TYPEC_SINK); typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ? TYPEC_SOURCE : TYPEC_SINK); + + /* Register/remove partners when a connect/disconnect occurs. */ + if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) { + if (typec->ports[port_num]->partner) + return; + + pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE; + ret = cros_typec_add_partner(typec, port_num, pd_en); + if (!ret) + dev_warn(typec->dev, + "Failed to register partner on port: %d\n", + port_num); + } else { + if (!typec->ports[port_num]->partner) + return; + + typec_unregister_partner(typec->ports[port_num]->partner); + typec->ports[port_num]->partner = NULL; + } } static int cros_typec_port_update(struct cros_typec_data *typec, int port_num) |