Skip to content

Commit

Permalink
usb: typec: tcpci: add support to set connector orientation
Browse files Browse the repository at this point in the history
This add the support to set the optional connector orientation bit which
is part of the optional CONFIG_STANDARD_OUTPUT register 0x18 [1]. This
allows system designers to connect the tcpc orientation pin directly to
the 2:1 ss-mux.

[1] https://www.usb.org/sites/default/files/documents/usb-port_controller_specification_rev2.0_v1.0_0.pdf

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20240701132133.3054394-1-m.felsch@pengutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Marco Felsch authored and Greg Kroah-Hartman committed Jul 3, 2024
1 parent 89b5a5a commit 62ce9ef
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
44 changes: 44 additions & 0 deletions drivers/usb/typec/tcpm/tcpci.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ static int tcpci_write16(struct tcpci *tcpci, unsigned int reg, u16 val)
return regmap_raw_write(tcpci->regmap, reg, &val, sizeof(u16));
}

static bool tcpci_check_std_output_cap(struct regmap *regmap, u8 mask)
{
unsigned int reg;
int ret;

ret = regmap_read(regmap, TCPC_STD_OUTPUT_CAP, &reg);
if (ret < 0)
return ret;

return (reg & mask) == mask;
}

static int tcpci_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc)
{
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
Expand Down Expand Up @@ -301,6 +313,28 @@ static int tcpci_set_polarity(struct tcpc_dev *tcpc,
TCPC_TCPC_CTRL_ORIENTATION : 0);
}

static int tcpci_set_orientation(struct tcpc_dev *tcpc,
enum typec_orientation orientation)
{
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
unsigned int reg;

switch (orientation) {
case TYPEC_ORIENTATION_NONE:
/* We can't put a single output into high impedance */
fallthrough;
case TYPEC_ORIENTATION_NORMAL:
reg = TCPC_CONFIG_STD_OUTPUT_ORIENTATION_NORMAL;
break;
case TYPEC_ORIENTATION_REVERSE:
reg = TCPC_CONFIG_STD_OUTPUT_ORIENTATION_FLIPPED;
break;
}

return regmap_update_bits(tcpci->regmap, TCPC_CONFIG_STD_OUTPUT,
TCPC_CONFIG_STD_OUTPUT_ORIENTATION_MASK, reg);
}

static void tcpci_set_partner_usb_comm_capable(struct tcpc_dev *tcpc, bool capable)
{
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
Expand Down Expand Up @@ -830,6 +864,9 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data)
if (tcpci->data->vbus_vsafe0v)
tcpci->tcpc.is_vbus_vsafe0v = tcpci_is_vbus_vsafe0v;

if (tcpci->data->set_orientation)
tcpci->tcpc.set_orientation = tcpci_set_orientation;

err = tcpci_parse_config(tcpci);
if (err < 0)
return ERR_PTR(err);
Expand Down Expand Up @@ -873,6 +910,13 @@ static int tcpci_probe(struct i2c_client *client)
if (err < 0)
return err;

err = tcpci_check_std_output_cap(chip->data.regmap,
TCPC_STD_OUTPUT_CAP_ORIENTATION);
if (err < 0)
return err;

chip->data.set_orientation = err;

chip->tcpci = tcpci_register_port(&client->dev, &chip->data);
if (IS_ERR(chip->tcpci))
return PTR_ERR(chip->tcpci);
Expand Down
8 changes: 8 additions & 0 deletions include/linux/usb/tcpci.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
#define TCPC_SINK_FAST_ROLE_SWAP BIT(0)

#define TCPC_CONFIG_STD_OUTPUT 0x18
#define TCPC_CONFIG_STD_OUTPUT_ORIENTATION_MASK BIT(0)
#define TCPC_CONFIG_STD_OUTPUT_ORIENTATION_NORMAL 0
#define TCPC_CONFIG_STD_OUTPUT_ORIENTATION_FLIPPED 1

#define TCPC_TCPC_CTRL 0x19
#define TCPC_TCPC_CTRL_ORIENTATION BIT(0)
Expand Down Expand Up @@ -127,6 +130,7 @@
#define TCPC_DEV_CAP_2 0x26
#define TCPC_STD_INPUT_CAP 0x28
#define TCPC_STD_OUTPUT_CAP 0x29
#define TCPC_STD_OUTPUT_CAP_ORIENTATION BIT(0)

#define TCPC_MSG_HDR_INFO 0x2e
#define TCPC_MSG_HDR_INFO_DATA_ROLE BIT(3)
Expand Down Expand Up @@ -209,13 +213,17 @@ struct tcpci;
* swap following Discover Identity on SOP' occurs.
* Return true when the TCPM is allowed to request a Vconn swap
* after Discovery Identity on SOP.
* @set_orientation:
* Optional; Enable setting the connector orientation
* CONFIG_STANDARD_OUTPUT (0x18) bit0.
*/
struct tcpci_data {
struct regmap *regmap;
unsigned char TX_BUF_BYTE_x_hidden:1;
unsigned char auto_discharge_disconnect:1;
unsigned char vbus_vsafe0v:1;
unsigned char cable_comm_capable:1;
unsigned char set_orientation:1;

int (*init)(struct tcpci *tcpci, struct tcpci_data *data);
int (*set_vconn)(struct tcpci *tcpci, struct tcpci_data *data,
Expand Down

0 comments on commit 62ce9ef

Please sign in to comment.