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

Commit a1172e5c authored by Sarada Prasanna Garnayak's avatar Sarada Prasanna Garnayak Committed by Gerrit - the friendly Code Review server
Browse files

net: cnss: enable rome_vreg regulator for cnss SDIO



rome_vreg regulator is a fixed regulator and this regulator
control by PMIC gpio which is used as vdd supply for
the wlan module SDIO based interface. Enable rome_vreg
voltage regulators to enable the power up support in CNSS SDIO
platform driver.

Change-Id: I629bacf89029ade87d880972a972098447fc79e2
Signed-off-by: default avatarSarada Prasanna Garnayak <sgarna@codeaurora.org>
parent 91f4e6e6
Loading
Loading
Loading
Loading
+86 −49
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/delay.h>
#include <linux/err.h>

#define WLAN_VREG_NAME		"vdd-wlan"
#define WLAN_VREG_IO_NAME	"vdd-wlan-io"
#define WLAN_VREG_XTAL_NAME	"vdd-wlan-xtal"

@@ -35,9 +36,14 @@ struct cnss_sdio_wlan_gpio_info {
	u32 flags;
};

struct cnss_sdio_regulator {
	struct regulator *wlan_io;
	struct regulator *wlan_xtal;
	struct regulator *wlan_vreg;
};

static struct cnss_sdio_data {
	struct regulator *wlan_reg_io;
	struct regulator *wlan_reg_xtal;
	struct cnss_sdio_regulator regulator;
	struct platform_device *pdev;
	struct cnss_sdio_wlan_gpio_info pmic_gpio;
} *cnss_pdata;
@@ -72,6 +78,37 @@ err_pmic_gpio:
	return error;
}

static int cnss_sdio_configure_wlan_enable_regulator(void)
{
	int error;
	struct device *dev = &cnss_pdata->pdev->dev;

	if (of_get_property(
		cnss_pdata->pdev->dev.of_node,
		WLAN_VREG_NAME "-supply", NULL)) {
		cnss_pdata->regulator.wlan_vreg = regulator_get(
			&cnss_pdata->pdev->dev, WLAN_VREG_NAME);
		if (IS_ERR(cnss_pdata->regulator.wlan_vreg)) {
			error = PTR_ERR(cnss_pdata->regulator.wlan_vreg);
			dev_err(dev, "VDD-VREG get failed error=%d\n", error);
			return error;
		}

		error = regulator_enable(cnss_pdata->regulator.wlan_vreg);
		if (error) {
			dev_err(dev, "VDD-VREG enable failed error=%d\n",
				error);
			goto err_vdd_vreg_regulator;
		}
	}

	return 0;

err_vdd_vreg_regulator:
	regulator_put(cnss_pdata->regulator.wlan_vreg);
	return error;
}

