2 * arch/arm/mach-tegra/board-tegratab-sdhci.c
4 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/resource.h>
18 #include <linux/platform_device.h>
19 #include <linux/delay.h>
20 #include <linux/gpio.h>
21 #include <linux/clk.h>
22 #include <linux/err.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/mmc/host.h>
26 #include <asm/mach-types.h>
27 #include <mach/irqs.h>
28 #include <mach/iomap.h>
29 #include <mach/sdhci.h>
30 #include <mach/gpio-tegra.h>
31 #include <mach/io_dpd.h>
32 #include <linux/wl12xx.h>
34 #include "tegra-board-id.h"
35 #include "gpio-names.h"
37 #include "board-tegratab.h"
40 #define TEGRATAB_SD_CD TEGRA_GPIO_PV2
41 #define TEGRATAB_SD_WP TEGRA_GPIO_PQ4
42 #define TEGRATAB_WLAN_PWR TEGRA_GPIO_PCC5
43 #define TEGRATAB_WLAN_RST TEGRA_GPIO_PX7
44 #define TEGRATAB_WLAN_WOW TEGRA_GPIO_PU5
45 #if defined(CONFIG_WLCORE_EDP_SUPPORT)
46 #define ON 808 /* 808.236 mW */
48 static unsigned int wl_states[] = {ON, OFF};
51 static void (*wifi_status_cb)(int card_present, void *dev_id);
52 static void *wifi_status_cb_devid;
53 static int tegratab_wifi_status_register(void (*callback)(int , void *),
56 static int tegratab_wifi_power(int on);
57 static int tegratab_wifi_set_carddetect(int val);
59 static struct wl12xx_platform_data tegratab_wl12xx_wlan_data __initdata = {
60 .board_ref_clock = WL12XX_REFCLOCK_26,
61 .board_tcxo_clock = 1,
62 .set_power = tegratab_wifi_power,
63 .set_carddetect = tegratab_wifi_set_carddetect,
64 #if defined(CONFIG_WLCORE_EDP_SUPPORT)
67 .name = "wl_edp_client",
69 .num_states = ARRAY_SIZE(wl_states),
71 .priority = EDP_MAX_PRIO,
78 static struct resource sdhci_resource0[] = {
82 .flags = IORESOURCE_IRQ,
85 .start = TEGRA_SDMMC1_BASE,
86 .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
87 .flags = IORESOURCE_MEM,
91 static struct resource sdhci_resource2[] = {
95 .flags = IORESOURCE_IRQ,
98 .start = TEGRA_SDMMC3_BASE,
99 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
100 .flags = IORESOURCE_MEM,
104 static struct resource sdhci_resource3[] = {
108 .flags = IORESOURCE_IRQ,
111 .start = TEGRA_SDMMC4_BASE,
112 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
113 .flags = IORESOURCE_MEM,
117 #ifdef CONFIG_MMC_EMBEDDED_SDIO
118 static struct embedded_sdio_data embedded_sdio_data0 = {
134 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
136 .register_status_notify = tegratab_wifi_status_register,
137 #ifdef CONFIG_MMC_EMBEDDED_SDIO
138 .embedded_sdio = &embedded_sdio_data0,
141 .ocr_mask = MMC_OCR_1V8_MASK,
143 #ifndef CONFIG_MMC_EMBEDDED_SDIO
144 .pm_flags = MMC_PM_KEEP_POWER,
151 .ddr_clk_limit = 41000000,
152 .uhs_mask = MMC_UHS_MASK_SDR104 |
156 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
157 .cd_gpio = TEGRATAB_SD_CD,
158 .wp_gpio = TEGRATAB_SD_WP,
162 .ddr_clk_limit = 41000000,
163 .max_clk_limit = 156000000,
165 .ocr_mask = MMC_OCR_2V8_MASK,
167 .uhs_mask = MMC_UHS_MASK_DDR50,
169 .edp_states = {966, 0},
170 .power_off_rail = true,
173 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
180 .ddr_clk_limit = 41000000,
181 .max_clk_limit = 156000000,
184 .ocr_mask = MMC_OCR_1V8_MASK,
187 .edp_states = {966, 0},
190 static struct platform_device tegra_sdhci_device0 = {
191 .name = "sdhci-tegra",
193 .resource = sdhci_resource0,
194 .num_resources = ARRAY_SIZE(sdhci_resource0),
196 .platform_data = &tegra_sdhci_platform_data0,
200 static struct platform_device tegra_sdhci_device2 = {
201 .name = "sdhci-tegra",
203 .resource = sdhci_resource2,
204 .num_resources = ARRAY_SIZE(sdhci_resource2),
206 .platform_data = &tegra_sdhci_platform_data2,
210 static struct platform_device tegra_sdhci_device3 = {
211 .name = "sdhci-tegra",
213 .resource = sdhci_resource3,
214 .num_resources = ARRAY_SIZE(sdhci_resource3),
216 .platform_data = &tegra_sdhci_platform_data3,
220 static int tegratab_wifi_status_register(
221 void (*callback)(int card_present, void *dev_id),
226 wifi_status_cb = callback;
227 wifi_status_cb_devid = dev_id;
231 static int tegratab_wifi_set_carddetect(int val)
233 pr_debug("%s: %d\n", __func__, val);
235 wifi_status_cb(val, wifi_status_cb_devid);
237 pr_warning("%s: Nobody to notify\n", __func__);
241 static int tegratab_wifi_power(int on)
243 pr_debug("%s: %d\n", __func__, on);
246 gpio_set_value(TEGRATAB_WLAN_RST, 1);
248 gpio_set_value(TEGRATAB_WLAN_RST, 0);
250 gpio_set_value(TEGRATAB_WLAN_RST, 1);
252 gpio_set_value(TEGRATAB_WLAN_PWR, 1);
255 gpio_set_value(TEGRATAB_WLAN_RST, 0);
257 gpio_set_value(TEGRATAB_WLAN_PWR, 0);
263 static int __init tegratab_wifi_init(void)
267 rc = gpio_request(TEGRATAB_WLAN_PWR, "wlan_power");
269 pr_err("WLAN_PWR gpio request failed:%d\n", rc);
270 rc = gpio_request(TEGRATAB_WLAN_RST, "wlan_rst");
272 pr_err("WLAN_RST gpio request failed:%d\n", rc);
273 rc = gpio_request(TEGRATAB_WLAN_WOW, "bcmsdh_sdmmc");
275 pr_err("WLAN_WOW gpio request failed:%d\n", rc);
277 rc = gpio_direction_output(TEGRATAB_WLAN_PWR, 0);
279 pr_err("WLAN_PWR gpio direction configuration failed:%d\n", rc);
280 rc = gpio_direction_output(TEGRATAB_WLAN_RST, 0);
282 pr_err("WLAN_RST gpio direction configuration failed:%d\n", rc);
283 rc = gpio_direction_input(TEGRATAB_WLAN_WOW);
285 pr_err("WLAN_WOW gpio direction configuration failed:%d\n", rc);
286 tegratab_wl12xx_wlan_data.irq = gpio_to_irq(TEGRATAB_WLAN_WOW);
287 wl12xx_set_platform_data(&tegratab_wl12xx_wlan_data);
291 #ifdef CONFIG_TEGRA_PREPOWER_WIFI
292 static int __init tegratab_wifi_prepower(void)
294 if (!machine_is_tegratab())
297 #ifdef CONFIG_ANDROID
298 /* In charger mode, don't power on wifi. */
299 if (get_androidboot_mode_charger())
303 tegratab_wifi_power(1);
308 subsys_initcall_sync(tegratab_wifi_prepower);
311 int __init tegratab_sdhci_init(void)
314 int min_vcore_override_mv;
316 struct board_info board_info;
318 tegra_dvfs_rail_get_nominal_millivolts(tegra_core_rail);
319 if (nominal_core_mv) {
320 tegra_sdhci_platform_data0.nominal_vcore_mv = nominal_core_mv;
321 tegra_sdhci_platform_data2.nominal_vcore_mv = nominal_core_mv;
322 tegra_sdhci_platform_data3.nominal_vcore_mv = nominal_core_mv;
324 min_vcore_override_mv =
325 tegra_dvfs_rail_get_override_floor(tegra_core_rail);
326 if (min_vcore_override_mv) {
327 tegra_sdhci_platform_data0.min_vcore_override_mv =
328 min_vcore_override_mv;
329 tegra_sdhci_platform_data2.min_vcore_override_mv =
330 min_vcore_override_mv;
331 tegra_sdhci_platform_data3.min_vcore_override_mv =
332 min_vcore_override_mv;
334 boot_vcore_mv = tegra_dvfs_rail_get_boot_level(tegra_core_rail);
336 tegra_sdhci_platform_data0.boot_vcore_mv = boot_vcore_mv;
337 tegra_sdhci_platform_data2.boot_vcore_mv = boot_vcore_mv;
338 tegra_sdhci_platform_data3.boot_vcore_mv = boot_vcore_mv;
341 tegra_get_board_info(&board_info);
342 if (board_info.board_id == BOARD_P1640)
343 tegra_sdhci_platform_data2.wp_gpio = -1;
344 if ((tegra_sdhci_platform_data3.uhs_mask & MMC_MASK_HS200)
345 && (!(tegra_sdhci_platform_data3.uhs_mask & MMC_UHS_MASK_DDR50)))
346 tegra_sdhci_platform_data3.trim_delay = 0;
347 platform_device_register(&tegra_sdhci_device3);
349 #ifdef CONFIG_ANDROID
350 /* In charger mode, don't register wifi and external sd. */
351 if (get_androidboot_mode_charger())
355 platform_device_register(&tegra_sdhci_device2);
356 platform_device_register(&tegra_sdhci_device0);
357 tegratab_wifi_init();