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

Commit 14c829cd authored by Manikandan Mohan's avatar Manikandan Mohan
Browse files

cnss2: Check for BT Enable GPIO in QCA6490



QCA6490 requires synchronization between BT and WLAN enable gpio
to avoid power up issue. Update platform driver to get BT enable
GPIO config and perform delayed WLAN enable if BT is off.

Change-Id: I77e5aa87b09128dbac41b59927f88f53fa4ddebd
Signed-off-by: default avatarManikandan Mohan <manikand@codeaurora.org>
parent da2e3647
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ struct cnss_pinctrl_info {
	struct pinctrl_state *bootstrap_active;
	struct pinctrl_state *wlan_en_active;
	struct pinctrl_state *wlan_en_sleep;
	int bt_en_gpio;
};

#if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
+53 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/regulator/consumer.h>
#include <soc/qcom/cmd-db.h>
#include <linux/of_gpio.h>

#include "main.h"
#include "debug.h"
@@ -41,6 +42,7 @@ static struct cnss_clk_cfg cnss_clk_list[] = {
#define BOOTSTRAP_GPIO			"qcom,enable-bootstrap-gpio"
#define BOOTSTRAP_ACTIVE		"bootstrap_active"
#define WLAN_EN_GPIO			"wlan-en-gpio"
#define BT_EN_GPIO			"qcom,bt-en-gpio"
#define WLAN_EN_ACTIVE			"wlan_en_active"
#define WLAN_EN_SLEEP			"wlan_en_sleep"

@@ -700,6 +702,15 @@ int cnss_get_pinctrl(struct cnss_plat_data *plat_priv)
		}
	}

	/* Added for QCA6490 PMU delayed WLAN_EN_GPIO */
	if (of_find_property(dev->of_node, BT_EN_GPIO, NULL)) {
		pinctrl_info->bt_en_gpio = of_get_named_gpio(dev->of_node,
							     BT_EN_GPIO, 0);
		cnss_pr_dbg("BT GPIO: %d\n", pinctrl_info->bt_en_gpio);
	} else {
		pinctrl_info->bt_en_gpio = -EINVAL;
	}

	return 0;
out:
	return ret;
@@ -763,6 +774,47 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
	return ret;
}

/**
 * cnss_select_pinctrl_enable - select WLAN_GPIO for Active pinctrl status
 * @plat_priv: Platform private data structure pointer
 *
 * For QCA6490, PMU requires minimum 100ms delay between BT_EN_GPIO off and
 * WLAN_EN_GPIO on. This is done to avoid power up issues.
 *
 * Return: Status of pinctrl select operation. 0 - Success.
 */
static int cnss_select_pinctrl_enable(struct cnss_plat_data *plat_priv)
{
	int ret = 0, bt_en_gpio = plat_priv->pinctrl_info.bt_en_gpio;
	u8 wlan_en_state = 0;

	if (bt_en_gpio < 0 || plat_priv->device_id != QCA6490_DEVICE_ID)
		goto set_wlan_en;

	if (gpio_get_value(bt_en_gpio)) {
		cnss_pr_dbg("BT_EN_GPIO State: On\n");
		ret = cnss_select_pinctrl_state(plat_priv, true);
		if (!ret)
			return ret;
		wlan_en_state = 1;
	}
	if (!gpio_get_value(bt_en_gpio)) {
		cnss_pr_dbg("BT_EN_GPIO State: Off. Delay WLAN_GPIO enable\n");
		/* check for BT_EN_GPIO down race during above operation */
		if (wlan_en_state) {
			cnss_pr_dbg("Reset WLAN_EN as BT got turned off during enable\n");
			cnss_select_pinctrl_state(plat_priv, false);
			wlan_en_state = 0;
		}
		/* 100 ms delay for BT_EN and WLAN_EN QCA6490 PMU sequencing */
		msleep(100);
	}
set_wlan_en:
	if (!wlan_en_state)
		ret = cnss_select_pinctrl_state(plat_priv, true);
	return ret;
}

int cnss_power_on_device(struct cnss_plat_data *plat_priv)
{
	int ret = 0;
@@ -784,7 +836,7 @@ int cnss_power_on_device(struct cnss_plat_data *plat_priv)
		goto vreg_off;
	}

	ret = cnss_select_pinctrl_state(plat_priv, true);
	ret = cnss_select_pinctrl_enable(plat_priv);
	if (ret) {
		cnss_pr_err("Failed to select pinctrl state, err = %d\n", ret);
		goto clk_off;