diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/mach/mmc.h | 13 | ||||
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 22 | ||||
-rw-r--r-- | arch/arm/mach-omap2/Makefile | 1 | ||||
-rwxr-xr-x | arch/arm/mach-omap2/board-4430sdp-wifi.c | 138 | ||||
-rwxr-xr-x[-rw-r--r--] | arch/arm/mach-omap2/board-4430sdp.c | 55 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mmc-twl4030.c | 55 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/mach/mmc.h | 11 | ||||
-rwxr-xr-x | arch/arm/plat-omap/include/mach/wifi_tiwlan.h | 23 |
8 files changed, 313 insertions, 5 deletions
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h index 4da332b03144..36c860347b66 100644 --- a/arch/arm/include/asm/mach/mmc.h +++ b/arch/arm/include/asm/mach/mmc.h @@ -6,6 +6,19 @@ #include <linux/mmc/host.h> +#ifdef CONFIG_MMC_EMBEDDED_SDIO +#include <linux/mmc/card.h> +#include <linux/mmc/sdio_func.h> + +struct embedded_sdio_data { + struct sdio_cis cis; + struct sdio_cccr cccr; + struct sdio_embedded_func *funcs; + int num_funcs; + unsigned int quirks; +}; +#endif + struct mmc_platform_data { unsigned int ocr_mask; /* available voltages */ u32 (*translate_vdd)(struct device *, unsigned int); diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index a755eb5e2361..3f8f74734987 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -60,6 +60,28 @@ config MACH_OMAP3EVM bool "OMAP 3530 EVM board" depends on ARCH_OMAP3 && ARCH_OMAP34XX +config WIFI_CONTROL_FUNC + bool "Enable WiFi control function abstraction" + depends on MACH_OMAP_4430SDP + default Y + help + Enables Power/Reset/Carddetect function abstraction +config TIWLAN_SDIO + bool "TI WLAN Enhanced SDIO Contoller support" + depends on MMC_OMAP || MMC_OMAP_MODULE || MMC_OMAP_HS || MMC_OMAP_HS_MODULE + help + Say Y here if you want to be able to use TI's WLAN device using the + SDIO interface. If unsure, say N. +config TIWLAN_MMC_CONTROLLER + int "MMC Controller number that TI WLAN chip is connected to" + range 1 5 + depends on TIWLAN_SDIO || MMC_EMBEDDED_SDIO + default "5" + help + Choose the number of the MMC controller that TI WLAN chip is + connected to. TI WLAN has SDIO host controller that will control + this MMC port. + config MACH_OMAP3_PANDORA bool "OMAP3 Pandora" depends on ARCH_OMAP3 && ARCH_OMAP34XX diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index a6cea7e84825..7e7dc29786bb 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \ obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \ mmc-twl4030.o +obj-$(CONFIG_MMC_EMBEDDED_SDIO) += board-4430sdp-wifi.o # Platform specific device init code obj-y += usb-musb.o \ usb-ehci.o diff --git a/arch/arm/mach-omap2/board-4430sdp-wifi.c b/arch/arm/mach-omap2/board-4430sdp-wifi.c new file mode 100755 index 000000000000..4789cbc32ea0 --- /dev/null +++ b/arch/arm/mach-omap2/board-4430sdp-wifi.c @@ -0,0 +1,138 @@ +/* + * Board support file for containing WiFi specific details for OMAP4430 SDP. + * + * Copyright (C) 2009 Texas Instruments + * + * Author: Pradeep Gurumath <pradeepgurumath@ti.com> + * + * Based on mach-omap2/board-3430sdp.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* linux/arch/arm/mach-omap2/board-4430sdp-wifi.c +*/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sdio_ids.h> +#include <linux/err.h> + +#include <asm/gpio.h> +#include <asm/io.h> +#include <mach/wifi_tiwlan.h> + +#define SDP4430_WIFI_PMENA_GPIO 54 +#define SDP4430_WIFI_IRQ_GPIO 53 + +static int sdp4430_wifi_cd; /* WIFI virtual 'card detect' status */ +static void (*wifi_status_cb)(int card_present, void *dev_id); +static void *wifi_status_cb_devid; + +int omap_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; +} + +int omap_wifi_status(int irq) +{ + return sdp4430_wifi_cd; +} + +int sdp4430_wifi_set_carddetect(int val) +{ + printk(KERN_WARNING"%s: %d\n", __func__, val); + sdp4430_wifi_cd = val; + if (wifi_status_cb) + wifi_status_cb(val, wifi_status_cb_devid); + else + printk(KERN_WARNING "%s: Nobody to notify\n", __func__); + return 0; +} +#ifndef CONFIG_WIFI_CONTROL_FUNC +EXPORT_SYMBOL(sdp4430_wifi_set_carddetect); +#endif + +static int sdp4430_wifi_power_state; + +int sdp4430_wifi_power(int on) +{ + printk(KERN_WARNING"%s: %d\n", __func__, on); + gpio_set_value(SDP4430_WIFI_PMENA_GPIO, on); + sdp4430_wifi_power_state = on; + return 0; +} +#ifndef CONFIG_WIFI_CONTROL_FUNC +EXPORT_SYMBOL(sdp4430_wifi_power); +#endif + +static int sdp4430_wifi_reset_state; +int sdp4430_wifi_reset(int on) +{ + printk(KERN_WARNING"%s: %d\n", __func__, on); + sdp4430_wifi_reset_state = on; + return 0; +} +#ifndef CONFIG_WIFI_CONTROL_FUNC +EXPORT_SYMBOL(sdp4430_wifi_reset); +#endif + +struct wifi_platform_data sdp4430_wifi_control = { + .set_power = sdp4430_wifi_power, + .set_reset = sdp4430_wifi_reset, + .set_carddetect = sdp4430_wifi_set_carddetect, +}; + +#ifdef CONFIG_WIFI_CONTROL_FUNC +static struct resource sdp4430_wifi_resources[] = { + [0] = { + .name = "device_wifi_irq", + .start = OMAP_GPIO_IRQ(SDP4430_WIFI_IRQ_GPIO), + .end = OMAP_GPIO_IRQ(SDP4430_WIFI_IRQ_GPIO), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, + }, +}; + +static struct platform_device sdp4430_wifi_device = { + .name = "device_wifi", + .id = 1, + .num_resources = ARRAY_SIZE(sdp4430_wifi_resources), + .resource = sdp4430_wifi_resources, + .dev = { + .platform_data = &sdp4430_wifi_control, + }, +}; +#endif + +static int __init sdp4430_wifi_init(void) +{ + int ret; + + printk(KERN_WARNING"%s: start\n", __func__); + ret = gpio_request(SDP4430_WIFI_IRQ_GPIO, "wifi_irq"); + if (ret < 0) { + printk(KERN_ERR "%s: can't reserve GPIO: %d\n", __func__, + SDP4430_WIFI_IRQ_GPIO); + goto out; + } + gpio_direction_input(SDP4430_WIFI_IRQ_GPIO); +#ifdef CONFIG_WIFI_CONTROL_FUNC + ret = platform_device_register(&sdp4430_wifi_device); +#endif +out: + return ret; +} + +device_initcall(sdp4430_wifi_init); diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 1fb4976e6e18..a1e9e32eb5c9 100644..100755 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -338,26 +338,26 @@ static struct twl4030_hsmmc_info mmc[] = { { .mmc = 2, .wires = 8, - .gpio_cd = -EINVAL, + .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, }, { .mmc = 3, .wires = -EINVAL, - .gpio_cd = -EINVAL, + .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, }, { .mmc = 4, .wires = -EINVAL, - .gpio_cd = -EINVAL, + .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, }, { .mmc = 5, - .wires = -EINVAL, + .wires = 8, .gpio_cd = -EINVAL, - .gpio_wp = -EINVAL, + .gpio_wp = 4, }, {} /* Terminator */ }; @@ -384,6 +384,14 @@ static int __init sdp4430_mmc_init(void) { /* Hard Coding Values for testing */ mmc[0].gpio_cd = 373; + +#ifdef CONFIG_MMC_EMBEDDED_SDIO + /* The controller that is connected to the 128x device + should have the card detect gpio disabled. This is + achieved by initializing it with a negative value */ + mmc[CONFIG_TIWLAN_MMC_CONTROLLER - 1].gpio_cd = -EINVAL; +#endif + twl4030_mmc_init(mmc); /* link regulators to MMC adapters ... we "know" the * regulators will be set up only *after* we return. @@ -725,6 +733,38 @@ static struct omap_usbhost_port_data sdp_usbhost_port_data[] = { }, }; +#ifdef CONFIG_MMC_EMBEDDED_SDIO +static void pad_config(unsigned long pad_addr, u32 andmask, u32 ormask) +{ + int val; + u32 *addr; + + addr = (u32 *) ioremap(pad_addr, 4); + if (!addr) { + printk(KERN_ERR"OMAP_pad_config: ioremap failed with addr %lx\n", + pad_addr); + return; + } + + val = __raw_readl(addr); + val &= andmask; + val |= ormask; + __raw_writel(val, addr); + + iounmap(addr); +} + +void wlan_1283_config() +{ + pad_config(0x4A100078, 0xFFECFFFF, 0x00030000); + pad_config(0x4A10007C, 0xFFFFFFEF, 0x0000000B); + if (gpio_request(54, NULL) != 0) + printk(KERN_ERR "GPIO 54 request failed\n"); + gpio_direction_output(54, 0); + return ; +} +#endif + static void __init omap_4430sdp_init(void) { omap4_i2c_init(); @@ -740,6 +780,11 @@ static void __init omap_4430sdp_init(void) ARRAY_SIZE(sdp4430_spi_board_info)); omap_mcbsp_init(); sdp4430_mmc_init(); + +#ifdef CONFIG_MMC_EMBEDDED_SDIO + wlan_1283_config(); +#endif + sdp4430_display_init(); omap_phoenix_init(); #ifdef CONFIG_NOP_USB_XCEIV diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c index 68891f26f951..aa84fed1edc6 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.c +++ b/arch/arm/mach-omap2/mmc-twl4030.c @@ -24,6 +24,11 @@ #include <mach/mmc.h> #include <mach/board.h> +#ifdef CONFIG_MMC_EMBEDDED_SDIO +#include <asm/mach/mmc.h> +#include <linux/mmc/sdio_ids.h> +#endif + #include "mmc-twl4030.h" #include <linux/i2c/twl.h> @@ -460,6 +465,43 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v static struct omap_mmc_platform_data *hsmmc_data[OMAP44XX_NR_MMC] __initdata; +#ifdef CONFIG_MMC_EMBEDDED_SDIO +int omap_wifi_status_register(void (*callback)(int card_present, + void *dev_id), void *dev_id); +int omap_wifi_status(int irq); + +static struct sdio_embedded_func wifi_func_array[] = { + { + .f_class = SDIO_CLASS_BT_A, + .f_maxblksize = 512, + }, + { + .f_class = SDIO_CLASS_WLAN, + .f_maxblksize = 512, + }, +}; + +static struct embedded_sdio_data omap_wifi_emb_data = { + .cis = { + .vendor = SDIO_VENDOR_ID_TI, + .device = SDIO_DEVICE_ID_TI_WL12xx, + .blksize = 512, + .max_dtr = 24000000, + }, + .cccr = { + .multi_block = 1, + .low_speed = 0, + .wide_bus = 1, + .high_power = 0, + .high_speed = 0, + .disable_cd = 1, + }, + .funcs = wifi_func_array, + .num_funcs = 2, + .quirks = MMC_QUIRK_VDD_165_195 | MMC_QUIRK_LENIENT_FUNC0, +}; +#endif + void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) { struct twl4030_hsmmc_info *c; @@ -513,6 +555,16 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) else snprintf(twl->name, ARRAY_SIZE(twl->name), "mmc%islot%i", c->mmc, 1); + +#ifdef CONFIG_MMC_EMBEDDED_SDIO + if (c->mmc == CONFIG_TIWLAN_MMC_CONTROLLER) { + mmc->slots[0].embedded_sdio = &omap_wifi_emb_data; + mmc->slots[0].register_status_notify = + &omap_wifi_status_register; + mmc->slots[0].card_detect = &omap_wifi_status; + } +#endif + mmc->slots[0].name = twl->name; mmc->nr_slots = 1; mmc->slots[0].wires = c->wires; @@ -598,6 +650,9 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) case 5: /* TODO */ mmc->slots[0].set_power = twl_mmc23_set_power; +#ifdef CONFIG_MMC_EMBEDDED_SDIO + mmc->slots[0].ocr_mask = MMC_VDD_165_195; +#endif break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h index c84a6d43bf90..5836aadd87c9 100644 --- a/arch/arm/plat-omap/include/mach/mmc.h +++ b/arch/arm/plat-omap/include/mach/mmc.h @@ -15,6 +15,10 @@ #include <linux/device.h> #include <linux/mmc/host.h> +#ifdef CONFIG_MMC_EMBEDDED_SDIO +#include <asm/mach/mmc.h> +#endif + #include <mach/board.h> #define OMAP15XX_NR_MMC 1 @@ -111,6 +115,13 @@ struct omap_mmc_platform_data { unsigned int ban_openended:1; +#ifdef CONFIG_MMC_EMBEDDED_SDIO + struct embedded_sdio_data *embedded_sdio; + int (*register_status_notify) + (void (*callback)(int card_present, void *dev_id), + void *dev_id); +#endif + } slots[OMAP_MMC_MAX_SLOTS]; }; diff --git a/arch/arm/plat-omap/include/mach/wifi_tiwlan.h b/arch/arm/plat-omap/include/mach/wifi_tiwlan.h new file mode 100755 index 000000000000..b0332b04ddc9 --- /dev/null +++ b/arch/arm/plat-omap/include/mach/wifi_tiwlan.h @@ -0,0 +1,23 @@ +/* mach/wifi_tiwlan.h + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _LINUX_WIFI_TIWLAN_H_ +#define _LINUX_WIFI_TIWLAN_H_ + +struct wifi_platform_data { + int (*set_power)(int val); + int (*set_reset)(int val); + int (*set_carddetect)(int val); + void *(*mem_prealloc)(int section, unsigned long size); +}; + +#endif |