Loading drivers/usb/dwc3/dwc3-msm.c +10 −0 Original line number Diff line number Diff line Loading @@ -2992,6 +2992,7 @@ static irqreturn_t msm_dwc3_pwr_irq(int irq, void *data) } static void dwc3_otg_sm_work(struct work_struct *w); static int get_psy_type(struct dwc3_msm *mdwc); static int dwc3_msm_get_clk_gdsc(struct dwc3_msm *mdwc) { Loading Loading @@ -3158,6 +3159,8 @@ static void check_for_sdp_connection(struct work_struct *w) } } #define DP_PULSE_WIDTH_MSEC 200 static int dwc3_msm_vbus_notifier(struct notifier_block *nb, unsigned long event, void *ptr) { Loading @@ -3181,6 +3184,13 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb, dev_dbg(mdwc->dev, "vbus:%ld event received\n", event); mdwc->vbus_active = event; if (get_psy_type(mdwc) == POWER_SUPPLY_TYPE_USB_CDP && mdwc->vbus_active) { dev_dbg(mdwc->dev, "Connected to CDP, pull DP up\n"); usb_phy_drive_dp_pulse(mdwc->hs_phy, DP_PULSE_WIDTH_MSEC); } if (dwc3_is_otg_or_drd(dwc) && !mdwc->in_restart) queue_work(mdwc->dwc3_wq, &mdwc->resume_work); Loading drivers/usb/phy/phy-msm-snps-hs.c +62 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,11 @@ #define OPMODE_MASK (0x3 << 3) #define OPMODE_NONDRIVING (0x1 << 3) #define SLEEPM BIT(0) #define OPMODE_NORMAL (0x00) #define TERMSEL BIT(5) #define USB2_PHY_USB_PHY_UTMI_CTRL1 (0x40) #define XCVRSEL BIT(0) #define USB2_PHY_USB_PHY_UTMI_CTRL5 (0x50) #define POR BIT(1) Loading Loading @@ -516,6 +521,62 @@ static int msm_hsphy_notify_disconnect(struct usb_phy *uphy, return 0; } static int msm_hsphy_drive_dp_pulse(struct usb_phy *uphy, unsigned int interval_ms) { struct msm_hsphy *phy = container_of(uphy, struct msm_hsphy, phy); int ret; ret = msm_hsphy_enable_power(phy, true); if (ret < 0) { dev_dbg(uphy->dev, "dpdm regulator enable failed:%d\n", ret); return ret; } msm_hsphy_enable_clocks(phy, true); /* set utmi_phy_cmn_cntrl_override_en & * utmi_phy_datapath_ctrl_override_en */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, UTMI_PHY_CMN_CTRL_OVERRIDE_EN); msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0, UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN, UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN); /* set opmode to normal i.e. 0x0 & termsel to fs */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL0, OPMODE_MASK, OPMODE_NORMAL); msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL0, TERMSEL, TERMSEL); /* set xcvrsel to fs */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL1, XCVRSEL, XCVRSEL); msleep(interval_ms); /* clear termsel to fs */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL0, TERMSEL, 0x00); /* clear xcvrsel */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL1, XCVRSEL, 0x00); /* clear utmi_phy_cmn_cntrl_override_en & * utmi_phy_datapath_ctrl_override_en */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 0x00); msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0, UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN, 0x00); msleep(20); msm_hsphy_enable_clocks(phy, false); ret = msm_hsphy_enable_power(phy, false); if (ret < 0) { dev_dbg(uphy->dev, "dpdm regulator disable failed:%d\n", ret); } return 0; } static int msm_hsphy_dpdm_regulator_enable(struct regulator_dev *rdev) { int ret = 0; Loading Loading @@ -788,6 +849,7 @@ static int msm_hsphy_probe(struct platform_device *pdev) phy->phy.notify_connect = msm_hsphy_notify_connect; phy->phy.notify_disconnect = msm_hsphy_notify_disconnect; phy->phy.type = USB_PHY_TYPE_USB2; phy->phy.drive_dp_pulse = msm_hsphy_drive_dp_pulse; ret = usb_add_phy_dev(&phy->phy); if (ret) Loading include/linux/usb/phy.h +10 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,7 @@ struct usb_phy { /* reset the PHY clocks */ int (*reset)(struct usb_phy *x); int (*drive_dp_pulse)(struct usb_phy *x, unsigned int pulse_width); }; /* for board-specific init logic */ Loading Loading @@ -240,6 +241,15 @@ usb_phy_reset(struct usb_phy *x) return 0; } static inline int usb_phy_drive_dp_pulse(struct usb_phy *x, unsigned int pulse_width) { if (x && x->drive_dp_pulse) return x->drive_dp_pulse(x, pulse_width); return 0; } /* for usb host and peripheral controller drivers */ #if IS_ENABLED(CONFIG_USB_PHY) extern struct usb_phy *usb_get_phy(enum usb_phy_type type); Loading Loading
drivers/usb/dwc3/dwc3-msm.c +10 −0 Original line number Diff line number Diff line Loading @@ -2992,6 +2992,7 @@ static irqreturn_t msm_dwc3_pwr_irq(int irq, void *data) } static void dwc3_otg_sm_work(struct work_struct *w); static int get_psy_type(struct dwc3_msm *mdwc); static int dwc3_msm_get_clk_gdsc(struct dwc3_msm *mdwc) { Loading Loading @@ -3158,6 +3159,8 @@ static void check_for_sdp_connection(struct work_struct *w) } } #define DP_PULSE_WIDTH_MSEC 200 static int dwc3_msm_vbus_notifier(struct notifier_block *nb, unsigned long event, void *ptr) { Loading @@ -3181,6 +3184,13 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb, dev_dbg(mdwc->dev, "vbus:%ld event received\n", event); mdwc->vbus_active = event; if (get_psy_type(mdwc) == POWER_SUPPLY_TYPE_USB_CDP && mdwc->vbus_active) { dev_dbg(mdwc->dev, "Connected to CDP, pull DP up\n"); usb_phy_drive_dp_pulse(mdwc->hs_phy, DP_PULSE_WIDTH_MSEC); } if (dwc3_is_otg_or_drd(dwc) && !mdwc->in_restart) queue_work(mdwc->dwc3_wq, &mdwc->resume_work); Loading
drivers/usb/phy/phy-msm-snps-hs.c +62 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,11 @@ #define OPMODE_MASK (0x3 << 3) #define OPMODE_NONDRIVING (0x1 << 3) #define SLEEPM BIT(0) #define OPMODE_NORMAL (0x00) #define TERMSEL BIT(5) #define USB2_PHY_USB_PHY_UTMI_CTRL1 (0x40) #define XCVRSEL BIT(0) #define USB2_PHY_USB_PHY_UTMI_CTRL5 (0x50) #define POR BIT(1) Loading Loading @@ -516,6 +521,62 @@ static int msm_hsphy_notify_disconnect(struct usb_phy *uphy, return 0; } static int msm_hsphy_drive_dp_pulse(struct usb_phy *uphy, unsigned int interval_ms) { struct msm_hsphy *phy = container_of(uphy, struct msm_hsphy, phy); int ret; ret = msm_hsphy_enable_power(phy, true); if (ret < 0) { dev_dbg(uphy->dev, "dpdm regulator enable failed:%d\n", ret); return ret; } msm_hsphy_enable_clocks(phy, true); /* set utmi_phy_cmn_cntrl_override_en & * utmi_phy_datapath_ctrl_override_en */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, UTMI_PHY_CMN_CTRL_OVERRIDE_EN); msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0, UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN, UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN); /* set opmode to normal i.e. 0x0 & termsel to fs */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL0, OPMODE_MASK, OPMODE_NORMAL); msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL0, TERMSEL, TERMSEL); /* set xcvrsel to fs */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL1, XCVRSEL, XCVRSEL); msleep(interval_ms); /* clear termsel to fs */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL0, TERMSEL, 0x00); /* clear xcvrsel */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL1, XCVRSEL, 0x00); /* clear utmi_phy_cmn_cntrl_override_en & * utmi_phy_datapath_ctrl_override_en */ msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 0x00); msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0, UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN, 0x00); msleep(20); msm_hsphy_enable_clocks(phy, false); ret = msm_hsphy_enable_power(phy, false); if (ret < 0) { dev_dbg(uphy->dev, "dpdm regulator disable failed:%d\n", ret); } return 0; } static int msm_hsphy_dpdm_regulator_enable(struct regulator_dev *rdev) { int ret = 0; Loading Loading @@ -788,6 +849,7 @@ static int msm_hsphy_probe(struct platform_device *pdev) phy->phy.notify_connect = msm_hsphy_notify_connect; phy->phy.notify_disconnect = msm_hsphy_notify_disconnect; phy->phy.type = USB_PHY_TYPE_USB2; phy->phy.drive_dp_pulse = msm_hsphy_drive_dp_pulse; ret = usb_add_phy_dev(&phy->phy); if (ret) Loading
include/linux/usb/phy.h +10 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,7 @@ struct usb_phy { /* reset the PHY clocks */ int (*reset)(struct usb_phy *x); int (*drive_dp_pulse)(struct usb_phy *x, unsigned int pulse_width); }; /* for board-specific init logic */ Loading Loading @@ -240,6 +241,15 @@ usb_phy_reset(struct usb_phy *x) return 0; } static inline int usb_phy_drive_dp_pulse(struct usb_phy *x, unsigned int pulse_width) { if (x && x->drive_dp_pulse) return x->drive_dp_pulse(x, pulse_width); return 0; } /* for usb host and peripheral controller drivers */ #if IS_ENABLED(CONFIG_USB_PHY) extern struct usb_phy *usb_get_phy(enum usb_phy_type type); Loading