aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-whistler-sdhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/board-whistler-sdhci.c')
-rw-r--r--arch/arm/mach-tegra/board-whistler-sdhci.c248
1 files changed, 248 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-whistler-sdhci.c b/arch/arm/mach-tegra/board-whistler-sdhci.c
new file mode 100644
index 00000000000..08ebe33ae8b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-sdhci.c
@@ -0,0 +1,248 @@
1/*
2 * arch/arm/mach-tegra/board-whistler-sdhci.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 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/wlan_plat.h>
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/mmc/host.h>
26
27#include <asm/mach-types.h>
28#include <mach/irqs.h>
29#include <mach/iomap.h>
30#include <mach/sdhci.h>
31
32#include "gpio-names.h"
33#include "board.h"
34
35#define WHISTLER_WLAN_PWR TEGRA_GPIO_PK5
36#define WHISTLER_WLAN_RST TEGRA_GPIO_PK6
37#define WHISTLER_WLAN_WOW TEGRA_GPIO_PU5
38
39#define WHISTLER_EXT_SDCARD_DETECT TEGRA_GPIO_PI5
40
41static void (*wifi_status_cb)(int card_present, void *dev_id);
42static void *wifi_status_cb_devid;
43
44static int whistler_wifi_status_register(
45 void (*sdhcicallback)(int card_present, void *dev_id),
46 void *dev_id)
47{
48 if (wifi_status_cb)
49 return -EAGAIN;
50 wifi_status_cb = sdhcicallback;
51 wifi_status_cb_devid = dev_id;
52 return 0;
53}
54
55static int whistler_wifi_set_carddetect(int val)
56{
57 pr_debug("%s: %d\n", __func__, val);
58 if (wifi_status_cb)
59 wifi_status_cb(val, wifi_status_cb_devid);
60 else
61 pr_warning("%s: Nobody to notify\n", __func__);
62 return 0;
63}
64
65static int whistler_wifi_power(int on)
66{
67 gpio_set_value(WHISTLER_WLAN_PWR, on);
68 mdelay(100);
69 gpio_set_value(WHISTLER_WLAN_RST, on);
70 mdelay(200);
71
72 return 0;
73}
74
75static int whistler_wifi_reset(int on)
76{
77 pr_debug("%s: do nothing\n", __func__);
78 return 0;
79}
80
81
82static struct wifi_platform_data whistler_wifi_control = {
83 .set_power = whistler_wifi_power,
84 .set_reset = whistler_wifi_reset,
85 .set_carddetect = whistler_wifi_set_carddetect,
86};
87
88static struct resource wifi_resource[] = {
89 [0] = {
90 .name = "bcm4329_wlan_irq",
91 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU5),
92 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU5),
93 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
94 },
95};
96
97static struct platform_device whistler_wifi_device = {
98 .name = "bcm4329_wlan",
99 .id = 1,
100 .num_resources = 1,
101 .resource = wifi_resource,
102 .dev = {
103 .platform_data = &whistler_wifi_control,
104 },
105};
106
107static struct resource sdhci_resource1[] = {
108 [0] = {
109 .start = INT_SDMMC2,
110 .end = INT_SDMMC2,
111 .flags = IORESOURCE_IRQ,
112 },
113 [1] = {
114 .start = TEGRA_SDMMC2_BASE,
115 .end = TEGRA_SDMMC2_BASE + TEGRA_SDMMC2_SIZE-1,
116 .flags = IORESOURCE_MEM,
117 },
118};
119
120
121static struct resource sdhci_resource2[] = {
122 [0] = {
123 .start = INT_SDMMC3,
124 .end = INT_SDMMC3,
125 .flags = IORESOURCE_IRQ,
126 },
127 [1] = {
128 .start = TEGRA_SDMMC3_BASE,
129 .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
130 .flags = IORESOURCE_MEM,
131 },
132};
133
134static struct resource sdhci_resource3[] = {
135 [0] = {
136 .start = INT_SDMMC4,
137 .end = INT_SDMMC4,
138 .flags = IORESOURCE_IRQ,
139 },
140 [1] = {
141 .start = TEGRA_SDMMC4_BASE,
142 .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
143 .flags = IORESOURCE_MEM,
144 },
145};
146
147static struct embedded_sdio_data embedded_sdio_data1 = {
148 .cccr = {
149 .sdio_vsn = 2,
150 .multi_block = 1,
151 .low_speed = 0,
152 .wide_bus = 0,
153 .high_power = 1,
154 .high_speed = 1,
155 },
156 .cis = {
157 .vendor = 0x02d0,
158 .device = 0x4329,
159 },
160};
161
162static struct tegra_sdhci_platform_data tegra_sdhci_platform_data1 = {
163 .mmc_data = {
164 .register_status_notify = whistler_wifi_status_register,
165 .embedded_sdio = &embedded_sdio_data1,
166 .built_in = 1,
167 },
168 .cd_gpio = -1,
169 .wp_gpio = -1,
170 .power_gpio = -1,
171 .max_clk_limit = 25000000,
172};
173
174static struct tegra_sdhci_platform_data tegra_sdhci_platform_data2 = {
175 .cd_gpio = WHISTLER_EXT_SDCARD_DETECT,
176 .wp_gpio = -1,
177 .power_gpio = -1,
178};
179
180static struct tegra_sdhci_platform_data tegra_sdhci_platform_data3 = {
181 .cd_gpio = -1,
182 .wp_gpio = -1,
183 .power_gpio = -1,
184 .mmc_data = {
185 .built_in = 1,
186 }
187};
188
189static struct platform_device tegra_sdhci_device1 = {
190 .name = "sdhci-tegra",
191 .id = 1,
192 .resource = sdhci_resource1,
193 .num_resources = ARRAY_SIZE(sdhci_resource1),
194 .dev = {
195 .platform_data = &tegra_sdhci_platform_data1,
196 },
197};
198
199static struct platform_device tegra_sdhci_device2 = {
200 .name = "sdhci-tegra",
201 .id = 2,
202 .resource = sdhci_resource2,
203 .num_resources = ARRAY_SIZE(sdhci_resource2),
204 .dev = {
205 .platform_data = &tegra_sdhci_platform_data2,
206 },
207};
208
209static struct platform_device tegra_sdhci_device3 = {
210 .name = "sdhci-tegra",
211 .id = 3,
212 .resource = sdhci_resource3,
213 .num_resources = ARRAY_SIZE(sdhci_resource3),
214 .dev = {
215 .platform_data = &tegra_sdhci_platform_data3,
216 },
217};
218
219static int __init whistler_wifi_init(void)
220{
221 gpio_request(WHISTLER_WLAN_PWR, "wlan_power");
222 gpio_request(WHISTLER_WLAN_RST, "wlan_rst");
223 gpio_request(WHISTLER_WLAN_WOW, "bcmsdh_sdmmc");
224
225 tegra_gpio_enable(WHISTLER_WLAN_PWR);
226 tegra_gpio_enable(WHISTLER_WLAN_RST);
227 tegra_gpio_enable(WHISTLER_WLAN_WOW);
228
229 gpio_direction_output(WHISTLER_WLAN_PWR, 0);
230 gpio_direction_output(WHISTLER_WLAN_RST, 0);
231 gpio_direction_input(WHISTLER_WLAN_WOW);
232
233 platform_device_register(&whistler_wifi_device);
234 return 0;
235}
236int __init whistler_sdhci_init(void)
237{
238 int ret;
239
240 tegra_gpio_enable(WHISTLER_EXT_SDCARD_DETECT);
241
242 platform_device_register(&tegra_sdhci_device3);
243 platform_device_register(&tegra_sdhci_device2);
244 platform_device_register(&tegra_sdhci_device1);
245
246 whistler_wifi_init();
247 return 0;
248}