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
committerBharat Nihalani <bnihalani@nvidia.com>2010-10-28 06:31:52 -0700
commit9122dfe195e6e2dd9c3d590ee6923e9139545a29 (patch)
tree3f67a42f1b3e52969256a0d2b702511d3cfb34c3 /arch/arm/mach-tegra/board-ventana-sdhci.c
parent19a478e0996b94fe26390c150f1c098d1a9b4e68 (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 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>
Diffstat (limited to 'arch/arm/mach-tegra/board-ventana-sdhci.c')
-rw-r--r--arch/arm/mach-tegra/board-ventana-sdhci.c111
1 files changed, 110 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/board-ventana-sdhci.c b/arch/arm/mach-tegra/board-ventana-sdhci.c
index 13ab48b1c7a1..7dc76f6111cc 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,9 +96,23 @@ static struct resource sdhci_resource3[] = {
},
};
+
static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
.clk_id = NULL,
- .force_hs = 1,
+ .force_hs = 0,
+ .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,
@@ -120,6 +164,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)
{
gpio_request(tegra_sdhci_platform_data2.power_gpio, "sdhci2_power");
@@ -140,5 +248,6 @@ int __init ventana_sdhci_init(void)
platform_device_register(&tegra_sdhci_device2);
platform_device_register(&tegra_sdhci_device0);
+ ventana_wifi_init();
return 0;
}