1 /*
2 * Copyright 2022 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/zephyr.h>
8 #include <zephyr/drivers/sdhc.h>
9 #include <zephyr/sd/sd.h>
10 #include <zephyr/sd/sdmmc.h>
11 #include <zephyr/sd/sd_spec.h>
12 #include <zephyr/logging/log.h>
13
14 #include "sd_utils.h"
15
16 LOG_MODULE_DECLARE(sd, CONFIG_SD_LOG_LEVEL);
17
18 /*
19 * Send SDIO OCR using CMD5
20 */
sdio_send_ocr(struct sd_card * card,uint32_t ocr)21 int sdio_send_ocr(struct sd_card *card, uint32_t ocr)
22 {
23 struct sdhc_command cmd = {0};
24 int ret;
25 int retries;
26
27 cmd.opcode = SDIO_SEND_OP_COND;
28 cmd.arg = ocr;
29 cmd.response_type = (SD_RSP_TYPE_R4 | SD_SPI_RSP_TYPE_R4);
30 cmd.timeout_ms = CONFIG_SD_CMD_TIMEOUT;
31 /* Send OCR5 to initialize card */
32 for (retries = 0; retries < CONFIG_SD_OCR_RETRY_COUNT; retries++) {
33 ret = sdhc_request(card->sdhc, &cmd, NULL);
34 if (ret) {
35 if (ocr == 0) {
36 /* Just probing card, likely not SDIO */
37 return SD_NOT_SDIO;
38 }
39 return ret;
40 }
41 if (ocr == 0) {
42 /* We are probing card, check number of IO functions */
43 card->num_io = (cmd.response[0] & SDIO_OCR_IO_NUMBER)
44 >> SDIO_OCR_IO_NUMBER_SHIFT;
45 if ((card->num_io == 0) ||
46 ((cmd.response[0] & SDIO_IO_OCR_MASK) == 0)) {
47 if (cmd.response[0] & SDIO_OCR_MEM_PRESENT_FLAG) {
48 /* Card is not an SDIO card */
49 return SD_NOT_SDIO;
50 }
51 /* Card is not a supported SD device */
52 return -ENOTSUP;
53 }
54 /* Card has IO present, return zero to
55 * indicate SDIO card
56 */
57 return 0;
58 }
59 }
60 }
61
62 /*
63 * Initialize an SDIO card for use with subsystem
64 */
sdio_card_init(struct sd_card * card)65 int sdio_card_init(struct sd_card *card)
66 {
67 int ret;
68
69 /* Probe card with SDIO OCR CM5 */
70 ret = sdio_send_ocr(card, 0);
71 if (ret) {
72 return ret;
73 }
74 /* Card responded to ACMD41, type is SDIO */
75 card->type = CARD_SDIO;
76 /* No support for SDIO */
77 return -ENOTSUP;
78 }
79