summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSarada Prasanna Garnayak <sgarna@codeaurora.org>2017-06-21 20:43:31 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-08-02 05:11:40 -0700
commitcca1739db38ce7c40d518255404c86b6046f5a03 (patch)
tree1302563f7ad7179b3640e531dd0889d05aa367c5
parent6d11c13b4311665ad0b438bf82908577d6d1a32f (diff)
wcnss: Update the wcnss wlan module power up sequence
The wcnss wlan module power up sequence has been changed. To add support for the wcnss new power up sequence configured 3.3v external GPIO in wcnss platform driver. Add check for the target to support the 3.3v external gpio for the wcnss power up and routine to control the gpio like gpio init, enable, disable for the device power management in different state of the wcnss wlan device. CRs-Fixed: 2065396 Change-Id: Ie6b79415b670522aa0abee58a23a31cffec76f5a Signed-off-by: Sarada Prasanna Garnayak <sgarna@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt6
-rw-r--r--drivers/net/wireless/wcnss/wcnss_vreg.c63
-rw-r--r--drivers/net/wireless/wcnss/wcnss_wlan.c84
-rw-r--r--include/linux/wcnss_wlan.h7
4 files changed, 128 insertions, 32 deletions
diff --git a/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt b/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
index d0855115b6d1..46cbc5206be4 100644
--- a/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
+++ b/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
@@ -64,6 +64,10 @@ support for pronto hardware.
to use for VBATT feature.
- qcom,has-a2xb-split-reg: boolean flag to determine A2xb split timeout limit
register is available or not.
+- qcom,wcn-external-gpio-support: boolean flag to determine 3.3v gpio support
+for pronto hardware for a target.
+- qcom,wcn-external-gpio: The wcnss wlan module 3.3v external GPIO for
+the pronto hardware.
Example:
@@ -85,6 +89,8 @@ Example:
gpios = <&msmgpio 36 0>, <&msmgpio 37 0>, <&msmgpio 38 0>,
<&msmgpio 39 0>, <&msmgpio 40 0>;
+ qcom,wcn-external-gpio = <&msmgpio 64 0>;
+ qcom,wcn-external-gpio-support;
qcom,has-48mhz-xo;
qcom,is-pronto-vt;
qcom,wlan-rx-buff-count = <512>;
diff --git a/drivers/net/wireless/wcnss/wcnss_vreg.c b/drivers/net/wireless/wcnss/wcnss_vreg.c
index 4f4ee15b133f..613f6fbc786c 100644
--- a/drivers/net/wireless/wcnss/wcnss_vreg.c
+++ b/drivers/net/wireless/wcnss/wcnss_vreg.c
@@ -101,6 +101,45 @@ enum {
IRIS_3610
};
+static int wcnss_external_gpio_set_state(bool state)
+{
+ int ret;
+ struct wcnss_wlan_config *cfg = wcnss_get_wlan_config();
+
+ if (!cfg)
+ return -EINVAL;
+
+ if (state) {
+ ret = gpio_request(cfg->wcn_external_gpio,
+ WCNSS_EXTERNAL_GPIO_NAME);
+ if (ret) {
+ pr_err("%s: Can't get GPIO %s, ret = %d\n",
+ __func__, WCNSS_EXTERNAL_GPIO_NAME, ret);
+ return ret;
+ }
+
+ ret = gpio_direction_output(cfg->wcn_external_gpio,
+ WCNSS_EXTERNAL_GPIO_DIR_OUT);
+ if (ret) {
+ pr_err("%s: Can't set GPIO %s direction, ret = %d\n",
+ __func__, WCNSS_EXTERNAL_GPIO_NAME, ret);
+ gpio_free(cfg->wcn_external_gpio);
+ return ret;
+ }
+
+ gpio_set_value(cfg->wcn_external_gpio,
+ WCNSS_EXTERNAL_GPIO_HIGH);
+ } else {
+ gpio_set_value(cfg->wcn_external_gpio, WCNSS_EXTERNAL_GPIO_LOW);
+ gpio_free(cfg->wcn_external_gpio);
+ }
+
+ pr_debug("%s: %d gpio is now %s\n", __func__,
+ cfg->wcn_external_gpio,
+ state ? "enabled" : "disabled");
+
+ return 0;
+}
int xo_auto_detect(u32 reg)
{
@@ -417,6 +456,12 @@ static void wcnss_vregs_off(struct vregs_info regulators[], uint size,
if (regulators[i].state == VREG_NULL_CONFIG)
continue;
+ if (cfg->wcn_external_gpio_support) {
+ if (!memcmp(regulators[i].name, VDD_PA,
+ sizeof(VDD_PA)))
+ continue;
+ }
+
/* Remove PWM mode */
if (regulators[i].state & VREG_OPTIMUM_MODE_MASK) {
rc = regulator_set_load(regulators[i].regulator, 0);
@@ -478,7 +523,13 @@ static int wcnss_vregs_on(struct device *dev,
}
for (i = 0; i < size; i++) {
- /* Get regulator source */
+ if (cfg->wcn_external_gpio_support) {
+ if (!memcmp(regulators[i].name, VDD_PA,
+ sizeof(VDD_PA)))
+ continue;
+ }
+
+ /* Get regulator source */
regulators[i].regulator =
regulator_get(dev, regulators[i].name);
if (IS_ERR(regulators[i].regulator)) {
@@ -622,6 +673,12 @@ int wcnss_wlan_power(struct device *dev,
down(&wcnss_power_on_lock);
if (on) {
+ if (cfg->wcn_external_gpio_support) {
+ rc = wcnss_external_gpio_set_state(true);
+ if (rc)
+ return rc;
+ }
+
/* RIVA regulator settings */
rc = wcnss_core_vregs_on(dev, hw_type,
cfg);
@@ -644,6 +701,8 @@ int wcnss_wlan_power(struct device *dev,
} else if (is_power_on) {
is_power_on = false;
+ if (cfg->wcn_external_gpio_support)
+ wcnss_external_gpio_set_state(false);
configure_iris_xo(dev, cfg,
WCNSS_WLAN_SWITCH_OFF, NULL);
wcnss_iris_vregs_off(hw_type, cfg);
@@ -660,6 +719,8 @@ fail_iris_on:
wcnss_core_vregs_off(hw_type, cfg);
fail_wcnss_on:
+ if (cfg->wcn_external_gpio_support)
+ wcnss_external_gpio_set_state(false);
up(&wcnss_power_on_lock);
return rc;
}
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 52095bb3c502..4a08979c249b 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -2757,23 +2757,42 @@ wcnss_trigger_config(struct platform_device *pdev)
int is_pronto_vadc;
int is_pronto_v3;
int pil_retry = 0;
- int has_pronto_hw = of_property_read_bool(pdev->dev.of_node,
- "qcom,has-pronto-hw");
-
- is_pronto_vadc = of_property_read_bool(pdev->dev.of_node,
- "qcom,is-pronto-vadc");
-
- is_pronto_v3 = of_property_read_bool(pdev->dev.of_node,
- "qcom,is-pronto-v3");
-
- penv->is_vsys_adc_channel = of_property_read_bool(pdev->dev.of_node,
- "qcom,has-vsys-adc-channel");
-
- penv->is_a2xb_split_reg = of_property_read_bool(pdev->dev.of_node,
- "qcom,has-a2xb-split-reg");
+ struct wcnss_wlan_config *wlan_cfg = &penv->wlan_config;
+ struct device_node *node = (&pdev->dev)->of_node;
+ int has_pronto_hw = of_property_read_bool(node, "qcom,has-pronto-hw");
+
+ is_pronto_vadc = of_property_read_bool(node, "qcom,is-pronto-vadc");
+ is_pronto_v3 = of_property_read_bool(node, "qcom,is-pronto-v3");
+
+ penv->is_vsys_adc_channel =
+ of_property_read_bool(node, "qcom,has-vsys-adc-channel");
+ penv->is_a2xb_split_reg =
+ of_property_read_bool(node, "qcom,has-a2xb-split-reg");
+
+ wlan_cfg->wcn_external_gpio_support =
+ of_property_read_bool(node, "qcom,wcn-external-gpio-support");
+ if (wlan_cfg->wcn_external_gpio_support) {
+ if (of_find_property(node, WCNSS_EXTERNAL_GPIO_NAME, NULL)) {
+ wlan_cfg->wcn_external_gpio =
+ of_get_named_gpio(
+ pdev->dev.of_node,
+ WCNSS_EXTERNAL_GPIO_NAME,
+ 0);
+ if (!gpio_is_valid(wlan_cfg->wcn_external_gpio)) {
+ pr_err("%s: Invalid %s num defined in DT\n",
+ __func__, WCNSS_EXTERNAL_GPIO_NAME);
+ ret = -EINVAL;
+ goto fail;
+ }
+ } else {
+ pr_err("%s: %s prop not defined in DT node\n",
+ __func__, WCNSS_EXTERNAL_GPIO_NAME);
+ goto fail;
+ }
+ }
- if (of_property_read_u32(pdev->dev.of_node,
- "qcom,wlan-rx-buff-count", &penv->wlan_rx_buff_count)) {
+ if (of_property_read_u32(node, "qcom,wlan-rx-buff-count",
+ &penv->wlan_rx_buff_count)) {
penv->wlan_rx_buff_count = WCNSS_DEF_WLAN_RX_BUFF_COUNT;
}
@@ -2834,15 +2853,18 @@ wcnss_trigger_config(struct platform_device *pdev)
goto fail;
}
- index++;
- ret = wcnss_dt_parse_vreg_level(&pdev->dev, index,
- "qcom,iris-vddpa-current",
- "qcom,iris-vddpa-voltage-level",
- penv->wlan_config.iris_vlevel);
-
- if (ret) {
- dev_err(&pdev->dev, "error reading voltage-level property\n");
- goto fail;
+ if (!wlan_cfg->wcn_external_gpio_support) {
+ index++;
+ ret = wcnss_dt_parse_vreg_level(
+ &pdev->dev, index,
+ "qcom,iris-vddpa-current",
+ "qcom,iris-vddpa-voltage-level",
+ penv->wlan_config.iris_vlevel);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "error reading voltage-level property\n");
+ goto fail;
+ }
}
index++;
@@ -2865,8 +2887,8 @@ wcnss_trigger_config(struct platform_device *pdev)
pdata = pdev->dev.platform_data;
if (WCNSS_CONFIG_UNSPECIFIED == has_48mhz_xo) {
if (has_pronto_hw) {
- has_48mhz_xo = of_property_read_bool(pdev->dev.of_node,
- "qcom,has-48mhz-xo");
+ has_48mhz_xo =
+ of_property_read_bool(node, "qcom,has-48mhz-xo");
} else {
has_48mhz_xo = pdata->has_48mhz_xo;
}
@@ -2877,8 +2899,8 @@ wcnss_trigger_config(struct platform_device *pdev)
penv->wlan_config.is_pronto_v3 = is_pronto_v3;
if (WCNSS_CONFIG_UNSPECIFIED == has_autodetect_xo && has_pronto_hw) {
- has_autodetect_xo = of_property_read_bool(pdev->dev.of_node,
- "qcom,has-autodetect-xo");
+ has_autodetect_xo =
+ of_property_read_bool(node, "qcom,has-autodetect-xo");
}
penv->thermal_mitigation = 0;
@@ -3159,8 +3181,8 @@ wcnss_trigger_config(struct platform_device *pdev)
goto fail_ioremap2;
}
- if (of_property_read_bool(
- pdev->dev.of_node, "qcom,is-dual-band-disabled")) {
+ if (of_property_read_bool(node,
+ "qcom,is-dual-band-disabled")) {
ret = wcnss_get_dual_band_capability_info(pdev);
if (ret) {
pr_err(
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 78ae70a92753..dbde018af4c6 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -20,6 +20,11 @@
#define IRIS_REGULATORS 4
#define PRONTO_REGULATORS 3
+#define WCNSS_EXTERNAL_GPIO_NAME "qcom,wcn-external-gpio"
+#define WCNSS_EXTERNAL_GPIO_HIGH 1
+#define WCNSS_EXTERNAL_GPIO_LOW 0
+#define WCNSS_EXTERNAL_GPIO_DIR_OUT 1
+
enum wcnss_opcode {
WCNSS_WLAN_SWITCH_OFF = 0,
WCNSS_WLAN_SWITCH_ON,
@@ -38,6 +43,8 @@ struct vregs_level {
};
struct wcnss_wlan_config {
+ bool wcn_external_gpio_support;
+ int wcn_external_gpio;
int use_48mhz_xo;
int is_pronto_vadc;
int is_pronto_v3;