Revert "Merge commit 'main-jb-2012.08.03-B4' into t114-0806"
[linux-2.6.git] / arch / arm / mach-tegra / board-kai-sdhci.c
1 /*
2  * arch/arm/mach-tegra/board-kai-sdhci.c
3  *
4  * Copyright (C) 2010 Google, Inc.
5  * Copyright (C) 2012 NVIDIA Corporation.
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <linux/resource.h>
19 #include <linux/platform_device.h>
20 #include <linux/delay.h>
21 #include <linux/gpio.h>
22 #include <linux/clk.h>
23 #include <linux/err.h>
24 #include <linux/mmc/host.h>
25 #include <linux/wl12xx.h>
26
27 #include <asm/mach-types.h>
28 #include <mach/irqs.h>
29 #include <mach/iomap.h>
30 #include <mach/sdhci.h>
31 #include <mach/gpio-tegra.h>
32
33 #include "gpio-names.h"
34 #include "board.h"
35 #include "board-kai.h"
36
37 #define KAI_SD_CD       TEGRA_GPIO_PI5
38 #define KAI_WLAN_EN     TEGRA_GPIO_PD3
39 #define KAI_WLAN_IRQ    TEGRA_GPIO_PV1
40
41 static void (*wifi_status_cb)(int card_present, void *dev_id);
42 static void *wifi_status_cb_devid;
43 static int kai_wifi_power(int power_on);
44 static int kai_wifi_set_carddetect(int val);
45
46 static int kai_wifi_status_register(
47                 void (*callback)(int card_present, void *dev_id),
48                 void *dev_id)
49 {
50         if (wifi_status_cb)
51                 return -EAGAIN;
52         wifi_status_cb = callback;
53         wifi_status_cb_devid = dev_id;
54         return 0;
55 }
56
57
58 static struct wl12xx_platform_data kai_wlan_data __initdata = {
59         .board_ref_clock = WL12XX_REFCLOCK_26,
60         .board_tcxo_clock = 1,
61         .set_power = kai_wifi_power,
62         .set_carddetect = kai_wifi_set_carddetect,
63 };
64
65 static struct resource sdhci_resource0[] = {
66         [0] = {
67                 .start  = INT_SDMMC1,
68                 .end    = INT_SDMMC1,
69                 .flags  = IORESOURCE_IRQ,
70         },
71         [1] = {
72                 .start  = TEGRA_SDMMC1_BASE,
73                 .end    = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
74                 .flags  = IORESOURCE_MEM,
75         },
76 };
77
78 static struct resource sdhci_resource2[] = {
79         [0] = {
80                 .start  = INT_SDMMC3,
81                 .end    = INT_SDMMC3,
82                 .flags  = IORESOURCE_IRQ,
83         },
84         [1] = {
85                 .start  = TEGRA_SDMMC3_BASE,
86                 .end    = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
87                 .flags  = IORESOURCE_MEM,
88         },
89 };
90
91 static struct resource sdhci_resource3[] = {
92         [0] = {
93                 .start  = INT_SDMMC4,
94                 .end    = INT_SDMMC4,
95                 .flags  = IORESOURCE_IRQ,
96         },
97         [1] = {
98                 .start  = TEGRA_SDMMC4_BASE,
99                 .end    = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
100                 .flags  = IORESOURCE_MEM,
101         },
102 };
103
104
105 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
106         .mmc_data = {
107                 .register_status_notify = kai_wifi_status_register,
108                 .built_in = 0,
109                 .ocr_mask = MMC_OCR_1V8_MASK,
110         },
111 #ifndef CONFIG_MMC_EMBEDDED_SDIO
112         .pm_flags = MMC_PM_KEEP_POWER,
113 #endif
114         .cd_gpio = -1,
115         .wp_gpio = -1,
116         .power_gpio = -1,
117         .tap_delay = 0x0F,
118         .ddr_clk_limit = 41000000,
119 /*      .is_voltage_switch_supported = false,
120         .vdd_rail_name = NULL,
121         .slot_rail_name = NULL,
122         .vdd_max_uv = -1,
123         .vdd_min_uv = -1,
124         .max_clk = 0,
125         .is_8bit_supported = false, */
126         /* .max_clk = 25000000, */
127 };
128
129 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
130         .cd_gpio = KAI_SD_CD,
131         .wp_gpio = -1,
132         .power_gpio = -1,
133         .tap_delay = 0x0F,
134         .ddr_clk_limit = 41000000,
135 /*      .is_voltage_switch_supported = true,
136         .vdd_rail_name = "vddio_sdmmc1",
137         .slot_rail_name = "vddio_sd_slot",
138         .vdd_max_uv = 3320000,
139         .vdd_min_uv = 3280000,
140         .max_clk = 208000000,
141         .is_8bit_supported = false, */
142 };
143
144 static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
145         .cd_gpio = -1,
146         .wp_gpio = -1,
147         .power_gpio = -1,
148         .is_8bit = 1,
149         .tap_delay = 0x0F,
150         .ddr_clk_limit = 41000000,
151         .mmc_data = {
152                 .built_in = 1,
153         }
154 /*      .is_voltage_switch_supported = false,
155         .vdd_rail_name = NULL,
156         .slot_rail_name = NULL,
157         .vdd_max_uv = -1,
158         .vdd_min_uv = -1,
159         .max_clk = 48000000,
160         .is_8bit_supported = true, */
161 };
162
163 static struct platform_device tegra_sdhci_device0 = {
164         .name           = "sdhci-tegra",
165         .id             = 0,
166         .resource       = sdhci_resource0,
167         .num_resources  = ARRAY_SIZE(sdhci_resource0),
168         .dev = {
169                 .platform_data = &tegra_sdhci_platform_data0,
170         },
171 };
172
173 static struct platform_device tegra_sdhci_device2 = {
174         .name           = "sdhci-tegra",
175         .id             = 2,
176         .resource       = sdhci_resource2,
177         .num_resources  = ARRAY_SIZE(sdhci_resource2),
178         .dev = {
179                 .platform_data = &tegra_sdhci_platform_data2,
180         },
181 };
182
183 static struct platform_device tegra_sdhci_device3 = {
184         .name           = "sdhci-tegra",
185         .id             = 3,
186         .resource       = sdhci_resource3,
187         .num_resources  = ARRAY_SIZE(sdhci_resource3),
188         .dev = {
189                 .platform_data = &tegra_sdhci_platform_data3,
190         },
191 };
192
193 static int kai_wifi_set_carddetect(int val)
194 {
195         pr_debug("%s: %d\n", __func__, val);
196         if (wifi_status_cb)
197                 wifi_status_cb(val, wifi_status_cb_devid);
198         else
199         pr_warning("%s: Nobody to notify\n", __func__);
200         return 0;
201 }
202
203 static int kai_wifi_power(int power_on)
204 {
205         pr_err("Powering %s wifi\n", (power_on ? "on" : "off"));
206
207         if (power_on) {
208                 gpio_set_value(KAI_WLAN_EN, 1);
209                 mdelay(15);
210                 gpio_set_value(KAI_WLAN_EN, 0);
211                 mdelay(1);
212                 gpio_set_value(KAI_WLAN_EN, 1);
213                 mdelay(70);
214         } else {
215                 gpio_set_value(KAI_WLAN_EN, 0);
216         }
217
218         return 0;
219 }
220
221 #ifdef CONFIG_TEGRA_PREPOWER_WIFI
222 static int __init kai_wifi_prepower(void)
223 {
224         if (!machine_is_kai())
225                 return 0;
226
227         kai_wifi_power(1);
228
229         return 0;
230 }
231
232 subsys_initcall_sync(kai_wifi_prepower);
233 #endif
234
235 static int __init kai_wifi_init(void)
236 {
237         int rc;
238
239         rc = gpio_request(KAI_WLAN_EN, "wl12xx");
240         if (rc)
241                 pr_err("WLAN_EN gpio request failed:%d\n", rc);
242
243         rc = gpio_request(KAI_WLAN_IRQ, "wl12xx");
244         if (rc)
245                 pr_err("WLAN_IRQ gpio request failed:%d\n", rc);
246
247         rc = gpio_direction_output(KAI_WLAN_EN, 0);
248         if (rc)
249                 pr_err("WLAN_EN gpio direction configuration failed:%d\n", rc);
250
251         rc = gpio_direction_input(KAI_WLAN_IRQ);
252         if (rc)
253                 pr_err("WLAN_IRQ gpio direction configuration failed:%d\n", rc);
254
255         kai_wlan_data.irq = gpio_to_irq(KAI_WLAN_IRQ);
256         if (wl12xx_set_platform_data(&kai_wlan_data))
257                 pr_err("Error setting wl12xx data\n");
258
259         return 0;
260 }
261
262 int __init kai_sdhci_init(void)
263 {
264         platform_device_register(&tegra_sdhci_device3);
265         platform_device_register(&tegra_sdhci_device2);
266         platform_device_register(&tegra_sdhci_device0);
267
268         kai_wifi_init();
269         return 0;
270 }