ARM: tegra: tegratab: macallan: rename wifi wow line
[linux-2.6.git] / arch / arm / mach-tegra / board-macallan-sdhci.c
1 /*
2  * arch/arm/mach-tegra/board-macallan-sdhci.c
3  *
4  * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
5  *
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.
9  *
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.
14  *
15  */
16
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>
25
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>
33
34 #include "gpio-names.h"
35 #include "board.h"
36 #include "board-macallan.h"
37 #include "dvfs.h"
38
39 #define MACALLAN_SD_CD  TEGRA_GPIO_PV2
40 #define MACALLAN_SD_WP  TEGRA_GPIO_PQ4
41 #define MACALLAN_WLAN_PWR       TEGRA_GPIO_PCC5
42 #define MACALLAN_WLAN_RST       TEGRA_GPIO_PX7
43 #define MACALLAN_WLAN_WOW       TEGRA_GPIO_PU5
44 #if defined(CONFIG_WLCORE_EDP_SUPPORT)
45 #define ON 808 /* 808.236 mW */
46 #define OFF 0
47 static unsigned int wl_states[] = {ON, OFF};
48 #endif
49
50 static void (*wifi_status_cb)(int card_present, void *dev_id);
51 static void *wifi_status_cb_devid;
52 static int macallan_wifi_status_register(void (*callback)(int , void *), void *);
53
54 static int macallan_wifi_power(int on);
55 static int macallan_wifi_set_carddetect(int val);
56
57 static struct wl12xx_platform_data macallan_wl12xx_wlan_data __initdata = {
58         .board_ref_clock = WL12XX_REFCLOCK_26,
59         .board_tcxo_clock = 1,
60         .set_power = macallan_wifi_power,
61         .set_carddetect = macallan_wifi_set_carddetect,
62 #if defined(CONFIG_WLCORE_EDP_SUPPORT)
63         .edp_info = {
64                 .client_info = {
65                         .name = "wl_edp_client",
66                         .states = wl_states,
67                         .num_states = ARRAY_SIZE(wl_states),
68                         .e0_index = 0,
69                         .priority = EDP_MAX_PRIO,
70                 },
71                 .registered = false,
72         },
73 #endif
74 };
75
76 static struct resource sdhci_resource0[] = {
77         [0] = {
78                 .start  = INT_SDMMC1,
79                 .end    = INT_SDMMC1,
80                 .flags  = IORESOURCE_IRQ,
81         },
82         [1] = {
83                 .start  = TEGRA_SDMMC1_BASE,
84                 .end    = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
85                 .flags  = IORESOURCE_MEM,
86         },
87 };
88
89 static struct resource sdhci_resource2[] = {
90         [0] = {
91                 .start  = INT_SDMMC3,
92                 .end    = INT_SDMMC3,
93                 .flags  = IORESOURCE_IRQ,
94         },
95         [1] = {
96                 .start  = TEGRA_SDMMC3_BASE,
97                 .end    = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
98                 .flags  = IORESOURCE_MEM,
99         },
100 };
101
102 static struct resource sdhci_resource3[] = {
103         [0] = {
104                 .start  = INT_SDMMC4,
105                 .end    = INT_SDMMC4,
106                 .flags  = IORESOURCE_IRQ,
107         },
108         [1] = {
109                 .start  = TEGRA_SDMMC4_BASE,
110                 .end    = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
111                 .flags  = IORESOURCE_MEM,
112         },
113 };
114
115 #ifdef CONFIG_MMC_EMBEDDED_SDIO
116 static struct embedded_sdio_data embedded_sdio_data0 = {
117         .cccr   = {
118                 .sdio_vsn       = 2,
119                 .multi_block    = 1,
120                 .low_speed      = 0,
121                 .wide_bus       = 0,
122                 .high_power     = 1,
123                 .high_speed     = 1,
124         },
125         .cis  = {
126                 .vendor  = 0x02d0,
127                 .device  = 0x4329,
128         },
129 };
130 #endif
131
132 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
133         .mmc_data = {
134                 .register_status_notify = macallan_wifi_status_register,
135 #ifdef CONFIG_MMC_EMBEDDED_SDIO
136                 .embedded_sdio = &embedded_sdio_data0,
137 #endif
138                 .built_in = 0,
139                 .ocr_mask = MMC_OCR_1V8_MASK,
140         },
141 #ifndef CONFIG_MMC_EMBEDDED_SDIO
142         .pm_flags = MMC_PM_KEEP_POWER,
143 #endif
144         .cd_gpio = -1,
145         .wp_gpio = -1,
146         .power_gpio = -1,
147         .tap_delay = 0x2,
148         .trim_delay = 0x2,
149         .ddr_clk_limit = 41000000,
150         .max_clk_limit = 82000000,
151         .uhs_mask = MMC_UHS_MASK_DDR50,
152         .edp_support = false,
153 };
154
155 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
156         .cd_gpio = MACALLAN_SD_CD,
157         .wp_gpio = MACALLAN_SD_WP,
158         .power_gpio = -1,
159         .tap_delay = 0x3,
160         .trim_delay = 0x3,
161         .ddr_clk_limit = 41000000,
162         .max_clk_limit = 156000000,
163         .uhs_mask = MMC_UHS_MASK_DDR50,
164         .edp_support = true,
165         .edp_states = {966, 0},
166 };
167
168 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
169         .cd_gpio = -1,
170         .wp_gpio = -1,
171         .power_gpio = -1,
172         .is_8bit = 1,
173         .tap_delay = 0x5,
174         .trim_delay = 0xA,
175         .ddr_clk_limit = 41000000,
176         .max_clk_limit = 156000000,
177         .mmc_data = {
178                 .built_in = 1,
179                 .ocr_mask = MMC_OCR_1V8_MASK,
180         },
181         .edp_support = true,
182         .edp_states = {966, 0},
183 };
184
185 static struct platform_device tegra_sdhci_device0 = {
186         .name           = "sdhci-tegra",
187         .id             = 0,
188         .resource       = sdhci_resource0,
189         .num_resources  = ARRAY_SIZE(sdhci_resource0),
190         .dev = {
191                 .platform_data = &tegra_sdhci_platform_data0,
192         },
193 };
194
195 static struct platform_device tegra_sdhci_device2 = {
196         .name           = "sdhci-tegra",
197         .id             = 2,
198         .resource       = sdhci_resource2,
199         .num_resources  = ARRAY_SIZE(sdhci_resource2),
200         .dev = {
201                 .platform_data = &tegra_sdhci_platform_data2,
202         },
203 };
204
205 static struct platform_device tegra_sdhci_device3 = {
206         .name           = "sdhci-tegra",
207         .id             = 3,
208         .resource       = sdhci_resource3,
209         .num_resources  = ARRAY_SIZE(sdhci_resource3),
210         .dev = {
211                 .platform_data = &tegra_sdhci_platform_data3,
212         },
213 };
214
215 static int macallan_wifi_status_register(
216                 void (*callback)(int card_present, void *dev_id),
217                 void *dev_id)
218 {
219         if (wifi_status_cb)
220                 return -EAGAIN;
221         wifi_status_cb = callback;
222         wifi_status_cb_devid = dev_id;
223         return 0;
224 }
225
226 static int macallan_wifi_set_carddetect(int val)
227 {
228         pr_debug("%s: %d\n", __func__, val);
229         if (wifi_status_cb)
230                 wifi_status_cb(val, wifi_status_cb_devid);
231         else
232                 pr_warning("%s: Nobody to notify\n", __func__);
233         return 0;
234 }
235
236 static int macallan_wifi_power(int on)
237 {
238         pr_debug("%s: %d\n", __func__, on);
239
240         if (on) {
241                 gpio_set_value(MACALLAN_WLAN_RST, 1);
242                 mdelay(100);
243                 gpio_set_value(MACALLAN_WLAN_RST, 0);
244                 mdelay(100);
245                 gpio_set_value(MACALLAN_WLAN_RST, 1);
246                 mdelay(100);
247                 gpio_set_value(MACALLAN_WLAN_PWR, 1);
248                 mdelay(200);
249         } else {
250                 gpio_set_value(MACALLAN_WLAN_RST, 0);
251                 mdelay(100);
252                 gpio_set_value(MACALLAN_WLAN_PWR, 0);
253         }
254
255         return 0;
256 }
257
258 static int __init macallan_wifi_init(void)
259 {
260         int rc;
261
262         rc = gpio_request(MACALLAN_WLAN_PWR, "wlan_power");
263         if (rc)
264                 pr_err("WLAN_PWR gpio request failed:%d\n", rc);
265         rc = gpio_request(MACALLAN_WLAN_RST, "wlan_rst");
266         if (rc)
267                 pr_err("WLAN_RST gpio request failed:%d\n", rc);
268         rc = gpio_request(MACALLAN_WLAN_WOW, "wlan_wow");
269         if (rc)
270                 pr_err("WLAN_WOW gpio request failed:%d\n", rc);
271
272         rc = gpio_direction_output(MACALLAN_WLAN_PWR, 0);
273         if (rc)
274                 pr_err("WLAN_PWR gpio direction configuration failed:%d\n", rc);
275         rc = gpio_direction_output(MACALLAN_WLAN_RST, 0);
276         if (rc)
277                 pr_err("WLAN_RST gpio direction configuration failed:%d\n", rc);
278         rc = gpio_direction_input(MACALLAN_WLAN_WOW);
279         if (rc)
280                 pr_err("WLAN_WOW gpio direction configuration failed:%d\n", rc);
281         macallan_wl12xx_wlan_data.irq = gpio_to_irq(MACALLAN_WLAN_WOW);
282         wl12xx_set_platform_data(&macallan_wl12xx_wlan_data);
283         return 0;
284 }
285
286 #ifdef CONFIG_TEGRA_PREPOWER_WIFI
287 static int __init macallan_wifi_prepower(void)
288 {
289         if (!machine_is_macallan())
290                 return 0;
291
292         macallan_wifi_power(1);
293
294         return 0;
295 }
296
297 subsys_initcall_sync(macallan_wifi_prepower);
298 #endif
299
300 int __init macallan_sdhci_init(void)
301 {
302         int nominal_core_mv;
303         int min_vcore_override_mv;
304         int boot_vcore_mv;
305
306         nominal_core_mv =
307                 tegra_dvfs_rail_get_nominal_millivolts(tegra_core_rail);
308         if (nominal_core_mv > 0) {
309                 tegra_sdhci_platform_data0.nominal_vcore_mv = nominal_core_mv;
310                 tegra_sdhci_platform_data2.nominal_vcore_mv = nominal_core_mv;
311                 tegra_sdhci_platform_data3.nominal_vcore_mv = nominal_core_mv;
312         }
313         min_vcore_override_mv =
314                 tegra_dvfs_rail_get_override_floor(tegra_core_rail);
315         if (min_vcore_override_mv) {
316                 tegra_sdhci_platform_data0.min_vcore_override_mv =
317                         min_vcore_override_mv;
318                 tegra_sdhci_platform_data2.min_vcore_override_mv =
319                         min_vcore_override_mv;
320                 tegra_sdhci_platform_data3.min_vcore_override_mv =
321                         min_vcore_override_mv;
322         }
323         boot_vcore_mv = tegra_dvfs_rail_get_boot_level(tegra_core_rail);
324         if (boot_vcore_mv) {
325                 tegra_sdhci_platform_data0.boot_vcore_mv = boot_vcore_mv;
326                 tegra_sdhci_platform_data2.boot_vcore_mv = boot_vcore_mv;
327                 tegra_sdhci_platform_data3.boot_vcore_mv = boot_vcore_mv;
328         }
329
330         if ((tegra_sdhci_platform_data3.uhs_mask & MMC_MASK_HS200)
331                 && (!(tegra_sdhci_platform_data3.uhs_mask &
332                 MMC_UHS_MASK_DDR50)))
333                 tegra_sdhci_platform_data3.trim_delay = 0;
334
335         platform_device_register(&tegra_sdhci_device3);
336         platform_device_register(&tegra_sdhci_device2);
337         platform_device_register(&tegra_sdhci_device0);
338         macallan_wifi_init();
339         return 0;
340 }