mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 12:25:00 -04:00
Merge "usb: dwc3: allow get orientation from redriver"
This commit is contained in:
commit
fa7e9b99b3
4 changed files with 88 additions and 110 deletions
|
|
@ -287,13 +287,6 @@ enum dwc3_id_state {
|
|||
DWC3_ID_FLOAT,
|
||||
};
|
||||
|
||||
/* for type c cable */
|
||||
enum plug_orientation {
|
||||
ORIENTATION_NONE,
|
||||
ORIENTATION_CC1,
|
||||
ORIENTATION_CC2,
|
||||
};
|
||||
|
||||
enum msm_usb_irq {
|
||||
HS_PHY_IRQ,
|
||||
PWR_EVNT_IRQ,
|
||||
|
|
@ -476,7 +469,6 @@ struct dwc3_msm {
|
|||
|
||||
atomic_t in_p3;
|
||||
unsigned int lpm_to_suspend_delay;
|
||||
enum plug_orientation typec_orientation;
|
||||
u32 num_gsi_event_buffers;
|
||||
struct dwc3_event_buffer **gsi_ev_buff;
|
||||
int pm_qos_latency;
|
||||
|
|
@ -2683,6 +2675,45 @@ static void dwc3_set_phy_speed_flags(struct dwc3_msm *mdwc)
|
|||
}
|
||||
}
|
||||
|
||||
static void dwc3_set_ssphy_orientation_flag(struct dwc3_msm *mdwc)
|
||||
{
|
||||
struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
|
||||
union extcon_property_value val;
|
||||
struct extcon_dev *edev = NULL;
|
||||
unsigned int extcon_id;
|
||||
int ret;
|
||||
|
||||
mdwc->ss_phy->flags &= ~(PHY_LANE_A | PHY_LANE_B);
|
||||
|
||||
if (mdwc->orientation_override) {
|
||||
mdwc->ss_phy->flags |= mdwc->orientation_override;
|
||||
} else if (mdwc->ss_redriver_node) {
|
||||
ret = redriver_orientation_get(mdwc->ss_redriver_node);
|
||||
if (ret == 0)
|
||||
mdwc->ss_phy->flags |= PHY_LANE_A;
|
||||
else
|
||||
mdwc->ss_phy->flags |= PHY_LANE_B;
|
||||
} else {
|
||||
if (mdwc->extcon && mdwc->vbus_active && !mdwc->in_restart) {
|
||||
extcon_id = EXTCON_USB;
|
||||
edev = mdwc->extcon[mdwc->ext_idx].edev;
|
||||
} else if (mdwc->extcon && mdwc->id_state == DWC3_ID_GROUND) {
|
||||
extcon_id = EXTCON_USB_HOST;
|
||||
edev = mdwc->extcon[mdwc->ext_idx].edev;
|
||||
}
|
||||
|
||||
if (edev && extcon_get_state(edev, extcon_id)) {
|
||||
ret = extcon_get_property(edev, extcon_id,
|
||||
EXTCON_PROP_USB_TYPEC_POLARITY, &val);
|
||||
if (ret == 0)
|
||||
mdwc->ss_phy->flags |= val.intval ?
|
||||
PHY_LANE_B : PHY_LANE_A;
|
||||
}
|
||||
}
|
||||
|
||||
dbg_event(0xFF, "ss_flag", mdwc->ss_phy->flags);
|
||||
}
|
||||
|
||||
static void msm_dwc3_perf_vote_update(struct dwc3_msm *mdwc,
|
||||
bool perf_mode);
|
||||
|
||||
|
|
@ -3094,13 +3125,7 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc)
|
|||
/* Resume SS PHY */
|
||||
if (dwc->maximum_speed >= USB_SPEED_SUPER &&
|
||||
mdwc->lpm_flags & MDWC3_SS_PHY_SUSPEND) {
|
||||
mdwc->ss_phy->flags &= ~(PHY_LANE_A | PHY_LANE_B);
|
||||
if (mdwc->orientation_override)
|
||||
mdwc->ss_phy->flags |= mdwc->orientation_override;
|
||||
else if (mdwc->typec_orientation == ORIENTATION_CC1)
|
||||
mdwc->ss_phy->flags |= PHY_LANE_A;
|
||||
else if (mdwc->typec_orientation == ORIENTATION_CC2)
|
||||
mdwc->ss_phy->flags |= PHY_LANE_B;
|
||||
dwc3_set_ssphy_orientation_flag(mdwc);
|
||||
usb_phy_set_suspend(mdwc->ss_phy, 0);
|
||||
mdwc->ss_phy->flags &= ~DEVICE_IN_SS_MODE;
|
||||
mdwc->lpm_flags &= ~MDWC3_SS_PHY_SUSPEND;
|
||||
|
|
@ -3284,25 +3309,18 @@ static void dwc3_resume_work(struct work_struct *w)
|
|||
}
|
||||
|
||||
dwc->maximum_speed = dwc->max_hw_supp_speed;
|
||||
/* Check speed and Type-C polarity values in order to configure PHY */
|
||||
|
||||
if (edev && extcon_get_state(edev, extcon_id)) {
|
||||
ret = extcon_get_property(edev, extcon_id,
|
||||
EXTCON_PROP_USB_SS, &val);
|
||||
|
||||
if (!ret && val.intval == 0)
|
||||
dwc->maximum_speed = USB_SPEED_HIGH;
|
||||
|
||||
ret = extcon_get_property(edev, extcon_id,
|
||||
EXTCON_PROP_USB_TYPEC_POLARITY, &val);
|
||||
if (ret)
|
||||
mdwc->typec_orientation = ORIENTATION_NONE;
|
||||
else
|
||||
mdwc->typec_orientation = val.intval ?
|
||||
ORIENTATION_CC2 : ORIENTATION_CC1;
|
||||
|
||||
dbg_event(0xFF, "cc_state", mdwc->typec_orientation);
|
||||
}
|
||||
|
||||
if (dwc->maximum_speed >= USB_SPEED_SUPER)
|
||||
dwc3_set_ssphy_orientation_flag(mdwc);
|
||||
|
||||
skip_update:
|
||||
dbg_log_string("max_speed:%d hw_supp_speed:%d override_speed:%d",
|
||||
dwc->maximum_speed, dwc->max_hw_supp_speed,
|
||||
|
|
@ -3820,7 +3838,7 @@ static ssize_t orientation_store(struct device *dev,
|
|||
else if (sysfs_streq(buf, "B"))
|
||||
mdwc->orientation_override = PHY_LANE_B;
|
||||
else
|
||||
mdwc->orientation_override = ORIENTATION_NONE;
|
||||
mdwc->orientation_override = 0;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@ struct ssusb_redriver {
|
|||
struct i2c_client *client;
|
||||
|
||||
int orientation_gpio;
|
||||
bool orientation_gpio_enable;
|
||||
enum plug_orientation typec_orientation;
|
||||
enum operation_mode op_mode;
|
||||
|
||||
|
|
@ -403,40 +402,15 @@ err:
|
|||
|
||||
static int ssusb_redriver_read_orientation(struct ssusb_redriver *redriver)
|
||||
{
|
||||
struct device *dev = redriver->dev;
|
||||
struct pinctrl *orientation_pinctrl;
|
||||
struct pinctrl_state *gpio_state;
|
||||
int ret;
|
||||
|
||||
if (!redriver->orientation_gpio_enable)
|
||||
if (!gpio_is_valid(redriver->orientation_gpio))
|
||||
return -EINVAL;
|
||||
|
||||
orientation_pinctrl = pinctrl_get(dev);
|
||||
if (IS_ERR_OR_NULL(orientation_pinctrl)) {
|
||||
dev_err(dev, "Failed to get pinctrl\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gpio_state = pinctrl_lookup_state(orientation_pinctrl, "enable_gpio");
|
||||
if (IS_ERR_OR_NULL(gpio_state)) {
|
||||
dev_err(dev, "Failed to get gpio state\n");
|
||||
ret = -ENODEV;
|
||||
goto put_pinctrl;
|
||||
}
|
||||
|
||||
ret = pinctrl_select_state(orientation_pinctrl, gpio_state);
|
||||
if (ret) {
|
||||
dev_err(redriver->dev, "fail to enable gpio state\n");
|
||||
ret = -EINVAL;
|
||||
goto put_pinctrl;
|
||||
}
|
||||
|
||||
/* wait for some time ??? */
|
||||
ret = gpio_get_value(redriver->orientation_gpio);
|
||||
if (ret < 0) {
|
||||
dev_err(redriver->dev, "fail to read gpio value\n");
|
||||
ret = -EINVAL;
|
||||
goto put_pinctrl;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
|
|
@ -444,14 +418,32 @@ static int ssusb_redriver_read_orientation(struct ssusb_redriver *redriver)
|
|||
else
|
||||
redriver->typec_orientation = ORIENTATION_CC2;
|
||||
|
||||
ret = 0;
|
||||
|
||||
put_pinctrl:
|
||||
pinctrl_put(orientation_pinctrl);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int redriver_orientation_get(struct device_node *node)
|
||||
{
|
||||
struct ssusb_redriver *redriver;
|
||||
struct i2c_client *client;
|
||||
|
||||
if (!node)
|
||||
return -ENODEV;
|
||||
|
||||
client = of_find_i2c_device_by_node(node);
|
||||
if (!client)
|
||||
return -ENODEV;
|
||||
|
||||
redriver = i2c_get_clientdata(client);
|
||||
if (!redriver)
|
||||
return -EINVAL;
|
||||
|
||||
if (!gpio_is_valid(redriver->orientation_gpio))
|
||||
return -EINVAL;
|
||||
|
||||
return gpio_get_value(redriver->orientation_gpio);
|
||||
}
|
||||
EXPORT_SYMBOL(redriver_orientation_get);
|
||||
|
||||
static int ssusb_redriver_ucsi_notifier(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
|
|
@ -669,9 +661,8 @@ static void ssusb_redriver_orientation_gpio_init(
|
|||
struct device *dev = redriver->dev;
|
||||
int rc;
|
||||
|
||||
redriver->orientation_gpio =
|
||||
of_get_named_gpio(dev->of_node, "orientation_gpio", 0);
|
||||
if (redriver->orientation_gpio < 0) {
|
||||
redriver->orientation_gpio = of_get_gpio(dev->of_node, 0);
|
||||
if (!gpio_is_valid(redriver->orientation_gpio)) {
|
||||
dev_err(dev, "Failed to get gpio\n");
|
||||
return;
|
||||
}
|
||||
|
|
@ -679,10 +670,9 @@ static void ssusb_redriver_orientation_gpio_init(
|
|||
rc = devm_gpio_request(dev, redriver->orientation_gpio, "redriver");
|
||||
if (rc < 0) {
|
||||
dev_err(dev, "Failed to request gpio\n");
|
||||
redriver->orientation_gpio = -EINVAL;
|
||||
return;
|
||||
}
|
||||
|
||||
redriver->orientation_gpio_enable = true;
|
||||
}
|
||||
|
||||
static const struct regmap_config redriver_regmap = {
|
||||
|
|
|
|||
|
|
@ -370,51 +370,6 @@ static void msm_ssphy_qmp_setmode(struct msm_ssphy_qmp *phy, u32 mode)
|
|||
readl_relaxed(phy->base + phy->phy_reg[USB3_DP_COM_PHY_MODE_CTRL]);
|
||||
}
|
||||
|
||||
static void usb_qmp_update_hw_portselect(struct msm_ssphy_qmp *phy)
|
||||
{
|
||||
struct pinctrl *portselect_pinctrl;
|
||||
struct pinctrl_state *portselect_state;
|
||||
u32 status;
|
||||
|
||||
if (phy->phy.dev->pins) {
|
||||
portselect_pinctrl = phy->phy.dev->pins->p;
|
||||
portselect_state = phy->phy.dev->pins->default_state;
|
||||
} else {
|
||||
portselect_pinctrl = pinctrl_get(phy->phy.dev);
|
||||
if (IS_ERR_OR_NULL(portselect_pinctrl)) {
|
||||
dev_dbg(phy->phy.dev, "failed to get pinctrl\n");
|
||||
return;
|
||||
}
|
||||
|
||||
portselect_state =
|
||||
pinctrl_lookup_state(portselect_pinctrl, "portselect");
|
||||
if (IS_ERR_OR_NULL(portselect_state)) {
|
||||
dev_dbg(phy->phy.dev,
|
||||
"failed to find portselect state\n");
|
||||
pinctrl_put(portselect_pinctrl);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
writel_relaxed(0x01,
|
||||
phy->base + phy->phy_reg[USB3_DP_COM_SW_RESET]);
|
||||
|
||||
pinctrl_select_state(portselect_pinctrl, portselect_state);
|
||||
|
||||
writel_relaxed(0x00,
|
||||
phy->base + phy->phy_reg[USB3_DP_COM_SW_RESET]);
|
||||
|
||||
if (!phy->phy.dev->pins)
|
||||
pinctrl_put(portselect_pinctrl);
|
||||
|
||||
if (phy->phy_reg[USB3_DP_COM_TYPEC_STATUS]) {
|
||||
status = readl_relaxed(phy->base +
|
||||
phy->phy_reg[USB3_DP_COM_TYPEC_STATUS]);
|
||||
dev_dbg(phy->phy.dev, "hw port select %s\n",
|
||||
status & PORTSELECT_RAW ? "CC2" : "CC1");
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_qmp_update_portselect_phymode(struct msm_ssphy_qmp *phy)
|
||||
{
|
||||
int val;
|
||||
|
|
@ -431,7 +386,16 @@ static void usb_qmp_update_portselect_phymode(struct msm_ssphy_qmp *phy)
|
|||
|
||||
switch (phy->phy_type) {
|
||||
case USB3_AND_DP:
|
||||
usb_qmp_update_hw_portselect(phy);
|
||||
if (phy->phy.dev->pins) {
|
||||
writel_relaxed(0x01,
|
||||
phy->base + phy->phy_reg[USB3_DP_COM_SW_RESET]);
|
||||
|
||||
pinctrl_select_state(phy->phy.dev->pins->p,
|
||||
phy->phy.dev->pins->default_state);
|
||||
|
||||
writel_relaxed(0x00,
|
||||
phy->base + phy->phy_reg[USB3_DP_COM_SW_RESET]);
|
||||
}
|
||||
|
||||
/* override hardware control for reset of qmp phy */
|
||||
writel_relaxed(SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ int redriver_release_usb_lanes(struct device_node *node);
|
|||
int redriver_gadget_pullup(struct device_node *node, int is_on);
|
||||
int redriver_notify_connect(struct device_node *node);
|
||||
int redriver_notify_disconnect(struct device_node *node);
|
||||
int redriver_orientation_get(struct device_node *node);
|
||||
|
||||
#else
|
||||
|
||||
|
|
@ -35,6 +36,11 @@ static inline int redriver_notify_disconnect(struct device_node *node)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int redriver_orientation_get(struct device_node *node)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /*__LINUX_USB_REDRIVER_H */
|
||||
|
|
|
|||
Loading…
Reference in a new issue