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