ARM: tegra: dalmore: sdhci device registration
naveenk [Wed, 29 Aug 2012 09:26:35 +0000 (14:26 +0530)]
Bug 1017708

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

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

index 8dc3d96..6a1ecca 100644 (file)
@@ -17,6 +17,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-dalmore.h"
 
-#define DALMORE_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 dalmore_wifi_status_register(void (*callback)(int , void *), void *);
+
+static int dalmore_wifi_reset(int on);
+static int dalmore_wifi_power(int on);
+static int dalmore_wifi_set_carddetect(int val);
+
+static struct wifi_platform_data dalmore_wifi_control = {
+       .set_power      = dalmore_wifi_power,
+       .set_reset      = dalmore_wifi_reset,
+       .set_carddetect = dalmore_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 dalmore_wifi_device = {
+       .name           = "bcm4329_wlan",
+       .id             = 1,
+       .num_resources  = 1,
+       .resource       = wifi_resource,
+       .dev            = {
+               .platform_data = &dalmore_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 = dalmore_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 dalmore_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 dalmore_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 dalmore_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
+        *
+        * dalmore 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(DALMORE_WLAN_PWR, on);
+       mdelay(100);
+       gpio_set_value(DALMORE_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 dalmore_wifi_reset(int on)
+{
+       pr_debug("%s: do nothing\n", __func__);
+       return 0;
+}
+
+static int __init dalmore_wifi_init(void)
+{
+       int rc;
+
+       rc = gpio_request(DALMORE_WLAN_PWR, "wlan_power");
+       if (rc)
+               pr_err("WLAN_PWR gpio request failed:%d\n", rc);
+       rc = gpio_request(DALMORE_WLAN_RST, "wlan_rst");
+       if (rc)
+               pr_err("WLAN_RST gpio request failed:%d\n", rc);
+       rc = gpio_request(DALMORE_WLAN_WOW, "bcmsdh_sdmmc");
+       if (rc)
+               pr_err("WLAN_WOW gpio request failed:%d\n", rc);
+
+       rc = gpio_direction_output(DALMORE_WLAN_PWR, 0);
+       if (rc)
+               pr_err("WLAN_PWR gpio direction configuration failed:%d\n", rc);
+       gpio_direction_output(DALMORE_WLAN_RST, 0);
+       if (rc)
+               pr_err("WLAN_RST gpio direction configuration failed:%d\n", rc);
+       rc = gpio_direction_input(DALMORE_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(&dalmore_wifi_device);
+       return 0;
+}
+
+#ifdef CONFIG_TEGRA_PREPOWER_WIFI
+static int __init dalmore_wifi_prepower(void)
+{
+       if (!machine_is_dalmore())
+               return 0;
+
+       dalmore_wifi_power(1);
+
+       return 0;
+}
+
+subsys_initcall_sync(dalmore_wifi_prepower);
+#endif
+
+int __init dalmore_sdhci_init(void)
+{
+       platform_device_register(&tegra_sdhci_device3);
+       platform_device_register(&tegra_sdhci_device2);
+       platform_device_register(&tegra_sdhci_device0);
+       dalmore_wifi_init();
+       return 0;
+}
+
+#else
+#define DALMORE_SD_CD  TEGRA_GPIO_PI5
+#define DALMORE_SD_WP  TEGRA_GPIO_PT3
+static struct resource sdhci_resource0[] = {
+       [0] = {
                .start  = INT_SDMMC1,
                .end    = INT_SDMMC1,
                .flags  = IORESOURCE_IRQ,
@@ -49,7 +326,6 @@ static struct resource sdhci_resource0[] = {
        },
 };
 
-
 static struct resource sdhci_resource3[] = {
        [0] = {
                .start  = INT_SDMMC4,
@@ -63,7 +339,6 @@ static struct resource sdhci_resource3[] = {
        },
 };
 
-
 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
        .cd_gpio = DALMORE_SD_CD,
        .wp_gpio = -1,
@@ -124,6 +399,6 @@ int __init dalmore_sdhci_init(void)
 {
        platform_device_register(&tegra_sdhci_device3);
        platform_device_register(&tegra_sdhci_device0);
-
        return 0;
 }
+#endif