msm: 8960: add ath6kl_wlan_power function to control AR6004 gpio
Add necessary functions for AR6004 to control BT related GPIO.
This change will only be used by AR6004
(cherry picked from commit 9baad179a8a7996e1912de14eb6f02f17c932e03)
(cherry picked from commit 493557fce821ae201b4cc3c6a125d703ac5de60e)
Signed-off-by: Ming-yi Lin <mylin@codeaurora.org>
Change-Id: I0fb3a59761dc3e994254bdc0241281e4bbcdf402
Signed-off-by: Neha Pandey <nehap@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8960-gpiomux.c b/arch/arm/mach-msm/board-8960-gpiomux.c
index 1771bb9..fe37f2a 100644
--- a/arch/arm/mach-msm/board-8960-gpiomux.c
+++ b/arch/arm/mach-msm/board-8960-gpiomux.c
@@ -449,6 +449,13 @@
},
},
{
+ .gpio = 26, /* GSBI6 WLAN_PWD_L for AR6004 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi6_suspended_cfg,
+ [GPIOMUX_ACTIVE] = &gsbi6_active_cfg,
+ },
+ },
+ {
.gpio = 27, /* GSBI6 BT_INT2AP_N for AR3002 */
.settings = {
[GPIOMUX_SUSPENDED] = &gsbi6_suspended_cfg,
diff --git a/arch/arm/mach-msm/board-8960-storage.c b/arch/arm/mach-msm/board-8960-storage.c
index 5360927..678474d 100644
--- a/arch/arm/mach-msm/board-8960-storage.c
+++ b/arch/arm/mach-msm/board-8960-storage.c
@@ -328,9 +328,11 @@
#endif
.vreg_data = &mmc_slot_vreg_data[SDCC3],
.pin_data = &mmc_slot_pin_data[SDCC3],
+#ifndef CONFIG_MMC_MSM_SDC3_POLLING
.status_gpio = PM8921_GPIO_PM_TO_SYS(26),
.status_irq = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
.irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+#endif
.is_status_gpio_active_low = true,
.xpc_cap = 1,
.uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index a12cc6c..8ee6a5c 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -102,6 +102,11 @@
#include "pm-boot.h"
#include "msm_watchdog.h"
+#if defined(CONFIG_BT) && defined(CONFIG_BT_HCIUART_ATH3K)
+#include <linux/wlan_plat.h>
+#include <linux/mutex.h>
+#endif
+
static struct platform_device msm_fm_platform_init = {
.name = "iris_fm",
.id = -1,
@@ -2539,6 +2544,76 @@
#endif
#if defined(CONFIG_BT) && defined(CONFIG_BT_HCIUART_ATH3K)
+enum WLANBT_STATUS {
+ WLANOFF_BTOFF = 1,
+ WLANOFF_BTON,
+ WLANON_BTOFF,
+ WLANON_BTON
+};
+
+static DEFINE_MUTEX(ath_wlanbt_mutex);
+static int gpio_wlan_sys_rest_en = 26;
+static int ath_wlanbt_status = WLANOFF_BTOFF;
+
+static int ath6kl_power_control(int on)
+{
+ int rc;
+
+ if (on) {
+ rc = gpio_request(gpio_wlan_sys_rest_en, "wlan sys_rst_n");
+ if (rc) {
+ pr_err("%s: unable to request gpio %d (%d)\n",
+ __func__, gpio_wlan_sys_rest_en, rc);
+ return rc;
+ }
+ rc = gpio_direction_output(gpio_wlan_sys_rest_en, 0);
+ msleep(200);
+ rc = gpio_direction_output(gpio_wlan_sys_rest_en, 1);
+ msleep(100);
+ } else {
+ gpio_set_value(gpio_wlan_sys_rest_en, 0);
+ rc = gpio_direction_input(gpio_wlan_sys_rest_en);
+ msleep(100);
+ gpio_free(gpio_wlan_sys_rest_en);
+ }
+ return 0;
+};
+
+static int ath6kl_wlan_power(int on)
+{
+ int ret = 0;
+
+ mutex_lock(&ath_wlanbt_mutex);
+ if (on) {
+ if (ath_wlanbt_status == WLANOFF_BTOFF) {
+ ret = ath6kl_power_control(1);
+ ath_wlanbt_status = WLANON_BTOFF;
+ } else if (ath_wlanbt_status == WLANOFF_BTON)
+ ath_wlanbt_status = WLANON_BTON;
+ } else {
+ if (ath_wlanbt_status == WLANON_BTOFF) {
+ ret = ath6kl_power_control(0);
+ ath_wlanbt_status = WLANOFF_BTOFF;
+ } else if (ath_wlanbt_status == WLANON_BTON)
+ ath_wlanbt_status = WLANOFF_BTON;
+ }
+ mutex_unlock(&ath_wlanbt_mutex);
+ pr_debug("%s on= %d, wlan_status= %d\n",
+ __func__, on, ath_wlanbt_status);
+ return ret;
+};
+
+static struct wifi_platform_data ath6kl_wifi_control = {
+ .set_power = ath6kl_wlan_power,
+};
+
+static struct platform_device msm_wlan_power_device = {
+ .name = "ath6kl_power",
+ .dev = {
+ .platform_data = &ath6kl_wifi_control,
+ },
+};
+
static struct resource bluesleep_resources[] = {
{
.name = "gpio_host_wake",
@@ -2571,50 +2646,54 @@
.name = "bt_power",
};
-int gpio_bt_sys_rest_en = 28;
+static int gpio_bt_sys_rest_en = 28;
static int bluetooth_power(int on)
{
int rc;
- pr_debug("%s on= %d\n", __func__, on);
-
+ mutex_lock(&ath_wlanbt_mutex);
if (on) {
+ if (ath_wlanbt_status == WLANOFF_BTOFF) {
+ ath6kl_power_control(1);
+ ath_wlanbt_status = WLANOFF_BTON;
+ } else if (ath_wlanbt_status == WLANON_BTOFF)
+ ath_wlanbt_status = WLANON_BTON;
+
rc = gpio_request(gpio_bt_sys_rest_en, "bt sys_rst_n");
if (rc) {
pr_err("%s: unable to request gpio %d (%d)\n",
__func__, gpio_bt_sys_rest_en, rc);
- goto out;
+ mutex_unlock(&ath_wlanbt_mutex);
+ return rc;
}
rc = gpio_direction_output(gpio_bt_sys_rest_en, 0);
- if (rc) {
- pr_err("%s: Unable to set gpio %d direction\n",
- __func__, gpio_bt_sys_rest_en);
- goto free_gpio;
- }
+ msleep(20);
+ rc = gpio_direction_output(gpio_bt_sys_rest_en, 1);
msleep(100);
- gpio_set_value(gpio_bt_sys_rest_en, 1);
- msleep(100);
- goto out;
} else {
gpio_set_value(gpio_bt_sys_rest_en, 0);
rc = gpio_direction_input(gpio_bt_sys_rest_en);
msleep(100);
- }
+ gpio_free(gpio_bt_sys_rest_en);
-free_gpio:
- gpio_free(gpio_bt_sys_rest_en);
-out:
- return rc;
-}
+ if (ath_wlanbt_status == WLANOFF_BTON) {
+ ath6kl_power_control(0);
+ ath_wlanbt_status = WLANOFF_BTOFF;
+ } else if (ath_wlanbt_status == WLANON_BTON)
+ ath_wlanbt_status = WLANON_BTOFF;
+ }
+ mutex_unlock(&ath_wlanbt_mutex);
+ pr_debug("%s on= %d, wlan_status= %d\n",
+ __func__, on, ath_wlanbt_status);
+ return 0;
+};
static void __init bt_power_init(void)
{
- pr_debug("%s enter\n", __func__);
msm_bt_power_device.dev.platform_data = &bluetooth_power;
-
return;
-}
+};
#else
#define bt_power_init(x) do {} while (0)
#endif
@@ -2640,6 +2719,7 @@
#if defined(CONFIG_BT) && defined(CONFIG_BT_HCIUART_ATH3K)
&msm_bluesleep_device,
&msm_bt_power_device,
+ &msm_wlan_power_device,
#endif
#if defined(CONFIG_QSEECOM)
&qseecom_device,
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 0c3f994..da38122 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -500,6 +500,10 @@
help
Select Y to enable Slot 3.
+config MMC_MSM_SDC3_POLLING
+ boolean "Qualcomm SDC3 support"
+ depends on MMC_MSM
+
config MMC_MSM_SDC3_8_BIT_SUPPORT
boolean "Qualcomm SDC3 8bit support"
depends on MMC_MSM_SDC3_SUPPORT