7d1d5240f457a1a262ae8dc224fde6b639a64cfd
[pandora-kernel.git] / arch / arm / mach-omap2 / hsmmc.c
1 /*
2  * linux/arch/arm/mach-omap2/board-sdp-hsmmc.c
3  *
4  * Copyright (C) 2007-2008 Texas Instruments
5  * Copyright (C) 2008 Nokia Corporation
6  * Author: Texas Instruments
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 #include <linux/err.h>
13 #include <linux/io.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/interrupt.h>
17 #include <linux/delay.h>
18 #include <linux/gpio.h>
19 #include <linux/i2c/twl4030.h>
20
21 #include <mach/hardware.h>
22 #include <mach/mmc.h>
23 #include <mach/board.h>
24
25 #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
26
27 #define VMMC1_DEV_GRP           0x27
28 #define P1_DEV_GRP              0x20
29 #define VMMC1_DEDICATED         0x2A
30 #define VSEL_3V                 0x02
31 #define VSEL_3V15               0x03
32 #define VSEL_18V                0x00
33 #define TWL_GPIO_IMR1A          0x1C
34 #define TWL_GPIO_ISR1A          0x19
35 #define LDO_CLR                 0x00
36 #define VSEL_S2_CLR             0x40
37 #define GPIO_0_BIT_POS          (1 << 0)
38
39 #define OMAP2_CONTROL_DEVCONF0  0x48002274
40 #define OMAP2_CONTROL_DEVCONF1  0x490022E8
41
42 #define OMAP2_CONTROL_DEVCONF0_LBCLK    (1 << 24)
43 #define OMAP2_CONTROL_DEVCONF1_ACTOV    (1 << 31)
44
45 #define OMAP2_CONTROL_PBIAS_VMODE       (1 << 0)
46 #define OMAP2_CONTROL_PBIAS_PWRDNZ      (1 << 1)
47 #define OMAP2_CONTROL_PBIAS_SCTRL       (1 << 2)
48
49
50 static const int mmc1_cd_gpio = OMAP_MAX_GPIO_LINES;            /* HACK!! */
51
52 static int hsmmc_card_detect(int irq)
53 {
54         return gpio_get_value_cansleep(mmc1_cd_gpio);
55 }
56
57 /*
58  * MMC Slot Initialization.
59  */
60 static int hsmmc_late_init(struct device *dev)
61 {
62         int ret = 0;
63
64         /*
65          * Configure TWL4030 GPIO parameters for MMC hotplug irq
66          */
67         ret = gpio_request(mmc1_cd_gpio, "mmc0_cd");
68         if (ret)
69                 goto err;
70
71         ret = twl4030_set_gpio_debounce(0, true);
72         if (ret)
73                 goto err;
74
75         return ret;
76
77 err:
78         dev_err(dev, "Failed to configure TWL4030 GPIO IRQ\n");
79         return ret;
80 }
81
82 static void hsmmc_cleanup(struct device *dev)
83 {
84         gpio_free(mmc1_cd_gpio);
85 }
86
87 #ifdef CONFIG_PM
88
89 /*
90  * To mask and unmask MMC Card Detect Interrupt
91  * mask : 1
92  * unmask : 0
93  */
94 static int mask_cd_interrupt(int mask)
95 {
96         u8 reg = 0, ret = 0;
97
98         ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &reg, TWL_GPIO_IMR1A);
99         if (ret)
100                 goto err;
101
102         reg = (mask == 1) ? (reg | GPIO_0_BIT_POS) : (reg & ~GPIO_0_BIT_POS);
103
104         ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, reg, TWL_GPIO_IMR1A);
105         if (ret)
106                 goto err;
107
108         ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &reg, TWL_GPIO_ISR1A);
109         if (ret)
110                 goto err;
111
112         reg = (mask == 1) ? (reg | GPIO_0_BIT_POS) : (reg & ~GPIO_0_BIT_POS);
113
114         ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, reg, TWL_GPIO_ISR1A);
115         if (ret)
116                 goto err;
117
118 err:
119         return ret;
120 }
121
122 static int hsmmc_suspend(struct device *dev, int slot)
123 {
124         int ret = 0;
125
126         disable_irq(TWL4030_GPIO_IRQ_NO(0));
127         ret = mask_cd_interrupt(1);
128
129         return ret;
130 }
131
132 static int hsmmc_resume(struct device *dev, int slot)
133 {
134         int ret = 0;
135
136         enable_irq(TWL4030_GPIO_IRQ_NO(0));
137         ret = mask_cd_interrupt(0);
138
139         return ret;
140 }
141
142 #endif
143
144 static int hsmmc_set_power(struct device *dev, int slot, int power_on,
145                                 int vdd)
146 {
147         u32 vdd_sel = 0, devconf = 0, reg = 0;
148         int ret = 0;
149
150         dev_dbg(dev, "power %s, vdd %i\n", power_on ? "on" : "off", vdd);
151
152         /* REVISIT: Using address directly till the control.h defines
153          * are settled.
154          */
155 #if defined(CONFIG_ARCH_OMAP2430)
156         #define OMAP2_CONTROL_PBIAS 0x490024A0
157 #else
158         #define OMAP2_CONTROL_PBIAS 0x48002520
159 #endif
160
161         if (power_on) {
162                 if (cpu_is_omap24xx())
163                         devconf = omap_readl(OMAP2_CONTROL_DEVCONF1);
164                 else
165                         devconf = omap_readl(OMAP2_CONTROL_DEVCONF0);
166
167                 switch (1 << vdd) {
168                 case MMC_VDD_33_34:
169                 case MMC_VDD_32_33:
170                         vdd_sel = VSEL_3V15;
171                         if (cpu_is_omap24xx())
172                                 devconf |= OMAP2_CONTROL_DEVCONF1_ACTOV;
173                         break;
174                 case MMC_VDD_165_195:
175                         vdd_sel = VSEL_18V;
176                         if (cpu_is_omap24xx())
177                                 devconf &= ~OMAP2_CONTROL_DEVCONF1_ACTOV;
178                 }
179
180                 if (cpu_is_omap24xx())
181                         omap_writel(devconf, OMAP2_CONTROL_DEVCONF1);
182                 else
183                         omap_writel(devconf | OMAP2_CONTROL_DEVCONF0_LBCLK,
184                                     OMAP2_CONTROL_DEVCONF0);
185
186                 reg = omap_readl(OMAP2_CONTROL_PBIAS);
187                 reg |= OMAP2_CONTROL_PBIAS_SCTRL;
188                 omap_writel(reg, OMAP2_CONTROL_PBIAS);
189
190                 reg = omap_readl(OMAP2_CONTROL_PBIAS);
191                 reg &= ~OMAP2_CONTROL_PBIAS_PWRDNZ;
192                 omap_writel(reg, OMAP2_CONTROL_PBIAS);
193
194                 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
195                                                 P1_DEV_GRP, VMMC1_DEV_GRP);
196                 if (ret)
197                         goto err;
198
199                 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
200                                                 vdd_sel, VMMC1_DEDICATED);
201                 if (ret)
202                         goto err;
203
204                 msleep(100);
205                 reg = omap_readl(OMAP2_CONTROL_PBIAS);
206                 reg |= (OMAP2_CONTROL_PBIAS_SCTRL |
207                         OMAP2_CONTROL_PBIAS_PWRDNZ);
208                 if (vdd_sel == VSEL_18V)
209                         reg &= ~OMAP2_CONTROL_PBIAS_VMODE;
210                 else
211                         reg |= OMAP2_CONTROL_PBIAS_VMODE;
212                 omap_writel(reg, OMAP2_CONTROL_PBIAS);
213
214                 return ret;
215
216         } else {
217                 /* Power OFF */
218
219                 /* For MMC1, Toggle PBIAS before every power up sequence */
220                 reg = omap_readl(OMAP2_CONTROL_PBIAS);
221                 reg &= ~OMAP2_CONTROL_PBIAS_PWRDNZ;
222                 omap_writel(reg, OMAP2_CONTROL_PBIAS);
223
224                 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
225                                                 LDO_CLR, VMMC1_DEV_GRP);
226                 if (ret)
227                         goto err;
228
229                 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
230                                                 VSEL_S2_CLR, VMMC1_DEDICATED);
231                 if (ret)
232                         goto err;
233
234                 /* 100ms delay required for PBIAS configuration */
235                 msleep(100);
236                 reg = omap_readl(OMAP2_CONTROL_PBIAS);
237                 reg |= (OMAP2_CONTROL_PBIAS_VMODE |
238                         OMAP2_CONTROL_PBIAS_PWRDNZ |
239                         OMAP2_CONTROL_PBIAS_SCTRL);
240                 omap_writel(reg, OMAP2_CONTROL_PBIAS);
241         }
242
243         return 0;
244
245 err:
246         return 1;
247 }
248
249 static struct omap_mmc_platform_data mmc1_data = {
250         .nr_slots                       = 1,
251         .init                           = hsmmc_late_init,
252         .cleanup                        = hsmmc_cleanup,
253 #ifdef CONFIG_PM
254         .suspend                        = hsmmc_suspend,
255         .resume                         = hsmmc_resume,
256 #endif
257         .dma_mask                       = 0xffffffff,
258         .slots[0] = {
259                 .wire4                  = 1,
260                 .set_power              = hsmmc_set_power,
261                 .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34 |
262                                                 MMC_VDD_165_195,
263                 .name                   = "first slot",
264
265                 .card_detect_irq        = TWL4030_GPIO_IRQ_NO(0),
266                 .card_detect            = hsmmc_card_detect,
267         },
268 };
269
270 /* ************************************************************************* */
271
272 #define VMMC2_DEV_GRP           0x2B
273 #define VMMC2_DEDICATED         0x2E
274
275 #define mmc2_cd_gpio (mmc1_cd_gpio + 1)
276
277 static int hsmmc2_card_detect(int irq)
278 {
279         return gpio_get_value_cansleep(mmc2_cd_gpio);
280 }
281
282 static int hsmmc2_late_init(struct device *dev)
283 {
284         int ret = 0;
285
286         ret = gpio_request(mmc2_cd_gpio, "mmc1_cd");
287         if (ret)
288                 goto err;
289
290         ret = twl4030_set_gpio_debounce(1, true);
291         if (ret)
292                 goto err;
293
294         return ret;
295
296 err:
297         dev_err(dev, "Failed to configure TWL4030 GPIO IRQ for MMC2\n");
298         return ret;
299 }
300
301 static void hsmmc2_cleanup(struct device *dev)
302 {
303         gpio_free(mmc2_cd_gpio);
304 }
305
306 static int hsmmc2_set_power(struct device *dev, int slot, int power_on,
307                                 int vdd)
308 {
309         u32 vdd_sel = 0, ret = 0;
310
311         dev_dbg(dev, "power %s, vdd %i\n", power_on ? "on" : "off", vdd);
312
313         if (power_on) {
314                 switch (1 << vdd) {
315                 case MMC_VDD_33_34:
316                 case MMC_VDD_32_33:
317                         vdd_sel = 0x0c;
318                         break;
319                 case MMC_VDD_165_195:
320                         vdd_sel = 0x05;
321                         break;
322                 default:
323                         dev_err(dev, "Bad vdd request %i for MMC2\n", vdd);
324                         goto err;
325                 }
326
327                 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
328                                                 P1_DEV_GRP, VMMC2_DEV_GRP);
329                 if (ret)
330                         goto err;
331
332                 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
333                                                 vdd_sel, VMMC2_DEDICATED);
334                 if (ret)
335                         goto err;
336
337                 msleep(100);
338         } else {
339                 /* Power OFF */
340                 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
341                                                 LDO_CLR, VMMC2_DEV_GRP);
342                 if (ret)
343                         goto err;
344
345                 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
346                                                 VSEL_S2_CLR, VMMC2_DEDICATED);
347                 if (ret)
348                         goto err;
349         }
350
351         return 0;
352
353 err:
354         return ret;
355 }
356
357 static struct omap_mmc_platform_data mmc2_data = {
358         .nr_slots                       = 1,
359         .init                           = hsmmc2_late_init,
360         .cleanup                        = hsmmc2_cleanup,
361         /* TODO: .suspend, .resume */
362         .dma_mask                       = 0xffffffff,
363         .slots[0] = {
364                 .wire4                  = 1,
365                 .set_power              = hsmmc2_set_power,
366                 .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34 |
367                                                 MMC_VDD_165_195,
368                 .name                   = "second slot",
369
370                 .card_detect_irq        = TWL4030_GPIO_IRQ_NO(1),
371                 .card_detect            = hsmmc2_card_detect,
372         },
373 };
374
375 /* ************************************************************************* */
376
377 static int hsmmc3_set_power(struct device *dev, int slot, int power_on,
378                 int vdd)
379 {
380         /* nothing to do for MMC3 */
381         return 0;
382 }
383
384 /*
385  * Hack: Hardcoded WL1251 embedded data for Pandora
386  * - passed up via a dirty hack to the MMC platform data.
387  */
388
389 #include <linux/mmc/host.h>
390 #include <linux/mmc/card.h>
391 #include <linux/mmc/sdio_func.h>
392 #include <linux/mmc/sdio_ids.h>
393
394 static struct sdio_embedded_func wifi_func = {
395         .f_class        = SDIO_CLASS_WLAN,
396         .f_maxblksize   = 512,
397 };
398
399 static struct embedded_sdio_data pandora_wifi_emb_data = {
400         .cis    = {
401                 .vendor         = 0x104c,
402                 .device         = 0x9066,
403                 .blksize        = 512,
404                 .max_dtr        = 20000000,
405         },
406         .cccr   = {
407                 .multi_block    = 0,
408                 .low_speed      = 0,
409                 .wide_bus       = 1,
410                 .high_power     = 0,
411                 .high_speed     = 0,
412         },
413         .funcs  = &wifi_func,
414         .num_funcs = 1,
415 };
416
417 static struct omap_mmc_platform_data mmc3_data = {
418         .nr_slots                       = 1,
419         .dma_mask                       = 0xffffffff,
420         .embedded_sdio                  = &pandora_wifi_emb_data,
421         .slots[0] = {
422                 .wire4                  = 1,
423                 .set_power              = hsmmc3_set_power,
424                 .ocr_mask               = MMC_VDD_165_195 | MMC_VDD_20_21,
425                 .name                   = "third slot",
426         },
427 };
428
429 /* ************************************************************************* */
430
431 static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC];
432
433 void __init hsmmc_init(void)
434 {
435         hsmmc_data[0] = &mmc1_data;
436         hsmmc_data[1] = &mmc2_data;
437         hsmmc_data[2] = &mmc3_data;
438         omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);
439 }
440
441 #else
442
443 void __init hsmmc_init(void)
444 {
445
446 }
447
448 #endif