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