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

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

Merge "cnss2: Add support XO Clock selection leakage prevention"

parents 58dc954a b3dd9f66
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ struct cnss_pinctrl_info {
	struct pinctrl_state *wlan_en_active;
	struct pinctrl_state *wlan_en_sleep;
	int bt_en_gpio;
	int xo_clk_gpio; /*qca6490 only */
};

#if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
+49 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ static struct cnss_clk_cfg cnss_clk_list[] = {
#define BOOTSTRAP_ACTIVE		"bootstrap_active"
#define WLAN_EN_GPIO			"wlan-en-gpio"
#define BT_EN_GPIO			"qcom,bt-en-gpio"
#define XO_CLK_GPIO			"qcom,xo-clk-gpio"
#define WLAN_EN_ACTIVE			"wlan_en_active"
#define WLAN_EN_SLEEP			"wlan_en_sleep"

@@ -711,11 +712,57 @@ int cnss_get_pinctrl(struct cnss_plat_data *plat_priv)
		pinctrl_info->bt_en_gpio = -EINVAL;
	}

	/* Added for QCA6490 to minimize XO CLK selection leakage prevention */
	if (of_find_property(dev->of_node, XO_CLK_GPIO, NULL)) {
		pinctrl_info->xo_clk_gpio = of_get_named_gpio(dev->of_node,
							      XO_CLK_GPIO, 0);
		cnss_pr_dbg("QCA6490 XO_CLK GPIO: %d\n",
			    pinctrl_info->xo_clk_gpio);
	} else {
		pinctrl_info->xo_clk_gpio = -EINVAL;
	}
	return 0;
out:
	return ret;
}

#define CNSS_XO_CLK_RETRY_COUNT_MAX 5
static void cnss_set_xo_clk_gpio_state(struct cnss_plat_data *plat_priv,
				       bool enable)
{
	int xo_clk_gpio = plat_priv->pinctrl_info.xo_clk_gpio, retry = 0, ret;

	if (xo_clk_gpio < 0 || plat_priv->device_id != QCA6490_DEVICE_ID)
		return;

retry_gpio_req:
	ret = gpio_request(xo_clk_gpio, "XO_CLK_GPIO");
	if (ret) {
		if (retry++ < CNSS_XO_CLK_RETRY_COUNT_MAX) {
			/* wait for ~(10 - 20) ms */
			usleep_range(10000, 20000);
			goto retry_gpio_req;
		}
	}

	if (ret) {
		cnss_pr_err("QCA6490 XO CLK Gpio request failed\n");
		return;
	}

	if (enable) {
		gpio_direction_output(xo_clk_gpio, 1);
		/*XO CLK must be asserted for some time before WLAN_EN */
		usleep_range(100, 200);
	} else {
		/* Assert XO CLK ~(2-5)ms before off for valid latch in HW */
		usleep_range(2000, 5000);
		gpio_direction_output(xo_clk_gpio, 0);
	}

	gpio_free(xo_clk_gpio);
}

static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
				     bool state)
{
@@ -742,7 +789,7 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
			}
			udelay(BOOTSTRAP_DELAY);
		}

		cnss_set_xo_clk_gpio_state(plat_priv, true);
		if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_active)) {
			ret = pinctrl_select_state
				(pinctrl_info->pinctrl,
@@ -754,6 +801,7 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
			}
			udelay(WLAN_ENABLE_DELAY);
		}
		cnss_set_xo_clk_gpio_state(plat_priv, false);
	} else {
		if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_sleep)) {
			ret = pinctrl_select_state(pinctrl_info->pinctrl,