]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-n800-mmc.c
Merge current mainline tree into linux-omap tree
[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/menelaus.h>
14 #include <asm/arch/gpio.h>
15
16 #include <asm/mach-types.h>
17 #include <linux/delay.h>
18
19 #ifdef CONFIG_MMC_OMAP
20
21 static const int slot_switch_gpio = 96;
22 static int slot1_cover_open;
23 static int slot2_cover_open;
24 static struct device *mmc_device;
25
26 /*
27  * VMMC --> slot 1
28  * VDCDC3_APE, VMCS2_APE --> slot 2
29  * GPIO96 --> Menelaus GPIO2
30  */
31
32 static int n800_mmc_switch_slot(struct device *dev, int slot)
33 {
34 #ifdef CONFIG_MMC_DEBUG
35         dev_dbg(dev, "Choose slot %d\n", slot + 1);
36 #endif
37         if (slot == 0)
38                 omap_set_gpio_dataout(slot_switch_gpio, 0);
39         else
40                 omap_set_gpio_dataout(slot_switch_gpio, 1);
41         return 0;
42 }
43
44 static int n800_mmc_set_power(struct device *dev, int slot, int power_on,
45                                 int vdd)
46 {
47         int mV;
48
49 #ifdef CONFIG_MMC_DEBUG
50         dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
51                 power_on ? "on" : "off", vdd);
52 #endif
53         if (slot == 0) {
54                 if (!power_on)
55                         return menelaus_set_vmmc(0);
56                 switch (1 << vdd) {
57                 case MMC_VDD_33_34:
58                 case MMC_VDD_32_33:
59                 case MMC_VDD_31_32:
60                         mV = 3100;
61                         break;
62                 case MMC_VDD_30_31:
63                         mV = 3000;
64                         break;
65                 case MMC_VDD_28_29:
66                         mV = 2800;
67                         break;
68                 case MMC_VDD_165_195:
69                         mV = 1850;
70                         break;
71                 default:
72                         BUG();
73                 }
74                 return menelaus_set_vmmc(mV);
75         } else {
76                 if (!power_on)
77                         return menelaus_set_vdcdc(3, 0);
78                 switch (1 << vdd) {
79                 case MMC_VDD_33_34:
80                 case MMC_VDD_32_33:
81                         mV = 3300;
82                         break;
83                 case MMC_VDD_30_31:
84                 case MMC_VDD_29_30:
85                         mV = 3000;
86                         break;
87                 case MMC_VDD_28_29:
88                 case MMC_VDD_27_28:
89                         mV = 2800;
90                         break;
91                 case MMC_VDD_24_25:
92                 case MMC_VDD_23_24:
93                         mV = 2400;
94                         break;
95                 case MMC_VDD_22_23:
96                 case MMC_VDD_21_22:
97                         mV = 2200;
98                         break;
99                 case MMC_VDD_20_21:
100                         mV = 2000;
101                         break;
102                 case MMC_VDD_165_195:
103                         mV = 1800;
104                         break;
105                 default:
106                         BUG();
107                 }
108                 return menelaus_set_vdcdc(3, mV);
109         }
110         return 0;
111 }
112
113 static int n800_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
114 {
115         int r;
116
117 #ifdef CONFIG_MMC_DEBUG
118         dev_dbg(dev, "Set slot %d bus mode %s\n", slot + 1,
119                 bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
120 #endif
121         BUG_ON(slot != 0 && slot != 1);
122         slot++;
123         switch (bus_mode) {
124         case MMC_BUSMODE_OPENDRAIN:
125                 r = menelaus_set_mmc_opendrain(slot, 1);
126                 break;
127         case MMC_BUSMODE_PUSHPULL:
128                 r = menelaus_set_mmc_opendrain(slot, 0);
129                 break;
130         default:
131                 BUG();
132         }
133         if (r != 0 && printk_ratelimit())
134                 dev_err(dev, "MMC: unable to set bus mode for slot %d\n",
135                         slot);
136         return r;
137 }
138
139 #if 0
140 static int n800_mmc_get_ro(struct device *dev, int slot)
141 {
142         int ro;
143
144         slot++;
145         if (slot == 1)
146                 ro = omap_get_gpio_datain(slot1_wp_gpio);
147         else
148                 ro = omap_get_gpio_datain(slot2_wp_gpio);
149 #ifdef CONFIG_MMC_DEBUG
150         dev_dbg(dev, "Get RO slot %d: %s\n",
151                 slot, ro ? "read-only" : "read-write");
152 #endif
153         return ro;
154 }
155 #endif
156
157 static int n800_mmc_get_cover_state(struct device *dev, int slot)
158 {
159         slot++;
160         BUG_ON(slot != 1 && slot != 2);
161         if (slot == 1)
162                 return slot1_cover_open;
163         else
164                 return slot2_cover_open;
165 }
166
167 static void n800_mmc_callback(void *data, u8 card_mask)
168 {
169         int bit, *openp, index;
170
171         if (machine_is_nokia_n800()) {
172                 bit = 1 << 1;
173                 openp = &slot2_cover_open;
174                 index = 1;
175         }
176
177         if (card_mask & bit)
178                 *openp = 1;
179         else
180                 *openp = 0;
181
182         omap_mmc_notify_cover_event(mmc_device, index, *openp);
183 }
184
185 void n800_mmc_slot1_cover_handler(void *arg, int state)
186 {
187         if (mmc_device == NULL)
188                 return;
189
190         slot1_cover_open = !state;
191         omap_mmc_notify_cover_event(mmc_device, 0, state);
192 }
193
194 static int n800_mmc_late_init(struct device *dev)
195 {
196         int r, bit, *openp;
197
198         mmc_device = dev;
199
200         r = menelaus_set_slot_sel(1);
201         if (r < 0)
202                 return r;
203
204         r = menelaus_set_mmc_slot(1, 1, 0, 1);
205         if (r < 0)
206                 return r;
207         r = menelaus_set_mmc_slot(2, 1, 0, 1);
208         if (r < 0)
209                 return r;
210
211         r = menelaus_get_slot_pin_states();
212         if (r < 0)
213                 return r;
214
215         if (machine_is_nokia_n800()) {
216                 bit = 1 << 1;
217                 openp = &slot2_cover_open;
218         }
219
220         /* All slot pin bits seem to be inversed until first swith change */
221         if (r == 0xf || r == (0xf & ~bit))
222                 r = ~r;
223
224         if (r & bit)
225                 *openp = 1;
226         else
227                 *openp = 0;
228
229         r = menelaus_register_mmc_callback(n800_mmc_callback, NULL);
230
231         return r;
232 }
233
234 static void n800_mmc_cleanup(struct device *dev)
235 {
236         menelaus_unregister_mmc_callback();
237 }
238
239 static struct omap_mmc_platform_data n800_mmc_data = {
240         .nr_slots               = 2,
241         .switch_slot            = n800_mmc_switch_slot,
242         .init                   = n800_mmc_late_init,
243         .cleanup                = n800_mmc_cleanup,
244         .slots[0] = {
245                 .set_power      = n800_mmc_set_power,
246                 .set_bus_mode   = n800_mmc_set_bus_mode,
247                 .get_ro         = NULL,
248                 .get_cover_state= n800_mmc_get_cover_state,
249                 .ocr_mask       = MMC_VDD_165_195 |
250                                   MMC_VDD_28_29 | MMC_VDD_30_31 |
251                                   MMC_VDD_32_33 | MMC_VDD_33_34,
252                 .name           = "internal",
253         },
254         .slots[1] = {
255                 .set_power      = n800_mmc_set_power,
256                 .set_bus_mode   = n800_mmc_set_bus_mode,
257                 .get_ro         = NULL,
258                 .get_cover_state= n800_mmc_get_cover_state,
259                 .ocr_mask       = MMC_VDD_165_195 | MMC_VDD_20_21 |
260                                   MMC_VDD_21_22 | MMC_VDD_22_23 | MMC_VDD_23_24 |
261                                   MMC_VDD_24_25 | MMC_VDD_27_28 | MMC_VDD_28_29 |
262                                   MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_32_33 |
263                                   MMC_VDD_33_34,
264                 .name           = "external",
265         },
266 };
267
268 void __init n800_mmc_init(void)
269 {
270         omap_set_mmc_info(1, &n800_mmc_data);
271         if (omap_request_gpio(slot_switch_gpio) < 0)
272                 BUG();
273         omap_set_gpio_dataout(slot_switch_gpio, 0);
274         omap_set_gpio_direction(slot_switch_gpio, 0);
275 }
276
277 #else
278
279 void __init n800_mmc_init(void)
280 {
281 }
282
283 void n800_mmc_slot1_cover_handler(void *arg, int state)
284 {
285 }
286
287 #endif