1 #include "ameba_soc.h"
2 
3 SDIOH_InitTypeDef sdioh_init_para;
4 
5 /**
6   * @brief  Check SDIOH is busy or not.
7   * @param  None
8   * @retval SDIOH busy status value:
9   *           - HAL_BUSY: Busy
10   *           - HAL_OK: Not Busy
11   */
SDIOH_Busy(void)12 u32 SDIOH_Busy(void)
13 {
14 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
15 	u8 idle_level = sdioh_init_para.SDIOH_idle_level;
16 
17 	/* check the SD bus status */
18 	if((psdioh->SD_BUS_STATUS & idle_level) == idle_level) {
19 		/* check the CMD & DATA state machine */
20 		if((psdioh->SD_CMD_STATE & SDIOH_CMD_FSM_IDLE) && (psdioh->SD_DATA_STATE & SDIOH_DATA_FSM_IDLE)) {
21 			/* check the SD card module state machine */
22 			if((psdioh->SD_TRANSFER & SDIOH_SD_MODULE_FSM_IDLE)) {
23 				return HAL_OK;
24 			} else {
25 				DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "SD card module state machine isn't in the idle state !\r\n");
26 				return HAL_BUSY;
27 			}
28 		} else {
29 			DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "CMD or DATA state machine isn't in the idle state !!\r\n");
30 			return HAL_BUSY;
31 		}
32 	} else {
33 		DBG_PRINTF(MODULE_SDIO, LEVEL_INFO, "CMD or DAT[3:0] pin isn't in the idle state !!\r\n");
34 		return HAL_BUSY;
35 	}
36 }
37 
38 /**
39   * @brief  Check if some error occurs when SDIOH transfer.
40   * @param  status: pointer to word which is used to save error status.
41   * @retval SDIOH status:
42   *           - HAL_ERR_UNKNOWN: Some error occurs when transfer, detailed error information
43   *				can be found in status parameter.
44   *           - HAL_OK: No error occurs when transfer.
45   */
SDIOH_CheckTxError(u16 * status)46 u32 SDIOH_CheckTxError(u16 *status)
47 {
48 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
49 
50 	if(psdioh->SD_TRANSFER & SDIOH_ERR_OCCUR) {
51 		if(status != NULL)
52 			*status = psdioh->SD_STATUS1 | (psdioh->SD_STATUS2 << 8);
53 
54 		return HAL_ERR_UNKNOWN;
55 	} else
56 		return HAL_OK;
57 }
58 
59 /**
60   * @brief  Wait some time for SDIOH tx done.
61   * @param  timeout_us: timeout value in microseconds.
62   * @retval SDIOH tx status value:
63   *           - HAL_TIMEOUT: SDIOH tx timeout.
64   *           - HAL_OK: SDIOH tx done within a specified time.
65   */
SDIOH_WaitTxDone(u32 timeout_us)66 u32 SDIOH_WaitTxDone(u32 timeout_us)
67 {
68 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
69 	u32 tmp;
70 
71 	do {
72 		tmp = psdioh->SD_TRANSFER & (SDIOH_TRANSFER_END | SDIOH_SD_MODULE_FSM_IDLE);
73 		if(tmp == (SDIOH_TRANSFER_END | SDIOH_SD_MODULE_FSM_IDLE))
74 			return HAL_OK;
75 
76 		DelayUs(1);
77 	} while (timeout_us-- != 0);
78 
79 	return HAL_TIMEOUT;
80 }
81 
82 /**
83   * @brief  Wait some time for SDIOH DMA done.
84   * @param  timeout_us: timeout value in microseconds.
85   * @retval SDIOH dma status:
86   *           - HAL_TIMEOUT: SDIOH DMA timeout.
87   *           - HAL_OK: SDIOH DMA done within a specified time.
88   */
SDIOH_WaitDMADone(u32 timeout_us)89 u32 SDIOH_WaitDMADone(u32 timeout_us)
90 {
91 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
92 
93 	do {
94 		if((psdioh->SD_TRANSFER & SDIOH_TRANSFER_END) && (!(psdioh->DMA_CRL3 & SDIOH_DMA_XFER))) {
95 			SDIOH_DMAReset();
96 			return HAL_OK;
97 		}
98 
99 		DelayUs(1);
100 	} while (timeout_us-- != 0);
101 
102 	return HAL_TIMEOUT;
103 }
104 
105 /**
106   * @brief  Get SDIOH interrupt status.
107   * @param  timeout_us: None.
108   * @retval SDIOH interrupt status.
109   */
SDIOH_GetISR(void)110 u32 SDIOH_GetISR(void)
111 {
112 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
113 
114 	return psdioh->SD_ISR;
115 }
116 
117 /**
118   * @brief  SDIOH interrupt configure.
119   * @param  SDIO_IT: SDIOH interrupt source, which can be one or combination of the following values:
120   * 		@arg SDIOH_DMA_CTL_INT_EN
121   * 		@arg SDIOH_CARD_ERR_INT_EN
122   * 		@arg SDIOH_CARD_END_INT_EN
123   * @param newState: can be ENABLE or Disable
124   * @retval None.
125   */
SDIOH_INTConfig(u8 SDIO_IT,u32 newState)126 void SDIOH_INTConfig(u8 SDIO_IT, u32 newState)
127 {
128 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
129 
130 	if(newState == ENABLE)
131 		psdioh->SD_ISREN |= SDIO_IT;
132 	else
133 		psdioh->SD_ISREN &= ~SDIO_IT;
134 }
135 
136 /**
137   * @brief  Clear SDIOH pending interrupt status.
138   * @param  SDIO_IT: SDIOH interrupt pending bit, which can be one or combination of the following values:
139   * 		@arg SDIOH_DMA_TRANSFER_DONE
140   * 		@arg SDIOH_CARD_ERROR
141   * 		@arg SDIOH_CARD_END
142   * @retval None.
143   */
SDIOH_INTClearPendingBit(u8 SDIO_IT)144 void SDIOH_INTClearPendingBit(u8 SDIO_IT)
145 {
146 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
147 
148 	psdioh->SD_ISR = SDIO_IT;
149 }
150 
151 /**
152   * @brief  Check if SDIOH bus switch to a specified state in some time.
153   * @param  status: SDIOH bus state, which can be 0 or 1:
154   * 		@arg 0: bus switch to low level
155   * 		@arg 1: bus switch to high level
156   * @param  timeout_us: timeout value in microseconds.
157   * @retval None.
158   */
SDIOH_CheckBusState(u8 status,u32 timeout_us)159 u32 SDIOH_CheckBusState(u8 status, u32 timeout_us)
160 {
161 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
162 	u8 idle_level = sdioh_init_para.SDIOH_idle_level;
163 	u32 tmp;
164 
165 	do {
166 		tmp = psdioh->SD_BUS_STATUS & idle_level;
167 		if(status) {
168 			if(tmp == idle_level)
169 				return HAL_OK;
170 		} else {
171 			if(tmp == 0)
172 				return HAL_OK;
173 		}
174 
175 		DelayUs(1);
176 	} while (timeout_us-- != 0);
177 
178 	return HAL_TIMEOUT;
179 }
180 
181 /**
182   * @brief  Get SDIOH bus width.
183   * @param  None.
184   * @retval Bus width: 0 or 1:
185   *		0: 1-bit bus
186   *		1: 4-bit bus
187   */
SDIOH_GetBusWidth(void)188 u8 SDIOH_GetBusWidth(void)
189 {
190 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
191 
192 	return psdioh->SD_CONFIG1 & SDIOH_MASK_BUS_WIDTH;
193 }
194 
195 /**
196   * @brief  Set SDIOH bus width.
197   * @param  width: can be SDIOH_BUS_WIDTH_1BIT or SDIOH_BUS_WIDTH_4BIT.
198   * @retval None
199   */
SDIOH_SetBusWidth(u8 width)200 void SDIOH_SetBusWidth(u8 width)
201 {
202 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
203 	u8 tmp;
204 
205 	tmp = psdioh->SD_CONFIG1;
206 	tmp &= ~SDIOH_MASK_BUS_WIDTH;
207 	tmp |= (width & SDIOH_MASK_BUS_WIDTH);
208 
209 	psdioh->SD_CONFIG1 = tmp;
210 }
211 
212 /**
213   * @brief  Set SDIOH DMA configuration.
214   * @param  dma_ctl: pointer to a SDIOH_DmaCtl structure which keep the dma parameters.
215   * @retval None
216   */
SDIOH_DMAConfig(SDIOH_DmaCtl * dma_ctl)217 void SDIOH_DMAConfig(SDIOH_DmaCtl *dma_ctl)
218 {
219 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
220 	u32 tmp= 0;
221 
222 	/* set block length and count */
223 	if((dma_ctl->type) == SDIOH_DMA_NORMAL) {
224 		/* 512 bytes (one block size) */
225 		psdioh->SD_BYTE_CNT_L = 0;
226 		psdioh->SD_BYTE_CNT_H = 2;
227 	} else {
228 		/* 64 bytes( CMD6, R2 response...) */
229 		psdioh->SD_BYTE_CNT_L = SDIOH_C6R2_BUF_LEN;
230 		psdioh->SD_BYTE_CNT_H = 0;
231 	}
232 	psdioh->SD_BLOCK_CNT_L = (dma_ctl->blk_cnt) & SDIOH_MASK_BLOCL_CNT_L;
233 	psdioh->SD_BLOCK_CNT_H = ((dma_ctl->blk_cnt) >> 8) & SDIOH_MASK_BLOCL_CNT_H;
234 
235 	/* set the DMA control register */
236 	psdioh->DMA_CRL1 = (dma_ctl->start_addr) & SDIOH_MASK_DRAM_SA;	/* DMA start address (unit: 8 Bytes) */
237 	psdioh->DMA_CRL2 = (dma_ctl->blk_cnt) & SDIOH_MASK_DMA_LEN;		/* DMA transfer length (unit: 512 Bytes) */
238 
239 	if((dma_ctl->type) == SDIOH_DMA_64B)
240 		tmp = SDIOH_DAT64_SEL;
241 	else if((dma_ctl->type) == SDIOH_DMA_R2)
242 		tmp = SDIOH_RSP17_SEL;
243 
244 	tmp |= (dma_ctl->op << SDIOH_SHIFT_DDR_WR);
245 	psdioh->DMA_CRL3 = tmp;
246 
247 	/* clear pending interrupt */
248 	SDIOH_INTClearPendingBit(SDIOH_DMA_TRANSFER_DONE | SDIOH_CARD_ERROR |SDIOH_CARD_END);
249 
250 	/* enable DMA transfer */
251 	tmp = psdioh->DMA_CRL3;
252 	tmp |= SDIOH_DMA_XFER;
253 	psdioh->DMA_CRL3 = tmp;
254 }
255 
256 /**
257   * @brief  Reset SDIOH DMA configuration.
258   * @param  None.
259   * @retval None
260   */
SDIOH_DMAReset(void)261 void SDIOH_DMAReset(void)
262 {
263 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
264 
265 	psdioh->SD_BYTE_CNT_L = 0;
266 	psdioh->SD_BYTE_CNT_H = 0;
267 	psdioh->SD_BLOCK_CNT_L = 0;
268 	psdioh->SD_BLOCK_CNT_H = 0;
269 	psdioh->DMA_CRL1 = 0;
270 	psdioh->DMA_CRL2 = 0;
271 	psdioh->DMA_CRL3 = 0;
272 }
273 
274 /**
275   * @brief  SDIOH send command to card.
276   * @param  cmd_attrib: pointer to a SDIOH_CmdTypeDef structure which keeps the command attributes.
277   * @param timeout_us: timeout value
278   * @retval 0: Send command ok.
279   *		  Other values: error occurs
280   */
SDIOH_SendCommand(SDIOH_CmdTypeDef * cmd_attrib,u32 timeout_us)281 u32 SDIOH_SendCommand(SDIOH_CmdTypeDef *cmd_attrib, u32 timeout_us)
282 {
283 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
284 	u8 cmd = cmd_attrib->idx, cmd_code, tmp;
285 	u32 val0 = 0, ret;
286 
287 	ret = SDIOH_Busy();
288 	if (ret != HAL_OK)
289 		return ret;
290 
291 	/* set SD_CONFIGURE2 (0x581) */
292 	val0 = SDIOH_CRC7_CAL_EN | (cmd_attrib->rsp_type);
293 
294 	if(cmd_attrib->rsp_crc_chk)
295 		val0 |= SDIOH_CRC7_CHK_EN;
296 	else
297 		val0 |= SDIOH_CRC7_CHK_DIS;
298 
299 	if((cmd == SD_CMD_RdSingleBlk) || (cmd == SD_CMD_RdMulBlk) || (cmd == SD_CMD_SendTuningBlk))
300 		val0 |= SDIOH_CRC16_CHK_EN;
301 	else
302 		val0 |= SDIOH_CRC16_CHK_DIS;
303 
304 	if((cmd == SD_CMD_WrBlk) || (cmd == SD_CMD_WrMulBlk))
305 		val0 |= SDIOH_WAIT_WR_CRCSTA_TO_EN | SDIOH_IGNORE_WR_CRC_ERR_EN;
306 	else
307 		val0 |= SDIOH_WAIT_WR_CRCSTA_TO_DIS | SDIOH_IGNORE_WR_CRC_ERR_DIS;
308 
309 	if(cmd == SD_CMD_VolSwitch)
310 		val0 |= SDIOH_WAIT_BUSY_END_DIS;
311 	else
312 		val0 |= SDIOH_WAIT_BUSY_END_EN;
313 
314 	psdioh->SD_CONFIG2 = val0;
315 
316 	/* set SD_CONFIGURE3 (0x582) */
317 	val0 = SDIOH_STOP_STA_WAIT_BUSY_EN | SDIOH_SD30_CLK_STOP_DIS | SDIOH_SD20_CLK_STOP_DIS | \
318 			SDIOH_SD_CMD_RESP_CHK_DIS | SDIOH_ADDR_MODE_SECTOR;
319 
320 	if((cmd == SD_CMD_RdMulBlk) || (cmd == SD_CMD_WrMulBlk) || (cmd == SD_CMD_StopXsmission))
321 		val0 |= SDIOH_CMD_STA_WAIT_BUSY_DIS;
322 	else
323 		val0 |= SDIOH_CMD_STA_WAIT_BUSY_EN;
324 
325 	if((cmd == SD_CMD_VolSwitch) || (cmd == SD_CMD_StopXsmission))
326 		val0 |= SDIOH_DATA_PHA_WAIT_BUSY_DIS;
327 	else
328 		val0 |= SDIOH_DATA_PHA_WAIT_BUSY_EN;
329 
330 	if((cmd_attrib->rsp_type) == SDIOH_NO_RESP)
331 		val0 |= SDIOH_CMD_RESP_TO_DIS;
332 	else
333 		val0 |= SDIOH_CMD_RESP_TO_EN;
334 
335 	psdioh->SD_CONFIG3 = val0;
336 
337 	/* fill the command register */
338 	psdioh->SD_CMD[0]= HOST_COMMAND | (cmd & 0x3F);
339 	psdioh->SD_CMD[1] = ((cmd_attrib->arg) >> 24) & 0xFF;
340 	psdioh->SD_CMD[2] = ((cmd_attrib->arg) >> 16) & 0xFF;
341 	psdioh->SD_CMD[3] = ((cmd_attrib->arg) >> 8) & 0xFF;
342 	psdioh->SD_CMD[4] = (cmd_attrib->arg) & 0xFF;
343 	psdioh->SD_CMD[5] = 0x0;
344 
345 	/* set the command code */
346 	switch (cmd) {
347 		case SD_CMD_SwitchFunc:
348 		case SD_CMD_SendSts:
349 			cmd_code = ((cmd_attrib->data_present) == SDIOH_NO_DATA) ? \
350 					SDIOH_SEND_CMD_GET_RSP : SDIOH_NORMAL_READ;
351 		break;
352 		case SD_CMD_SendTuningBlk:
353 			cmd_code = SDIOH_TUNING;
354 		break;
355 		case SD_CMD_RdSingleBlk:
356 #if defined(SDIO) && (SDIO == EMMC)
357 		case EMMC_CMD_SendExtCsd:
358 #endif
359 			cmd_code = SDIOH_AUTO_READ2;
360 		break;
361 		case SD_CMD_RdMulBlk:
362 			cmd_code = SDIOH_AUTO_READ1;
363 		break;
364 		case SD_CMD_WrBlk:
365 			cmd_code = SDIOH_AUTO_WRITE2;
366 		break;
367 		case SD_CMD_WrMulBlk:
368 			cmd_code = SDIOH_AUTO_WRITE1;
369 		break;
370 		case SD_CMD_SendScr:
371 			cmd_code = SDIOH_NORMAL_READ;
372 		break;
373 		default:
374 			cmd_code = SDIOH_SEND_CMD_GET_RSP;
375 	}
376 
377 	tmp = psdioh->SD_TRANSFER;
378 	tmp &= ~SDIOH_MASK_COM_CODE;
379 	tmp |= cmd_code;
380 	psdioh->SD_TRANSFER = tmp;
381 
382 	/* start to transfer */
383 	psdioh->SD_TRANSFER |= SDIOH_START_TRANSFER;
384 
385 	if(timeout_us != 0)
386 		ret = SDIOH_WaitTxDone(timeout_us);
387 
388 	return ret;
389 }
390 
391 /**
392   * @brief  SDIOH get command response.
393   * @param  byte_index: which byte of the response to be read
394   * @retval the specified byte value of Response
395   */
SDIOH_GetResponse(u8 byte_index)396 u8 SDIOH_GetResponse(u8 byte_index)
397 {
398 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
399 
400 	return psdioh->SD_CMD[byte_index];
401 }
402 
403 /**
404   * @brief  Switch speed of SDIOH.
405   * @param  clk_div: can be one of the following values:
406   *		 @arg SDIOH_CLK_DIV1:  divide by 1
407   *		 @arg SDIOH_CLK_DIV2:  divide by 2
408   *		 @arg SDIOH_CLK_DIV4:  divide by 4
409   *		 @arg SDIOH_CLK_DIV8:  divide by 8
410   * @param  mode: mode selection, can be one of the following values:
411   *		 @arg SDIOH_SD20_MODE
412   * @retval None
413   * @note AmebaD only support SD20_MODE
414   */
SDIOH_SwitchSpeed(u8 clk_div,u8 mode)415 void SDIOH_SwitchSpeed(u8 clk_div, u8 mode)
416 {
417 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
418 	u32 value32;
419 	u8 value8;
420 
421 	value32 = psdioh->CKGEN_CTL;
422 	value32 &= ~SDIOH_MASK_CLKDIV;
423 	value32 |= clk_div;
424 	psdioh->CKGEN_CTL = value32;
425 
426 	value8 = psdioh->SD_CONFIG1;
427 	value8 &= ~SDIOH_MASK_MODE_SEL;
428 	value8 |= (mode << SDIOH_SHIFT_MODE_SEL);
429 	psdioh->SD_CONFIG1 = value8;
430 }
431 
432 /**
433   * @brief  Configure SDIOH to initialization mode or not.
434   * @param  NewState: can be ENABLE/DISABLE
435   * @param  level: signal level, which can be @arg SDIOH_SIG_VOL_33.
436   * @retval  0: SDIOH is configured successfully
437   *			others: SDIOH is fail to configure.
438   */
SDIOH_InitialModeCmd(u8 NewState,u8 Level)439 u32 SDIOH_InitialModeCmd(u8 NewState, u8 Level)
440 {
441 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
442 	u32 ret = HAL_OK;
443 
444 	ret = SDIOH_Busy();
445 	if (ret != HAL_OK) {
446 		return ret;
447 	}
448 
449 	if (NewState) {
450 		psdioh->CKGEN_CTL = SDIOH_SD30_SAMP_CLK_VP1 | SDIOH_SD30_PUSH_CLK_VP0 | \
451 			SDIOH_CRC_CLK_SSC | SDIOH_CLK_DIV4;
452 
453 		/* SDCLK (Card Identification mode) : 390.625 KHz */
454 		psdioh->SD_CONFIG1 = (SDIOH_SD20_MODE << SDIOH_SHIFT_MODE_SEL) | \
455 			SDIOH_CLK_DIV_BY_128 | SDIOH_INITIAL_MODE | SDIOH_SD30_ASYNC_FIFO_RST_N |\
456 			(SDIOH_BUS_WIDTH_1BIT << SDIOH_SHIFT_BUS_WIDTH);
457 	} else {
458 		/* Switch to DS mode (3.3V) or SDR12 (1.8V). SDCLK (Data Transfer mode) : 25 MHz */
459 		if(Level == SDIOH_SIG_VOL_18) {
460 			psdioh->CKGEN_CTL = SDIOH_SD30_SAMP_CLK_VP1 | SDIOH_SD30_PUSH_CLK_VP0 | \
461 				SDIOH_CRC_CLK_SSC | SDIOH_CLK_DIV4;
462 
463 			psdioh->SD_CONFIG1 = (SDIOH_SD30_MODE << SDIOH_SHIFT_MODE_SEL) | \
464 				SDIOH_CLK_DIV_BY_128 | SDIOH_SD30_ASYNC_FIFO_RST_N |\
465 				(SDIOH_BUS_WIDTH_1BIT << SDIOH_SHIFT_BUS_WIDTH);
466 		} else {
467 			psdioh->CKGEN_CTL = SDIOH_SD30_SAMP_CLK_VP1 | SDIOH_SD30_PUSH_CLK_VP0 | \
468 				SDIOH_CRC_CLK_SSC | (SDIOH_CLK_DIV4);
469 
470 			psdioh->SD_CONFIG1 = (SDIOH_SD20_MODE << SDIOH_SHIFT_MODE_SEL) | \
471 				SDIOH_CLK_DIV_BY_128 |(SDIOH_BUS_WIDTH_1BIT << SDIOH_SHIFT_BUS_WIDTH);
472 		}
473 	}
474 
475 	return ret;
476 }
477 
478 /**
479   * @brief  Initialize SDIOH peripheral.
480   * @param  None
481   * @retval  0: SDIOH is initialized successfully
482   *		   others: SDIOH is fail to initialize
483   */
SDIOH_Init(u8 BusBitMode)484 u32 SDIOH_Init (u8 BusBitMode)
485 {
486 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
487 	u32 ret = HAL_OK;
488 	u32 tmp, i = 0;
489 
490 	/* Set pin idle level */
491 	if(BusBitMode == SDIOH_BUS_WIDTH_4BIT)
492 		sdioh_init_para.SDIOH_idle_level = 0x1F;
493 	else
494 		sdioh_init_para.SDIOH_idle_level = 0x03;
495 
496 	/* SDIOH func & clock enable */
497 	RCC_PeriphClockCmd(APBPeriph_SDIOH, APBPeriph_SDIOH_CLOCK, ENABLE);
498 
499 	/* Wait for SDIOH clock ready */
500 	while(1) {
501 		tmp = HAL_READ32(SYSTEM_CTRL_BASE, REG_HS_SDIO_CTRL);
502 		if(tmp & BIT_HS_SDIOH_CLK_READY)
503 			break;
504 
505 		DelayUs(1);
506 		if(i++ > 10000) {
507 			DBG_PRINTF(MODULE_SDIO, LEVEL_ERROR, "Wait SDIOH clock ready timeout !\r\n");
508 			return HAL_TIMEOUT;
509 		}
510 	}
511 
512 	/* Enable interrupt */
513 	psdioh->CARD_INT_EN = SDIOH_SDMMC_INT_EN;
514 
515 	psdioh->SRAM_CRL = SDIOH_LX_BURST_SIZE_64B | SDIOH_MAP_SEL_DEC;
516 	psdioh->CARD_SELECT = SDIOH_CARD_SEL_SD_MODULE;
517 	psdioh->CARD_STOP = SDIOH_TARGET_MODULE_SD;
518 
519 	/* Initial mode */
520 	ret = SDIOH_InitialModeCmd(ENABLE, 0);
521 	if (ret != HAL_OK) {
522 		return ret;
523 	}
524 
525 	psdioh->CARD_CLK_EN_CTL = SDIOH_SD_CARD_MOUDLE_EN;
526 
527 	return ret;
528 }
529 
530 /**
531   * @brief  De-initialize SDIOH peripheral.
532   * @param  None
533   * @retval  None
534   */
SDIOH_DeInit(void)535 void SDIOH_DeInit (void)
536 {
537 	SDIOH_TypeDef *psdioh = SDIOH_BASE;
538 
539 	/* disable interrupt & clear all pending interrupts */
540 	psdioh->CARD_INT_PEND |= SDIOH_SDMMC_INT_PEND;
541 	psdioh->CARD_INT_EN &= ~ SDIOH_SDMMC_INT_EN;
542 	SDIOH_INTClearPendingBit(SDIOH_SD_ISR_ALL);
543 	SDIOH_INTConfig(SDIOH_SD_ISR_ALL, DISABLE);
544 }
545 
546