/* * arch/arm/mach-tegra/board-vcm30_t124-sdhci.c * * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "iomap.h" #include "gpio-names.h" #include "board.h" #include "board-vcm30_t124.h" #include "devices.h" static void (*wifi_status_cb) (int card_present, void *dev_id); static void *wifi_status_cb_devid; static int vcm30_t124_wifi_status_register(void (*callback) (int, void *), void *); static int vcm30_t124_wifi_reset(int on); static int vcm30_t124_wifi_power(int on); static int vcm30_t124_wifi_set_carddetect(int val); static struct wifi_platform_data vcm30_t124_wifi_control = { .set_power = vcm30_t124_wifi_power, .set_reset = vcm30_t124_wifi_reset, .set_carddetect = vcm30_t124_wifi_set_carddetect, }; static struct platform_device broadcom_wifi_device = { .name = "bcm4329_wlan", .id = 1, .dev = { .platform_data = &vcm30_t124_wifi_control, }, }; #ifdef CONFIG_MMC_EMBEDDED_SDIO static struct embedded_sdio_data embedded_sdio_data1 = { .cccr = { .sdio_vsn = 2, .multi_block = 1, .low_speed = 0, .wide_bus = 0, .high_power = 1, .high_speed = 1, }, .cis = { .vendor = 0x02d0, .device = 0x4329, }, }; #endif static struct tegra_sdhci_platform_data tegra_sdhci_platform_data1 = { .mmc_data = { .register_status_notify = vcm30_t124_wifi_status_register, #ifdef CONFIG_MMC_EMBEDDED_SDIO .embedded_sdio = &embedded_sdio_data1, #endif .built_in = 0, .ocr_mask = MMC_OCR_1V8_MASK, }, #ifndef CONFIG_MMC_EMBEDDED_SDIO .pm_flags = MMC_PM_KEEP_POWER, #endif .cd_gpio = -1, .wp_gpio = -1, .power_gpio = -1, .tap_delay = 0x5, .trim_delay = 0x2, .is_8bit = false, .ddr_clk_limit = 30000000, .max_clk_limit = 50000000, /* * FIXME: Wifi currently working on HS mode. * enable SDR104, DDR50 and SDR50 mode for wifi using * bug 1457466 */ .uhs_mask = MMC_UHS_MASK_SDR104 | MMC_UHS_MASK_DDR50 | MMC_UHS_MASK_SDR50, .calib_3v3_offsets = 0x7676, .calib_1v8_offsets = 0x7676, .disable_clock_gate = 1, }; static int vcm30_t124_wifi_status_register( void (*callback) (int card_present, void *dev_id), void *dev_id) { if (wifi_status_cb) return -EBUSY; wifi_status_cb = callback; wifi_status_cb_devid = dev_id; return 0; } static int vcm30_t124_wifi_set_carddetect(int val) { if (wifi_status_cb) wifi_status_cb(val, wifi_status_cb_devid); else pr_warn("%s: Nobody to notify\n", __func__); return 0; } static int vcm30_t124_wifi_power(int on) { int ret; /* Deassert WiFi RST GPIO */ ret = gpio_request(MISCIO_WF_EN_GPIO, "wifi_en"); if (ret < 0) goto fail; gpio_direction_output(MISCIO_WF_EN_GPIO, on); gpio_free(MISCIO_WF_EN_GPIO); ret = gpio_request(MISCIO_WF_RST_GPIO, "wifi_rst"); if (ret < 0) goto fail; gpio_direction_output(MISCIO_WF_RST_GPIO, on); gpio_free(MISCIO_WF_RST_GPIO); mdelay(100); return 0; fail: printk(KERN_ERR "%s: gpio_request failed(%d)\r\n", __func__, ret); return ret; } static int vcm30_t124_wifi_reset(int on) { /* * FIXME: Implement wifi reset */ return 0; } int __init vcm30_t124_wifi_init(void) { platform_device_register(&broadcom_wifi_device); return 0; } int __init vcm30_t124_sdhci_init(void) { tegra_sdhci_device1.dev.platform_data = &tegra_sdhci_platform_data1; platform_device_register(&tegra_sdhci_device1); vcm30_t124_wifi_init(); return 0; }