aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-ventana-sdhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/board-ventana-sdhci.c')
-rw-r--r--arch/arm/mach-tegra/board-ventana-sdhci.c267
1 files changed, 267 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-ventana-sdhci.c b/arch/arm/mach-tegra/board-ventana-sdhci.c
new file mode 100644
index 00000000000..49720cd7a6d
--- /dev/null
+++ b/arch/arm/mach-tegra/board-ventana-sdhci.c
@@ -0,0 +1,267 @@
1/*
2 * arch/arm/mach-tegra/board-harmony-sdhci.c
3 *
4 * Copyright (C) 2010 Google, Inc.
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/wlan_plat.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
26#include <asm/mach-types.h>
27#include <mach/irqs.h>
28#include <mach/iomap.h>
29#include <mach/sdhci.h>
30
31#include "gpio-names.h"
32#include "board.h"
33
34#define VENTANA_WLAN_PWR TEGRA_GPIO_PK5
35#define VENTANA_WLAN_RST TEGRA_GPIO_PK6
36#define VENTANA_WLAN_WOW TEGRA_GPIO_PS0
37
38static void (*wifi_status_cb)(int card_present, void *dev_id);
39static void *wifi_status_cb_devid;
40static int ventana_wifi_status_register(void (*callback)(int , void *), void *);
41static struct clk *wifi_32k_clk;
42
43static int ventana_wifi_reset(int on);
44static int ventana_wifi_power(int on);
45static int ventana_wifi_set_carddetect(int val);
46
47static struct wifi_platform_data ventana_wifi_control = {
48 .set_power = ventana_wifi_power,
49 .set_reset = ventana_wifi_reset,
50 .set_carddetect = ventana_wifi_set_carddetect,
51};
52
53static struct resource wifi_resource[] = {
54 [0] = {
55 .name = "bcm4329_wlan_irq",
56 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS0),
57 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PS0),
58 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
59 },
60};
61
62static struct platform_device ventana_wifi_device = {
63 .name = "bcm4329_wlan",
64 .id = 1,
65 .num_resources = 1,
66 .resource = wifi_resource,
67 .dev = {
68 .platform_data = &ventana_wifi_control,
69 },
70};
71
72static struct resource sdhci_resource0[] = {
73 [0] = {
74 .start = INT_SDMMC1,
75 .end = INT_SDMMC1,
76 .flags = IORESOURCE_IRQ,
77 },
78 [1] = {
79 .start = TEGRA_SDMMC1_BASE,
80 .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
81 .flags = IORESOURCE_MEM,
82 },
83};
84
85static struct resource sdhci_resource2[] = {
86 [0] = {
87 .start = INT_SDMMC3,
88 .end = INT_SDMMC3,
89 .flags = IORESOURCE_IRQ,
90 },
91 [1] = {
92 .start = TEGRA_SDMMC3_BASE,
93 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
94 .flags = IORESOURCE_MEM,
95 },
96};
97
98static struct resource sdhci_resource3[] = {
99 [0] = {
100 .start = INT_SDMMC4,
101 .end = INT_SDMMC4,
102 .flags = IORESOURCE_IRQ,
103 },
104 [1] = {
105 .start = TEGRA_SDMMC4_BASE,
106 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
107 .flags = IORESOURCE_MEM,
108 },
109};
110
111static struct embedded_sdio_data embedded_sdio_data0 = {
112 .cccr = {
113 .sdio_vsn = 2,
114 .multi_block = 1,
115 .low_speed = 0,
116 .wide_bus = 0,
117 .high_power = 1,
118 .high_speed = 1,
119 },
120 .cis = {
121 .vendor = 0x02d0,
122 .device = 0x4329,
123 },
124};
125
126static struct tegra_sdhci_platform_data tegra_sdhci_platform_data0 = {
127 .mmc_data = {
128 .register_status_notify = ventana_wifi_status_register,
129 .embedded_sdio = &embedded_sdio_data0,
130 .built_in = 1,
131 },
132 .cd_gpio = -1,
133 .wp_gpio = -1,
134 .power_gpio = -1,
135};
136
137static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
138 .cd_gpio = TEGRA_GPIO_PI5,
139 .wp_gpio = TEGRA_GPIO_PH1,
140 .power_gpio = TEGRA_GPIO_PI6,
141};
142
143static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
144 .is_8bit = 1,
145 .cd_gpio = -1,
146 .wp_gpio = -1,
147 .power_gpio = -1,
148 .mmc_data = {
149 .built_in = 1,
150 }
151};
152
153static struct platform_device tegra_sdhci_device0 = {
154 .name = "sdhci-tegra",
155 .id = 0,
156 .resource = sdhci_resource0,
157 .num_resources = ARRAY_SIZE(sdhci_resource0),
158 .dev = {
159 .platform_data = &tegra_sdhci_platform_data0,
160 },
161};
162
163static struct platform_device tegra_sdhci_device2 = {
164 .name = "sdhci-tegra",
165 .id = 2,
166 .resource = sdhci_resource2,
167 .num_resources = ARRAY_SIZE(sdhci_resource2),
168 .dev = {
169 .platform_data = &tegra_sdhci_platform_data2,
170 },
171};
172
173static struct platform_device tegra_sdhci_device3 = {
174 .name = "sdhci-tegra",
175 .id = 3,
176 .resource = sdhci_resource3,
177 .num_resources = ARRAY_SIZE(sdhci_resource3),
178 .dev = {
179 .platform_data = &tegra_sdhci_platform_data3,
180 },
181};
182
183static int ventana_wifi_status_register(
184 void (*callback)(int card_present, void *dev_id),
185 void *dev_id)
186{
187 if (wifi_status_cb)
188 return -EAGAIN;
189 wifi_status_cb = callback;
190 wifi_status_cb_devid = dev_id;
191 return 0;
192}
193
194static int ventana_wifi_set_carddetect(int val)
195{
196 pr_debug("%s: %d\n", __func__, val);
197 if (wifi_status_cb)
198 wifi_status_cb(val, wifi_status_cb_devid);
199 else
200 pr_warning("%s: Nobody to notify\n", __func__);
201 return 0;
202}
203
204static int ventana_wifi_power(int on)
205{
206 pr_debug("%s: %d\n", __func__, on);
207
208 gpio_set_value(VENTANA_WLAN_PWR, on);
209 mdelay(100);
210 gpio_set_value(VENTANA_WLAN_RST, on);
211 mdelay(200);
212
213 if (on)
214 clk_enable(wifi_32k_clk);
215 else
216 clk_disable(wifi_32k_clk);
217
218 return 0;
219}
220
221static int ventana_wifi_reset(int on)
222{
223 pr_debug("%s: do nothing\n", __func__);
224 return 0;
225}
226
227static int __init ventana_wifi_init(void)
228{
229 wifi_32k_clk = clk_get_sys(NULL, "blink");
230 if (IS_ERR(wifi_32k_clk)) {
231 pr_err("%s: unable to get blink clock\n", __func__);
232 return PTR_ERR(wifi_32k_clk);
233 }
234
235 gpio_request(VENTANA_WLAN_PWR, "wlan_power");
236 gpio_request(VENTANA_WLAN_RST, "wlan_rst");
237 gpio_request(VENTANA_WLAN_WOW, "bcmsdh_sdmmc");
238
239 tegra_gpio_enable(VENTANA_WLAN_PWR);
240 tegra_gpio_enable(VENTANA_WLAN_RST);
241 tegra_gpio_enable(VENTANA_WLAN_WOW);
242
243 gpio_direction_output(VENTANA_WLAN_PWR, 0);
244 gpio_direction_output(VENTANA_WLAN_RST, 0);
245 gpio_direction_input(VENTANA_WLAN_WOW);
246
247 platform_device_register(&ventana_wifi_device);
248
249 device_init_wakeup(&ventana_wifi_device.dev, 1);
250 device_set_wakeup_enable(&ventana_wifi_device.dev, 0);
251
252 return 0;
253}
254int __init ventana_sdhci_init(void)
255{
256 tegra_gpio_enable(tegra_sdhci_platform_data2.power_gpio);
257 tegra_gpio_enable(tegra_sdhci_platform_data2.cd_gpio);
258 tegra_gpio_enable(tegra_sdhci_platform_data2.wp_gpio);
259 tegra_gpio_enable(tegra_sdhci_platform_data3.power_gpio);
260
261 platform_device_register(&tegra_sdhci_device3);
262 platform_device_register(&tegra_sdhci_device2);
263 platform_device_register(&tegra_sdhci_device0);
264
265 ventana_wifi_init();
266 return 0;
267}