omap: Rename mmc-twl4030 files to hsmmc
[pandora-kernel.git] / arch / arm / mach-omap2 / hsmmc.c
1 /*
2  * linux/arch/arm/mach-omap2/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/kernel.h>
13 #include <linux/slab.h>
14 #include <linux/string.h>
15 #include <linux/delay.h>
16 #include <mach/hardware.h>
17 #include <plat/control.h>
18 #include <plat/mmc.h>
19
20 #include "hsmmc.h"
21
22 #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
23
24 static u16 control_pbias_offset;
25 static u16 control_devconf1_offset;
26
27 #define HSMMC_NAME_LEN  9
28
29 static struct twl_mmc_controller {
30         char                            name[HSMMC_NAME_LEN + 1];
31 } hsmmc[OMAP34XX_NR_MMC];
32
33 #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
34
35 static int twl4030_mmc_get_context_loss(struct device *dev)
36 {
37         /* FIXME: PM DPS not implemented yet */
38         return 0;
39 }
40
41 #else
42 #define twl4030_mmc_get_context_loss NULL
43 #endif
44
45 static void hsmmc1_before_set_reg(struct device *dev, int slot,
46                                   int power_on, int vdd)
47 {
48         u32 reg, prog_io;
49         struct omap_mmc_platform_data *mmc = dev->platform_data;
50
51         /*
52          * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
53          * card with Vcc regulator (from twl4030 or whatever).  OMAP has both
54          * 1.8V and 3.0V modes, controlled by the PBIAS register.
55          *
56          * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
57          * is most naturally TWL VSIM; those pins also use PBIAS.
58          *
59          * FIXME handle VMMC1A as needed ...
60          */
61         if (power_on) {
62                 if (cpu_is_omap2430()) {
63                         reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
64                         if ((1 << vdd) >= MMC_VDD_30_31)
65                                 reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE;
66                         else
67                                 reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE;
68                         omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
69                 }
70
71                 if (mmc->slots[0].internal_clock) {
72                         reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
73                         reg |= OMAP2_MMCSDIO1ADPCLKISEL;
74                         omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
75                 }
76
77                 reg = omap_ctrl_readl(control_pbias_offset);
78                 if (cpu_is_omap3630()) {
79                         /* Set MMC I/O to 52Mhz */
80                         prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
81                         prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL;
82                         omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1);
83                 } else {
84                         reg |= OMAP2_PBIASSPEEDCTRL0;
85                 }
86                 reg &= ~OMAP2_PBIASLITEPWRDNZ0;
87                 omap_ctrl_writel(reg, control_pbias_offset);
88         } else {
89                 reg = omap_ctrl_readl(control_pbias_offset);
90                 reg &= ~OMAP2_PBIASLITEPWRDNZ0;
91                 omap_ctrl_writel(reg, control_pbias_offset);
92         }
93 }
94
95 static void hsmmc1_after_set_reg(struct device *dev, int slot,
96                                  int power_on, int vdd)
97 {
98         u32 reg;
99
100         /* 100ms delay required for PBIAS configuration */
101         msleep(100);
102
103         if (power_on) {
104                 reg = omap_ctrl_readl(control_pbias_offset);
105                 reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0);
106                 if ((1 << vdd) <= MMC_VDD_165_195)
107                         reg &= ~OMAP2_PBIASLITEVMODE0;
108                 else
109                         reg |= OMAP2_PBIASLITEVMODE0;
110                 omap_ctrl_writel(reg, control_pbias_offset);
111         } else {
112                 reg = omap_ctrl_readl(control_pbias_offset);
113                 reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
114                         OMAP2_PBIASLITEVMODE0);
115                 omap_ctrl_writel(reg, control_pbias_offset);
116         }
117 }
118
119 static void hsmmc23_before_set_reg(struct device *dev, int slot,
120                                    int power_on, int vdd)
121 {
122         struct omap_mmc_platform_data *mmc = dev->platform_data;
123
124         if (power_on) {
125                 /* Only MMC2 supports a CLKIN */
126                 if (mmc->slots[0].internal_clock) {
127                         u32 reg;
128
129                         reg = omap_ctrl_readl(control_devconf1_offset);
130                         reg |= OMAP2_MMCSDIO2ADPCLKISEL;
131                         omap_ctrl_writel(reg, control_devconf1_offset);
132                 }
133         }
134 }
135
136 static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
137
138 void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
139 {
140         struct twl4030_hsmmc_info *c;
141         int nr_hsmmc = ARRAY_SIZE(hsmmc_data);
142         int i;
143
144         if (cpu_is_omap2430()) {
145                 control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
146                 control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1;
147         } else {
148                 control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
149                 control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
150         }
151
152         for (c = controllers; c->mmc; c++) {
153                 struct twl_mmc_controller *twl = hsmmc + c->mmc - 1;
154                 struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];
155
156                 if (!c->mmc || c->mmc > nr_hsmmc) {
157                         pr_debug("MMC%d: no such controller\n", c->mmc);
158                         continue;
159                 }
160                 if (mmc) {
161                         pr_debug("MMC%d: already configured\n", c->mmc);
162                         continue;
163                 }
164
165                 mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
166                 if (!mmc) {
167                         pr_err("Cannot allocate memory for mmc device!\n");
168                         goto done;
169                 }
170
171                 if (c->name)
172                         strncpy(twl->name, c->name, HSMMC_NAME_LEN);
173                 else
174                         snprintf(twl->name, ARRAY_SIZE(twl->name),
175                                 "mmc%islot%i", c->mmc, 1);
176                 mmc->slots[0].name = twl->name;
177                 mmc->nr_slots = 1;
178                 mmc->slots[0].wires = c->wires;
179                 mmc->slots[0].internal_clock = !c->ext_clock;
180                 mmc->dma_mask = 0xffffffff;
181
182                 mmc->get_context_loss_count =
183                                 twl4030_mmc_get_context_loss;
184
185                 mmc->slots[0].switch_pin = c->gpio_cd;
186                 mmc->slots[0].gpio_wp = c->gpio_wp;
187
188                 if (c->cover_only)
189                         mmc->slots[0].cover = 1;
190
191                 if (c->nonremovable)
192                         mmc->slots[0].nonremovable = 1;
193
194                 if (c->power_saving)
195                         mmc->slots[0].power_saving = 1;
196
197                 /* NOTE:  MMC slots should have a Vcc regulator set up.
198                  * This may be from a TWL4030-family chip, another
199                  * controllable regulator, or a fixed supply.
200                  *
201                  * temporary HACK: ocr_mask instead of fixed supply
202                  */
203                 mmc->slots[0].ocr_mask = c->ocr_mask;
204
205                 switch (c->mmc) {
206                 case 1:
207                         /* on-chip level shifting via PBIAS0/PBIAS1 */
208                         mmc->slots[0].before_set_reg = hsmmc1_before_set_reg;
209                         mmc->slots[0].after_set_reg = hsmmc1_after_set_reg;
210
211                         /* Omap3630 HSMMC1 supports only 4-bit */
212                         if (cpu_is_omap3630() && c->wires > 4) {
213                                 c->wires = 4;
214                                 mmc->slots[0].wires = c->wires;
215                         }
216                         break;
217                 case 2:
218                         if (c->ext_clock)
219                                 c->transceiver = 1;
220                         if (c->transceiver && c->wires > 4)
221                                 c->wires = 4;
222                         /* FALLTHROUGH */
223                 case 3:
224                         /* off-chip level shifting, or none */
225                         mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
226                         mmc->slots[0].after_set_reg = NULL;
227                         break;
228                 default:
229                         pr_err("MMC%d configuration not supported!\n", c->mmc);
230                         kfree(mmc);
231                         continue;
232                 }
233                 hsmmc_data[c->mmc - 1] = mmc;
234         }
235
236         omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);
237
238         /* pass the device nodes back to board setup code */
239         for (c = controllers; c->mmc; c++) {
240                 struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];
241
242                 if (!c->mmc || c->mmc > nr_hsmmc)
243                         continue;
244                 c->dev = mmc->dev;
245         }
246
247 done:
248         for (i = 0; i < nr_hsmmc; i++)
249                 kfree(hsmmc_data[i]);
250 }
251
252 #endif