Skip to content

Commit

Permalink
platform/chrome: cros_ec_typec: Get retimer handle
Browse files Browse the repository at this point in the history
Where available, obtain the handle to retimer switch specified via
firmware, and update the mux configuration callsites to add retimer
support for supported modes.

Signed-off-by: Prashant Malani <pmalani@chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20220816214857.2088914-8-pmalani@chromium.org
  • Loading branch information
Prashant Malani committed Aug 18, 2022
1 parent d5f6652 commit 1a8912c
Showing 1 changed file with 41 additions and 3 deletions.
44 changes: 41 additions & 3 deletions drivers/platform/chrome/cros_ec_typec.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/usb/typec_altmode.h>
#include <linux/usb/typec_dp.h>
#include <linux/usb/typec_mux.h>
#include <linux/usb/typec_retimer.h>
#include <linux/usb/typec_tbt.h>
#include <linux/usb/role.h>

Expand Down Expand Up @@ -55,6 +56,7 @@ struct cros_typec_port {
struct usb_pd_identity c_identity;
struct typec_switch *ori_sw;
struct typec_mux *mux;
struct typec_retimer *retimer;
struct usb_role_switch *role_sw;

/* Variables keeping track of switch state. */
Expand Down Expand Up @@ -143,6 +145,12 @@ static int cros_typec_get_switch_handles(struct cros_typec_port *port,
goto mux_err;
}

port->retimer = fwnode_typec_retimer_get(fwnode);
if (IS_ERR(port->retimer)) {
dev_dbg(dev, "Retimer handle not found.\n");
goto retimer_sw_err;
}

port->ori_sw = fwnode_typec_switch_get(fwnode);
if (IS_ERR(port->ori_sw)) {
dev_dbg(dev, "Orientation switch handle not found.\n");
Expand All @@ -160,6 +168,8 @@ static int cros_typec_get_switch_handles(struct cros_typec_port *port,
role_sw_err:
typec_switch_put(port->ori_sw);
ori_sw_err:
typec_retimer_put(port->retimer);
retimer_sw_err:
typec_mux_put(port->mux);
mux_err:
return -ENODEV;
Expand Down Expand Up @@ -204,6 +214,21 @@ static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int po
}
}

/*
* Map the Type-C Mux state to retimer state and call the retimer set function. We need this
* because we re-use the Type-C mux state for retimers.
*/
static int cros_typec_retimer_set(struct typec_retimer *retimer, struct typec_mux_state state)
{
struct typec_retimer_state rstate = {
.alt = state.alt,
.mode = state.mode,
.data = state.data,
};

return typec_retimer_set(retimer, &rstate);
}

static int cros_typec_usb_disconnect_state(struct cros_typec_port *port)
{
port->state.alt = NULL;
Expand All @@ -212,6 +237,7 @@ static int cros_typec_usb_disconnect_state(struct cros_typec_port *port)

usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE);
typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE);
cros_typec_retimer_set(port->retimer, port->state);

return typec_mux_set(port->mux, &port->state);
}
Expand Down Expand Up @@ -409,9 +435,14 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)

static int cros_typec_usb_safe_state(struct cros_typec_port *port)
{
int ret;
port->state.mode = TYPEC_STATE_SAFE;

return typec_mux_set(port->mux, &port->state);
ret = cros_typec_retimer_set(port->retimer, port->state);
if (!ret)
ret = typec_mux_set(port->mux, &port->state);

return ret;
}

/*
Expand Down Expand Up @@ -508,7 +539,11 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec,
port->state.data = &dp_data;
port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode));

return typec_mux_set(port->mux, &port->state);
ret = cros_typec_retimer_set(port->retimer, port->state);
if (!ret)
ret = typec_mux_set(port->mux, &port->state);

return ret;
}

static int cros_typec_enable_usb4(struct cros_typec_data *typec,
Expand Down Expand Up @@ -597,7 +632,10 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
} else if (port->mux_flags & USB_PD_MUX_USB_ENABLED) {
port->state.alt = NULL;
port->state.mode = TYPEC_STATE_USB;
ret = typec_mux_set(port->mux, &port->state);

ret = cros_typec_retimer_set(port->retimer, port->state);
if (!ret)
ret = typec_mux_set(port->mux, &port->state);
} else {
dev_dbg(typec->dev,
"Unrecognized mode requested, mux flags: %x\n",
Expand Down

0 comments on commit 1a8912c

Please sign in to comment.