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