1 /*********************************************************************
\r
2 ** File Name: sdio_pal.c
\r
3 ** Author: yanping.xie
\r
5 ** Copyright: 2004 Spreadtrum, Incoporated. All Rights Reserved.
\r
6 ** Description: This file describe operation of sdio host.
\r
7 *********************************************************************
\r
9 *********************************************************************
\r
11 ** ------------------------------------------------------------------------- **
\r
12 ** DATE NAME DESCRIPTION
\r
13 ** 09/05/2013 ypxie Create.
\r
14 ********************************************************************/
\r
15 #include "sdio_reg.h"
\r
16 #include "sdio_phy.h"
\r
17 #include "sdio_core.h"
\r
20 #define sdio_printf(x) printf(x)
\r
33 // response Name cmd int filter , rsp , cmd error filter
\r
34 #define CARD_SDIO_NO_RSP NULL | INT_CMD_CMPLT , SDIO_NO_RSP , NULL
\r
35 #define CARD_SDIO_R1 NULL | INT_CMD_CMPLT , SDIO_R1 , INT_TRGT_RESP | INT_CMD_IND | INT_CMD_END_BIT | INT_CMD_CRC | INT_CMD_TIMEOUT
\r
36 #define CARD_SDIO_R2 NULL | INT_CMD_CMPLT , SDIO_R2 , INT_TRGT_RESP | INT_CMD_END_BIT | INT_CMD_CRC | INT_CMD_TIMEOUT
\r
37 #define CARD_SDIO_R3 NULL | INT_CMD_CMPLT , SDIO_R3 , INT_TRGT_RESP | INT_CMD_END_BIT | INT_CMD_TIMEOUT
\r
38 #define CARD_SDIO_R4 NULL | INT_CMD_CMPLT , SDIO_R4 , INT_TRGT_RESP | INT_CMD_IND | INT_CMD_END_BIT | INT_CMD_CRC | INT_CMD_TIMEOUT
\r
39 #define CARD_SDIO_R5 NULL | INT_CMD_CMPLT , SDIO_R5 , INT_TRGT_RESP | INT_CMD_IND | INT_CMD_END_BIT | INT_CMD_CRC | INT_CMD_TIMEOUT
\r
40 #define CARD_SDIO_R6 NULL | INT_CMD_CMPLT , SDIO_R6 , INT_TRGT_RESP | INT_CMD_IND | INT_CMD_END_BIT | INT_CMD_CRC | INT_CMD_TIMEOUT
\r
41 #define CARD_SDIO_R7 NULL | INT_CMD_CMPLT , SDIO_R7 , INT_TRGT_RESP | INT_CMD_IND | INT_CMD_END_BIT | INT_CMD_CRC | INT_CMD_TIMEOUT
\r
42 #define CARD_SDIO_R1B NULL | INT_CMD_CMPLT , SDIO_R1B , INT_TRGT_RESP | INT_CMD_IND | INT_CMD_END_BIT | INT_CMD_CRC | INT_CMD_TIMEOUT
\r
43 //#define CARD_SDIO_R5B NULL | INT_CMD_CMPLT , SDIO_R5B , INT_TRGT_RESP | INT_CMD_IND | INT_CMD_END_BIT | INT_CMD_CRC | INT_CMD_TIMEOUT
\r
45 const cmd_ctl_flg_t sdio_cmd_detail[]=
\r
47 // cmdindex,rsp,transmode
\r
48 //#define CMDname cmdindex ,data int filter + (cmd int filter+)rsp(+cmd error filter) + ,data error filter , transmode
\r
49 { CMD0_GO_IDLE_STATE , 0 , NULL | CARD_SDIO_NO_RSP | NULL , NULL },
\r
50 { CMD1_SEND_OP_COND , 1 , NULL | CARD_SDIO_R3 | NULL , NULL },
\r
51 { CMD2_ALL_SEND_CID , 2 , NULL | CARD_SDIO_R2 | NULL , NULL },
\r
52 { CMD3_SET_RELATIVE_ADDR_SD , 3 , NULL | CARD_SDIO_R6 | NULL , NULL },
\r
53 { CMD3_SET_RELATIVE_ADDR , 3 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
54 { CMD4_SET_DSR , 4 , NULL | CARD_SDIO_NO_RSP | NULL , NULL },
\r
55 // { CMD5_SLEEP_AWAKE , 5 , NULL | CARD_SDIO_R4 , NULL , CMD_TYPE_NORMAL },
\r
56 { CMD6_SWITCH , 6 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_END_BIT | INT_DATA_CRC | INT_DATA_TIMEOUT , SDIO_TRANS_DIR_READ | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
57 { CMD7_SELECT_CARD_SD , 7 , NULL | CARD_SDIO_R1B | NULL , NULL },
\r
58 { CMD7_SELECT_CARD , 7 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
59 { CMD8_SEND_IF_COND_SD , 8 , NULL | CARD_SDIO_R7 | NULL , NULL },
\r
60 { CMD8_SEND_IF_COND , 8 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_END_BIT | INT_DATA_CRC | INT_DATA_TIMEOUT , SDIO_TRANS_DIR_READ | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
61 { CMD9_SEND_CSD , 9 , NULL | CARD_SDIO_R2 | NULL , NULL },
\r
62 { CMD10_SEND_CID , 10 , NULL | CARD_SDIO_R2 | NULL , NULL },
\r
63 { CMD11_READ_DAT_UNTIL_STOP , 11 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_END_BIT | INT_DATA_CRC | INT_DATA_TIMEOUT , SDIO_TRANS_MULTIBLK | SDIO_TRANS_DIR_READ | SDIO_TRANS_BLK_CNT_EN | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
64 { CMD11_READ_DAT_UNTIL_STOP_AUT12 , 11 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_END_BIT | INT_DATA_CRC | INT_DATA_TIMEOUT | INT_AUTO_CMD12 , SDIO_TRANS_MULTIBLK | SDIO_TRANS_DIR_READ | SDIO_TRANS_AUTO_CMD12_EN| SDIO_TRANS_BLK_CNT_EN | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
65 { CMD12_STOP_TRANSMISSION , 12 , INT_TR_CMPLT | CARD_SDIO_R1B | NULL , NULL },
\r
66 { CMD13_SEND_STATUS , 13 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
67 { CMD15_GO_INACTIVE_STATE , 15 , NULL | CARD_SDIO_NO_RSP | NULL , NULL },
\r
68 { CMD16_SET_BLOCKLEN , 16 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
69 { CMD17_READ_SINGLE_BLOCK , 17 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_END_BIT | INT_DATA_CRC | INT_DATA_TIMEOUT , SDIO_TRANS_DIR_READ | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
70 { CMD18_READ_MULTIPLE_BLOCK , 18 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_END_BIT | INT_DATA_CRC | INT_DATA_TIMEOUT , SDIO_TRANS_MULTIBLK | SDIO_TRANS_DIR_READ | SDIO_TRANS_BLK_CNT_EN | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
71 { CMD18_READ_MULTIPLE_BLOCK_AUT12 , 18 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_END_BIT | INT_DATA_CRC | INT_DATA_TIMEOUT | INT_AUTO_CMD12 , SDIO_TRANS_MULTIBLK | SDIO_TRANS_DIR_READ | SDIO_TRANS_AUTO_CMD12_EN| SDIO_TRANS_BLK_CNT_EN | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
72 { CMD20_WRITE_DAT_UNTIL_STOP , 20 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_CRC | INT_DATA_TIMEOUT , SDIO_TRANS_MULTIBLK | SDIO_TRANS_BLK_CNT_EN | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
73 { CMD20_WRITE_DAT_UNTIL_STOP_AUT12 , 20 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_CRC | INT_DATA_TIMEOUT | INT_AUTO_CMD12 , SDIO_TRANS_MULTIBLK | SDIO_TRANS_AUTO_CMD12_EN | SDIO_TRANS_BLK_CNT_EN | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
74 { CMD23_SET_BLOCK_COUNT , 23 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
75 { CMD24_WRITE_BLOCK , 24 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_CRC | INT_DATA_TIMEOUT , SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
76 { CMD25_WRITE_MULTIPLE_BLOCK , 25 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_CRC | INT_DATA_TIMEOUT , SDIO_TRANS_MULTIBLK | SDIO_TRANS_BLK_CNT_EN | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
77 { CMD25_WRITE_MULTIPLE_BLOCK_AUT12 , 25 , INT_TR_CMPLT | CARD_SDIO_R1 | INT_DATA_CRC | INT_DATA_TIMEOUT | INT_AUTO_CMD12 , SDIO_TRANS_MULTIBLK | SDIO_TRANS_AUTO_CMD12_EN | SDIO_TRANS_BLK_CNT_EN | SDIO_TRANS_DMA_EN | SDIO_DATA_PRE },
\r
78 { CMD26_PROGRAM_CID , 26 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
79 { CMD27_PROGRAM_CSD , 27 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
80 { CMD28_SET_WRITE_PROT , 28 , INT_TR_CMPLT | CARD_SDIO_R1B | NULL , NULL },
\r
81 { CMD29_CLR_WRITE_PROT , 29 , INT_TR_CMPLT | CARD_SDIO_R1B | NULL , NULL },
\r
82 { CMD30_SEND_WRITE_PROT , 30 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
83 { CMD32_ERASE_WR_BLK_START , 32 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
84 { CMD33_ERASE_WR_BLK_END , 33 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
85 { CMD35_ERASE_GROUP_START , 35 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
86 { CMD36_ERASE_GROUP_END , 36 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
87 { CMD38_ERASE , 38 , INT_CMD_CMPLT | CARD_SDIO_R1B | NULL , NULL },
\r
88 { CMD39_FAST_IO , 39 , NULL | CARD_SDIO_R4 | NULL , NULL },
\r
89 { CMD40_GO_IRQ_STATE , 40 , NULL | CARD_SDIO_R5 | NULL , NULL },
\r
90 { CMD42_LOCK_UNLOCK_SD , 42 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
91 { CMD42_LOCK_UNLOCK_MMC , 42 , NULL | CARD_SDIO_R1B | NULL , NULL },
\r
92 { CMD55_APP_CMD , 55 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
93 { CMD56_GEN_CMD_SD , 56 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
94 { CMD56_GEN_CMD_MMC , 56 , NULL | CARD_SDIO_R1B | NULL , NULL },
\r
95 { ACMD6_SET_BUS_WIDTH , 6 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
96 { ACMD13_SD_STATUS , 13 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
97 { ACMD22_SEND_NUM_WR_BLCOKS , 22 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
98 { ACMD23_SET_WR_BLK_ERASE_COUNT , 23 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
99 { ACMD41_SD_SEND_OP_COND , 41 , NULL | CARD_SDIO_R3 | NULL , NULL },
\r
100 { ACMD42_SET_CLR_CARD_DETECT , 42 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
101 { ACMD51_SEND_SCR , 51 , NULL | CARD_SDIO_R1 | NULL , NULL },
\r
103 { CMD_MAX , 0 , NULL | CARD_SDIO_NO_RSP | NULL , NULL }
\r
106 /* every sdio controller have one s_sdio_pal_hd table */
\r
107 /* slot0,1,2 is sdio0; slot3,4,5 is sdio1; slot6,7,8 is sdio2; slot9,10,11 is sdio3; */
\r
108 sdio_pal_t pal_hd[SLOT_MAX_NUM] = {0,0,0, 0,0,0, 0,0,0, 0,0,0};
\r
110 /*********************************************************************
112 ** This function used to init card event.
\r
114 ** p_hd : sdio pal handle.
\r
117 ** Date Author Operation
118 ** 2013/09/12 ypxie create
\r
119 *********************************************************************/
\r
120 void init_card_event (sdio_pal_ptr p_hd)
\r
122 p_hd->card_event = 0;
\r
123 } /* end of card_event_init */
\r
125 uint32 wait_card_event (sdio_pal_ptr p_hd, uint32 event_id)
\r
127 if (event_id == (p_hd->card_event & event_id)) {
\r
135 void set_card_event (sdio_pal_ptr p_hd, uint32 event_id)
\r
137 p_hd->card_event |= event_id;
\r
140 /*********************************************************************
142 ** This function used to controller irq process function.
\r
144 ** msg : int status information.
\r
145 ** slot_no : slot no.
\r
148 ** Date Author Operation
149 ** 2013/09/12 ypxie create
\r
150 *********************************************************************/
\r
151 void irq_handle (uint32 isr_num)
\r
156 if(isr_num == SLOT_MAX_NUM){
\r
159 p_hd = &pal_hd[(isr_num/3)];
\r
161 msg = sdhost_get_int_st(p_hd->host_cfg);
\r
163 sdhost_int_st_sig_dis(p_hd->host_cfg, msg);
\r
164 sdhost_int_st_clr(p_hd->host_cfg, msg);
\r
166 if (0 != (msg & INT_TR_CMPLT)) {
\r
167 msg &= ~INT_DATA_TIMEOUT;
\r
168 set_card_event(p_hd, msg);
\r
170 else if (0 != (msg & INT_DMA_INT)) {
\r
171 volatile uint32 next_addr;
\r
173 next_addr = sdhost_get_dma_addr(p_hd->host_cfg);
\r
174 sdhost_set_dma_addr(p_hd->host_cfg, next_addr);
\r
176 sdhost_int_st_sig_en(p_hd->host_cfg, INT_DMA_INT);
\r
179 if (0 != (msg & INT_CMD_CMPLT)) {
\r
180 msg &= ~INT_CMD_TIMEOUT;
\r
182 set_card_event(p_hd, msg);
\r
184 } /* end of irq_card_proc */
\r
186 sdio_pal_err_e get_cmd_err_info(uint32 card_event)
\r
191 if (INT_ERR_INT & card_event) {
\r
192 err_st &= (card_event & 0x1FFF0000) >> 15;
\r
197 /*********************************************************************
\r
199 ** This function used to register sdio.
\r
201 ** slot_no : slot no.
\r
202 ** base_clk : base clock must be set val in table.
\r
204 ** p_hd : return sdio pal handle
\r
205 ** Date Author Operation
206 ** 2013/09/12 ypxie create
\r
207 *********************************************************************/
\r
208 sdio_pal_ptr sdio_pal_open (uint32 slot_no, uint32 base_clk)
\r
210 if (slot_no >= SLOT_MAX_NUM) {
\r
214 /* step 1: init members */
\r
215 pal_hd[slot_no].slot_no = slot_no;
\r
216 pal_hd[slot_no].sdio_type = (sdio_type_e)(slot_no/3);
\r
217 pal_hd[slot_no].sdio_version = sdhost_get_sdio_version(slot_no);
\r
218 pal_hd[slot_no].card_event = 0;
\r
220 /* step 2: get base address */
\r
221 pal_hd[slot_no].host_cfg = sdhost_get_base_addr(slot_no);
\r
222 if (pal_hd[slot_no].host_cfg == 0) {
\r
226 /* step 3: select slot */
\r
227 sdhost_slot_select(slot_no);
\r
229 /* step 4: enable sdio ahb clock */
\r
230 sdhost_ahb_sdio_en(slot_no);
\r
232 /* step 5: disable sd clock for delete glitch in clock line. */
\r
233 sdhost_set_sd_clk(pal_hd[slot_no].host_cfg, SDIO_OFF);
\r
235 /* step 6: ahb soft reset. */
\r
236 sdhost_ahb_sdio_rst(slot_no);
\r
238 /* step 7: set base clock */
\r
239 pal_hd[slot_no].base_clock = sdhost_set_base_clk(slot_no, base_clk);
\r
240 if (pal_hd[slot_no].base_clock == 0) {
\r
244 return &pal_hd[slot_no];
\r
245 } /* end of sdio_pal_open */
\r
247 /*********************************************************************
249 ** This function used to set power and clock, and set initialize freq, bus width.
\r
251 ** p_hd : sdio pal handle.
\r
252 ** onoff : power on or off
\r
255 ** Date Author Operation
256 ** 2013/09/22 ypxie create
\r
257 ** 2013/10/08 ypxie alter return and added check handle.
\r
258 *********************************************************************/
\r
259 BOOLEAN sdio_pal_power (sdio_pal_ptr p_hd, sdio_onoff_e onoff)
\r
267 /* reset controller */
\r
268 sdhost_reset(p_hd->host_cfg, RST_ALL);
\r
270 /* set power for sdio controller. */
\r
271 sdhost_set_voltage(p_hd->slot_no, 1800, 3000);
\r
272 sdhost_set_power(p_hd->slot_no, SDIO_ON);
\r
274 /* set base bus width and speed */
\r
275 if (p_hd->sdio_version == SDIO_20) {
\r
276 sdhost_set_speed_mode_v20(p_hd->host_cfg, SDIO_LOWSPEED);
\r
277 sdhost_set_clk_freq_v20(p_hd->host_cfg, p_hd->base_clock, 400000);
\r
278 sdhost_set_bus_width_v20(p_hd->host_cfg, SDIO_BUS_1_BIT);
\r
280 else if (p_hd->sdio_version == SDIO_30) {
\r
281 sdhost_set_speed_mode_v30(p_hd->host_cfg, SDIO_SDR13);
\r
282 sdhost_set_clk_freq_v30(p_hd->host_cfg, p_hd->base_clock, 400000);
\r
283 sdhost_set_bus_width_v30(p_hd->host_cfg, SDIO_BUS_1_BIT);
\r
286 /* open clock in sdio controller. */
\r
287 sdhost_set_internal_clk(p_hd->host_cfg, SDIO_ON);
\r
288 sdhost_set_sd_clk(p_hd->host_cfg, SDIO_ON);
\r
292 sdhost_set_sd_clk(p_hd->host_cfg, SDIO_OFF);
\r
293 sdhost_reset(p_hd->host_cfg, RST_ALL);
\r
294 sdhost_set_power(p_hd->slot_no, SDIO_OFF);
\r
303 } /* end of sdio_pal_power */
\r
305 /*********************************************************************
307 ** This function used to set clock.
\r
309 ** p_hd : sdio pal handle.
\r
310 ** clk : SDIO_CLK_400K,
\r
318 ** Date Author Operation
319 ** 2013/09/22 ypxie create
\r
320 ** 2013/10/08 ypxie alter return and added check handle.
\r
321 *********************************************************************/
\r
322 BOOLEAN sdio_set_clk (sdio_pal_ptr p_hd, uint32 clk)
\r
328 sdhost_set_sd_clk(p_hd->host_cfg, SDIO_OFF);
\r
330 if (p_hd->sdio_version == SDIO_30) {
\r
331 p_hd->sd_clock = sdhost_set_clk_freq_v30(p_hd->host_cfg, p_hd->base_clock, clk);
\r
333 else if (p_hd->sdio_version == SDIO_20) {
\r
334 p_hd->sd_clock = sdhost_set_clk_freq_v20(p_hd->host_cfg, p_hd->base_clock, clk);
\r
340 sdhost_set_internal_clk(p_hd->host_cfg, SDIO_ON);
\r
341 sdhost_set_sd_clk(p_hd->host_cfg, SDIO_ON);
\r
344 } /* end of sdio_set_clk */
\r
346 /*********************************************************************
348 ** This function used to set bus width.
\r
350 ** p_hd : sdio pal handle.
\r
351 ** bus_type : SDIO_BUS_1_BIT,
\r
356 ** Date Author Operation
357 ** 2013/09/23 ypxie create
\r
358 ** 2013/10/08 ypxie alter return and added check handle.
\r
359 *********************************************************************/
\r
360 BOOLEAN sdio_set_bus_width (sdio_pal_ptr p_hd, sdio_buswidth_e bus_type)
\r
362 if ((p_hd == NULL) || (bus_type > SDIO_BUS_8_BIT)) {
\r
366 if (p_hd->sdio_version == SDIO_30) {
\r
367 sdhost_set_bus_width_v30(p_hd->host_cfg, bus_type);
\r
368 p_hd->bus_width = bus_type;
\r
370 else if (p_hd->sdio_version == SDIO_20) {
\r
371 sdhost_set_bus_width_v20(p_hd->host_cfg, bus_type);
\r
372 p_hd->bus_width = bus_type;
\r
381 /*********************************************************************
383 ** This function used to set speed mode.
\r
385 ** p_hd : sdio pal handle.
\r
386 ** onoff : SDIO_LOWSPEED,
\r
396 ** Date Author Operation
397 ** 2013/09/23 ypxie create
\r
398 ** 2013/10/08 ypxie alter return and added check handle.
\r
399 *********************************************************************/
\r
400 BOOLEAN sdio_set_speed_mode (sdio_pal_ptr p_hd, sdio_speedmode_e spd_type)
\r
402 if ((p_hd == NULL) || (spd_type > SDIO_HS200)) {
\r
406 if (p_hd->sdio_version == SDIO_30) {
\r
407 sdhost_set_speed_mode_v30(p_hd->host_cfg, spd_type);
\r
408 p_hd->spd_mode = spd_type;
\r
410 else if (p_hd->sdio_version == SDIO_20) {
\r
411 sdhost_set_speed_mode_v20(p_hd->host_cfg, spd_type);
\r
412 p_hd->spd_mode = spd_type;
\r
421 /*********************************************************************
423 ** This function used to send command to card
\r
425 ** p_hd : sdio pal handle.
\r
426 ** cmd : command index.
\r
427 ** argu : argument of card.
\r
428 ** data_param : data information.
\r
429 ** rsp_buf : used to store response data.
\r
432 ** Date Author Operation
433 ** 2013/10/08 ypxie create
\r
434 *********************************************************************/
\r
435 PUBLIC sdio_pal_err_e sdio_send_cmd (sdio_pal_ptr p_hd,
\r
438 sdio_data_param_t *data_param,
\r
441 uint32 tmp_msg, ret_val;
\r
443 const cmd_ctl_flg_t* cmd_info = NULL;
\r
445 cmd_info = &s_cmdDetail[cmd];
\r
447 if ((cmd != cmd_info->cmd) || (p_hd == NULL)) {
\r
448 return ERR_BAD_PARAM;
\r
451 sdio_printf("%s : cmd:%x, cmdIndex:%x, argument:%x\r\n", __FUNCTION__,
\r
452 cmd, cmd_info->cmd_index, argu);
\r
454 sdhost_int_st_clr(p_hd->host_cfg, INT_ALL);
\r
455 sdhost_int_st_sig_dis(p_hd->host_cfg, INT_ALL);
\r
457 sdhost_set_data_timeout_value(p_hd->host_cfg, 0x0E);
\r
459 tmp_msg = cmd_info->int_filter;
\r
460 if (NULL != cmd_info->err_filter) {
\r
461 tmp_msg |= cmd_info->err_filter;
\r
464 if (NULL != data_param) {
\r
465 tmp_msg |= INT_DMA_INT;
\r
468 sdhost_int_st_sig_en(p_hd->host_cfg, tmp_msg);
\r
470 init_card_event(p_hd);
\r
472 if (NULL != data_param) {
\r
473 uint32 buf_size = 0;
\r
475 buf_size = data_param->blk_len * (data_param->blk_num);
\r
477 /* enable mmu, must be update cache */
\r
478 Dcache_CleanRegion((unsigned int)(data_param->data_buf), buf_size);
\r
479 Dcache_InvalRegion((unsigned int)(data_param->data_buf), buf_size);
\r
481 sdhost_set_dma_addr(p_hd->host_cfg, (uint32)(data_param->data_buf));
\r
482 sdhost_set_data_param(p_hd->host_cfg, data_param->blk_len,
\r
483 data_param->blk_num, SDIO_DMA_512K);
\r
486 sdhost_set_cmd_argu(p_hd->host_cfg, argu);
\r
487 sdhost_set_cmd(p_hd->host_cfg, cmd_info->cmd_index, cmd_info->transmode,
\r
488 SDIO_CMD_TYPE_NML, cmd_info->response);
\r
490 while (0 != wait_card_event(p_hd, cmd_info->int_filter)) {
\r
491 irq_handle(p_hd->slot_no);
\r
493 sdhost_delayus(100);
\r
495 if (time_out > 100000) {
\r
500 sdhost_reset (p_hd->host_cfg, RST_CMD_DAT_LINE);
\r
502 if (0 != (p_hd->card_event & INT_DATA_TIMEOUT))
\r
504 if ( CMD38_ERASE == cmd)
\r
506 sdio_printf ("sdio may be erase R1b is too long");
\r
507 time_out = SCI_GetTickCount();
\r
509 /* BIT_20 is data[0]'s pin status */
\r
510 while(0 == (BIT_20 & sdhost_get_pin_state(p_hd->host_cfg))) {
\r
511 sdhost_delayus (1000);
\r
512 if ((time_out + 20000) < SCI_GetTickCount()) {
\r
513 sdhost_reset(p_hd->host_cfg, RST_CMD_DAT_LINE);
\r
514 return ERR_DATA_TIMEOUT;
\r
518 p_hd->card_event &= ~INT_DATA_TIMEOUT;
\r
522 sdio_printf ("SDIO_Card error = 0x%x", p_hd->card_event);
\r
523 return p_hd->card_event;
\r
527 sdhost_get_response(p_hd->host_cfg, cmd_info->response, rsp_buf);
\r
529 sdio_printf(("resp[0-4]:%02X, %02X, %02X, %02X\r\n",
\r
530 rsp_buf[0], rsp_buf[1], rsp_buf[2], rsp_buf[3]));
\r
531 return get_cmd_err_info(p_hd->card_event);
\r
532 } /* end of sdio_send_cmd */