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

Commit 94d1501d authored by Linyu Yuan's avatar Linyu Yuan
Browse files

usb: phy: qmp: support multiple function of portselect



On QRD device we want to read pmic CC output through gpio function,
thus request and release phy pinctrl state here,
it allow other function driver request gpio pin state.

Change-Id: I9901e3019656691d1f4ae17cd55ef2cd6784a330
Signed-off-by: default avatarLinyu Yuan <linyyuan@codeaurora.org>
parent 6d967e6d
Loading
Loading
Loading
Loading
+39 −10
Original line number Diff line number Diff line
@@ -365,6 +365,44 @@ 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;

	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;
		}
	}

	dev_dbg(phy->phy.dev, "use hw port select\n");

	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);
}

static void usb_qmp_update_portselect_phymode(struct msm_ssphy_qmp *phy)
{
@@ -382,16 +420,7 @@ static void usb_qmp_update_portselect_phymode(struct msm_ssphy_qmp *phy)

	switch (phy->phy_type) {
	case USB3_AND_DP:
		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]);
		}
		usb_qmp_update_hw_portselect(phy);

		/* override hardware control for reset of qmp phy */
		writel_relaxed(SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |