Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de1df690 authored by Hemant Kumar's avatar Hemant Kumar Committed by Mayank Rana
Browse files

usb: dwc3: Add support to select maximum speed via extcon notification



Use extcon notification to select the maximum speed for host as well
as for peripheral mode. Notification handler sets maximum speed based
on the extcon cable state flag. This provides an option to start host
or peripheral in high speed only mode and leave ss phy suspended.

Change-Id: Ic48c661e68a293822d30cbd491e0fe6e46d385c9
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 8caff358
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -191,6 +191,9 @@ static int dwc3_init_usb_phys(struct dwc3 *dwc)
		return ret;
	}

	if (dwc->maximum_speed == USB_SPEED_HIGH)
		goto generic_phy_init;

	ret = usb_phy_init(dwc->usb3_phy);
	if (ret == -EBUSY) {
		/*
@@ -203,6 +206,8 @@ static int dwc3_init_usb_phys(struct dwc3 *dwc)
				__func__, ret);
		return ret;
	}

generic_phy_init:
	ret = phy_init(dwc->usb2_generic_phy);
	if (ret < 0)
		return ret;
@@ -226,6 +231,8 @@ static int dwc3_core_reset(struct dwc3 *dwc)

	/* Reset PHYs */
	usb_phy_reset(dwc->usb2_phy);

	if (dwc->maximum_speed == USB_SPEED_SUPER)
		usb_phy_reset(dwc->usb3_phy);

	/* Initialize PHYs */
+20 −4
Original line number Diff line number Diff line
@@ -1904,7 +1904,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc)
	usb_phy_set_suspend(mdwc->hs_phy, 1);

	/* Suspend SS PHY */
	if (can_suspend_ssphy) {
	if (dwc->maximum_speed == USB_SPEED_SUPER && can_suspend_ssphy) {
		/* indicate phy about SS mode */
		if (dwc3_msm_is_superspeed(mdwc))
			mdwc->ss_phy->flags |= DEVICE_IN_SS_MODE;
@@ -2049,7 +2049,8 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc)
		clk_prepare_enable(mdwc->bus_aggr_clk);

	/* Resume SS PHY */
	if (mdwc->lpm_flags & MDWC3_SS_PHY_SUSPEND) {
	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->typec_orientation == ORIENTATION_CC1)
			mdwc->ss_phy->flags |= PHY_LANE_A;
@@ -2404,9 +2405,11 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb,
	unsigned long event, void *ptr)
{
	struct dwc3_msm *mdwc = container_of(nb, struct dwc3_msm, id_nb);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
	struct extcon_dev *edev = ptr;
	enum dwc3_id_state id;
	int cc_state;
	int speed;

	if (!edev) {
		dev_err(mdwc->dev, "%s: edev null\n", __func__);
@@ -2424,6 +2427,11 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb,
		mdwc->typec_orientation =
			cc_state ? ORIENTATION_CC2 : ORIENTATION_CC1;

	dev_dbg(mdwc->dev, "cc_state:%d", mdwc->typec_orientation);

	speed = extcon_get_cable_state_(edev, EXTCON_USB_SPEED);
	dwc->maximum_speed = (speed == 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER;

	if (mdwc->id_state != id) {
		mdwc->id_state = id;
		queue_work(mdwc->dwc3_wq, &mdwc->resume_work);
@@ -2440,6 +2448,7 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
	struct extcon_dev *edev = ptr;
	int cc_state;
	int speed;

	if (!edev) {
		dev_err(mdwc->dev, "%s: edev null\n", __func__);
@@ -2458,6 +2467,11 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
		mdwc->typec_orientation =
			cc_state ? ORIENTATION_CC2 : ORIENTATION_CC1;

	dev_dbg(mdwc->dev, "cc_state:%d", mdwc->typec_orientation);

	speed = extcon_get_cable_state_(edev, EXTCON_USB_SPEED);
	dwc->maximum_speed = (speed == 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER;

	mdwc->vbus_active = event;
	if (dwc->is_drd && !mdwc->in_restart)
		queue_work(mdwc->dwc3_wq, &mdwc->resume_work);
@@ -3000,9 +3014,11 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
	if (on) {
		dev_dbg(mdwc->dev, "%s: turn on host\n", __func__);

		pm_runtime_get_sync(mdwc->dev);
		mdwc->hs_phy->flags |= PHY_HOST_MODE;
		if (dwc->maximum_speed == USB_SPEED_SUPER)
			mdwc->ss_phy->flags |= PHY_HOST_MODE;

		pm_runtime_get_sync(mdwc->dev);
		usb_phy_notify_connect(mdwc->hs_phy, USB_SPEED_HIGH);
		if (!IS_ERR(mdwc->vbus_reg))
			ret = regulator_enable(mdwc->vbus_reg);