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