aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/mmc.c
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2006-12-30 18:11:32 -0500
committerPierre Ossman <drzeus@drzeus.cx>2007-05-01 07:41:06 -0400
commit7ea239d9e6d6993469a6a8ca83ff23834dfc3fce (patch)
tree40629c00e317ca8f4ce0a6394dcb4b7535e7b7ab /drivers/mmc/core/mmc.c
parentb2670b1c6ddd54be4a0f72f853122510ea5ef285 (diff)
mmc: add bus handler
Delegate protocol handling to "bus handlers". This allows the core to just handle the task of arbitrating the bus. Initialisation and pampering of cards is now done by the different bus handlers. This design also allows MMC and SD (and later SDIO) to be more cleanly separated, allowing easier maintenance. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r--drivers/mmc/core/mmc.c430
1 files changed, 430 insertions, 0 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
new file mode 100644
index 00000000000..c528017d612
--- /dev/null
+++ b/drivers/mmc/core/mmc.c
@@ -0,0 +1,430 @@
1/*
2 * linux/drivers/mmc/mmc.c
3 *
4 * Copyright (C) 2003-2004 Russell King, All Rights Reserved.
5 * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
6 * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/err.h>
14
15#include <linux/mmc/host.h>
16#include <linux/mmc/card.h>
17#include <linux/mmc/mmc.h>
18
19#include "core.h"
20#include "sysfs.h"
21#include "mmc_ops.h"
22
23static const unsigned int tran_exp[] = {
24 10000, 100000, 1000000, 10000000,
25 0, 0, 0, 0
26};
27
28static const unsigned char tran_mant[] = {
29 0, 10, 12, 13, 15, 20, 25, 30,
30 35, 40, 45, 50, 55, 60, 70, 80,
31};
32
33static const unsigned int tacc_exp[] = {
34 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
35};
36
37static const unsigned int tacc_mant[] = {
38 0, 10, 12, 13, 15, 20, 25, 30,
39 35, 40, 45, 50, 55, 60, 70, 80,
40};
41
42#define UNSTUFF_BITS(resp,start,size) \
43 ({ \
44 const int __size = size; \
45 const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
46 const int __off = 3 - ((start) / 32); \
47 const int __shft = (start) & 31; \
48 u32 __res; \
49 \
50 __res = resp[__off] >> __shft; \
51 if (__size + __shft > 32) \
52 __res |= resp[__off-1] << ((32 - __shft) % 32); \
53 __res & __mask; \
54 })
55
56/*
57 * Given the decoded CSD structure, decode the raw CID to our CID structure.
58 */
59static void mmc_decode_cid(struct mmc_card *card)
60{
61 u32 *resp = card->raw_cid;
62
63 /*
64 * The selection of the format here is based upon published
65 * specs from sandisk and from what people have reported.
66 */
67 switch (card->csd.mmca_vsn) {
68 case 0: /* MMC v1.0 - v1.2 */
69 case 1: /* MMC v1.4 */
70 card->cid.manfid = UNSTUFF_BITS(resp, 104, 24);
71 card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
72 card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
73 card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
74 card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
75 card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
76 card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
77 card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8);
78 card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4);
79 card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4);
80 card->cid.serial = UNSTUFF_BITS(resp, 16, 24);
81 card->cid.month = UNSTUFF_BITS(resp, 12, 4);
82 card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997;
83 break;
84
85 case 2: /* MMC v2.0 - v2.2 */
86 case 3: /* MMC v3.1 - v3.3 */
87 case 4: /* MMC v4 */
88 card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
89 card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
90 card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
91 card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
92 card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
93 card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
94 card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
95 card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
96 card->cid.serial = UNSTUFF_BITS(resp, 16, 32);
97 card->cid.month = UNSTUFF_BITS(resp, 12, 4);
98 card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997;
99 break;
100
101 default:
102 printk("%s: card has unknown MMCA version %d\n",
103 mmc_hostname(card->host), card->csd.mmca_vsn);
104 mmc_card_set_bad(card);
105 break;
106 }
107}
108
109/*
110 * Given a 128-bit response, decode to our card CSD structure.
111 */
112static void mmc_decode_csd(struct mmc_card *card)
113{
114 struct mmc_csd *csd = &card->csd;
115 unsigned int e, m, csd_struct;
116 u32 *resp = card->raw_csd;
117
118 /*
119 * We only understand CSD structure v1.1 and v1.2.
120 * v1.2 has extra information in bits 15, 11 and 10.
121 */
122 csd_struct = UNSTUFF_BITS(resp, 126, 2);
123 if (csd_struct != 1 && csd_struct != 2) {
124 printk("%s: unrecognised CSD structure version %d\n",
125 mmc_hostname(card->host), csd_struct);
126 mmc_card_set_bad(card);
127 return;
128 }
129
130 csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4);
131 m = UNSTUFF_BITS(resp, 115, 4);
132 e = UNSTUFF_BITS(resp, 112, 3);
133 csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
134 csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
135
136 m = UNSTUFF_BITS(resp, 99, 4);
137 e = UNSTUFF_BITS(resp, 96, 3);
138 csd->max_dtr = tran_exp[e] * tran_mant[m];
139 csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
140
141 e = UNSTUFF_BITS(resp, 47, 3);
142 m = UNSTUFF_BITS(resp, 62, 12);
143 csd->capacity = (1 + m) << (e + 2);
144
145 csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
146 csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
147 csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
148 csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
149 csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
150 csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
151 csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
152}
153
154/*
155 * Read and decode extended CSD. Switch to high-speed and wide bus
156 * if supported.
157 */
158static int mmc_process_ext_csd(struct mmc_card *card)
159{
160 int err;
161 u8 *ext_csd;
162
163 BUG_ON(!card);
164
165 err = MMC_ERR_FAILED;
166
167 if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
168 return MMC_ERR_NONE;
169
170 /*
171 * As the ext_csd is so large and mostly unused, we don't store the
172 * raw block in mmc_card.
173 */
174 ext_csd = kmalloc(512, GFP_KERNEL);
175 if (!ext_csd) {
176 printk(KERN_ERR "%s: could not allocate a buffer to "
177 "receive the ext_csd. mmc v4 cards will be "
178 "treated as v3.\n", mmc_hostname(card->host));
179 return MMC_ERR_FAILED;
180 }
181
182 err = mmc_send_ext_csd(card, ext_csd);
183 if (err != MMC_ERR_NONE) {
184 /*
185 * High capacity cards should have this "magic" size
186 * stored in their CSD.
187 */
188 if (card->csd.capacity == (4096 * 512)) {
189 printk(KERN_ERR "%s: unable to read EXT_CSD "
190 "on a possible high capacity card. "
191 "Card will be ignored.\n",
192 mmc_hostname(card->host));
193 } else {
194 printk(KERN_WARNING "%s: unable to read "
195 "EXT_CSD, performance might "
196 "suffer.\n",
197 mmc_hostname(card->host));
198 err = MMC_ERR_NONE;
199 }
200 goto out;
201 }
202
203 card->ext_csd.sectors =
204 ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
205 ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
206 ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
207 ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
208 if (card->ext_csd.sectors)
209 mmc_card_set_blockaddr(card);
210
211 switch (ext_csd[EXT_CSD_CARD_TYPE]) {
212 case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
213 card->ext_csd.hs_max_dtr = 52000000;
214 break;
215 case EXT_CSD_CARD_TYPE_26:
216 card->ext_csd.hs_max_dtr = 26000000;
217 break;
218 default:
219 /* MMC v4 spec says this cannot happen */
220 printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
221 "support any high-speed modes.\n",
222 mmc_hostname(card->host));
223 goto out;
224 }
225
226 if (card->host->caps & MMC_CAP_MMC_HIGHSPEED) {
227 /* Activate highspeed support. */
228 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
229 EXT_CSD_HS_TIMING, 1);
230 if (err != MMC_ERR_NONE) {
231 printk(KERN_WARNING "%s: failed to switch "
232 "card to mmc v4 high-speed mode.\n",
233 mmc_hostname(card->host));
234 err = MMC_ERR_NONE;
235 goto out;
236 }
237
238 mmc_card_set_highspeed(card);
239
240 mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
241 }
242
243 /* Check for host support for wide-bus modes. */
244 if (card->host->caps & MMC_CAP_4_BIT_DATA) {
245 /* Activate 4-bit support. */
246 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
247 EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
248 if (err != MMC_ERR_NONE) {
249 printk(KERN_WARNING "%s: failed to switch "
250 "card to mmc v4 4-bit bus mode.\n",
251 mmc_hostname(card->host));
252 err = MMC_ERR_NONE;
253 goto out;
254 }
255
256 mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
257 }
258
259out:
260 kfree(ext_csd);
261
262 return err;
263}
264
265/*
266 * Host is being removed. Free up the current card.
267 */
268static void mmc_remove(struct mmc_host *host)
269{
270 BUG_ON(!host);
271 BUG_ON(!host->card);
272
273 mmc_remove_card(host->card);
274 host->card = NULL;
275}
276
277/*
278 * Card detection callback from host.
279 */
280static void mmc_detect(struct mmc_host *host)
281{
282 int err;
283
284 BUG_ON(!host);
285 BUG_ON(!host->card);
286
287 mmc_claim_host(host);
288
289 /*
290 * Just check if our card has been removed.
291 */
292 err = mmc_send_status(host->card, NULL);
293
294 mmc_release_host(host);
295
296 if (err != MMC_ERR_NONE) {
297 mmc_remove_card(host->card);
298 host->card = NULL;
299
300 mmc_claim_host(host);
301 mmc_detach_bus(host);
302 mmc_release_host(host);
303 }
304}
305
306static const struct mmc_bus_ops mmc_ops = {
307 .remove = mmc_remove,
308 .detect = mmc_detect,
309};
310
311/*
312 * Starting point for MMC card init.
313 */
314int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
315{
316 struct mmc_card *card;
317 int err;
318 u32 cid[4];
319 unsigned int max_dtr;
320
321 BUG_ON(!host);
322 BUG_ON(!host->claimed);
323
324 mmc_attach_bus(host, &mmc_ops);
325
326 host->ocr = mmc_select_voltage(host, ocr);
327
328 /*
329 * Can we support the voltage of the card?
330 */
331 if (!host->ocr)
332 goto err;
333
334 /*
335 * Since we're changing the OCR value, we seem to
336 * need to tell some cards to go back to the idle
337 * state. We wait 1ms to give cards time to
338 * respond.
339 */
340 mmc_go_idle(host);
341
342 /* The extra bit indicates that we support high capacity */
343 mmc_send_op_cond(host, host->ocr | (1 << 30), NULL);
344
345 /*
346 * Fetch CID from card.
347 */
348 err = mmc_all_send_cid(host, cid);
349 if (err != MMC_ERR_NONE)
350 goto err;
351
352 /*
353 * Allocate card structure.
354 */
355 card = mmc_alloc_card(host);
356 if (IS_ERR(card))
357 goto err;
358
359 card->type = MMC_TYPE_MMC;
360 card->rca = 1;
361 memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
362
363 /*
364 * Set card RCA.
365 */
366 err = mmc_set_relative_addr(card);
367 if (err != MMC_ERR_NONE)
368 goto free_card;
369
370 mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
371
372 /*
373 * Fetch CSD from card.
374 */
375 err = mmc_send_csd(card, card->raw_csd);
376 if (err != MMC_ERR_NONE)
377 goto free_card;
378
379 mmc_decode_csd(card);
380 mmc_decode_cid(card);
381
382 /*
383 * Fetch and process extened CSD.
384 * This will switch into high-speed and wide bus modes,
385 * as available.
386 */
387 err = mmc_select_card(card);
388 if (err != MMC_ERR_NONE)
389 goto free_card;
390
391 err = mmc_process_ext_csd(card);
392 if (err != MMC_ERR_NONE)
393 goto free_card;
394
395 /*
396 * Compute bus speed.
397 */
398 max_dtr = (unsigned int)-1;
399
400 if (mmc_card_highspeed(card)) {
401 if (max_dtr > card->ext_csd.hs_max_dtr)
402 max_dtr = card->ext_csd.hs_max_dtr;
403 } else if (max_dtr > card->csd.max_dtr) {
404 max_dtr = card->csd.max_dtr;
405 }
406
407 mmc_set_clock(host, max_dtr);
408
409 host->card = card;
410
411 mmc_release_host(host);
412
413 err = mmc_register_card(card);
414 if (err)
415 goto reclaim_host;
416
417 return 0;
418
419reclaim_host:
420 mmc_claim_host(host);
421free_card:
422 mmc_remove_card(card);
423 host->card = NULL;
424err:
425 mmc_detach_bus(host);
426 mmc_release_host(host);
427
428 return 0;
429}
430