diff options
author | Ricardo Perez Olivares <x0081762@ti.com> | 2010-07-10 03:30:23 -0500 |
---|---|---|
committer | Ricardo Perez Olivares <x0081762@ti.com> | 2010-07-10 03:30:23 -0500 |
commit | ae2c6358a12bd46e175136eea6679822a7fc4149 (patch) | |
tree | c47083d583ff02ec96e139ec37353cc001fe731f /arch/arm | |
parent | 45f033c9186be11e0a223113a2d5a7ccafe35a8b (diff) | |
parent | 2d45669beed28c2f926a2bc2df98c981b2bd478c (diff) |
Merge branch 'Wlan-next' of git://dev.omapzoom.org/pub/scm/pradeep/wlan-1283 into L24x8
Conflicts:
arch/arm/mach-omap2/board-4430sdp.c
drivers/mmc/host/omap_hsmmc.c
Signed-off-by: Ricardo Perez Olivares <x0081762@ti.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 26 | ||||
-rw-r--r-- | arch/arm/mach-omap2/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-4430sdp-wifi.c | 138 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-4430sdp.c | 51 | ||||
-rw-r--r-- | arch/arm/mach-omap2/hsmmc.c | 42 | ||||
-rw-r--r-- | arch/arm/mach-omap2/hsmmc.h | 6 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/mmc.h | 18 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/wifi_tiwlan.h | 23 |
8 files changed, 305 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 2ae09b48df84..c54cae27444b 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -79,6 +79,32 @@ config MACH_OMAP3EVM depends on ARCH_OMAP3 select OMAP_PACKAGE_CBB +config WIFI_CONTROL_FUNC + bool "Enable WiFi control function abstraction" + depends on MACH_OMAP_4430SDP + select WIRELESS_EXT + select WEXT_CORE + select WEXT_PROC + select WEXT_PRIV + 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 + 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_OMAP3517EVM bool "OMAP3517/ AM3517 EVM board" depends on ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 6c4afe050c2a..0ab62c2082a2 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -168,6 +168,7 @@ obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \ hsmmc.o obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \ hsmmc.o +obj-$(CONFIG_TIWLAN_SDIO) += board-4430sdp-wifi.o obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o diff --git a/arch/arm/mach-omap2/board-4430sdp-wifi.c b/arch/arm/mach-omap2/board-4430sdp-wifi.c new file mode 100644 index 000000000000..b13e9fc3767a --- /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 <plat/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 f2ba4ff103b1..888bcb6e549b 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -595,6 +595,14 @@ static struct omap_dss_device sdp4430_picoDLP_device = { .channel = OMAP_DSS_CHANNEL_LCD2, }; +/* wl128x BT, FM, GPS connectivity chip */ +static int gpios[] = {55, -1, -1}; +static struct platform_device wl128x_device = { + .name = "kim", + .id = -1, + .dev.platform_data = &gpios, +}; + static struct omap_dss_device *sdp4430_dss_devices[] = { &sdp4430_lcd_device, &sdp4430_lcd2_device, @@ -626,6 +634,7 @@ static struct platform_device *sdp4430_devices[] __initdata = { &sdp4430_proximity_device, &sdp4430_leds_gpio, &sdp4430_leds_pwm, + &wl128x_device, }; static struct omap_lcd_config sdp4430_lcd_config __initdata = { @@ -750,6 +759,13 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) for (c = controllers; c->mmc; c++) omap4_twl6030_hsmmc_set_late_init(c->dev); +#ifdef CONFIG_TIWLAN_SDIO + /* The controller that is connected to the 128x device + should hould have the card detect gpio disabled. This is + achieved by initializing it with a negative value */ + c[CONFIG_TIWLAN_MMC_CONTROLLER - 1].gpio_cd = -EINVAL; +#endif + return 0; } @@ -1053,6 +1069,38 @@ fail1: gpio_free(OMAP4_SFH7741_SENSOR_OUTPUT_GPIO); } +#ifdef CONFIG_TIWLAN_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 omap_cma3000accl_init(void) { if (gpio_request(OMAP4_CMA3000ACCL_GPIO, "Accelerometer") < 0) { @@ -1081,6 +1129,9 @@ static void __init omap_4430sdp_init(void) platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); omap_serial_init(); omap4_twl6030_hsmmc_init(mmc); +#ifdef CONFIG_TIWLAN_SDIO + wlan_1283_config(); +#endif /* OMAP4 SDP uses internal transceiver so register nop transceiver */ usb_nop_xceiv_register(); usb_musb_init(&musb_board_data); diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 6a6dd3e7a772..215bb3fadabb 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -19,6 +19,11 @@ #include <plat/omap-pm.h> #include <plat/omap_device.h> +#ifdef CONFIG_TIWLAN_SDIO +#include <linux/mmc/sdio_ids.h> +#include <linux/mmc/sdio_func.h> +#endif + #include "hsmmc.h" #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) @@ -197,6 +202,30 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot, static struct omap_mmc_platform_data *hsmmc_data[OMAP44XX_NR_MMC] __initdata; +#ifdef CONFIG_TIWLAN_SDIO +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, + }, + .funcs = wifi_func_array, + .quirks = MMC_QUIRK_VDD_165_195 | MMC_QUIRK_LENIENT_FUNC0, +}; +#endif + void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) { struct omap2_hsmmc_info *c; @@ -254,6 +283,16 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) else snprintf(hc->name, ARRAY_SIZE(hc->name), "mmc%islot%i", c->mmc, 1); + +#ifdef CONFIG_TIWLAN_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 = hc->name; mmc->nr_slots = 1; mmc->slots[0].wires = c->wires; @@ -327,6 +366,9 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) /* TODO Update required */ mmc->slots[0].before_set_reg = NULL; mmc->slots[0].after_set_reg = NULL; +#ifdef CONFIG_TIWLAN_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/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h index 36f0ba8d89e2..abaaa753dc53 100644 --- a/arch/arm/mach-omap2/hsmmc.h +++ b/arch/arm/mach-omap2/hsmmc.h @@ -25,6 +25,12 @@ struct omap2_hsmmc_info { void (*remux)(struct device *dev, int slot, int power_on); }; +#ifdef CONFIG_TIWLAN_SDIO +int omap_wifi_status_register(void (*callback)(int card_present, + void *dev_id), void *dev_id); +int omap_wifi_status(int irq); +#endif + #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) void omap2_hsmmc_init(struct omap2_hsmmc_info *); diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index f5a08367cd0c..ac33cc848097 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -20,6 +20,10 @@ #include <plat/board.h> #include <plat/omap_hwmod.h> +#ifdef CONFIG_TIWLAN_SDIO +#include <linux/mmc/card.h> +#endif + #define OMAP15XX_NR_MMC 1 #define OMAP16XX_NR_MMC 2 #define OMAP1_MMC_SIZE 0x080 @@ -50,6 +54,13 @@ #define MMC_SUPPORT_18V_3V (1 << 0) #define MMC_SUPPORT_3V (1 << 1) +#ifdef CONFIG_TIWLAN_SDIO +struct embedded_sdio_data { +struct sdio_cis cis; +struct sdio_embedded_func *funcs; +unsigned int quirks; +}; +#endif struct mmc_dev_attr { u8 flags; @@ -151,6 +162,13 @@ struct omap_mmc_platform_data { unsigned int ban_openended:1; +#ifdef CONFIG_TIWLAN_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/plat/wifi_tiwlan.h b/arch/arm/plat-omap/include/plat/wifi_tiwlan.h new file mode 100644 index 000000000000..b0332b04ddc9 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/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 |