Loading drivers/usb/dwc3/dwc3-msm.c +45 −27 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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; } Loading drivers/usb/misc/ssusb-redriver-nb7vpq904m.c +27 −37 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -403,40 +402,15 @@ static int ssusb_redriver_read_configuration(struct ssusb_redriver *redriver) 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) return -EINVAL; orientation_pinctrl = pinctrl_get(dev); if (IS_ERR_OR_NULL(orientation_pinctrl)) { dev_err(dev, "Failed to get pinctrl\n"); if (!gpio_is_valid(redriver->orientation_gpio)) 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) Loading @@ -444,13 +418,31 @@ static int ssusb_redriver_read_orientation(struct ssusb_redriver *redriver) else redriver->typec_orientation = ORIENTATION_CC2; ret = 0; return 0; } int redriver_orientation_get(struct device_node *node) { struct ssusb_redriver *redriver; struct i2c_client *client; if (!node) return -ENODEV; put_pinctrl: pinctrl_put(orientation_pinctrl); client = of_find_i2c_device_by_node(node); if (!client) return -ENODEV; return ret; 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) Loading Loading @@ -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; } Loading @@ -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 = { Loading drivers/usb/phy/phy-msm-ssusb-qmp.c +10 −46 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 | Loading include/linux/usb/redriver.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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
drivers/usb/dwc3/dwc3-msm.c +45 −27 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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; } Loading
drivers/usb/misc/ssusb-redriver-nb7vpq904m.c +27 −37 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -403,40 +402,15 @@ static int ssusb_redriver_read_configuration(struct ssusb_redriver *redriver) 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) return -EINVAL; orientation_pinctrl = pinctrl_get(dev); if (IS_ERR_OR_NULL(orientation_pinctrl)) { dev_err(dev, "Failed to get pinctrl\n"); if (!gpio_is_valid(redriver->orientation_gpio)) 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) Loading @@ -444,13 +418,31 @@ static int ssusb_redriver_read_orientation(struct ssusb_redriver *redriver) else redriver->typec_orientation = ORIENTATION_CC2; ret = 0; return 0; } int redriver_orientation_get(struct device_node *node) { struct ssusb_redriver *redriver; struct i2c_client *client; if (!node) return -ENODEV; put_pinctrl: pinctrl_put(orientation_pinctrl); client = of_find_i2c_device_by_node(node); if (!client) return -ENODEV; return ret; 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) Loading Loading @@ -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; } Loading @@ -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 = { Loading
drivers/usb/phy/phy-msm-ssusb-qmp.c +10 −46 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 | Loading
include/linux/usb/redriver.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 */