]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/board-h4-mmc.c
48c0358b78156bfb744a2f16b69867bf3b7261ec
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / board-h4-mmc.c
1 /*
2  * linux/arch/arm/mach-omap2/board-h4-mmc.c
3  *
4  * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT
5  * Authors: David Cohen <david.cohen@indt.org.br>
6  *          Carlos Eduardo Aguiar <carlos.aguiar@indt.org.br>
7  *
8  * This code is based on linux/arch/arm/mach-omap2/board-n800-mmc.c, which is:
9  * Copyright (C) 2006 Nokia Corporation
10  * Author: Juha Yrjola
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  */
16
17 #include <linux/delay.h>
18 #include <linux/platform_device.h>
19 #include <linux/i2c/menelaus.h>
20
21 #include <asm/mach-types.h>
22
23 #include <mach/mmc.h>
24
25 #ifdef CONFIG_MMC_OMAP
26
27 /* Bit mask for slots detection interrupts */
28 #define SD1_CD_ST       (1 << 0)
29 #define SD2_CD_ST       (1 << 1)
30
31 static int slot1_cover_open;
32 static int slot2_cover_open;
33 static struct device *mmc_device;
34
35 /*
36  * VMMC --> slot 1
37  * VDCDC3_APE, VMCS2_APE --> slot 2
38  */
39
40 static int h4_mmc_switch_slot(struct device *dev, int slot)
41 {
42         int r = 0;
43
44 #ifdef CONFIG_MMC_DEBUG
45         dev_dbg(dev, "Choose slot %d\n", slot + 1);
46 #endif
47         if (slot == 0) {
48                 r = menelaus_enable_slot(2, 0);
49                 r |= menelaus_enable_slot(1, 1);
50         } else {
51                 r = menelaus_enable_slot(1, 0);
52                 r |= menelaus_enable_slot(2, 1);
53         }
54
55         return r ? -ENODEV : 0;
56 }
57
58 static int h4_mmc_set_power(struct device *dev, int slot, int power_on,
59                                 int vdd)
60 {
61         int mV = 0;
62
63 #ifdef CONFIG_MMC_DEBUG
64         dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
65                 power_on ? "on" : "off", vdd);
66 #endif
67         if (slot == 0) {
68                 if (!power_on)
69                         return menelaus_set_vmmc(3000);
70                 switch (1 << vdd) {
71                         case MMC_VDD_33_34:
72                         case MMC_VDD_32_33:
73                         case MMC_VDD_31_32:
74                                 mV = 3100;
75                                 break;
76                         case MMC_VDD_30_31:
77                                 mV = 3000;
78                                 break;
79                         case MMC_VDD_28_29:
80                                 mV = 2800;
81                                 break;
82                         case MMC_VDD_165_195:
83                                 mV = 1850;
84                                 break;
85                         default:
86                                 BUG();
87                 }
88                 return menelaus_set_vmmc(mV);
89         } else {
90                 if (!power_on)
91                         return menelaus_set_vdcdc(3, 3000);
92                 switch (1 << vdd) {
93                         case MMC_VDD_33_34:
94                         case MMC_VDD_32_33:
95                                 mV = 3300;
96                                 break;
97                         case MMC_VDD_30_31:
98                         case MMC_VDD_29_30:
99                                 mV = 3000;
100                                 break;
101                         case MMC_VDD_28_29:
102                         case MMC_VDD_27_28:
103                                 mV = 2800;
104                                 break;
105                         case MMC_VDD_24_25:
106                         case MMC_VDD_23_24:
107                                 mV = 2400;
108                                 break;
109                         case MMC_VDD_22_23:
110                         case MMC_VDD_21_22:
111                                 mV = 2200;
112                                 break;
113                         case MMC_VDD_20_21:
114                                 mV = 2000;
115                                 break;
116                         case MMC_VDD_165_195:
117                                 mV = 1800;
118                                 break;
119                         default:
120                                 BUG();
121                 }
122                 return menelaus_set_vdcdc(3, mV);
123         }
124         return 0;
125 }
126
127 static int h4_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
128 {
129         int r = 0;
130
131 #ifdef CONFIG_MMC_DEBUG
132         dev_dbg(dev, "Set slot %d bus mode %s\n", slot + 1,
133                 bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
134 #endif
135         BUG_ON(slot != 0 && slot != 1);
136         slot++;
137         switch (bus_mode) {
138         case MMC_BUSMODE_OPENDRAIN:
139                 r = menelaus_set_mmc_opendrain(slot, 1);
140                 break;
141         case MMC_BUSMODE_PUSHPULL:
142                 r = menelaus_set_mmc_opendrain(slot, 0);
143                 break;
144         default:
145                 BUG();
146         }
147         if (r != 0 && printk_ratelimit()) {
148                 dev_err(dev, "MMC: unable to set bus mode for slot %d\n",
149                         slot);
150         }
151         return r;
152 }
153
154 static int h4_mmc_slot1_cover_state(struct device *dev, int slot)
155 {
156         BUG_ON(slot != 0);
157         return slot1_cover_open;
158 }
159
160 static int h4_mmc_slot2_cover_state(struct device *dev, int slot)
161 {
162         BUG_ON(slot != 1);
163         return slot2_cover_open;
164 }
165
166 static void h4_mmc_slot_callback(void *data, u8 card_mask)
167 {
168         int cover_open;
169
170         cover_open = (card_mask & SD1_CD_ST) ? 0 : 1;
171         if (cover_open != slot1_cover_open) {
172                 slot1_cover_open = cover_open;
173                 omap_mmc_notify_cover_event(mmc_device, 0, slot1_cover_open);
174         }
175
176         cover_open = (card_mask & SD2_CD_ST) ? 0 : 1;
177         if (cover_open != slot2_cover_open) {
178                 slot2_cover_open = cover_open;
179                 omap_mmc_notify_cover_event(mmc_device, 1, slot2_cover_open);
180         }
181 }
182
183 static int h4_mmc_late_init(struct device *dev)
184 {
185         int r;
186
187         mmc_device = dev;
188
189         r = menelaus_set_mmc_slot(1, 0, 0, 1);
190         if (r < 0)
191                 goto out;
192         r = menelaus_set_mmc_slot(2, 0, 0, 1);
193         if (r < 0)
194                 goto out;
195
196         r = menelaus_get_slot_pin_states();
197         if (r < 0)
198                 goto out;
199
200         if (r & SD1_CD_ST)
201                 slot1_cover_open = 1;
202         else
203                 slot1_cover_open = 0;
204
205         /* Slot pin bits seem to be inversed until first swith change,
206          * but just for slot 2
207          */
208         if ((r == 0xf) || (r == (0xf & ~SD2_CD_ST)))
209                 r = ~r;
210
211         if (r & SD2_CD_ST)
212                 slot2_cover_open = 1;
213         else
214                 slot2_cover_open = 0;
215
216         r = menelaus_register_mmc_callback(h4_mmc_slot_callback, NULL);
217
218 out:
219         return r;
220 }
221
222 static void h4_mmc_cleanup(struct device *dev)
223 {
224         menelaus_unregister_mmc_callback();
225 }
226
227 static struct omap_mmc_platform_data mmc1_data = {
228         .nr_slots               = 2,
229         .switch_slot            = h4_mmc_switch_slot,
230         .init                   = h4_mmc_late_init,
231         .cleanup                = h4_mmc_cleanup,
232         .dma_mask               = 0xffffffff,
233         .slots[0] = {
234                 .wires          = 4,
235                 .set_power      = h4_mmc_set_power,
236                 .set_bus_mode   = h4_mmc_set_bus_mode,
237                 .get_cover_state= h4_mmc_slot1_cover_state,
238                 .ocr_mask       = MMC_VDD_165_195 |
239                                   MMC_VDD_28_29 | MMC_VDD_30_31 |
240                                   MMC_VDD_32_33 | MMC_VDD_33_34,
241                 .name           = "slot1",
242         },
243         .slots[1] = {
244                 .wires          = 4,
245                 .set_power      = h4_mmc_set_power,
246                 .set_bus_mode   = h4_mmc_set_bus_mode,
247                 .get_cover_state= h4_mmc_slot2_cover_state,
248                 .ocr_mask       = MMC_VDD_165_195 | 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           = "slot2",
254         },
255 };
256
257 static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC];
258
259 void __init h4_mmc_init(void)
260 {
261         mmc_data[0] = &mmc1_data;
262         omap2_init_mmc(mmc_data, OMAP24XX_NR_MMC);
263 }
264
265 #else
266
267 void __init h4_mmc_init(void)
268 {
269 }
270
271 #endif
272