📄 sdio_protocol.c
字号:
sdio_card->fbr[func].fun_ext_if_code = r5.data; SDIO_FN0_READ_REG(FNn_CIS_POINTER_1(func)); tmp = r5.data; SDIO_FN0_READ_REG(FNn_CIS_POINTER_2(func)); tmp |= r5.data << 8; SDIO_FN0_READ_REG(FNn_CIS_POINTER_3(func)); tmp |= r5.data << 16; sdio_card->fbr[func].pfcis = tmp; SDIO_FN0_READ_REG(FNn_CSA_POINTER_1(func)); tmp = r5.data; SDIO_FN0_READ_REG(FNn_CSA_POINTER_2(func)); tmp |= r5.data << 8; SDIO_FN0_READ_REG(FNn_CSA_POINTER_3(func)); tmp |= r5.data << 16; sdio_card->fbr[func].pcsa = tmp; SDIO_FN0_READ_REG(FNn_BLKSZ_1(func)); tmp = r5.data; SDIO_FN0_READ_REG(FNn_BLKSZ_2(func)); tmp |= r5.data << 8; sdio_card->fbr[func].fn_blksz = tmp; dbg("func:%d, csa:0x%x, cis:0x%x, blksz:0x%x", func, sdio_card->fbr[func].pcsa, sdio_card->fbr[func].pfcis, sdio_card->fbr[func].fn_blksz); return 0;}static int get_sdio_cccr_info(struct mss_card *card){ struct mss_host *host = card->slot->host; struct sdio_card *sdio_card = card->prot_card; struct mss_cmd *cmd = &sdio_card->cmd; struct mss_ll_request *llreq = &sdio_card->llreq; struct sdio_response_r5 r5; int ret, arg; u32 tmp; SDIO_FN0_READ_REG(CCCR_SDIO_REVISION); sdio_card->cccr.sdiox = (r5.data >> 4) & 0xf; sdio_card->cccr.cccrx = r5.data & 0xf; SDIO_FN0_READ_REG(SD_SPEC_REVISION); sdio_card->cccr.sdx = r5.data & 0xf; SDIO_FN0_READ_REG(IO_ENABLE); sdio_card->cccr.ioex = r5.data; SDIO_FN0_READ_REG(IO_READY); sdio_card->cccr.iorx = r5.data; SDIO_FN0_READ_REG(INT_ENABLE); sdio_card->cccr.intex = r5.data; SDIO_FN0_READ_REG(INT_PENDING); sdio_card->cccr.intx = r5.data; SDIO_FN0_READ_REG(BUS_IF_CTRL); sdio_card->cccr.buswidth = r5.data & 0x3; sdio_card->cccr.cd = (r5.data >> 7) & 0x1; SDIO_FN0_READ_REG(CARD_CAPABILITY); sdio_card->cccr.sdc = r5.data & 0x1; sdio_card->cccr.smb = (r5.data >> 1) & 0x1; sdio_card->cccr.srw = (r5.data >> 2) & 0x1; sdio_card->cccr.sbs = (r5.data >> 3) & 0x1; sdio_card->cccr.s4mi = (r5.data >> 4) & 0x1; sdio_card->cccr.e4mi = (r5.data >> 5) & 0x1; sdio_card->cccr.lsc = (r5.data >> 6) & 0x1; sdio_card->cccr.ls4b = (r5.data >> 7) & 0x1; SDIO_FN0_READ_REG(COMMON_CIS_POINTER_1); tmp = r5.data; SDIO_FN0_READ_REG(COMMON_CIS_POINTER_2); tmp |= r5.data << 8; SDIO_FN0_READ_REG(COMMON_CIS_POINTER_3); tmp |= r5.data << 16; sdio_card->cccr.pccis = tmp; SDIO_FN0_READ_REG(BUS_SUSPEND); sdio_card->cccr.bs = r5.data & 0x1; sdio_card->cccr.br = (r5.data >> 1) & 0x1; SDIO_FN0_READ_REG(FUNCTION_SELECT); sdio_card->cccr.fsx = r5.data & 0xf; sdio_card->cccr.df = (r5.data >> 7) & 0x1; SDIO_FN0_READ_REG(EXEC_FLAGS); sdio_card->cccr.exx = r5.data; SDIO_FN0_READ_REG(READY_FLAGS); sdio_card->cccr.rfx = r5.data; SDIO_FN0_READ_REG(FN0_BLKSZ_1); tmp = r5.data; SDIO_FN0_READ_REG(FN0_BLKSZ_2); tmp |= r5.data << 8; sdio_card->cccr.fn0_blksz = tmp; SDIO_FN0_READ_REG(POWER_CTRL); sdio_card->cccr.smpc = r5.data & 0x1; sdio_card->cccr.empc = (r5.data >> 1) & 0x1;#if 0 dbg("cccr, card capability: low_speed_card:%d" " low_speed_card_4bit:%d int_bw_block:%d\n" " suspend/resume:%d read/wait:%d multiblcok:%d direct_cmd:%d\n", sdio_card->cccr.lsc, sdio_card->cccr.ls4b, sdio_card->cccr.s4mi, sdio_card->cccr.sbs, sdio_card->cccr.srw, sdio_card->cccr.smb, sdio_card->cccr.sdc); dbg("sdio:%d, sd:%d, cccr:%d, common cis:0x%x\n", sdio_card->cccr.sdiox, sdio_card->cccr.sdx, sdio_card->cccr.cccrx, sdio_card->cccr.pccis); dbg("spmc:%d\n", sdio_card->cccr.smpc); dbg("ioe:0x%x, ior:0x%x\n", sdio_card->cccr.ioex, sdio_card->cccr.iorx);#endif return 0;}static int get_sdio_fcis_info(struct mss_card *card, int func){ struct mss_host *host= card->slot->host; struct sdio_card *sdio_card = card->prot_card; struct mss_cmd *cmd = &sdio_card->cmd; struct mss_ll_request *llreq = &sdio_card->llreq; int ret, arg, tuple_body_len, tuple_type; struct sdio_response_r5 r5; u32 addr, next_addr; u32 tmp; u16 tmp16; addr = sdio_card->fbr[func].pfcis; while(1) { SDIO_FN0_READ_REG(addr); tuple_type = r5.data; SDIO_FN0_READ_REG(addr + 1); tuple_body_len = r5.data; next_addr = addr + 2 + r5.data; switch (tuple_type) { case CISTPL_NULL: case CISTPL_END: dbg("cistpl null/end\n"); goto finish; case CISTPL_CHECKSUM: dbg("cistpl checksum\n"); break; case CISTPL_VERS_1: dbg("cistpl vers level 1\n"); break; case CISTPL_ALTSTR: dbg("cistpl altstr\n"); break; case CISTPL_MANFID: dbg("cistpl manfid\n"); break; case CISTPL_FUNCID: dbg("cistpl funcid\n"); SDIO_FN0_READ_REG(addr + 2); if (r5.data != 0x0c) dbg("not a sdio card\n"); else dbg(" a sdio card\n"); break; case CISTPL_FUNCE: /* Type of extended data, should be 1 */ SDIO_FN0_READ_REG(addr + 2); if (r5.data == 0x01) dbg("1 type extended tuple\n"); /* FUNCTION_INFO */ SDIO_FN0_READ_REG(addr + 3); sdio_card->fcis[func].func_info = r5.data; /* STD_IO_REV */ SDIO_FN0_READ_REG(addr + 4); sdio_card->fcis[func].std_io_rev = r5.data; /* card psn */ SDIO_FN0_READ_REG(addr + 5); tmp = r5.data; SDIO_FN0_READ_REG(addr + 6); tmp |= r5.data << 8; SDIO_FN0_READ_REG(addr + 7); tmp |= r5.data << 16; SDIO_FN0_READ_REG(addr + 8); tmp |= r5.data << 24; sdio_card->fcis[func].card_psn = tmp; /* card csa size */ SDIO_FN0_READ_REG(addr + 9); tmp = r5.data; SDIO_FN0_READ_REG(addr + 10); tmp |= r5.data << 8; SDIO_FN0_READ_REG(addr + 11); tmp |= r5.data << 16; SDIO_FN0_READ_REG(addr + 12); tmp |= r5.data << 24; sdio_card->fcis[func].csa_size = tmp; /* csa property */ SDIO_FN0_READ_REG(addr + 13); sdio_card->fcis[func].csa_property = r5.data; /* max_blk_size */ SDIO_FN0_READ_REG(addr + 14); tmp16 = r5.data; SDIO_FN0_READ_REG(addr + 15); tmp16 |= r5.data << 8; sdio_card->fcis[func].max_blk_size = tmp16; /* ocr */ SDIO_FN0_READ_REG(addr + 16); tmp = r5.data; SDIO_FN0_READ_REG(addr + 17); tmp |= r5.data << 8; SDIO_FN0_READ_REG(addr + 18); tmp |= r5.data << 16; SDIO_FN0_READ_REG(addr + 19); tmp |= r5.data << 24; sdio_card->fcis[func].ocr = tmp; /* pwr */ SDIO_FN0_READ_REG(addr + 20); sdio_card->fcis[func].op_min_pwr = r5.data; SDIO_FN0_READ_REG(addr + 21); sdio_card->fcis[func].op_avg_pwr = r5.data; SDIO_FN0_READ_REG(addr + 22); sdio_card->fcis[func].op_max_pwr = r5.data; SDIO_FN0_READ_REG(addr + 23); sdio_card->fcis[func].sb_min_pwr = r5.data; SDIO_FN0_READ_REG(addr + 24); sdio_card->fcis[func].sb_avg_pwr = r5.data; SDIO_FN0_READ_REG(addr + 25); sdio_card->fcis[func].sb_max_pwr = r5.data; SDIO_FN0_READ_REG(addr + 26); tmp16 = r5.data; SDIO_FN0_READ_REG(addr + 27); tmp16 |= r5.data << 8; sdio_card->fcis[func].min_bw = tmp16; SDIO_FN0_READ_REG(addr + 28); tmp16 = r5.data; SDIO_FN0_READ_REG(addr + 29); tmp16 |= r5.data << 8; sdio_card->fcis[func].opt_bw = tmp16; // SDIO1.0 is 28, and 1.1 is 36 if (sdio_card->cccr.sdiox == 0) break; SDIO_FN0_READ_REG(addr + 30); tmp16 = r5.data; SDIO_FN0_READ_REG(addr + 31); tmp16 |= r5.data << 8; sdio_card->fcis[func].enable_timeout_val= tmp16; break; case CISTPL_SDIO_STD: dbg("sdio std\n"); break; case CISTPL_SDIO_EXT: dbg("sdio std ext\n"); break; default : dbg("not supported cis\n"); } addr = next_addr; }finish:#if 0 dbg("fcis %d\nfunction_info:0x%x std_io_rev:0x%x card_psn:0x%x\n" "csa_size:0x%x csa_property:0x%x max_blk_size:0x%x\n" "ocr:0x%x op_min_pwr:0x%x op_avg_pwr:0x%x op_max_pwr:0x%x" "sb_min_pwr:0x%x sb_avg_pwr:0x%x sb_max_pwr:0x%x" "min_bw:0x%x opt_bw:0x%x time out:%x\n",func, sdio_card->fcis[func].func_info, sdio_card->fcis[func].std_io_rev, sdio_card->fcis[func].card_psn, sdio_card->fcis[func].csa_size, sdio_card->fcis[func].csa_property, sdio_card->fcis[func].max_blk_size, sdio_card->fcis[func].ocr, sdio_card->fcis[func].op_min_pwr, sdio_card->fcis[func].op_avg_pwr, sdio_card->fcis[func].op_max_pwr, sdio_card->fcis[func].sb_min_pwr, sdio_card->fcis[func].sb_avg_pwr, sdio_card->fcis[func].sb_max_pwr, sdio_card->fcis[func].min_bw, sdio_card->fcis[func].opt_bw, sdio_card->fcis[func].enable_timeout_val);#endif return 0;}static int get_sdio_ccis_info(struct mss_card *card){ struct mss_host *host= card->slot->host; struct sdio_card *sdio_card = card->prot_card; struct mss_cmd *cmd = &sdio_card->cmd; struct mss_ll_request *llreq = &sdio_card->llreq; int ret, arg, tuple_body_len, tuple_type; struct sdio_response_r5 r5; u32 addr, next_addr; u16 tmp16; addr = sdio_card->cccr.pccis; while (1) { SDIO_FN0_READ_REG(addr); tuple_type = r5.data; SDIO_FN0_READ_REG(addr + 1); tuple_body_len = r5.data; next_addr = addr + 2 + r5.data; switch (tuple_type) { case CISTPL_NULL: case CISTPL_END: dbg("cistpl null/end\n"); goto finish; case CISTPL_CHECKSUM: dbg("cistpl checksum\n"); break; case CISTPL_VERS_1: dbg("cistpl vers level 1\n"); break; case CISTPL_ALTSTR: dbg("cistpl altstr\n"); break; case CISTPL_MANFID: dbg("cistpl manfid\n"); SDIO_FN0_READ_REG(addr + 2); tmp16 = r5.data; SDIO_FN0_READ_REG(addr + 3); tmp16 |= r5.data << 8; sdio_card->ccis.manufacturer = tmp16; SDIO_FN0_READ_REG(addr + 4); tmp16 = r5.data; SDIO_FN0_READ_REG(addr + 5); tmp16 |= r5.data << 8; sdio_card->ccis.card_id = tmp16; break; case CISTPL_FUNCID: dbg("cistpl funcid\n"); SDIO_FN0_READ_REG(addr + 2); if (r5.data != 0x0c) dbg("not a sdio card\n"); else dbg(" a sdio card\n"); break; case CISTPL_FUNCE: dbg("cistpl funce\n"); SDIO_FN0_READ_REG(addr + 2); if (r5.data == 0x00) dbg("0 type extended tuple\n"); SDIO_FN0_READ_REG(addr + 3); tmp16 = r5.data; SDIO_FN0_READ_REG(addr + 4); tmp16 = r5.data << 8; sdio_card->ccis.fn0_block_size = tmp16; SDIO_FN0_READ_REG(addr + 5); sdio_card->ccis.max_tran_speed = r5.data; //slot->tran_speed = card->ccis.max_tran_speed; break; case CISTPL_SDIO_STD: dbg("sdio std\n"); break; case CISTPL_SDIO_EXT: dbg("sdio std ext\n"); break; default: dbg("not supported cis\n"); } addr = next_addr; } finish:#if 0 dbg("ccis:\nmanf:0x%x card_id:0x%x block_size:0x%x\nmax_tran_speed:0x%x\n",sdio_card->ccis.manufacturer, sdio_card->ccis.card_id, sdio_card->ccis.fn0_block_size, sdio_card->ccis.max_tran_speed);#endif return 0;}/*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -