Skip to content

Commit

Permalink
usb: typec: mux: intel_pmc_mux: Support for static SBU/HSL orientation
Browse files Browse the repository at this point in the history
The SBU and HSL orientation may be fixed/static from the mux
PoW. Apparently the retimer may take care of the orientation
of these lines. Handling the static SBU (AUX) and HSL
orientation with device properties.

If the SBU orientation is static, a device property
"sbu-orintation" can be used. When the property exists, the
driver always sets the SBU orientation according to the
property value, and when it's not set, the driver uses the
cable plug orientation with SBU.

And with static HSL orientation, "hsl-orientation" device
property can be used in the same way.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20200507150900.12102-3-heikki.krogerus@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Heikki Krogerus authored and Greg Kroah-Hartman committed May 13, 2020
1 parent 8c49c9e commit ff4a30d
Showing 1 changed file with 36 additions and 6 deletions.
42 changes: 36 additions & 6 deletions drivers/usb/typec/mux/intel_pmc_mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ struct pmc_usb_port {

u8 usb2_port;
u8 usb3_port;

enum typec_orientation sbu_orientation;
enum typec_orientation hsl_orientation;
};

struct pmc_usb {
Expand All @@ -99,6 +102,22 @@ struct pmc_usb {
struct pmc_usb_port *port;
};

static int sbu_orientation(struct pmc_usb_port *port)
{
if (port->sbu_orientation)
return port->sbu_orientation - 1;

return port->orientation - 1;
}

static int hsl_orientation(struct pmc_usb_port *port)
{
if (port->hsl_orientation)
return port->hsl_orientation - 1;

return port->orientation - 1;
}

static int pmc_usb_command(struct pmc_usb_port *port, u8 *msg, u32 len)
{
u8 response[4];
Expand Down Expand Up @@ -151,8 +170,9 @@ pmc_usb_mux_dp(struct pmc_usb_port *port, struct typec_mux_state *state)

req.mode_data = (port->orientation - 1) << PMC_USB_ALTMODE_ORI_SHIFT;
req.mode_data |= (port->role - 1) << PMC_USB_ALTMODE_UFP_SHIFT;
req.mode_data |= (port->orientation - 1) << PMC_USB_ALTMODE_ORI_AUX_SHIFT;
req.mode_data |= (port->orientation - 1) << PMC_USB_ALTMODE_ORI_HSL_SHIFT;

req.mode_data |= sbu_orientation(port) << PMC_USB_ALTMODE_ORI_AUX_SHIFT;
req.mode_data |= hsl_orientation(port) << PMC_USB_ALTMODE_ORI_HSL_SHIFT;

req.mode_data |= (state->mode - TYPEC_STATE_MODAL) <<
PMC_USB_ALTMODE_DP_MODE_SHIFT;
Expand All @@ -177,8 +197,9 @@ pmc_usb_mux_tbt(struct pmc_usb_port *port, struct typec_mux_state *state)

req.mode_data = (port->orientation - 1) << PMC_USB_ALTMODE_ORI_SHIFT;
req.mode_data |= (port->role - 1) << PMC_USB_ALTMODE_UFP_SHIFT;
req.mode_data |= (port->orientation - 1) << PMC_USB_ALTMODE_ORI_AUX_SHIFT;
req.mode_data |= (port->orientation - 1) << PMC_USB_ALTMODE_ORI_HSL_SHIFT;

req.mode_data |= sbu_orientation(port) << PMC_USB_ALTMODE_ORI_AUX_SHIFT;
req.mode_data |= hsl_orientation(port) << PMC_USB_ALTMODE_ORI_HSL_SHIFT;

if (TBT_ADAPTER(data->device_mode) == TBT_ADAPTER_TBT3)
req.mode_data |= PMC_USB_ALTMODE_TBT_TYPE;
Expand Down Expand Up @@ -215,8 +236,8 @@ static int pmc_usb_connect(struct pmc_usb_port *port)
msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;

msg[1] = port->usb2_port << PMC_USB_MSG_USB2_PORT_SHIFT;
msg[1] |= (port->orientation - 1) << PMC_USB_MSG_ORI_HSL_SHIFT;
msg[1] |= (port->orientation - 1) << PMC_USB_MSG_ORI_AUX_SHIFT;
msg[1] |= hsl_orientation(port) << PMC_USB_MSG_ORI_HSL_SHIFT;
msg[1] |= sbu_orientation(port) << PMC_USB_MSG_ORI_AUX_SHIFT;

return pmc_usb_command(port, msg, sizeof(msg));
}
Expand Down Expand Up @@ -300,6 +321,7 @@ static int pmc_usb_register_port(struct pmc_usb *pmc, int index,
struct usb_role_switch_desc desc = { };
struct typec_switch_desc sw_desc = { };
struct typec_mux_desc mux_desc = { };
const char *str;
int ret;

ret = fwnode_property_read_u8(fwnode, "usb2-port-number", &port->usb2_port);
Expand All @@ -310,6 +332,14 @@ static int pmc_usb_register_port(struct pmc_usb *pmc, int index,
if (ret)
return ret;

ret = fwnode_property_read_string(fwnode, "sbu-orientation", &str);
if (!ret)
port->sbu_orientation = typec_find_orientation(str);

ret = fwnode_property_read_string(fwnode, "hsl-orientation", &str);
if (!ret)
port->hsl_orientation = typec_find_orientation(str);

port->num = index;
port->pmc = pmc;

Expand Down

0 comments on commit ff4a30d

Please sign in to comment.