[ARM] tegra: stingray: Use WL_REG_ON GPIO for BT
authorJaikumar Ganesh <jaikumar@google.com>
Thu, 3 Feb 2011 06:32:39 +0000 (22:32 -0800)
committerJaikumar Ganesh <jaikumar@google.com>
Thu, 3 Feb 2011 19:10:17 +0000 (11:10 -0800)
BT was using BT_REG_ON and Wlan was using WL_REG_ON.
4329 ORs both these GPIOs. However, there are problems
with BT_REG_ON while coming out of LP0 suspend.
So temporaraily have both wifi and BT use the same GPIO
for power on. For BT, set the BT_REG_ON to output low.

Change-Id: I75606ba124418fc7c606b434e4b7968fbc046228
Signed-off-by: Jaikumar Ganesh <jaikumar@google.com>
arch/arm/mach-tegra/board-stingray-bluetooth.c
arch/arm/mach-tegra/board-stingray-wifi.c
arch/arm/mach-tegra/board-stingray.c
arch/arm/mach-tegra/board-stingray.h

index 45c72bcc7a706015b449a2afc30c69e8bc991e4b..f4419c3874bb4f1e837f7c0006ae2c6d61649acf 100644 (file)
@@ -38,6 +38,7 @@
 #define BT_WAKE_GPIO TEGRA_GPIO_PU1
 #define BT_HOST_WAKE_GPIO TEGRA_GPIO_PU6
 
+extern void change_power_brcm_4329(bool);
 static struct rfkill *bt_rfkill;
 
 struct bcm_bt_lpm {
@@ -58,9 +59,11 @@ static int bcm4329_bt_rfkill_set_power(void *data, bool blocked)
 {
        // rfkill_ops callback. Turn transmitter on when blocked is false
        if (!blocked) {
+               change_power_brcm_4329(true);
                gpio_direction_output(BT_RESET_GPIO, 1);
-               gpio_direction_output(BT_SHUTDOWN_GPIO, 1);
+               gpio_direction_output(BT_SHUTDOWN_GPIO, 0);
        } else {
+               change_power_brcm_4329(false);
                gpio_direction_output(BT_SHUTDOWN_GPIO, 0);
                gpio_direction_output(BT_RESET_GPIO, 0);
        }
index 5c37461b09e3b5e405643762f107502ed15422d7..82a001803ff9ef6d110c3b75fe6fca9a1080369b 100644 (file)
@@ -21,7 +21,6 @@
 #include "gpio-names.h"
 
 #define STINGRAY_WLAN_IRQ      TEGRA_GPIO_PU5
-#define STINGRAY_WLAN_PWR      TEGRA_GPIO_PU4
 #define STINGRAY_WLAN_RST      TEGRA_GPIO_PU2
 
 #define ATAG_STINGRAY_MAC      0x57464d41
@@ -158,7 +157,7 @@ static int stingray_wifi_power(int on)
        pr_debug("%s: %d\n", __func__, on);
 
        mdelay(100);
-       gpio_set_value(STINGRAY_WLAN_PWR, on);
+       change_power_brcm_4329(on);
        mdelay(100);
        gpio_set_value(STINGRAY_WLAN_RST, on);
        mdelay(200);
@@ -238,10 +237,6 @@ static struct platform_device stingray_wifi_device = {
 
 static void __init stingray_wlan_gpio(void)
 {
-       tegra_gpio_enable(STINGRAY_WLAN_PWR);
-       gpio_request(STINGRAY_WLAN_PWR, "wlan_pwr");
-       gpio_direction_output(STINGRAY_WLAN_PWR, 0);
-
        tegra_gpio_enable(STINGRAY_WLAN_RST);
        gpio_request(STINGRAY_WLAN_RST, "wlan_rst");
        gpio_direction_output(STINGRAY_WLAN_RST, 0);
index 6452ae054ec2fac42c0505a620c3d1445b0cadb9..dc46ee5f89fd5482fc384f46d677eb96fb6baea3 100644 (file)
@@ -658,6 +658,9 @@ static int __init parse_tag_bdaddr(const struct tag *tag)
 }
 __tagtable(ATAG_BDADDR, parse_tag_bdaddr);
 
+static DEFINE_SPINLOCK(brcm_4329_enable_lock);
+static int brcm_4329_enable_count;
+
 static void stingray_w1_init(void)
 {
        tegra_w1_device.dev.platform_data = &tegra_w1_pdata;
@@ -888,6 +891,26 @@ static void init_dac2(bool bluetooth)
        }
 }
 
+void change_power_brcm_4329(bool enable) {
+       unsigned long flags;
+
+       spin_lock_irqsave(&brcm_4329_enable_lock, flags);
+       if (enable) {
+               gpio_set_value(TEGRA_GPIO_PU4, enable);
+               brcm_4329_enable_count++;
+               // The following shouldn't happen but protect
+               // if the user doesn't cleanup.
+               if (brcm_4329_enable_count > 2)
+                       brcm_4329_enable_count = 2;
+       } else {
+               if (brcm_4329_enable_count > 0)
+                       brcm_4329_enable_count--;
+               if (!brcm_4329_enable_count)
+                       gpio_set_value(TEGRA_GPIO_PU4, enable);
+       }
+       spin_unlock_irqrestore(&brcm_4329_enable_lock, flags);
+}
+
 static void __init tegra_stingray_init(void)
 {
        struct clk *clk;
@@ -995,6 +1018,11 @@ static void __init tegra_stingray_init(void)
                tegra_dvfs_rail_disable_by_name("vdd_core");
        }
 
+       /* Enable 4329 Power GPIO */
+       tegra_gpio_enable(TEGRA_GPIO_PU4);
+       gpio_request(TEGRA_GPIO_PU4, "4329_pwr");
+       gpio_direction_output(TEGRA_GPIO_PU4, 0);
+
        stingray_pinmux_init();
 
        tegra_clk_init_from_table(stingray_clk_init_table);
index 33353ddf63cd75fbc76db498c0c8ec93f660b373..0c1b790935dc79e1d6e355abb4b2bb8569301a39 100644 (file)
@@ -31,6 +31,7 @@ unsigned int stingray_powerup_reason (void);
 void stingray_gps_init(void);
 int stingray_qbp_usb_hw_bypass_enabled(void);
 void stingray_init_emc(void);
+void change_power_brcm_4329(bool);
 
 /* as defined in the bootloader*/
 #define HWREV(x)    (((x)>>16) & 0xFFFF)