ARM: tegra: pluto: sdhci device registration
naveenk [Wed, 29 Aug 2012 10:11:01 +0000 (15:11 +0530)]
Bug 1017708

Change-Id: I67ac76a6c69b4f1439afb93f6c5569dc6659cda2
Signed-off-by: naveen kumar arepalli <naveenk@nvidia.com>
Reviewed-on: http://git-master/r/128148
Reviewed-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>

arch/arm/mach-tegra/board-pluto-sdhci.c

index 99f8044..b7139eb 100644 (file)
@@ -16,6 +16,7 @@
 
 #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 <mach/irqs.h>
 #include <mach/iomap.h>
 #include <mach/sdhci.h>
+#include<mach/gpio-tegra.h>
+#include <mach/io_dpd.h>
 
 #include "gpio-names.h"
 #include "board.h"
 #include "board-pluto.h"
 
-#define PLUTO_SD_CD    TEGRA_GPIO_PI5
+#if defined(CONFIG_ARCH_TEGRA_11x_SOC)
+#define DALMORE_WLAN_PWR       TEGRA_GPIO_PCC5
+#define DALMORE_WLAN_RST       TEGRA_GPIO_PX7
+#define DALMORE_WLAN_WOW       TEGRA_GPIO_PU5
+static void (*wifi_status_cb)(int card_present, void *dev_id);
+static void *wifi_status_cb_devid;
+static int pluto_wifi_status_register(void (*callback)(int , void *), void *);
+
+static int pluto_wifi_reset(int on);
+static int pluto_wifi_power(int on);
+static int pluto_wifi_set_carddetect(int val);
+
+static struct wifi_platform_data pluto_wifi_control = {
+       .set_power      = pluto_wifi_power,
+       .set_reset      = pluto_wifi_reset,
+       .set_carddetect = pluto_wifi_set_carddetect,
+};
+
+static struct resource wifi_resource[] = {
+       [0] = {
+               .name   = "bcm4329_wlan_irq",
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL
+                               | IORESOURCE_IRQ_SHAREABLE,
+       },
+};
+
+static struct platform_device pluto_wifi_device = {
+       .name           = "bcm4329_wlan",
+       .id             = 1,
+       .num_resources  = 1,
+       .resource       = wifi_resource,
+       .dev            = {
+               .platform_data = &pluto_wifi_control,
+       },
+};
+
+static struct resource sdhci_resource0[] = {
+       [0] = {
+               .start  = INT_SDMMC1,
+               .end    = INT_SDMMC1,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [1] = {
+               .start  = TEGRA_SDMMC1_BASE,
+               .end    = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct resource sdhci_resource2[] = {
+       [0] = {
+               .start  = INT_SDMMC3,
+               .end    = INT_SDMMC3,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [1] = {
+               .start  = TEGRA_SDMMC3_BASE,
+               .end    = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct resource sdhci_resource3[] = {
+       [0] = {
+               .start  = INT_SDMMC4,
+               .end    = INT_SDMMC4,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [1] = {
+               .start  = TEGRA_SDMMC4_BASE,
+               .end    = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
+static struct embedded_sdio_data embedded_sdio_data0 = {
+       .cccr   = {
+               .sdio_vsn       = 2,
+               .multi_block    = 1,
+               .low_speed      = 0,
+               .wide_bus       = 0,
+               .high_power     = 1,
+               .high_speed     = 1,
+       },
+       .cis  = {
+               .vendor         = 0x02d0,
+               .device         = 0x4329,
+       },
+};
+#endif
+
+static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
+       .mmc_data = {
+               .register_status_notify = pluto_wifi_status_register,
+#ifdef CONFIG_MMC_EMBEDDED_SDIO
+               .embedded_sdio = &embedded_sdio_data0,
+#endif
+               .built_in = 0,
+               .ocr_mask = MMC_OCR_1V8_MASK,
+       },
+#ifndef CONFIG_MMC_EMBEDDED_SDIO
+       .pm_flags = MMC_PM_KEEP_POWER,
+#endif
+       .cd_gpio = -1,
+       .wp_gpio = -1,
+       .power_gpio = -1,
+       .tap_delay = 0x0F,
+       .ddr_clk_limit = 41000000,
+};
+
+static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
+       .cd_gpio = -1,
+       .wp_gpio = -1,
+       .power_gpio = -1,
+       .tap_delay = 0x0F,
+       .ddr_clk_limit = 41000000,
+};
+
+static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
+       .cd_gpio = -1,
+       .wp_gpio = -1,
+       .power_gpio = -1,
+       .is_8bit = 1,
+       .tap_delay = 0x0F,
+       .ddr_clk_limit = 41000000,
+       .mmc_data = {
+               .built_in = 1,
+       }
+};
+
+static struct platform_device tegra_sdhci_device0 = {
+       .name           = "sdhci-tegra",
+       .id             = 0,
+       .resource       = sdhci_resource0,
+       .num_resources  = ARRAY_SIZE(sdhci_resource0),
+       .dev = {
+               .platform_data = &tegra_sdhci_platform_data0,
+       },
+};
 
+static struct platform_device tegra_sdhci_device2 = {
+       .name           = "sdhci-tegra",
+       .id             = 2,
+       .resource       = sdhci_resource2,
+       .num_resources  = ARRAY_SIZE(sdhci_resource2),
+       .dev = {
+               .platform_data = &tegra_sdhci_platform_data2,
+       },
+};
+
+static struct platform_device tegra_sdhci_device3 = {
+       .name           = "sdhci-tegra",
+       .id             = 3,
+       .resource       = sdhci_resource3,
+       .num_resources  = ARRAY_SIZE(sdhci_resource3),
+       .dev = {
+               .platform_data = &tegra_sdhci_platform_data3,
+       },
+};
+
+static int pluto_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 pluto_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 pluto_wifi_power(int on)
+{
+       struct tegra_io_dpd *sd_dpd;
 
+       pr_debug("%s: %d\n", __func__, on);
+
+       /*
+        * FIXME : we need to revisit IO DPD code
+        * on how should multiple pins under DPD get controlled
+        *
+        * pluto GPIO WLAN enable is part of SDMMC3 pin group
+        */
+       sd_dpd = tegra_io_dpd_get(&tegra_sdhci_device2.dev);
+       if (sd_dpd) {
+               mutex_lock(&sd_dpd->delay_lock);
+               tegra_io_dpd_disable(sd_dpd);
+               mutex_unlock(&sd_dpd->delay_lock);
+       }
+       gpio_set_value(PLUTO_WLAN_PWR, on);
+       mdelay(100);
+       gpio_set_value(PLUTO_WLAN_RST, on);
+       mdelay(200);
+       if (sd_dpd) {
+               mutex_lock(&sd_dpd->delay_lock);
+               tegra_io_dpd_enable(sd_dpd);
+               mutex_unlock(&sd_dpd->delay_lock);
+       }
+
+       return 0;
+}
+
+static int pluto_wifi_reset(int on)
+{
+       pr_debug("%s: do nothing\n", __func__);
+       return 0;
+}
+
+static int __init pluto_wifi_init(void)
+{
+       int rc;
+
+       rc = gpio_request(PLUTO_WLAN_PWR, "wlan_power");
+       if (rc)
+               pr_err("WLAN_PWR gpio request failed:%d\n", rc);
+       rc = gpio_request(PLUTO_WLAN_RST, "wlan_rst");
+       if (rc)
+               pr_err("WLAN_RST gpio request failed:%d\n", rc);
+       rc = gpio_request(PLUTO_WLAN_WOW, "bcmsdh_sdmmc");
+       if (rc)
+               pr_err("WLAN_WOW gpio request failed:%d\n", rc);
+
+       rc = gpio_direction_output(PLUTO_WLAN_PWR, 0);
+       if (rc)
+               pr_err("WLAN_PWR gpio direction configuration failed:%d\n", rc);
+       gpio_direction_output(PLUTO_WLAN_RST, 0);
+       if (rc)
+               pr_err("WLAN_RST gpio direction configuration failed:%d\n", rc);
+       rc = gpio_direction_input(PLUTO_WLAN_WOW);
+       if (rc)
+               pr_err("WLAN_WOW gpio direction configuration failed:%d\n", rc);
+
+       wifi_resource[0].start = wifi_resource[0].end =
+               gpio_to_irq(TEGRA_GPIO_PO4);
+
+       platform_device_register(&pluto_wifi_device);
+       return 0;
+}
+
+#ifdef CONFIG_TEGRA_PREPOWER_WIFI
+static int __init pluto_wifi_prepower(void)
+{
+       if (!machine_is_pluto())
+               return 0;
+
+       pluto_wifi_power(1);
+
+       return 0;
+}
+
+subsys_initcall_sync(pluto_wifi_prepower);
+#endif
+
+int __init pluto_sdhci_init(void)
+{
+       platform_device_register(&tegra_sdhci_device3);
+       platform_device_register(&tegra_sdhci_device2);
+       platform_device_register(&tegra_sdhci_device0);
+       pluto_wifi_init();
+       return 0;
+}
+
+#else
+#define PLUTO_SD_CD    TEGRA_GPIO_PI5
+#define PLUTO_SD_WP    TEGRA_GPIO_PT3
 static struct resource sdhci_resource0[] = {
        [0] = {
                .start  = INT_SDMMC1,
@@ -126,3 +402,4 @@ int __init pluto_sdhci_init(void)
 
        return 0;
 }
+#endif