]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-n800-mmc.c
OMAP2EVM: twl4030 keypad Kconfig dependency fix
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / board-n800-mmc.c
1 /*
2  * linux/arch/arm/mach-omap2/board-n800-mmc.c
3  *
4  * Copyright (C) 2006 Nokia Corporation
5  * Author: Juha Yrjola
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <asm/arch/mmc.h>
13 #include <asm/arch/gpio.h>
14
15 #include <asm/mach-types.h>
16 #include <linux/delay.h>
17 #include <linux/i2c/menelaus.h>
18
19 #ifdef CONFIG_MMC_OMAP
20
21 static const int slot_switch_gpio = 96;
22
23 static const int n810_slot2_pw_vddf = 23;
24 static const int n810_slot2_pw_vdd = 9;
25
26 static int slot1_cover_open;
27 static int slot2_cover_open;
28 static struct device *mmc_device;
29
30 /*
31  * VMMC   --> slot 1 (N800 & N810)
32  * VDCDC3_APE, VMCS2_APE --> slot 2 on N800
33  * GPIO96 --> Menelaus GPIO2
34  * GPIO23 --> controls slot2 VSD    (N810 only)
35  * GPIO9  --> controls slot2 VIO_SD (N810 only)
36  */
37
38 static int n800_mmc_switch_slot(struct device *dev, int slot)
39 {
40 #ifdef CONFIG_MMC_DEBUG
41         dev_dbg(dev, "Choose slot %d\n", slot + 1);
42 #endif
43         if (slot == 0)
44                 omap_set_gpio_dataout(slot_switch_gpio, 0);
45         else
46                 omap_set_gpio_dataout(slot_switch_gpio, 1);
47         return 0;
48 }
49
50 static int n800_mmc_set_power_menelaus(struct device *dev, int slot,
51                                         int power_on, int vdd)
52 {
53         int mV;
54
55 #ifdef CONFIG_MMC_DEBUG
56         dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
57                 power_on ? "on" : "off", vdd);
58 #endif
59         if (slot == 0) {
60                 if (!power_on)
61                         return menelaus_set_vmmc(0);
62                 switch (1 << vdd) {
63                 case MMC_VDD_33_34:
64                 case MMC_VDD_32_33:
65                 case MMC_VDD_31_32:
66                         mV = 3100;
67                         break;
68                 case MMC_VDD_30_31:
69                         mV = 3000;
70                         break;
71                 case MMC_VDD_28_29:
72                         mV = 2800;
73                         break;
74                 case MMC_VDD_165_195:
75                         mV = 1850;
76                         break;
77                 default:
78                         BUG();
79                 }
80                 return menelaus_set_vmmc(mV);
81         } else {
82                 if (!power_on)
83                         return menelaus_set_vdcdc(3, 0);
84                 switch (1 << vdd) {
85                 case MMC_VDD_33_34:
86                 case MMC_VDD_32_33:
87                         mV = 3300;
88                         break;
89                 case MMC_VDD_30_31:
90                 case MMC_VDD_29_30:
91                         mV = 3000;
92                         break;
93                 case MMC_VDD_28_29:
94                 case MMC_VDD_27_28:
95                         mV = 2800;
96                         break;
97                 case MMC_VDD_24_25:
98                 case MMC_VDD_23_24:
99                         mV = 2400;
100                         break;
101                 case MMC_VDD_22_23:
102                 case MMC_VDD_21_22:
103                         mV = 2200;
104                         break;
105                 case MMC_VDD_20_21:
106                         mV = 2000;
107                         break;
108                 case MMC_VDD_165_195:
109                         mV = 1800;
110                         break;
111                 default:
112                         BUG();
113                 }
114                 return menelaus_set_vdcdc(3, mV);
115         }
116         return 0;
117 }
118
119 static void nokia_mmc_set_power_internal(struct device *dev,
120                                          int power_on)
121 {
122         dev_dbg(dev, "Set internal slot power %s\n",
123                 power_on ? "on" : "off");
124
125         if (power_on) {
126                 omap_set_gpio_dataout(n810_slot2_pw_vddf, 1);
127                 udelay(30);
128                 omap_set_gpio_dataout(n810_slot2_pw_vdd, 1);
129                 udelay(100);
130         } else {
131                 omap_set_gpio_dataout(n810_slot2_pw_vdd, 0);
132                 msleep(50);
133                 omap_set_gpio_dataout(n810_slot2_pw_vddf, 0);
134                 msleep(50);
135         }
136 }
137
138 static int n800_mmc_set_power(struct device *dev, int slot, int power_on,
139                               int vdd)
140 {
141         if (machine_is_nokia_n800() || slot == 0)
142                 return n800_mmc_set_power_menelaus(dev, slot, power_on, vdd);
143
144         nokia_mmc_set_power_internal(dev, power_on);
145
146         return 0;
147 }
148
149 static int n800_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
150 {
151         int r;
152
153         dev_dbg(dev, "Set slot %d bus mode %s\n", slot + 1,
154                 bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
155         BUG_ON(slot != 0 && slot != 1);
156         slot++;
157         switch (bus_mode) {
158         case MMC_BUSMODE_OPENDRAIN:
159                 r = menelaus_set_mmc_opendrain(slot, 1);
160                 break;
161         case MMC_BUSMODE_PUSHPULL:
162                 r = menelaus_set_mmc_opendrain(slot, 0);
163                 break;
164         default:
165                 BUG();
166         }
167         if (r != 0 && printk_ratelimit())
168                 dev_err(dev, "MMC: unable to set bus mode for slot %d\n",
169                         slot);
170         return r;
171 }
172
173 static int n800_mmc_get_cover_state(struct device *dev, int slot)
174 {
175         slot++;
176         BUG_ON(slot != 1 && slot != 2);
177         if (slot == 1)
178                 return slot1_cover_open;
179         else
180                 return slot2_cover_open;
181 }
182
183 static void n800_mmc_callback(void *data, u8 card_mask)
184 {
185         int bit, *openp, index;
186
187         if (machine_is_nokia_n800()) {
188                 bit = 1 << 1;
189                 openp = &slot2_cover_open;
190                 index = 1;
191         } else {
192                 bit = 1;
193                 openp = &slot1_cover_open;
194                 index = 0;
195         }
196
197         if (card_mask & bit)
198                 *openp = 1;
199         else
200                 *openp = 0;
201
202         omap_mmc_notify_cover_event(mmc_device, index, *openp);
203 }
204
205 void n800_mmc_slot1_cover_handler(void *arg, int closed_state)
206 {
207         if (mmc_device == NULL)
208                 return;
209
210         slot1_cover_open = !closed_state;
211         omap_mmc_notify_cover_event(mmc_device, 0, closed_state);
212 }
213
214 static int n800_mmc_late_init(struct device *dev)
215 {
216         int r, bit, *openp;
217         int vs2sel;
218
219         mmc_device = dev;
220
221         r = menelaus_set_slot_sel(1);
222         if (r < 0)
223                 return r;
224
225         if (machine_is_nokia_n800())
226                 vs2sel = 0;
227         else
228                 vs2sel = 2;
229
230         r = menelaus_set_mmc_slot(2, 0, vs2sel, 1);
231         if (r < 0)
232                 return r;
233
234         n800_mmc_set_power(dev, 0, MMC_POWER_ON, 16); /* MMC_VDD_28_29 */
235         n800_mmc_set_power(dev, 1, MMC_POWER_ON, 16);
236
237         r = menelaus_set_mmc_slot(1, 1, 0, 1);
238         if (r < 0)
239                 return r;
240         r = menelaus_set_mmc_slot(2, 1, vs2sel, 1);
241         if (r < 0)
242                 return r;
243
244         r = menelaus_get_slot_pin_states();
245         if (r < 0)
246                 return r;
247
248         if (machine_is_nokia_n800()) {
249                 bit = 1 << 1;
250                 openp = &slot2_cover_open;
251         } else {
252                 bit = 1;
253                 openp = &slot1_cover_open;
254                 slot2_cover_open = 0;
255         }
256
257         /* All slot pin bits seem to be inversed until first swith change */
258         if (r == 0xf || r == (0xf & ~bit))
259                 r = ~r;
260
261         if (r & bit)
262                 *openp = 1;
263         else
264                 *openp = 0;
265
266         r = menelaus_register_mmc_callback(n800_mmc_callback, NULL);
267
268         return r;
269 }
270
271 static void n800_mmc_shutdown(struct device *dev)
272 {
273         int vs2sel;
274
275         if (machine_is_nokia_n800())
276                 vs2sel = 0;
277         else
278                 vs2sel = 2;
279
280         menelaus_set_mmc_slot(1, 0, 0, 0);
281         menelaus_set_mmc_slot(2, 0, vs2sel, 0);
282 }
283
284 static void n800_mmc_cleanup(struct device *dev)
285 {
286         menelaus_unregister_mmc_callback();
287
288         omap_free_gpio(slot_switch_gpio);
289
290         if (machine_is_nokia_n810()) {
291                 omap_free_gpio(n810_slot2_pw_vddf);
292                 omap_free_gpio(n810_slot2_pw_vdd);
293         }
294 }
295
296 static struct omap_mmc_platform_data n800_mmc_data = {
297         .nr_slots               = 2,
298         .switch_slot            = n800_mmc_switch_slot,
299         .init                   = n800_mmc_late_init,
300         .cleanup                = n800_mmc_cleanup,
301         .shutdown               = n800_mmc_shutdown,
302         .max_freq               = 24000000,
303         .slots[0] = {
304                 .set_power      = n800_mmc_set_power,
305                 .set_bus_mode   = n800_mmc_set_bus_mode,
306                 .get_ro         = NULL,
307                 .get_cover_state= n800_mmc_get_cover_state,
308                 .ocr_mask       = MMC_VDD_165_195 | MMC_VDD_30_31 |
309                                   MMC_VDD_32_33   | MMC_VDD_33_34,
310                 .name           = "internal",
311         },
312         .slots[1] = {
313                 .set_power      = n800_mmc_set_power,
314                 .set_bus_mode   = n800_mmc_set_bus_mode,
315                 .get_ro         = NULL,
316                 .get_cover_state= n800_mmc_get_cover_state,
317                 .ocr_mask       = MMC_VDD_165_195 | MMC_VDD_20_21 |
318                                   MMC_VDD_21_22 | MMC_VDD_22_23 | MMC_VDD_23_24 |
319                                   MMC_VDD_24_25 | MMC_VDD_27_28 | MMC_VDD_28_29 |
320                                   MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_32_33 |
321                                   MMC_VDD_33_34,
322                 .name           = "external",
323         },
324 };
325
326 void __init n800_mmc_init(void)
327
328 {
329         if (machine_is_nokia_n810()) {
330                 n800_mmc_data.slots[0].name = "external";
331
332                 /*
333                  * Some Samsung Movinand chips do not like open-ended
334                  * multi-block reads and fall to braind-dead state
335                  * while doing so. Reducing the number of blocks in
336                  * the transfer or delays in clock disable do not help
337                  */
338                 n800_mmc_data.slots[1].name = "internal";
339                 n800_mmc_data.slots[1].ban_openended = 1;
340         }
341
342         omap_set_mmc_info(1, &n800_mmc_data);
343         if (omap_request_gpio(slot_switch_gpio) < 0)
344                 BUG();
345         omap_set_gpio_dataout(slot_switch_gpio, 0);
346         omap_set_gpio_direction(slot_switch_gpio, 0);
347
348         if (machine_is_nokia_n810()) {
349                 if (omap_request_gpio(n810_slot2_pw_vddf) < 0)
350                         BUG();
351                 omap_set_gpio_dataout(n810_slot2_pw_vddf, 0);
352                 omap_set_gpio_direction(n810_slot2_pw_vddf, 0);
353
354                 if (omap_request_gpio(n810_slot2_pw_vdd) < 0)
355                         BUG();
356                 omap_set_gpio_dataout(n810_slot2_pw_vdd, 0);
357                 omap_set_gpio_direction(n810_slot2_pw_vdd, 0);
358         }
359 }
360 #else
361
362 void __init n800_mmc_init(void)
363 {
364 }
365
366 void n800_mmc_slot1_cover_handler(void *arg, int state)
367 {
368 }
369
370 #endif