MLK-16013-27 staging: typec: add super speed signal mux selection
According to the polarity of cc line, we need to do USB3 signal mux selection if it's controlled by software. Reviewed-by: Peter Chen <peter.chen@nxp.com> Signed-off-by: Li Jun <jun.li@nxp.com>pull/10/head
parent
45927e4eb2
commit
13f735b060
|
@ -21,6 +21,7 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/usb/typec.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
#include "pd.h"
|
||||
#include "tcpci.h"
|
||||
|
@ -37,6 +38,7 @@ struct tcpci {
|
|||
struct regmap *regmap;
|
||||
|
||||
bool controls_vbus;
|
||||
int ss_sel_gpio;
|
||||
|
||||
struct tcpc_dev tcpc;
|
||||
unsigned int irq_mask;
|
||||
|
@ -258,6 +260,19 @@ static int tcpci_set_polarity(struct tcpc_dev *tcpc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tcpci_set_ss_mux(struct tcpc_dev *tcpc,
|
||||
enum typec_cc_polarity polarity)
|
||||
{
|
||||
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
|
||||
|
||||
if (polarity == TYPEC_POLARITY_CC1)
|
||||
gpio_set_value(tcpci->ss_sel_gpio, 1);
|
||||
else
|
||||
gpio_set_value(tcpci->ss_sel_gpio, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable)
|
||||
{
|
||||
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
|
||||
|
@ -583,6 +598,27 @@ static int tcpci_parse_config(struct tcpci *tcpci)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tcpci_ss_mux_control_init(struct tcpci *tcpci)
|
||||
{
|
||||
struct device *dev = tcpci->dev;
|
||||
int retval = 0;
|
||||
|
||||
tcpci->ss_sel_gpio = of_get_named_gpio(dev->of_node,
|
||||
"ss-sel-gpios", 0);
|
||||
if (!gpio_is_valid(tcpci->ss_sel_gpio)) {
|
||||
/* Super speed signal mux conrol gpio is optional */
|
||||
dev_dbg(dev, "no Super Speed mux gpio pin available");
|
||||
} else {
|
||||
retval = devm_gpio_request_one(dev, tcpci->ss_sel_gpio,
|
||||
GPIOF_OUT_INIT_LOW, "typec_ss_sel");
|
||||
if (retval < 0)
|
||||
dev_err(dev, "Unable to request super speed mux gpio %d\n",
|
||||
retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int tcpci_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *i2c_id)
|
||||
{
|
||||
|
@ -612,6 +648,7 @@ static int tcpci_probe(struct i2c_client *client,
|
|||
tcpci->tcpc.vbus_discharge = tcpci_vbus_force_discharge;
|
||||
tcpci->tcpc.get_vbus_vol = tcpci_get_vbus_vol;
|
||||
tcpci->tcpc.bist_mode = tcpci_bist_mode;
|
||||
tcpci->tcpc.ss_mux_sel = tcpci_set_ss_mux;
|
||||
|
||||
tcpci->tcpc.set_pd_rx = tcpci_set_pd_rx;
|
||||
tcpci->tcpc.set_roles = tcpci_set_roles;
|
||||
|
@ -632,6 +669,10 @@ static int tcpci_probe(struct i2c_client *client,
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = tcpci_ss_mux_control_init(tcpci);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
|
||||
return PTR_ERR_OR_ZERO(tcpci->port);
|
||||
}
|
||||
|
|
|
@ -1988,6 +1988,9 @@ static int tcpm_src_attach(struct tcpm_port *port)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (port->tcpc->ss_mux_sel)
|
||||
port->tcpc->ss_mux_sel(port->tcpc, polarity);
|
||||
|
||||
tcpm_start_drp_toggling(port);
|
||||
|
||||
ret = tcpm_set_roles(port, true, TYPEC_SOURCE, TYPEC_HOST);
|
||||
|
@ -2096,16 +2099,20 @@ static void tcpm_src_detach(struct tcpm_port *port)
|
|||
|
||||
static int tcpm_snk_attach(struct tcpm_port *port)
|
||||
{
|
||||
enum typec_cc_polarity polarity = port->cc2 != TYPEC_CC_OPEN ?
|
||||
TYPEC_POLARITY_CC2 : TYPEC_POLARITY_CC1;
|
||||
int ret;
|
||||
|
||||
if (port->attached)
|
||||
return 0;
|
||||
|
||||
ret = tcpm_set_polarity(port, port->cc2 != TYPEC_CC_OPEN ?
|
||||
TYPEC_POLARITY_CC2 : TYPEC_POLARITY_CC1);
|
||||
ret = tcpm_set_polarity(port, polarity);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (port->tcpc->ss_mux_sel)
|
||||
port->tcpc->ss_mux_sel(port->tcpc, polarity);
|
||||
|
||||
tcpm_start_drp_toggling(port);
|
||||
|
||||
ret = tcpm_set_roles(port, true, TYPEC_SINK, TYPEC_DEVICE);
|
||||
|
|
|
@ -140,6 +140,8 @@ struct tcpc_dev {
|
|||
int (*vbus_detect)(struct tcpc_dev *dev, bool enable);
|
||||
int (*vbus_discharge)(struct tcpc_dev *tcpc, bool enable);
|
||||
void (*bist_mode)(struct tcpc_dev *tcpc, bool enable);
|
||||
int (*ss_mux_sel)(struct tcpc_dev *dev,
|
||||
enum typec_cc_polarity polarity);
|
||||
|
||||
struct tcpc_mux_dev *mux;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue