summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/board-ventana-sdhci.c
diff options
context:
space:
mode:
authorRakesh Kumar <krakesh@nvidia.com>2010-10-28 13:57:00 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:52:11 -0800
commitff955eaa11756ce5884670b8455f347c6ad7ab39 (patch)
tree0e75485d57511841d657c8a61e32ec6d9bc25557 /arch/arm/mach-tegra/board-ventana-sdhci.c
parentea4fdb48af589698e2215cdb10ac69131e987a2a (diff)
[arm/tegra/ventana] provide wifi power/carddetect abstraction
When user switches on wifi, wifi driver need to poweron wifi card and ask sdhci stack to enumerate the card. Sdhci stack does not provide any interface to do so. BCM4329 depend on platform to provide wifi poweron/reset/carddetect abstraction functions bug 724105 Original-Change-Id: Ib82ac12cd0a3c33c8406434e64872c4cda3c2cc7 Reviewed-on: http://git-master/r/9883 Reviewed-by: Rakesh Kumar <krakesh@nvidia.com> Tested-by: Rakesh Kumar <krakesh@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Rebase-Id: Rbf9f008102990bd125f6ce4d4ed781a9beac02af
Diffstat (limited to 'arch/arm/mach-tegra/board-ventana-sdhci.c')
-rw-r--r--arch/arm/mach-tegra/board-ventana-sdhci.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-ventana-sdhci.c b/arch/arm/mach-tegra/board-ventana-sdhci.c
index 0396b70935e9..5e4ddf971c58 100644
--- a/arch/arm/mach-tegra/board-ventana-sdhci.c
+++ b/arch/arm/mach-tegra/board-ventana-sdhci.c
@@ -16,8 +16,12 @@
#include <linux/resource.h>
#include <linux/platform_device.h>
+#include <linux/wlan_plat.h>
#include <linux/delay.h>
#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/mmc/host.h>
#include <asm/mach-types.h>
#include <mach/irqs.h>
@@ -27,6 +31,32 @@
#include "gpio-names.h"
#include "board.h"
+#define VENTANA_WLAN_PWR TEGRA_GPIO_PK5
+#define VENTANA_WLAN_RST TEGRA_GPIO_PK6
+
+static void (*wifi_status_cb)(int card_present, void *dev_id);
+static void *wifi_status_cb_devid;
+static int ventana_wifi_status_register(void (*callback)(int , void *), void *);
+static struct clk *wifi_32k_clk;
+
+static int ventana_wifi_reset(int on);
+static int ventana_wifi_power(int on);
+static int ventana_wifi_set_carddetect(int val);
+
+static struct wifi_platform_data ventana_wifi_control = {
+ .set_power = ventana_wifi_power,
+ .set_reset = ventana_wifi_reset,
+ .set_carddetect = ventana_wifi_set_carddetect,
+};
+
+static struct platform_device ventana_wifi_device = {
+ .name = "bcm4329_wlan",
+ .id = 1,
+ .dev = {
+ .platform_data = &ventana_wifi_control,
+ },
+};
+
static struct resource sdhci_resource0[] = {
[0] = {
.start = INT_SDMMC1,
@@ -66,7 +96,21 @@ static struct resource sdhci_resource3[] = {
},
};
+
static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
+ .register_status_notify = ventana_wifi_status_register,
+ .cccr = {
+ .sdio_vsn = 2,
+ .multi_block = 1,
+ .low_speed = 0,
+ .wide_bus = 0,
+ .high_power = 1,
+ .high_speed = 1,
+ },
+ .cis = {
+ .vendor = 0x02d0,
+ .device = 0x4329,
+ },
.cd_gpio = -1,
.wp_gpio = -1,
.power_gpio = -1,
@@ -114,6 +158,70 @@ static struct platform_device tegra_sdhci_device3 = {
},
};
+static int ventana_wifi_status_register(
+ void (*callback)(int card_present, void *dev_id),
+ void *dev_id)
+{
+ if (wifi_status_cb)
+ return -EAGAIN;
+ wifi_status_cb = callback;
+ wifi_status_cb_devid = dev_id;
+ return 0;
+}
+
+static int ventana_wifi_set_carddetect(int val)
+{
+ pr_debug("%s: %d\n", __func__, val);
+ if (wifi_status_cb)
+ wifi_status_cb(val, wifi_status_cb_devid);
+ else
+ pr_warning("%s: Nobody to notify\n", __func__);
+ return 0;
+}
+
+static int ventana_wifi_power(int on)
+{
+ pr_debug("%s: %d\n", __func__, on);
+
+ gpio_set_value(VENTANA_WLAN_PWR, on);
+ mdelay(100);
+ gpio_set_value(VENTANA_WLAN_RST, on);
+ mdelay(200);
+
+ if (on)
+ clk_enable(wifi_32k_clk);
+ else
+ clk_disable(wifi_32k_clk);
+
+ return 0;
+}
+
+static int ventana_wifi_reset(int on)
+{
+ pr_debug("%s: do nothing\n", __func__);
+ return 0;
+}
+
+static int __init ventana_wifi_init(void)
+{
+ wifi_32k_clk = clk_get_sys(NULL, "blink");
+ if (IS_ERR(wifi_32k_clk)) {
+ pr_err("%s: unable to get blink clock\n", __func__);
+ return PTR_ERR(wifi_32k_clk);
+ }
+
+ gpio_request(VENTANA_WLAN_PWR, "wlan_power");
+ gpio_request(VENTANA_WLAN_RST, "wlan_rst");
+
+ tegra_gpio_enable(VENTANA_WLAN_PWR);
+ tegra_gpio_enable(VENTANA_WLAN_RST);
+
+ gpio_direction_output(VENTANA_WLAN_PWR, 0);
+ gpio_direction_output(VENTANA_WLAN_RST, 0);
+
+ platform_device_register(&ventana_wifi_device);
+ return 0;
+}
int __init ventana_sdhci_init(void)
{
tegra_gpio_enable(tegra_sdhci_platform_data2.power_gpio);
@@ -125,5 +233,6 @@ int __init ventana_sdhci_init(void)
platform_device_register(&tegra_sdhci_device2);
platform_device_register(&tegra_sdhci_device0);
+ ventana_wifi_init();
return 0;
}