This source file includes following definitions.
- sdmmc_mem_enable
- sdmmc_mem_scan
- sdmmc_decode_csd
- sdmmc_decode_cid
- sdmmc_print_cid
- sdmmc_mem_init
- sdmmc_mem_send_op_cond
- sdmmc_mem_set_blocklen
- sdmmc_mem_read_block
- sdmmc_mem_write_block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <sys/param.h>
22 #include <sys/kernel.h>
23 #include <sys/malloc.h>
24 #include <sys/systm.h>
25
26 #include <dev/sdmmc/sdmmcchip.h>
27 #include <dev/sdmmc/sdmmcreg.h>
28 #include <dev/sdmmc/sdmmcvar.h>
29
30 int sdmmc_decode_csd(struct sdmmc_softc *, sdmmc_response,
31 struct sdmmc_function *);
32 int sdmmc_decode_cid(struct sdmmc_softc *, sdmmc_response,
33 struct sdmmc_function *);
34 void sdmmc_print_cid(struct sdmmc_cid *);
35
36 int sdmmc_mem_send_op_cond(struct sdmmc_softc *, u_int32_t, u_int32_t *);
37 int sdmmc_mem_set_blocklen(struct sdmmc_softc *, struct sdmmc_function *);
38
39 #ifdef SDMMC_DEBUG
40 #define DPRINTF(s) printf s
41 #else
42 #define DPRINTF(s)
43 #endif
44
45
46
47
48 int
49 sdmmc_mem_enable(struct sdmmc_softc *sc)
50 {
51 u_int32_t host_ocr;
52 u_int32_t card_ocr;
53
54
55 SET(sc->sc_flags, SMF_SD_MODE|SMF_MEM_MODE);
56
57
58 sdmmc_go_idle_state(sc);
59
60
61
62
63
64
65
66 mmc_mode:
67 if (sdmmc_mem_send_op_cond(sc, 0, &card_ocr) != 0) {
68 if (ISSET(sc->sc_flags, SMF_SD_MODE) &&
69 !ISSET(sc->sc_flags, SMF_IO_MODE)) {
70
71 CLR(sc->sc_flags, SMF_SD_MODE);
72 goto mmc_mode;
73 }
74 if (!ISSET(sc->sc_flags, SMF_SD_MODE)) {
75 DPRINTF(("%s: can't read memory OCR\n",
76 SDMMCDEVNAME(sc)));
77 return 1;
78 } else {
79
80 CLR(sc->sc_flags, SMF_MEM_MODE);
81 return 0;
82 }
83 }
84
85
86 host_ocr = sdmmc_chip_host_ocr(sc->sct, sc->sch);
87 if (sdmmc_set_bus_power(sc, host_ocr, card_ocr) != 0) {
88 DPRINTF(("%s: can't supply voltage requested by card\n",
89 SDMMCDEVNAME(sc)));
90 return 1;
91 }
92
93
94 sdmmc_go_idle_state(sc);
95
96
97 if (sdmmc_mem_send_op_cond(sc, host_ocr, NULL) != 0) {
98 DPRINTF(("%s: can't send memory OCR\n", SDMMCDEVNAME(sc)));
99 return 1;
100 }
101 return 0;
102 }
103
104
105
106
107
108 void
109 sdmmc_mem_scan(struct sdmmc_softc *sc)
110 {
111 struct sdmmc_command cmd;
112 struct sdmmc_function *sf;
113 u_int16_t next_rca;
114 int error;
115 int i;
116
117
118
119
120
121
122
123
124 for (i = 0; i < 100; i++) {
125 bzero(&cmd, sizeof cmd);
126 cmd.c_opcode = MMC_ALL_SEND_CID;
127 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R2;
128
129 error = sdmmc_mmc_command(sc, &cmd);
130 if (error == ETIMEDOUT) {
131
132 break;
133 } else if (error != 0) {
134 DPRINTF(("%s: can't read CID\n", SDMMCDEVNAME(sc)));
135 break;
136 }
137
138
139 next_rca = 1;
140 if (!ISSET(sc->sc_flags, SMF_SD_MODE))
141 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list)
142 next_rca++;
143
144
145 sf = sdmmc_function_alloc(sc);
146 sf->rca = next_rca;
147
148
149
150
151
152 bcopy(cmd.c_resp, sf->raw_cid, sizeof sf->raw_cid);
153
154
155
156
157
158 if (sdmmc_set_relative_addr(sc, sf) != 0) {
159 printf("%s: can't set mem RCA\n", SDMMCDEVNAME(sc));
160 sdmmc_function_free(sf);
161 break;
162 }
163
164 #if 0
165
166 if (sdmmc_select_card(sc, sf) != 0) {
167 printf("%s: can't select mem RCA %d\n",
168 SDMMCDEVNAME(sc), sf->rca);
169 sdmmc_function_free(sf);
170 break;
171 }
172
173
174 (void)sdmmc_select_card(sc, NULL);
175 #endif
176
177
178
179
180
181 if (sc->sc_fn0 == NULL)
182 sc->sc_fn0 = sf;
183
184 SIMPLEQ_INSERT_TAIL(&sc->sf_head, sf, sf_list);
185 }
186
187
188
189
190
191 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
192 bzero(&cmd, sizeof cmd);
193 cmd.c_opcode = MMC_SEND_CSD;
194 cmd.c_arg = MMC_ARG_RCA(sf->rca);
195 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R2;
196
197 if (sdmmc_mmc_command(sc, &cmd) != 0) {
198 SET(sf->flags, SFF_ERROR);
199 continue;
200 }
201
202 if (sdmmc_decode_csd(sc, cmd.c_resp, sf) != 0 ||
203 sdmmc_decode_cid(sc, sf->raw_cid, sf) != 0) {
204 SET(sf->flags, SFF_ERROR);
205 continue;
206 }
207
208 #ifdef SDMMC_DEBUG
209 printf("%s: CID: ", SDMMCDEVNAME(sc));
210 sdmmc_print_cid(&sf->cid);
211 #endif
212 }
213 }
214
215 int
216 sdmmc_decode_csd(struct sdmmc_softc *sc, sdmmc_response resp,
217 struct sdmmc_function *sf)
218 {
219 struct sdmmc_csd *csd = &sf->csd;
220
221 if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
222
223
224
225
226 csd->csdver = SD_CSD_CSDVER(resp);
227 if (csd->csdver != SD_CSD_CSDVER_1_0) {
228 printf("%s: unknown SD CSD structure version 0x%x\n",
229 SDMMCDEVNAME(sc), csd->csdver);
230 return 1;
231 }
232
233 csd->capacity = SD_CSD_CAPACITY(resp);
234 csd->read_bl_len = SD_CSD_READ_BL_LEN(resp);
235 } else {
236 csd->csdver = MMC_CSD_CSDVER(resp);
237 if (csd->csdver != MMC_CSD_CSDVER_1_0 &&
238 csd->csdver != MMC_CSD_CSDVER_2_0) {
239 printf("%s: unknown MMC CSD structure version 0x%x\n",
240 SDMMCDEVNAME(sc), csd->csdver);
241 return 1;
242 }
243
244 csd->mmcver = MMC_CSD_MMCVER(resp);
245 csd->capacity = MMC_CSD_CAPACITY(resp);
246 csd->read_bl_len = MMC_CSD_READ_BL_LEN(resp);
247 }
248 csd->sector_size = MIN(1 << csd->read_bl_len,
249 sdmmc_chip_host_maxblklen(sc->sct, sc->sch));
250 if (csd->sector_size < (1<<csd->read_bl_len))
251 csd->capacity *= (1<<csd->read_bl_len) /
252 csd->sector_size;
253
254 return 0;
255 }
256
257 int
258 sdmmc_decode_cid(struct sdmmc_softc *sc, sdmmc_response resp,
259 struct sdmmc_function *sf)
260 {
261 struct sdmmc_cid *cid = &sf->cid;
262
263 if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
264 cid->mid = SD_CID_MID(resp);
265 cid->oid = SD_CID_OID(resp);
266 SD_CID_PNM_CPY(resp, cid->pnm);
267 cid->rev = SD_CID_REV(resp);
268 cid->psn = SD_CID_PSN(resp);
269 cid->mdt = SD_CID_MDT(resp);
270 } else {
271 switch(sf->csd.mmcver) {
272 case MMC_CSD_MMCVER_1_0:
273 case MMC_CSD_MMCVER_1_4:
274 cid->mid = MMC_CID_MID_V1(resp);
275 MMC_CID_PNM_V1_CPY(resp, cid->pnm);
276 cid->rev = MMC_CID_REV_V1(resp);
277 cid->psn = MMC_CID_PSN_V1(resp);
278 cid->mdt = MMC_CID_MDT_V1(resp);
279 break;
280 case MMC_CSD_MMCVER_2_0:
281 case MMC_CSD_MMCVER_3_1:
282 case MMC_CSD_MMCVER_4_0:
283 cid->mid = MMC_CID_MID_V2(resp);
284 cid->oid = MMC_CID_OID_V2(resp);
285 MMC_CID_PNM_V2_CPY(resp, cid->pnm);
286 cid->psn = MMC_CID_PSN_V2(resp);
287 break;
288 default:
289 printf("%s: unknown MMC version %d\n",
290 SDMMCDEVNAME(sc), sf->csd.mmcver);
291 return 1;
292 }
293 }
294 return 0;
295 }
296
297 #ifdef SDMMC_DEBUG
298 void
299 sdmmc_print_cid(struct sdmmc_cid *cid)
300 {
301 printf("mid=0x%02x oid=0x%04x pnm=\"%s\" rev=0x%02x psn=0x%08x"
302 " mdt=%03x\n", cid->mid, cid->oid, cid->pnm, cid->rev, cid->psn,
303 cid->mdt);
304 }
305 #endif
306
307
308
309
310 int
311 sdmmc_mem_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
312 {
313 int error = 0;
314
315 SDMMC_LOCK(sc);
316 if (sdmmc_select_card(sc, sf) != 0 ||
317 sdmmc_mem_set_blocklen(sc, sf) != 0)
318 error = 1;
319 SDMMC_UNLOCK(sc);
320 return error;
321 }
322
323
324
325
326 int
327 sdmmc_mem_send_op_cond(struct sdmmc_softc *sc, u_int32_t ocr,
328 u_int32_t *ocrp)
329 {
330 struct sdmmc_command cmd;
331 int error;
332 int i;
333
334 SDMMC_LOCK(sc);
335
336
337
338
339
340
341 for (i = 0; i < 100; i++) {
342 bzero(&cmd, sizeof cmd);
343 cmd.c_arg = ocr;
344 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R3;
345
346 if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
347 cmd.c_opcode = SD_APP_OP_COND;
348 error = sdmmc_app_command(sc, &cmd);
349 } else {
350 cmd.c_opcode = MMC_SEND_OP_COND;
351 error = sdmmc_mmc_command(sc, &cmd);
352 }
353 if (error != 0)
354 break;
355 if (ISSET(MMC_R3(cmd.c_resp), MMC_OCR_MEM_READY) ||
356 ocr == 0)
357 break;
358 error = ETIMEDOUT;
359 sdmmc_delay(10000);
360 }
361 if (error == 0 && ocrp != NULL)
362 *ocrp = MMC_R3(cmd.c_resp);
363
364 SDMMC_UNLOCK(sc);
365 return error;
366 }
367
368
369
370
371
372 int
373 sdmmc_mem_set_blocklen(struct sdmmc_softc *sc, struct sdmmc_function *sf)
374 {
375 struct sdmmc_command cmd;
376
377 bzero(&cmd, sizeof cmd);
378 cmd.c_opcode = MMC_SET_BLOCKLEN;
379 cmd.c_arg = sf->csd.sector_size;
380 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
381 DPRINTF(("%s: read_bl_len=%d sector_size=%d\n", SDMMCDEVNAME(sc),
382 1 << sf->csd.read_bl_len, sf->csd.sector_size));
383
384 return sdmmc_mmc_command(sc, &cmd);
385 }
386
387 int
388 sdmmc_mem_read_block(struct sdmmc_function *sf, int blkno, u_char *data,
389 size_t datalen)
390 {
391 struct sdmmc_softc *sc = sf->sc;
392 struct sdmmc_command cmd;
393 int error;
394
395 SDMMC_LOCK(sc);
396
397 if ((error = sdmmc_select_card(sc, sf)) != 0)
398 goto err;
399
400 bzero(&cmd, sizeof cmd);
401 cmd.c_data = data;
402 cmd.c_datalen = datalen;
403 cmd.c_blklen = sf->csd.sector_size;
404 cmd.c_opcode = (datalen / cmd.c_blklen) > 1 ?
405 MMC_READ_BLOCK_MULTIPLE : MMC_READ_BLOCK_SINGLE;
406 cmd.c_arg = blkno << 9;
407 cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1;
408
409 error = sdmmc_mmc_command(sc, &cmd);
410 if (error != 0)
411 goto err;
412
413
414 #ifdef __zaurus__
415 if (cmd.c_opcode == MMC_READ_BLOCK_MULTIPLE) {
416 bzero(&cmd, sizeof cmd);
417 cmd.c_opcode = MMC_STOP_TRANSMISSION;
418 cmd.c_arg = MMC_ARG_RCA(sf->rca);
419 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B;
420 error = sdmmc_mmc_command(sc, &cmd);
421 if (error != 0)
422 goto err;
423 }
424 #endif
425
426 do {
427 bzero(&cmd, sizeof cmd);
428 cmd.c_opcode = MMC_SEND_STATUS;
429 cmd.c_arg = MMC_ARG_RCA(sf->rca);
430 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
431 error = sdmmc_mmc_command(sc, &cmd);
432 if (error != 0)
433 break;
434
435 } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA));
436
437 err:
438 SDMMC_UNLOCK(sc);
439 return error;
440 }
441
442 int
443 sdmmc_mem_write_block(struct sdmmc_function *sf, int blkno, u_char *data,
444 size_t datalen)
445 {
446 struct sdmmc_softc *sc = sf->sc;
447 struct sdmmc_command cmd;
448 int error;
449
450 SDMMC_LOCK(sc);
451
452 if ((error = sdmmc_select_card(sc, sf)) != 0)
453 goto err;
454
455 bzero(&cmd, sizeof cmd);
456 cmd.c_data = data;
457 cmd.c_datalen = datalen;
458 cmd.c_blklen = sf->csd.sector_size;
459 cmd.c_opcode = (datalen / cmd.c_blklen) > 1 ?
460 MMC_WRITE_BLOCK_MULTIPLE : MMC_WRITE_BLOCK_SINGLE;
461 cmd.c_arg = blkno << 9;
462 cmd.c_flags = SCF_CMD_ADTC | SCF_RSP_R1;
463
464 error = sdmmc_mmc_command(sc, &cmd);
465 if (error != 0)
466 goto err;
467
468
469 #ifdef __zaurus__
470 if (cmd.c_opcode == MMC_WRITE_BLOCK_MULTIPLE) {
471 bzero(&cmd, sizeof cmd);
472 cmd.c_opcode = MMC_STOP_TRANSMISSION;
473 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B;
474 error = sdmmc_mmc_command(sc, &cmd);
475 if (error != 0)
476 goto err;
477 }
478 #endif
479
480 do {
481 bzero(&cmd, sizeof cmd);
482 cmd.c_opcode = MMC_SEND_STATUS;
483 cmd.c_arg = MMC_ARG_RCA(sf->rca);
484 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
485 error = sdmmc_mmc_command(sc, &cmd);
486 if (error != 0)
487 break;
488
489 } while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA));
490
491 err:
492 SDMMC_UNLOCK(sc);
493 return error;
494 }