1 /*
2  * @ : Copyright (c) 2021 Phytium Information Technology, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0.
5  *
6  * @Date: 2021-03-31 14:59:20
7  * @LastEditTime: 2021-05-25 16:49:01
8  * @Description:  This files is for implemenation of sd ctrl
9  *
10  * @Modify History: * * Ver   Who        Date         Changes
11  * ----- ------     --------    --------------------------------------
12  */
13 
14 #include "ft_parameters.h"
15 #include "ft_assert.h"
16 #include "ft_io.h"
17 #include "ft_sdctrl.h"
18 #include "ft_sdctrl_hw.h"
19 #include "ft_debug.h"
20 #include "ft_printf.h"
21 #include "ft_trace.h"
22 #include "ft_cache.h"
23 #define FT_SD_CTRL_DEBUG_I(format, ...) FT_DEBUG_PRINT_I(FT_SD_CTRL_DEBUG_TAG, format, ##__VA_ARGS__)
24 #define FT_SD_CTRL_DEBUG_E(format, ...) FT_DEBUG_PRINT_E(FT_SD_CTRL_DEBUG_TAG, format, ##__VA_ARGS__)
25 #define FT_SD_CTRL_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(FT_SD_CTRL_DEBUG_TAG, format, ##__VA_ARGS__)
26 
FSdCtrl_ClkFreqSetup(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN u32 sdClk)27 void FSdCtrl_ClkFreqSetup(FT_INOUT FtsdCtrl_t *pFtsdCtrl, FT_IN u32 sdClk)
28 {
29     FSdCtrl_Config_t *pConfig;
30     u32 clkDiv;
31     u32 inputClk;
32     u32 tmpSdFreq;
33     u32 workSpeed;
34 
35     Ft_assertVoid(FT_NULL != pFtsdCtrl);
36     pConfig = &pFtsdCtrl->config;
37     inputClk = pConfig->inputClockHz;
38 
39     /* sd work speed is limit to 25MHz */
40     workSpeed = (sdClk < SD_CLK_FREQ_25MHZ) ? sdClk : SD_CLK_FREQ_25MHZ;
41 
42     /* if sd clk freq is valid and is two times greater than io input clk */
43     if ((SD_CLK_FREQ_400KHZ < workSpeed) && (inputClk > (2 * workSpeed)))
44     {
45         clkDiv = (u32)(inputClk / (2 * workSpeed)) - 1;
46 
47         /* calculte sd freq one more time base on divsor */
48         tmpSdFreq = (u32)inputClk / (2 * (clkDiv + 1));
49 
50         /* if calculated sd freq is greater than the real val  */
51         if (tmpSdFreq > workSpeed)
52         {
53             clkDiv += 1;
54         }
55     }
56     else
57     {
58         clkDiv = SD_FRRQ_DIV_DEFAULT;
59     }
60 
61     Ft_out32(pConfig->baseAddress + CLOCK_DIV_REG_OFFSET, clkDiv);
62 
63     return;
64 }
65 
FsdCtrl_Init(FT_INOUT FtsdCtrl_t * pFtsdCtrl)66 ft_error_t FsdCtrl_Init(FT_INOUT FtsdCtrl_t *pFtsdCtrl)
67 {
68     FSdCtrl_Config_t *pConfig;
69     Ft_assertNonvoid(FT_NULL != pFtsdCtrl);
70     pConfig = &pFtsdCtrl->config;
71 
72     /* Disable card detection */
73     Ft_out32(pConfig->baseAddress + SD_SEN_REG_OFFSET, 0);
74 
75     /* Disable all interrupts */
76     Ft_out32(pConfig->baseAddress + NORMAL_INT_EN_REG_OFFSET, 0);
77     Ft_out32(pConfig->baseAddress + ERROR_INT_EN_REG_OFFSET, 0);
78     Ft_out32(pConfig->baseAddress + BD_ISR_EN_REG_OFFSET, 0);
79     // Ft_out32(pConfig->baseAddress + NORMAL_INT_EN_REG_OFFSET, NORMAL_INT_EN_ECCRCE);
80 
81     /* Clear status register */
82     Ft_out32(pConfig->baseAddress + NORMAL_INT_STATUS_REG, 0);
83     Ft_out32(pConfig->baseAddress + ERROR_INT_STATUS_REG, 0);
84     Ft_out32(pConfig->baseAddress + BD_ISR_REG, 0);
85 
86     /* Set default ctrl register  */
87     Ft_out32(pConfig->baseAddress + CONTROLL_SETTING_REG_OFFSET, 0x0f00);
88 
89     /* Set default drive and sampling register */
90     Ft_out32(pConfig->baseAddress + SD_DRV_REG_OFFSET, 0);
91     Ft_out32(pConfig->baseAddress + SD_SAMP_REG_OFFSET, 0);
92 
93     /* Configure to default cmd data timeout */
94     Ft_out32(pConfig->baseAddress + TIMEOUT_CMD_REG_OFFSET, 0xFFFFFFFF);
95     //FSdCtrl_ClkFreqSetup(pFtsdCtrl, 1);
96 
97     Ft_out32(pConfig->baseAddress + CLOCK_DIV_REG_OFFSET, SD_FRRQ_DIV_DEFAULT);
98     Ft_out32(pConfig->baseAddress + SD_SAMP_REG_OFFSET, SD_SAMP_DEFAULT);
99 
100     pFtsdCtrl->isReady = FT_COMPONENT_IS_READLY;
101 
102     return FTSDC_SUCCESS;
103 }
104 
FSdCtrl_CardDetect(FT_INOUT FtsdCtrl_t * pFtsdCtrl)105 bool_t FSdCtrl_CardDetect(FT_INOUT FtsdCtrl_t *pFtsdCtrl)
106 {
107     FSdCtrl_Config_t *pConfig;
108     u32 status;
109 
110     Ft_assertBool(FT_NULL != pFtsdCtrl);
111     pConfig = &pFtsdCtrl->config;
112     status = Ft_in32(pConfig->baseAddress + STATUS_REG);
113 
114     /* check card-detection signal */
115     if (((status)&STATUS_REG_CDSL) == STATUS_REG_CDSL)
116     {
117         pConfig->cardDetect = 0;
118     }
119     else
120     {
121         pConfig->cardDetect = 1;
122     }
123 
124     return pConfig->cardDetect;
125 }
126 
FSdCtrl_ResetDma(FT_INOUT FtsdCtrl_t * pFtsdCtrl)127 void FSdCtrl_ResetDma(FT_INOUT FtsdCtrl_t *pFtsdCtrl)
128 {
129     FSdCtrl_Config_t *pConfig;
130     Ft_assertVoid(FT_NULL != pFtsdCtrl);
131     pConfig = &pFtsdCtrl->config;
132 
133     Ft_setBit32((UINTPTR)(pConfig->baseAddress + SOFTWARE_RESET_REG_OFFSET), SOFTWARE_RESET_BDRST);
134     Ft_clearBit32((UINTPTR)(pConfig->baseAddress + SOFTWARE_RESET_REG_OFFSET), SOFTWARE_RESET_BDRST);
135 }
136 
FSdCtrl_PrepareCmdRaw(FT_IN u32 cmdIndex,FT_IN u32 rspType)137 u32 FSdCtrl_PrepareCmdRaw(FT_IN u32 cmdIndex, FT_IN u32 rspType)
138 {
139     u32 rawCmd = 0;
140 
141     rawCmd |= CMD_SETTING_CMDI(cmdIndex);
142 
143     switch (rspType)
144     {
145     case FTSDCTRL_CMD_RES_NONE:
146         rawCmd |= CMD_SETTING_RTS(0);
147         break;
148     case FTSDCTRL_CMD_RES_LONG:
149         rawCmd |= CMD_SETTING_RTS(1);
150         break;
151     case FTSDCTRL_CMD_RES_SHORT:
152         rawCmd |= CMD_SETTING_RTS(2);
153         break;
154     default:
155         rawCmd |= CMD_SETTING_RTS(0);
156         break;
157     }
158 
159     return rawCmd;
160 }
161 
FSdCtrl_WriteData(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN UINTPTR dataAddr,FT_IN UINTPTR cardAddr,FT_IN u32 blkNum)162 void FSdCtrl_WriteData(FT_INOUT FtsdCtrl_t *pFtsdCtrl, FT_IN UINTPTR dataAddr,
163                        FT_IN UINTPTR cardAddr, FT_IN u32 blkNum)
164 {
165 
166     FSdCtrl_Config_t *pConfig;
167     Ft_assertVoid(FT_NULL != pFtsdCtrl);
168     pConfig = &pFtsdCtrl->config;
169 
170     /* write 1 to clear data status register and command status register */
171     Ft_out32(pConfig->baseAddress + BD_ISR_REG, BD_ISR_REG_TRS);
172     Ft_out32(pConfig->baseAddress + NORMAL_INT_STATUS_REG, NORMAL_INT_STATUS_CC);
173 
174     /* set DMA BD  */
175     Ft_setBit32((UINTPTR)(pConfig->baseAddress + SOFTWARE_RESET_REG_OFFSET), SOFTWARE_RESET_BDRST);
176     Ft_clearBit32((UINTPTR)(pConfig->baseAddress + SOFTWARE_RESET_REG_OFFSET), SOFTWARE_RESET_BDRST);
177 
178     /* set transfer lenth */
179     Ft_out32(pConfig->baseAddress + BLK_CNT_REG, blkNum);
180 
181     /* set DMA discriptor data low address,data high address,card low address,card high address*/
182     Ft_out32(pConfig->baseAddress + DAT_IN_M_TX_BD, dataAddr);
183     Ft_out32(pConfig->baseAddress + DAT_IN_M_TX_BD, 0);
184     Ft_out32(pConfig->baseAddress + DAT_IN_M_TX_BD, cardAddr);
185     Ft_out32(pConfig->baseAddress + DAT_IN_M_TX_BD, 0);
186 }
187 
FSdCtrl_ReadData(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN UINTPTR dataAddr,FT_IN UINTPTR cardAddr,FT_IN u32 blkNum)188 void FSdCtrl_ReadData(FT_INOUT FtsdCtrl_t *pFtsdCtrl,
189                       FT_IN UINTPTR dataAddr,
190                       FT_IN UINTPTR cardAddr,
191                       FT_IN u32 blkNum)
192 {
193     FSdCtrl_Config_t *pConfig;
194     Ft_assertVoid(FT_NULL != pFtsdCtrl);
195     pConfig = &pFtsdCtrl->config;
196 
197     /* clear data status register and command status register */
198     Ft_out32(pConfig->baseAddress + BD_ISR_REG, BD_ISR_EN_ETRS);
199     Ft_out32(pConfig->baseAddress + NORMAL_INT_STATUS_REG, NORMAL_INT_EN_ECC);
200 
201     /* set DMA BD  */
202     Ft_setBit32((UINTPTR)(pConfig->baseAddress + SOFTWARE_RESET_REG_OFFSET), SOFTWARE_RESET_BDRST);
203     Ft_clearBit32((UINTPTR)(pConfig->baseAddress + SOFTWARE_RESET_REG_OFFSET), SOFTWARE_RESET_BDRST);
204 
205     /* set transfer lenth */
206     Ft_out32(pConfig->baseAddress + BLK_CNT_REG, blkNum);
207 
208     /* set DMA discriptor data low address,data high address,card low address,card high address*/
209 
210     Ft_out32(pConfig->baseAddress + DAT_IN_M_RX_BD, dataAddr);
211     Ft_out32(pConfig->baseAddress + DAT_IN_M_RX_BD, 0);
212     Ft_out32(pConfig->baseAddress + DAT_IN_M_RX_BD, cardAddr);
213     Ft_out32(pConfig->baseAddress + DAT_IN_M_RX_BD, 0);
214 }
215 
FsdCtrl_privateSendCmd(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN pFtsdCtrl_delayTimer_t pDelayTimer_fun,FT_IN u32 cmd,FT_IN u32 respType,FT_IN u32 arg)216 static ft_error_t FsdCtrl_privateSendCmd(FT_INOUT FtsdCtrl_t *pFtsdCtrl, FT_IN pFtsdCtrl_delayTimer_t pDelayTimer_fun, FT_IN u32 cmd, FT_IN u32 respType, FT_IN u32 arg)
217 {
218     u32 temp;
219     u32 sd_cmd;
220     u32 sd_arg;
221     FSdCtrl_Config_t *pConfig;
222     Ft_assertNonvoid(FT_NULL != pFtsdCtrl);
223     pConfig = &pFtsdCtrl->config;
224 
225     /* enable cmd finished irq */
226     Ft_out32(pConfig->baseAddress + NORMAL_INT_STATUS_REG, NORMAL_INT_EN_ECC);
227     Ft_out32(pConfig->baseAddress + NORMAL_INT_STATUS_REG, 0);
228 
229     Ft_out32(pConfig->baseAddress + ERROR_INT_STATUS_REG, BD_ISR_EN_ETRS);
230     Ft_out32(pConfig->baseAddress + ERROR_INT_STATUS_REG, 0);
231 
232     /* prepare cmd msg, along with arg */
233     sd_cmd = FSdCtrl_PrepareCmdRaw(cmd, respType);
234     sd_arg = arg;
235 
236     /* send cmd and arg */
237     Ft_out32(pConfig->baseAddress + CMD_SETTING_REG_OFFSET, sd_cmd);
238     Ft_out32(pConfig->baseAddress + ARGUMENT_REG_OFFSET, sd_arg);
239 
240     if (pConfig->workMode & FTSDCTRL_CMD_IRQ_MASK)
241     {
242         if (pFtsdCtrl->cmdWaitCallback)
243         {
244             /* if irq is enabled and call back registered, enter call back procedure */
245             return pFtsdCtrl->cmdWaitCallback(pFtsdCtrl);
246         }
247         else
248         {
249             return FTSDC_INVALID_PARAM;
250         }
251     }
252     else
253     {
254         temp = Ft_in32(pConfig->baseAddress + NORMAL_INT_STATUS_REG);
255         /* polling wait for cmd-finished response */
256         while (NORMAL_INT_STATUS_CC != (temp & NORMAL_INT_STATUS_CC))
257         {
258             temp = Ft_in32(pConfig->baseAddress + NORMAL_INT_STATUS_REG);
259             pDelayTimer_fun(1);
260         }
261     }
262 
263     return FTSDC_SUCCESS;
264 }
265 
FSdCtrl_WaitWriteDataEnd(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN pFtsdCtrl_delayTimer_t pDelayTimer_fun,FT_IN u32 blkNum)266 ft_error_t FSdCtrl_WaitWriteDataEnd(FT_INOUT FtsdCtrl_t *pFtsdCtrl,
267                                     FT_IN pFtsdCtrl_delayTimer_t pDelayTimer_fun,
268                                     FT_IN u32 blkNum)
269 {
270     u32 status;
271     u32 statusMask;
272     ft_error_t ret;
273     s32 timeout = 1000;
274     FSdCtrl_Config_t *pConfig;
275 
276     Ft_assertNonvoid(FT_NULL != pFtsdCtrl);
277     pConfig = &pFtsdCtrl->config;
278 
279     if (pConfig->workMode & FTSDCTRL_DATA_WRITE_IRQ_MASK)
280     {
281         /* enter irq mode */
282         if (NULL == pFtsdCtrl->writeWaitCallback)
283         {
284             return FTSDC_INVALID_PARAM;
285         }
286 
287         ret = pFtsdCtrl->writeWaitCallback(pFtsdCtrl);
288         if (FTSDC_SUCCESS != ret)
289         {
290             return FTSDC_EILSEQ;
291         }
292     }
293     else
294     {
295         /* wait for DMA-error or DMA-finished status */
296         statusMask = BD_ISR_REG_DAIS | BD_ISR_REG_TRS;
297         do
298         {
299             status = (Ft_in32(pConfig->baseAddress + BD_ISR_REG) & statusMask);
300             pDelayTimer_fun(1);
301             timeout--;
302         } while ((!status) && timeout);
303 
304         if (status & BD_ISR_REG_DAIS)
305         {
306             if (status & (BD_ISR_REG_TRE | BD_ISR_REG_NRCRC | BD_ISR_REG_CMDE))
307             {
308                 return FTSDC_EILSEQ;
309             }
310             else if (!timeout)
311             {
312                 return FTSDC_TIMEOUT;
313             }
314         }
315     }
316 
317     /* multi block needs MMC_STOP_TRANSMISSION to stop process*/
318     if (blkNum > 1)
319     {
320         return FsdCtrl_privateSendCmd(pFtsdCtrl, pDelayTimer_fun, 12, CMD_SETTING_RTS(2), 0);
321     }
322 
323     return FTSDC_SUCCESS;
324 }
325 
FSdCtrl_WaitReadDataEnd(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN pFtsdCtrl_delayTimer_t pDelayTimer_fun,FT_IN u32 blkNum)326 ft_error_t FSdCtrl_WaitReadDataEnd(FT_INOUT FtsdCtrl_t *pFtsdCtrl,
327                                    FT_IN pFtsdCtrl_delayTimer_t pDelayTimer_fun,
328                                    FT_IN u32 blkNum)
329 {
330     u32 status;
331     u32 statusMask;
332     ft_error_t ret;
333     s32 timeout = 1000;
334     FSdCtrl_Config_t *pConfig;
335 
336     Ft_assertNonvoid(FT_NULL != pFtsdCtrl);
337     pConfig = &pFtsdCtrl->config;
338 
339     if (pConfig->workMode & FTSDCTRL_DATA_READ_IRQ_MASK)
340     {
341         if (pFtsdCtrl->readWaitCallback)
342         {
343             ret = pFtsdCtrl->readWaitCallback(pFtsdCtrl);
344             if (FTSDC_SUCCESS != ret)
345             {
346                 return FTSDC_EILSEQ;
347             }
348         }
349         else
350         {
351             return FTSDC_INVALID_PARAM;
352         }
353     }
354     else
355     {
356         /* wait for DMA-error or Read-finish status */
357         statusMask = BD_ISR_REG_DAIS | BD_ISR_REG_RESPE;
358         do
359         {
360             status = (Ft_in32(pConfig->baseAddress + BD_ISR_REG) & statusMask);
361             pDelayTimer_fun(1);
362             timeout--;
363         } while ((!status) && timeout);
364 
365         if (status & BD_ISR_REG_DAIS)
366         {
367             /* error handle */
368             if (status & (BD_ISR_REG_TRE | BD_ISR_REG_NRCRC | BD_ISR_REG_CMDE))
369             {
370                 return FTSDC_EILSEQ;
371             }
372             else if (!timeout)
373             {
374                 return FTSDC_TIMEOUT;
375             }
376         }
377     }
378 
379     // /* multi block needs MMC_STOP_TRANSMISSION to stop process*/
380     if (blkNum > 1)
381     {
382         return FsdCtrl_privateSendCmd(pFtsdCtrl, pDelayTimer_fun, 12, CMD_SETTING_RTS(2), 0);
383     }
384 
385     return FTSDC_SUCCESS;
386 }
387 
FSdCtrl_WaitCmdEnd(FT_OUT FtsdCtrl_t * pFtsdCtrl,FT_IN pFtsdCtrl_delayTimer_t pDelayTimer_fun,FT_IN u32 rspType,FT_OUT u32 * cmdRsp)388 ft_error_t FSdCtrl_WaitCmdEnd(FT_OUT FtsdCtrl_t *pFtsdCtrl,
389                               FT_IN pFtsdCtrl_delayTimer_t pDelayTimer_fun,
390                               FT_IN u32 rspType,
391                               FT_OUT u32 *cmdRsp)
392 {
393     u32 status;
394     u32 statusMask;
395     s32 timeout = 1000;
396     const FSdCtrl_Config_t *pConfig;
397     ft_error_t result = FST_SUCCESS;
398 
399     Ft_assertNonvoid(FT_NULL != pFtsdCtrl);
400     pConfig = &pFtsdCtrl->config;
401 
402     if (pConfig->workMode & FTSDCTRL_CMD_IRQ_MASK)
403     {
404         if (pFtsdCtrl->cmdWaitCallback)
405         {
406             result = pFtsdCtrl->cmdWaitCallback(pFtsdCtrl);
407         }
408         else
409         {
410             return FTSDC_INVALID_PARAM;
411         }
412         status = Ft_in32(pConfig->baseAddress + NORMAL_INT_STATUS_REG);
413     }
414     else
415     {
416         /* wait for cmd-error or cmd-finish respones */
417         statusMask = NORMAL_INT_STATUS_EI | NORMAL_INT_STATUS_CC;
418 
419         do
420         {
421             status = (Ft_in32(pConfig->baseAddress + NORMAL_INT_STATUS_REG) & statusMask);
422             pDelayTimer_fun(1);
423             timeout--;
424 
425         } while ((!status) && timeout);
426     }
427 
428     if (status & NORMAL_INT_STATUS_EI)
429     {
430         /* error handle */
431         status = Ft_in32(pConfig->baseAddress + ERROR_INT_STATUS_REG);
432 
433         if (!timeout)
434         {
435             return FTSDC_TIMEOUT;
436         }
437         else if ((status & NORMAL_INT_EN_ECCRCE))
438         {
439             return FTSDC_EILSEQ;
440         }
441     }
442 
443     if (rspType != FTSDCTRL_CMD_RES_NONE)
444     {
445         /* get cmd respones */
446         if (rspType == FTSDCTRL_CMD_RES_LONG)
447         {
448             cmdRsp[0] = Ft_in32(pConfig->baseAddress + CMD_RESP_1);
449             cmdRsp[1] = Ft_in32(pConfig->baseAddress + CMD_RESP_2);
450             cmdRsp[2] = Ft_in32(pConfig->baseAddress + CMD_RESP_3);
451             cmdRsp[3] = Ft_in32(pConfig->baseAddress + CMD_RESP_4);
452         }
453         else
454         {
455             cmdRsp[0] = Ft_in32(pConfig->baseAddress + CMD_RESP_1);
456             cmdRsp[1] = 0;
457             cmdRsp[2] = 0;
458             cmdRsp[3] = 0;
459         }
460     }
461 
462     return result;
463 }
464 
FSdCtrl_DoCmd(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN u32 cmdIndex,FT_IN u32 rspType,u32 arg)465 void FSdCtrl_DoCmd(FT_INOUT FtsdCtrl_t *pFtsdCtrl,
466                    FT_IN u32 cmdIndex,
467                    FT_IN u32 rspType,
468                    u32 arg)
469 {
470     u32 cmd;
471 
472     FSdCtrl_Config_t *pConfig;
473     Ft_assertVoid(FT_NULL != pFtsdCtrl);
474     pConfig = &pFtsdCtrl->config;
475 
476     /* clear normal interrupt status */
477     Ft_out32(pConfig->baseAddress + NORMAL_INT_STATUS_REG, NORMAL_INT_STATUS_EI);
478 
479     /* set command*/
480     cmd = FSdCtrl_PrepareCmdRaw(cmdIndex, rspType);
481     Ft_out32(pConfig->baseAddress + CMD_SETTING_REG_OFFSET, cmd);
482 
483     if (cmdIndex == 41)
484     {
485         arg = 0x40ff8000;
486     }
487 
488     Ft_out32(pConfig->baseAddress + ARGUMENT_REG_OFFSET, arg);
489 }
490 
FSdCtrl_DoACmd(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN u32 cmdIndex,FT_IN u32 rspType,u32 arg)491 void FSdCtrl_DoACmd(FT_INOUT FtsdCtrl_t *pFtsdCtrl,
492                     FT_IN u32 cmdIndex,
493                     FT_IN u32 rspType,
494                     u32 arg)
495 {
496     u32 cmd;
497 
498     FSdCtrl_Config_t *pConfig;
499     Ft_assertVoid(FT_NULL != pFtsdCtrl);
500     pConfig = &pFtsdCtrl->config;
501 
502     /* clear normal interrupt status */
503     Ft_out32(pConfig->baseAddress + NORMAL_INT_STATUS_REG, NORMAL_INT_EN_ECC);
504     /* set command*/
505     cmd = FSdCtrl_PrepareCmdRaw(cmdIndex, rspType);
506     cmd |= CMD_SETTING_TRTY(2);
507     Ft_out32(pConfig->baseAddress + CMD_SETTING_REG_OFFSET, cmd);
508 }
509 
FSdCtrl_WriteWaitRegister(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN pFtsdCtrl_irqWaitCallback_t callBack)510 void FSdCtrl_WriteWaitRegister(FT_INOUT FtsdCtrl_t *pFtsdCtrl, FT_IN pFtsdCtrl_irqWaitCallback_t callBack)
511 {
512     Ft_assertVoid(FT_NULL != pFtsdCtrl);
513     pFtsdCtrl->writeWaitCallback = callBack;
514 }
515 
FSdCtrl_ReadWaitRegister(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN pFtsdCtrl_irqWaitCallback_t callBack)516 void FSdCtrl_ReadWaitRegister(FT_INOUT FtsdCtrl_t *pFtsdCtrl, FT_IN pFtsdCtrl_irqWaitCallback_t callBack)
517 {
518     Ft_assertVoid(FT_NULL != pFtsdCtrl);
519     pFtsdCtrl->readWaitCallback = callBack;
520 }
521 
FSdCtrl_CmdWaitRegister(FT_INOUT FtsdCtrl_t * pFtsdCtrl,FT_IN pFtsdCtrl_irqWaitCallback_t callBack)522 void FSdCtrl_CmdWaitRegister(FT_INOUT FtsdCtrl_t *pFtsdCtrl, FT_IN pFtsdCtrl_irqWaitCallback_t callBack)
523 {
524     Ft_assertVoid(FT_NULL != pFtsdCtrl);
525     pFtsdCtrl->cmdWaitCallback = callBack;
526 }
527 
FSdCtrl_GetNormalIrqStatus(FT_INOUT FtsdCtrl_t * pFtsdCtrl)528 u32 FSdCtrl_GetNormalIrqStatus(FT_INOUT FtsdCtrl_t *pFtsdCtrl)
529 {
530     Ft_assertNonvoid(FT_NULL != pFtsdCtrl);
531     FSdCtrl_Config_t *pConfig;
532     pConfig = &pFtsdCtrl->config;
533     return Ft_in32(pConfig->baseAddress + NORMAL_INT_STATUS_REG);
534 }
535 
FSdCtrl_GetDataIrqStatus(FT_INOUT FtsdCtrl_t * pFtsdCtrl)536 u32 FSdCtrl_GetDataIrqStatus(FT_INOUT FtsdCtrl_t *pFtsdCtrl)
537 {
538     Ft_assertNonvoid(FT_NULL != pFtsdCtrl);
539     FSdCtrl_Config_t *pConfig;
540     pConfig = &pFtsdCtrl->config;
541 
542     return Ft_in32(pConfig->baseAddress + BD_ISR_REG);
543 }
544 
FSdCtrl_GetErrorIrqStatus(FT_INOUT FtsdCtrl_t * pFtsdCtrl)545 u32 FSdCtrl_GetErrorIrqStatus(FT_INOUT FtsdCtrl_t *pFtsdCtrl)
546 {
547     Ft_assertNonvoid(FT_NULL != pFtsdCtrl);
548     FSdCtrl_Config_t *pConfig;
549     pConfig = &pFtsdCtrl->config;
550 
551     return Ft_in32(pConfig->baseAddress + ERROR_INT_STATUS_REG);
552 }
553