summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorRicardo Perez Olivares <x0081762@ti.com>2010-07-10 03:30:23 -0500
committerRicardo Perez Olivares <x0081762@ti.com>2010-07-10 03:30:23 -0500
commitae2c6358a12bd46e175136eea6679822a7fc4149 (patch)
treec47083d583ff02ec96e139ec37353cc001fe731f /arch/arm
parent45f033c9186be11e0a223113a2d5a7ccafe35a8b (diff)
parent2d45669beed28c2f926a2bc2df98c981b2bd478c (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/Kconfig26
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rw-r--r--arch/arm/mach-omap2/board-4430sdp-wifi.c138
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c51
-rw-r--r--arch/arm/mach-omap2/hsmmc.c42
-rw-r--r--arch/arm/mach-omap2/hsmmc.h6
-rw-r--r--arch/arm/plat-omap/include/plat/mmc.h18
-rw-r--r--arch/arm/plat-omap/include/plat/wifi_tiwlan.h23
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