1 /*
2  * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define SDMMC_FREQ_DEFAULT   20000 /*!< SD/MMC Default speed (limited by clock divider) */
8 #define SDMMC_FREQ_HIGHSPEED 40000 /*!< SD High speed (limited by clock divider) */
9 #define SDMMC_FREQ_PROBING   400   /*!< SD/MMC probing speed */
10 #define SDMMC_FREQ_52M       52000 /*!< MMC 52MHz speed */
11 #define SDMMC_FREQ_26M       26000 /*!< MMC 26MHz speed */
12 
13 #define SDMMC_DATA_ERR_MASK                                                                        \
14 	(uint32_t)(SDMMC_INTMASK_DTO | SDMMC_INTMASK_DCRC | SDMMC_INTMASK_HTO |                    \
15 		   SDMMC_INTMASK_SBE | SDMMC_INTMASK_EBE)
16 
17 #define SDMMC_DMA_DONE_MASK                                                                        \
18 	(uint32_t)(SDMMC_IDMAC_INTMASK_RI | SDMMC_IDMAC_INTMASK_TI | SDMMC_IDMAC_INTMASK_NI)
19 
20 #define SDMMC_CMD_ERR_MASK                                                                         \
21 	(uint32_t)(SDMMC_INTMASK_RTO | SDMMC_INTMASK_RCRC | SDMMC_INTMASK_RESP_ERR)
22 
23 enum sdmmc_req_state {
24 	SDMMC_IDLE,
25 	SDMMC_SENDING_CMD,
26 	SDMMC_SENDING_DATA,
27 	SDMMC_BUSY,
28 };
29 
30 /* SDHC command flags */
31 #define SCF_ITSDONE     0x0001 /*!< command is complete */
32 #define SCF_CMD(flags)  ((flags) & 0x00f0)
33 #define SCF_CMD_AC      0x0000
34 #define SCF_CMD_ADTC    0x0010
35 #define SCF_CMD_BC      0x0020
36 #define SCF_CMD_BCR     0x0030
37 #define SCF_CMD_READ    0x0040 /*!< read command (data expected) */
38 #define SCF_RSP_BSY     0x0100
39 #define SCF_RSP_136     0x0200
40 #define SCF_RSP_CRC     0x0400
41 #define SCF_RSP_IDX     0x0800
42 #define SCF_RSP_PRESENT 0x1000
43 /* response types */
44 #define SCF_RSP_R0      0 /*!< none */
45 #define SCF_RSP_R1      (SCF_RSP_PRESENT | SCF_RSP_CRC | SCF_RSP_IDX)
46 #define SCF_RSP_R1B     (SCF_RSP_PRESENT | SCF_RSP_CRC | SCF_RSP_IDX | SCF_RSP_BSY)
47 #define SCF_RSP_R2      (SCF_RSP_PRESENT | SCF_RSP_CRC | SCF_RSP_136)
48 #define SCF_RSP_R3      (SCF_RSP_PRESENT)
49 #define SCF_RSP_R4      (SCF_RSP_PRESENT)
50 #define SCF_RSP_R5      (SCF_RSP_PRESENT | SCF_RSP_CRC | SCF_RSP_IDX)
51 #define SCF_RSP_R5B     (SCF_RSP_PRESENT | SCF_RSP_CRC | SCF_RSP_IDX | SCF_RSP_BSY)
52 #define SCF_RSP_R6      (SCF_RSP_PRESENT | SCF_RSP_CRC | SCF_RSP_IDX)
53 #define SCF_RSP_R7      (SCF_RSP_PRESENT | SCF_RSP_CRC | SCF_RSP_IDX)
54 /* special flags */
55 #define SCF_WAIT_BUSY   0x2000 /*!< Wait for completion of card busy signal before returning */
56 
57 #define SD_OCR_SDHC_CAP (1 << 30)
58 #define SD_OCR_VOL_MASK 0xFF8000 /* bits 23:15 */
59 
60 /* For debug only */
61 static const char *const timingStr[] = {"UNKNOWN", "LEGACY", "HS",    "SDR12", "SDR25", "SDR50",
62 					"SDR104",  "DDR50",  "DDR52", "HS200", "HS400"};
63 
64 struct sdmmc_transfer_state {
65 	uint8_t *ptr;
66 	size_t size_remaining;
67 	size_t next_desc;
68 	size_t desc_remaining;
69 };
70 
71 struct sdmmc_event {
72 	uint32_t header_DUMMY; /* Reserved for system use (Zephyr message queue) */
73 	uint32_t sdmmc_status; /* masked SDMMC interrupt status */
74 	uint32_t dma_status;   /* masked DMA interrupt status */
75 };
76 
77 /**
78  * Host contexts
79  */
80 struct host_ctx {
81 	intr_handle_t intr_handle;
82 	struct k_msgq *event_queue;
83 };
84 
85 /**
86  * SD/MMC command information
87  */
88 struct sdmmc_command {
89 	uint32_t opcode;      /*!< SD or MMC command index */
90 	uint32_t arg;         /*!< SD/MMC command argument */
91 	uint32_t response[4]; /*!< response buffer */
92 	void *data;           /*!< buffer to send or read into */
93 	size_t datalen;       /*!< length of data in the buffer */
94 	size_t buflen;        /*!< length of the buffer */
95 	size_t blklen;        /*!< block length */
96 	int flags;            /*!< see below */
97 	esp_err_t error;      /*!< error returned from transfer */
98 	uint32_t timeout_ms;  /*!< response timeout, in milliseconds */
99 };
100 
101 /**
102  * @brief Convert ESP to Zephyr error codes
103  *
104  * @param ret_esp ESP return value
105  *
106  * @return Zephyr error code
107  */
err_esp2zep(int ret_esp)108 static __attribute__((always_inline)) inline int err_esp2zep(int ret_esp)
109 {
110 	int ret;
111 
112 	switch (ret_esp) {
113 	/* Treating the error codes most relevant to be individuated */
114 	case ESP_ERR_INVALID_ARG:
115 		ret = -EINVAL;
116 		break;
117 	case ESP_ERR_TIMEOUT:
118 		ret = -ETIMEDOUT;
119 		break;
120 	case ESP_ERR_NOT_FOUND:
121 		ret = -ENODEV; /* SD card not inserted (requires CD signal) */
122 		break;
123 	case ESP_ERR_INVALID_STATE:
124 		ret = -EACCES; /* SD card write-protected (requires WP sinal) */
125 		break;
126 	default:
127 		ret = -EIO;
128 		break;
129 	}
130 
131 	return ret;
132 }
133