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