static int cnss_sdio_configure_regulator(void)
{
	int error;
@@ -80,22 +117,22 @@ static int cnss_sdio_configure_regulator(void)
	if (of_get_property(
		cnss_pdata->pdev->dev.of_node,
		WLAN_VREG_IO_NAME "-supply", NULL)) {
		cnss_pdata->wlan_reg_io = regulator_get(
		cnss_pdata->regulator.wlan_io = regulator_get(
			&cnss_pdata->pdev->dev, WLAN_VREG_IO_NAME);
		if (IS_ERR(cnss_pdata->wlan_reg_io)) {
			error = PTR_ERR(cnss_pdata->wlan_reg_io);
		if (IS_ERR(cnss_pdata->regulator.wlan_io)) {
			error = PTR_ERR(cnss_pdata->regulator.wlan_io);
			dev_err(dev, "VDD-IO get failed error=%d\n", error);
			return error;
		}

		error = regulator_set_voltage(
			cnss_pdata->wlan_reg_io,
			cnss_pdata->regulator.wlan_io,
			WLAN_VREG_IO_MIN, WLAN_VREG_IO_MAX);
		if (error) {
			dev_err(dev, "VDD-IO set failed error=%d\n", error);
			goto err_vdd_io_regulator;
		} else {
			error = regulator_enable(cnss_pdata->wlan_reg_io);
			error = regulator_enable(cnss_pdata->regulator.wlan_io);
			if (error) {
				dev_err(dev, "VDD-IO enable failed error=%d\n",
					error);
@@ -107,22 +144,23 @@ static int cnss_sdio_configure_regulator(void)
	if (of_get_property(
		cnss_pdata->pdev->dev.of_node,
		WLAN_VREG_XTAL_NAME "-supply", NULL)) {
		cnss_pdata->wlan_reg_xtal = regulator_get(
		cnss_pdata->regulator.wlan_xtal = regulator_get(
			&cnss_pdata->pdev->dev, WLAN_VREG_XTAL_NAME);
		if (IS_ERR(cnss_pdata->wlan_reg_xtal)) {
			error = PTR_ERR(cnss_pdata->wlan_reg_xtal);
		if (IS_ERR(cnss_pdata->regulator.wlan_xtal)) {
			error = PTR_ERR(cnss_pdata->regulator.wlan_xtal);
			dev_err(dev, "VDD-XTAL get failed error=%d\n", error);
			goto err_vdd_xtal_regulator;
		}

		error = regulator_set_voltage(
			cnss_pdata->wlan_reg_xtal,
			cnss_pdata->regulator.wlan_xtal,
			WLAN_VREG_XTAL_MIN, WLAN_VREG_XTAL_MAX);
		if (error) {
			dev_err(dev, "VDD-XTAL set failed error=%d\n", error);
			goto err_vdd_xtal_regulator;
		} else {
			error = regulator_enable(cnss_pdata->wlan_reg_xtal);
			error = regulator_enable(
				cnss_pdata->regulator.wlan_xtal);
			if (error) {
				dev_err(dev, "VDD-XTAL enable failed err=%d\n",
					error);
@@ -134,40 +172,24 @@ static int cnss_sdio_configure_regulator(void)
	return 0;

err_vdd_xtal_regulator:
	regulator_put(cnss_pdata->wlan_reg_xtal);
	regulator_put(cnss_pdata->regulator.wlan_xtal);
err_vdd_io_regulator:
	regulator_put(cnss_pdata->wlan_reg_io);
	regulator_put(cnss_pdata->regulator.wlan_io);
	return error;
}

static int cnss_sdio_get_resource(struct device *dev)
{
	struct device_node *np = dev->of_node;

	/* wlan enable pmic gpio info */
	cnss_pdata->pmic_gpio.num = of_get_named_gpio_flags(np,
		"cnss_sdio,wlan-pmic-gpio", 0, &cnss_pdata->pmic_gpio.flags);
	if (cnss_pdata->pmic_gpio.num < 0)
		return cnss_pdata->pmic_gpio.num;
	return 0;
}

static void cnss_sdio_release_regulator(void)
{
	if (cnss_pdata->wlan_reg_xtal)
		regulator_put(cnss_pdata->wlan_reg_xtal);
	if (cnss_pdata->wlan_reg_io)
		regulator_put(cnss_pdata->wlan_reg_io);
}

static void cnss_sdio_release_resourse(void)
static void cnss_sdio_release_resource(void)
{
	if (gpio_is_valid(cnss_pdata->pmic_gpio.num)) {
		gpio_set_value_cansleep(cnss_pdata->pmic_gpio.num, 0);
		gpio_free(cnss_pdata->pmic_gpio.num);
	}

	cnss_sdio_release_regulator();
	if (cnss_pdata->regulator.wlan_xtal)
		regulator_put(cnss_pdata->regulator.wlan_xtal);
	if (cnss_pdata->regulator.wlan_vreg)
		regulator_put(cnss_pdata->regulator.wlan_xtal);
	if (cnss_pdata->regulator.wlan_io)
		regulator_put(cnss_pdata->regulator.wlan_io);
}

static int cnss_sdio_probe(struct platform_device *pdev)
@@ -179,10 +201,6 @@ static int cnss_sdio_probe(struct platform_device *pdev)
			&pdev->dev, sizeof(*cnss_pdata), GFP_KERNEL);
		if (!cnss_pdata)
			return -ENOMEM;

		error = cnss_sdio_get_resource(&pdev->dev);
		if (error)
			return error;
	} else {
		cnss_pdata = pdev->dev.platform_data;
	}
@@ -197,23 +215,42 @@ static int cnss_sdio_probe(struct platform_device *pdev)
		return error;
	}

	cnss_pdata->pmic_gpio.num = of_get_named_gpio_flags(pdev->dev.of_node,
		"cnss_sdio,wlan-pmic-gpio", 0, &cnss_pdata->pmic_gpio.flags);
	if (cnss_pdata->pmic_gpio.num) {
		error = cnss_sdio_configure_gpio();
		if (error) {
		dev_err(&pdev->dev, "Failed to config gpio\n");
		goto err_gpio_config;
			dev_err(&pdev->dev,
				"Failed to enable wlan enable gpio\n");
			goto err_wlan_enable_gpio;
		}
	}

	if (of_get_property(
		cnss_pdata->pdev->dev.of_node,
			WLAN_VREG_NAME "-supply", NULL)) {
		error = cnss_sdio_configure_wlan_enable_regulator();
		if (error) {
			dev_err(&pdev->dev,
				"Failed to enable wlan enable regulator\n");
			goto err_wlan_enable_regulator;
		}
	}

	dev_dbg(&pdev->dev, "CNSS SDIO Driver registered");
	dev_info(&pdev->dev, "CNSS SDIO Driver registered");
	return 0;

err_gpio_config:
	cnss_sdio_release_regulator();
err_wlan_enable_regulator:
	regulator_put(cnss_pdata->regulator.wlan_vreg);
err_wlan_enable_gpio:
	regulator_put(cnss_pdata->regulator.wlan_xtal);
	regulator_put(cnss_pdata->regulator.wlan_io);
	return error;
}

static int cnss_sdio_remove(struct platform_device *pdev)
{
	cnss_sdio_release_resourse();
	cnss_sdio_release_resource();
	return 0;
}