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

Commit 670c7fe2 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cnss: Add support for external 1.15V supply for QCA6174"

parents 6fcd3b26 d8f87b5d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ Required properties:
Optional properties:
  - qcom,notify-modem-status: Boolean property to decide whether modem
    notification should be enabled or not in this platform
  - wlan-soc-swreg-supply: phandle to the external 1.15V regulator for QCA6174

Example:

@@ -30,4 +31,5 @@ Example:
        wlan-en-gpio = <&msmgpio 82 0>;
        vdd-wlan-supply = <&wlan_vreg>;
        qcom,notify-modem-status;
        wlan-soc-swreg-supply = <&pma8084_l27>;
    };
+111 −11
Original line number Diff line number Diff line
@@ -52,9 +52,13 @@
#define QCA6174_FW_3_0	(0x30)

#define WLAN_VREG_NAME		"vdd-wlan"
#define WLAN_SWREG_NAME		"wlan-soc-swreg"
#define WLAN_EN_GPIO_NAME	"wlan-en-gpio"
#define PM_OPTIONS		0

#define SOC_SWREG_VOLT_MAX	1150000
#define SOC_SWREG_VOLT_MIN	1150000

#define POWER_ON_DELAY		2000
#define WLAN_ENABLE_DELAY	10000

@@ -68,6 +72,7 @@ struct cnss_wlan_gpio_info {

struct cnss_wlan_vreg_info {
	struct regulator *wlan_reg;
	struct regulator *soc_swreg;
	bool state;
};

@@ -101,27 +106,87 @@ static struct cnss_data {
	bool notify_modem_status;
} *penv;

static int cnss_wlan_vreg_set(struct cnss_wlan_vreg_info *vreg_info, bool state)

static int cnss_wlan_vreg_on(struct cnss_wlan_vreg_info *vreg_info)
{
	int ret;

	ret = regulator_enable(vreg_info->wlan_reg);
	if (ret) {
		pr_err("%s: regulator enable failed for WLAN power\n",
				__func__);
		goto error_enable;
	}

	if (vreg_info->soc_swreg) {
		ret = regulator_enable(vreg_info->soc_swreg);
		if (ret) {
			pr_err("%s: regulator enable failed for external soc-swreg\n",
					__func__);
			goto error_enable2;
		}
	}
	return ret;

error_enable2:
	regulator_disable(vreg_info->wlan_reg);
error_enable:
	return ret;
}

static int cnss_wlan_vreg_off(struct cnss_wlan_vreg_info *vreg_info)
{
	int ret, ret2;

	if (vreg_info->soc_swreg) {
		ret = regulator_disable(vreg_info->soc_swreg);
		if (ret) {
			pr_err("%s: regulator disable failed for external soc-swreg\n",
					__func__);
			goto error_disable;
		}
	}
	ret = regulator_disable(vreg_info->wlan_reg);
	if (ret) {
		pr_err("%s: regulator disable failed for WLAN power\n",
				__func__);
		goto error_disable2;
	}
	return ret;

error_disable2:
	if (vreg_info->soc_swreg) {
		ret2 = regulator_enable(vreg_info->soc_swreg);
		if (ret2)
			ret = ret2;
	}
error_disable:
	return ret;
}

static int cnss_wlan_vreg_set(struct cnss_wlan_vreg_info *vreg_info, bool state)
{
	int ret = 0;

	if (vreg_info->state == state) {
		pr_debug("Already wlan vreg state is %s\n",
				state ? "enabled" : "disabled");
		return 0;
		goto out;
	}

	if (state)
		ret = regulator_enable(vreg_info->wlan_reg);
		ret = cnss_wlan_vreg_on(vreg_info);
	else
		ret = regulator_disable(vreg_info->wlan_reg);
		ret = cnss_wlan_vreg_off(vreg_info);

	if (ret)
		goto out;

	if (!ret) {
		vreg_info->state = state;
	pr_debug("%s: wlan vreg is now %s\n", __func__,
			state ? "enabled" : "disabled");
	}
	vreg_info->state = state;

out:
	return ret;
}

@@ -195,6 +260,31 @@ static int cnss_wlan_get_resources(struct platform_device *pdev)
		pr_err("%s: vreg initial vote failed\n", __func__);
		goto err_reg_enable;
	}

	if (of_get_property(pdev->dev.of_node,
		    WLAN_SWREG_NAME"-supply", NULL)) {

		vreg_info->soc_swreg = regulator_get(&pdev->dev,
			WLAN_SWREG_NAME);
		if (IS_ERR(vreg_info->soc_swreg)) {
			pr_err("%s: soc-swreg node not found\n",
					__func__);
			goto err_reg_get2;
		}
		ret = regulator_set_voltage(vreg_info->soc_swreg,
				SOC_SWREG_VOLT_MIN, SOC_SWREG_VOLT_MAX);
		if (ret) {
			pr_err("%s: vreg initial voltage set failed on soc-swreg\n",
					__func__);
			goto err_reg_set;
		}
		ret = regulator_enable(vreg_info->soc_swreg);
		if (ret) {
			pr_err("%s: vreg initial vote failed\n", __func__);
			goto err_reg_enable2;
		}
	}

	vreg_info->state = VREG_ON;

	if (!of_find_property((&pdev->dev)->of_node, gpio_info->name, NULL)) {
@@ -230,14 +320,21 @@ end:

err_gpio_init:
err_get_gpio:
	regulator_disable(vreg_info->wlan_reg);
	if (vreg_info->soc_swreg)
		regulator_disable(vreg_info->soc_swreg);
	vreg_info->state = VREG_OFF;

err_reg_enable2:
err_reg_set:
	if (vreg_info->soc_swreg)
		regulator_put(vreg_info->soc_swreg);

err_reg_get2:
	regulator_disable(vreg_info->wlan_reg);
err_reg_enable:
	regulator_put(vreg_info->wlan_reg);

err_reg_get:

	return ret;
}

@@ -247,7 +344,10 @@ static void cnss_wlan_release_resources(void)
	struct cnss_wlan_vreg_info *vreg_info = &penv->vreg_info;

	gpio_free(gpio_info->num);
	cnss_wlan_vreg_set(vreg_info, VREG_OFF);
	regulator_put(vreg_info->wlan_reg);
	if (vreg_info->soc_swreg)
		regulator_put(vreg_info->soc_swreg);
	gpio_info->state = WLAN_EN_LOW;
	gpio_info->prop = false;
	vreg_info->state = VREG_OFF;