diff options
Diffstat (limited to 'arch/arm/mach-tegra/board-cardhu-sdhci.c')
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu-sdhci.c | 97 |
1 files changed, 95 insertions, 2 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu-sdhci.c b/arch/arm/mach-tegra/board-cardhu-sdhci.c index fc1af6e67e35..5e205fda45a0 100644 --- a/arch/arm/mach-tegra/board-cardhu-sdhci.c +++ b/arch/arm/mach-tegra/board-cardhu-sdhci.c @@ -17,6 +17,7 @@ #include <linux/resource.h> #include <linux/platform_device.h> +#include <linux/wlan_plat.h> #include <linux/delay.h> #include <linux/gpio.h> #include <linux/clk.h> @@ -32,10 +33,34 @@ #include "board.h" #include "board-cardhu.h" +#define CARDHU_WLAN_PWR TEGRA_GPIO_PD4 +#define CARDHU_WLAN_RST TEGRA_GPIO_PD3 #define CARDHU_SD_CD TEGRA_GPIO_PI5 #define CARDHU_SD_WP TEGRA_GPIO_PT3 #define PM269_SD_WP -1 +static void (*wifi_status_cb)(int card_present, void *dev_id); +static void *wifi_status_cb_devid; +static int cardhu_wifi_status_register(void (*callback)(int , void *), void *); + +static int cardhu_wifi_reset(int on); +static int cardhu_wifi_power(int on); +static int cardhu_wifi_set_carddetect(int val); + +static struct wifi_platform_data cardhu_wifi_control = { + .set_power = cardhu_wifi_power, + .set_reset = cardhu_wifi_reset, + .set_carddetect = cardhu_wifi_set_carddetect, +}; + +static struct platform_device cardhu_wifi_device = { + .name = "bcm4329_wlan", + .id = 1, + .dev = { + .platform_data = &cardhu_wifi_control, + }, +}; + static struct resource sdhci_resource0[] = { [0] = { .start = INT_SDMMC1, @@ -76,7 +101,20 @@ static struct resource sdhci_resource3[] = { }; -static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = { +static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = { + .register_status_notify = cardhu_wifi_status_register, + .cccr = { + .sdio_vsn = 2, + .multi_block = 1, + .low_speed = 0, + .wide_bus = 0, + .high_power = 1, + .high_speed = 1, + }, + .cis = { + .vendor = 0x02d0, + .device = 0x4329, + }, .cd_gpio = -1, .wp_gpio = -1, .power_gpio = -1, @@ -90,7 +128,7 @@ static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = { .is_8bit_supported = false, */ }; -static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = { +static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = { .cd_gpio = -1, .wp_gpio = -1, .power_gpio = -1, @@ -212,6 +250,60 @@ static int pm269_sd_wp_gpio_init(void) return 0; } +static int cardhu_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; +} + +static int cardhu_wifi_set_carddetect(int val) +{ + pr_debug("%s: %d\n", __func__, val); + if (wifi_status_cb) + wifi_status_cb(val, wifi_status_cb_devid); + else + pr_warning("%s: Nobody to notify\n", __func__); + return 0; +} + +static int cardhu_wifi_power(int on) +{ + pr_debug("%s: %d\n", __func__, on); + gpio_set_value(CARDHU_WLAN_PWR, on); + mdelay(100); + gpio_set_value(CARDHU_WLAN_RST, on); + mdelay(200); + + return 0; +} + +static int cardhu_wifi_reset(int on) +{ + pr_debug("%s: do nothing\n", __func__); + return 0; +} + +static int __init cardhu_wifi_init(void) +{ + + gpio_request(CARDHU_WLAN_PWR, "wlan_power"); + gpio_request(CARDHU_WLAN_RST, "wlan_rst"); + + tegra_gpio_enable(CARDHU_WLAN_PWR); + tegra_gpio_enable(CARDHU_WLAN_RST); + + gpio_direction_output(CARDHU_WLAN_PWR, 0); + gpio_direction_output(CARDHU_WLAN_RST, 0); + + platform_device_register(&cardhu_wifi_device); + return 0; +} + int __init cardhu_sdhci_init(void) { #if 0 @@ -259,5 +351,6 @@ int __init cardhu_sdhci_init(void) (void)pm269_sd_wp_gpio_init; #endif + cardhu_wifi_init(); return 0; } |