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

Commit fa7e9b99 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: dwc3: allow get orientation from redriver"

parents b869650d f32272fd
Loading
Loading
Loading
Loading
+45 −27
Original line number Diff line number Diff line
@@ -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;
}
+27 −37
Original line number Diff line number Diff line
@@ -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 @@ 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)
@@ -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)
@@ -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 = {
+10 −46
Original line number Diff line number Diff line
@@ -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 |
+6 −0
Original line number Diff line number Diff line
@@ -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 */