---------------------------------------------------------------- arch/arm/mach-omap2/board-ti8168evm.c ------------------------------------- static struct omap2_hsmmc_info mmc[] = { { //CTI Modified. //Custom Usage #ifdef CONFIG_WL12XX_PLATFORM_DATA /* WLAN_EN is GP1[9] */ #define GPIO_WLAN_EN ((1 * 32) + 11) /* WLAN_IRQ is GP1[11] */ #define GPIO_WLAN_IRQ ((1 * 32) + 9) .mmc = 1, //CTI Modified. .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, //.caps = MMC_CAP_4_BIT_DATA, .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, .ocr_mask = MMC_VDD_165_195, .nonremovable = true, }, #endif { .mmc = 1, .caps = MMC_CAP_4_BIT_DATA, .gpio_cd = -EINVAL, /* Dedicated pins for CD and WP */ .gpio_wp = -EINVAL, .ocr_mask = MMC_VDD_33_34, }, {} /* Terminator */ }; ---------------- static struct omap_board_mux board_mux[] __initdata = { TI816X_MUX(SC0_DET, OMAP_MUX_MODE2), /* gpio1-09 */ TI816X_MUX(SC0_CLK, OMAP_MUX_MODE2), /* gpio1-11 */ TI816X_MUX(MMC_CLK, OMAP_MUX_MODE0 | 0x10), TI816X_MUX(MMC_CMD, OMAP_MUX_MODE0 | 0x10), TI816X_MUX(MMC_DAT0, OMAP_MUX_MODE0 | 0x10), TI816X_MUX(MMC_DAT1_SDIRQ, OMAP_MUX_MODE0 | 0x10), TI816X_MUX(MMC_DAT2_SDRW, OMAP_MUX_MODE0 | 0x10), TI816X_MUX(MMC_DAT3, OMAP_MUX_MODE0 | 0x10), } ---------------- #ifdef CONFIG_WL12XX_PLATFORM_DATA static struct wl12xx_platform_data wlan_data __initdata = { .irq = OMAP_GPIO_IRQ(GPIO_WLAN_IRQ), /* COM6 (127x) uses FREF */ .board_ref_clock = WL12XX_REFCLOCK_26, /* COM7 (128x) uses TCXO */ .board_tcxo_clock = WL12XX_TCXOCLOCK_26, }; static int wl12xx_set_power(struct device *dev, int slot, int power_on, int vdd) { static bool power_state; printk("Powering %s wl12xx", power_on ? "on" : "off"); if (power_on == power_state) return 0; power_state = power_on; if (power_on) { /* Power up sequence required for wl127x devices */ gpio_set_value(GPIO_WLAN_EN, 1); usleep_range(15000, 15000); gpio_set_value(GPIO_WLAN_EN, 0); usleep_range(1000, 1000); gpio_set_value(GPIO_WLAN_EN, 1); msleep(70); } else { gpio_set_value(GPIO_WLAN_EN, 0); } return 0; } static void __init ti816x_wl12xx_wlan_init(void) { struct device *dev; struct omap_mmc_platform_data *pdata; int ret; /* Set up the WLAN_EN and WLAN_IRQ muxes * / //Custom Usage omap_mux_init_signal("gp1_io11", TI816X_PULL_DIS); omap_mux_init_signal("gp1_io9", TI816X_INPUT_EN | TI816X_PULL_DIS);*/ /* Pass the wl12xx platform data information to the wl12xx driver */ if (wl12xx_set_platform_data(&wlan_data)) { pr_err("Error setting wl12xx data\n"); return; } /* * The WLAN_EN gpio has to be toggled without using a fixed regulator, * as the omap_hsmmc does not enable/disable regulators on the TI816X. */ ret = gpio_request_one(GPIO_WLAN_EN, GPIOF_OUT_INIT_LOW, "wlan_en"); //ret = gpio_request_one(GPIO_WLAN_EN, GPIOF_OUT_INIT_HIGH, "wlan_en"); if (ret) { pr_err("Error requesting wlan enable gpio: %d\n", ret); return; } /* * Set our set_power callback function which will be called from * set_ios. This is requireq since, unlike other omap2+ platforms, a * no-op set_power function is registered. Thus, we cannot use a fixed * regulator, as it will never be toggled. * Moreover, even if this was not the case, we're on mmc0, for which * omap_hsmmc' set_power functions do not toggle any regulators. * TODO: Consider modifying omap_hsmmc so it would enable/disable a * regulator for ti814x/mmc0. */ dev = mmc[0].dev; if (!dev) { pr_err("wl12xx mmc device initialization failed\n"); return; } pdata = dev->platform_data; if (!pdata) { pr_err("Platform data of wl12xx device not set\n"); return; } pdata->slots[0].set_power = wl12xx_set_power; } static void __init ti816x_wl12xx_init(void) { ti816x_wl12xx_wlan_init(); } #else /* CONFIG_WL12XX_PLATFORM_DATA */ static void __init ti816x_wl12xx_init(void) { } #endif --------------------- static void __init ti8168_evm_init(void) { //Added ti816x_wl12xx_init(); } -------------------------------------------------------------------------------- arch/arm/mach-omap2/devices.c ------------------------------ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers) { else if (cpu_is_ti816x()) { printk("cpu_is_ti816x() case 0 \n"); base = TI816X_MMC1_BASE; //CTI Modified. #ifndef CONFIG_WL12XX_PLATFORM_DATA printk("TI81XX_IRQ_SD case 0 = %d \n", TI81XX_IRQ_SD); irq = TI81XX_IRQ_SD; #else printk("TI81XX_IRQ_SD case 0 = %d \n", TI81XX_IRQ_SD); irq = TI81XX_IRQ_SD; #endif } ------------------------------------------------------------------------------------- arch/arm/mach-omap2/kconfig ---------------------------- config TI8168EVM_WL12XX bool "TI816x wl12xx daughter board" depends on MACH_TI8168EVM select WL12XX_PLATFORM_DATA help The COM6/COM7 cards are wireless connectivity cards based on Murata's type TN module and Texas Insturments wl12xx chipset. Say Y if you want to use a wl12xx expansion card connected to the TI8168 EVM. -------------------------------------------------------------------------------------- arch/arm/plat-omap/include/plat/mmc.h -------------------------------------- //CTI Modified. #ifdef CONFIG_WL12XX_PLATFORM_DATA #define TI816X_NR_MMC 1 #else #define TI81XX_NR_MMC 1 #endif //CTI Modified #ifdef CONFIG_ARCH_TI814X #define TI81XX_NR_MMC TI814X_NR_MMC #else /* TI816X */ #define TI81XX_NR_MMC TI816X_NR_MMC #endif -------------------------------------------------------------------------------------- /drivers/mmc/core/core.c ------------------------ //CTI Modified #include void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) { //CTI Modified. // timeout_us += data->timeout_clks * 1000 / // (card->host->ios.clock / 1000); if (card->host->ios.clock) timeout_us += data->timeout_clks * 1000 / (card->host->ios.clock / 1000); } -------- void mmc_rescan(struct work_struct *work) { //CTI Modified /* if there is a card registered, check whether it is still present */ // if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead) /* * if there is a _removable_ card registered, check whether it is * still present */ if (host->bus_ops && host->bus_ops->detect && !host->bus_dead && mmc_card_is_removable(host)) host->bus_ops->detect(host); } ---------- int mmc_resume_host(struct mmc_host *host) { //CTI Modified. /* * Tell runtime PM core we just powered up the card, * since it still believes the card is powered off. * Note that currently runtime PM is only enabled * for SDIO cards that are MMC_CAP_POWER_OFF_CARD */ if (mmc_card_sdio(host->card) && (host->caps & MMC_CAP_POWER_OFF_CARD)) { pm_runtime_disable(&host->card->dev); pm_runtime_set_active(&host->card->dev); pm_runtime_enable(&host->card->dev); } } } -------------------------------------------------------------------------------------- /drivers/mmc/core/sdio.c ------------------------ static int sdio_read_cccr(struct mmc_card *card) { //CTI ADDED #if 0 // WL18xx returns CCR_REV_2_00 and so this is not an error if (cccr_vsn > SDIO_CCCR_REV_1_20) { printk(KERN_ERR "%s: unrecognised CCCR structure version %d\n", mmc_hostname(card->host), cccr_vsn); return -EINVAL; } #endif } ----------- static int mmc_sdio_resume(struct mmc_host *host) { //CTI Modified // err = mmc_sdio_init_card(host, host->ocr, host->card,(host->pm_flags & MMC_PM_KEEP_POWER)); /* No need to reinitialize powered-resumed nonremovable cards */ if (mmc_card_is_removable(host) || !mmc_card_is_powered_resumed(host)) err = mmc_sdio_init_card(host, host->ocr, host->card, (host->pm_flags & MMC_PM_KEEP_POWER)); else if (mmc_card_is_powered_resumed(host)) { /* We may have switched to 1-bit mode during suspend */ err = sdio_enable_4bit_bus(host->card); if (err > 0) { mmc_set_bus_width(host, MMC_BUS_WIDTH_4); err = 0; } } } -------------------------------------------------------------------------------------- /drivers/mmc/core/sdio_bus.c ---------------------------- //CTI Modified. #if 0 static int sdio_bus_pm_prepare(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); /* * Resume an SDIO device which was suspended at run time at this * point, in order to allow standard SDIO suspend/resume paths * to keep working as usual. * * Ultimately, the SDIO driver itself will decide (in its * suspend handler, or lack thereof) whether the card should be * removed or kept, and if kept, at what power state. * * At this point, PM core have increased our use count, so it's * safe to directly resume the device. After system is resumed * again, PM core will drop back its runtime PM use count, and if * needed device will be suspended again. * * The end result is guaranteed to be a power state that is * coherent with the device's runtime PM use count. * * The return value of pm_runtime_resume is deliberately unchecked * since there is little point in failing system suspend if a * device can't be resumed. */ if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) pm_runtime_resume(dev); return 0; } #endif ---------------- static const struct dev_pm_ops sdio_bus_pm_ops = { //CTI Modified. // .prepare = sdio_bus_pm_prepare, } ------------------------------------------------------------------------------------------ include/linux/wl12xx.h ---------------------- //CTI Modified. /* Reference clock values */ enum { WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */ WL12XX_REFCLOCK_26 = 1, /* 26 MHz */ WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */ WL12XX_REFCLOCK_52 = 3, /* 52 MHz */ WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */ WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */ }; /* TCXO clock values */ enum { WL12XX_TCXOCLOCK_19_2 = 0, /* 19.2MHz */ WL12XX_TCXOCLOCK_26 = 1, /* 26 MHz */ WL12XX_TCXOCLOCK_38_4 = 2, /* 38.4MHz */ WL12XX_TCXOCLOCK_52 = 3, /* 52 MHz */ WL12XX_TCXOCLOCK_16_368 = 4, /* 16.368 MHz */ WL12XX_TCXOCLOCK_32_736 = 5, /* 32.736 MHz */ WL12XX_TCXOCLOCK_16_8 = 6, /* 16.8 MHz */ WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */ }; struct wl12xx_platform_data { void (*set_power)(bool enable); /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ int irq; bool use_eeprom; int board_ref_clock; //CTI Modified. int board_tcxo_clock; unsigned long platform_quirks; }; //CTI Modified. /* Platform does not support level trigger interrupts */ #define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0) ------------------------------------------------------------------------------------------------- include/linux/mmc/host.h ------------------------ //CTI Modified static inline int mmc_card_is_powered_resumed(struct mmc_host *host) { return host->pm_flags & MMC_PM_KEEP_POWER; } ------------------------------------------------------------------------------------------------- include/linux/mmc/sdio.h ------------------------ //CTI ADDED // Backport for Wilink8 driver build #define SDIO_SDIO_REV_3_00 4 /* SDIO Spec Version 3.00 */ --------------------------------------------------------------------------------------------------