summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/include/asm/mach/mmc.h13
-rw-r--r--arch/arm/mach-omap2/Kconfig22
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rwxr-xr-xarch/arm/mach-omap2/board-4430sdp-wifi.c138
-rwxr-xr-x[-rw-r--r--]arch/arm/mach-omap2/board-4430sdp.c55
-rw-r--r--arch/arm/mach-omap2/mmc-twl4030.c55
-rw-r--r--arch/arm/plat-omap/include/mach/mmc.h11
-rwxr-xr-xarch/arm/plat-omap/include/mach/wifi_tiwlan.h23
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