* Given a 128-bit response, decode to our card CSD structure. */
| 64 | * Given a 128-bit response, decode to our card CSD structure. |
| 65 | */ |
| 66 | static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card) |
| 67 | { |
| 68 | rt_uint32_t a, b; |
| 69 | struct rt_mmcsd_csd *csd = &card->csd; |
| 70 | rt_uint32_t *resp = card->resp_csd; |
| 71 | |
| 72 | /* |
| 73 | * We only understand CSD structure v1.1 and v1.2. |
| 74 | * v1.2 has extra information in bits 15, 11 and 10. |
| 75 | * We also support eMMC v4.4 & v4.41. |
| 76 | */ |
| 77 | csd->csd_structure = GET_BITS(resp, 126, 2); |
| 78 | if (csd->csd_structure == 0) |
| 79 | { |
| 80 | LOG_E("unrecognised CSD structure version %d!", csd->csd_structure); |
| 81 | |
| 82 | return -RT_ERROR; |
| 83 | } |
| 84 | |
| 85 | csd->taac = GET_BITS(resp, 112, 8); |
| 86 | csd->nsac = GET_BITS(resp, 104, 8); |
| 87 | csd->tran_speed = GET_BITS(resp, 96, 8); |
| 88 | csd->card_cmd_class = GET_BITS(resp, 84, 12); |
| 89 | csd->rd_blk_len = GET_BITS(resp, 80, 4); |
| 90 | csd->rd_blk_part = GET_BITS(resp, 79, 1); |
| 91 | csd->wr_blk_misalign = GET_BITS(resp, 78, 1); |
| 92 | csd->rd_blk_misalign = GET_BITS(resp, 77, 1); |
| 93 | csd->dsr_imp = GET_BITS(resp, 76, 1); |
| 94 | csd->c_size = GET_BITS(resp, 62, 12); |
| 95 | csd->c_size_mult = GET_BITS(resp, 47, 3); |
| 96 | csd->r2w_factor = GET_BITS(resp, 26, 3); |
| 97 | csd->wr_blk_len = GET_BITS(resp, 22, 4); |
| 98 | csd->wr_blk_partial = GET_BITS(resp, 21, 1); |
| 99 | csd->csd_crc = GET_BITS(resp, 1, 7); |
| 100 | |
| 101 | card->card_blksize = 1 << csd->rd_blk_len; |
| 102 | card->tacc_clks = csd->nsac * 100; |
| 103 | card->tacc_ns = (tacc_uint[csd->taac & 0x07] * tacc_value[(csd->taac & 0x78) >> 3] + 9) / 10; |
| 104 | card->max_data_rate = tran_unit[csd->tran_speed & 0x07] * tran_value[(csd->tran_speed & 0x78) >> 3]; |
| 105 | if (csd->wr_blk_len >= 9) |
| 106 | { |
| 107 | a = GET_BITS(resp, 42, 5); |
| 108 | b = GET_BITS(resp, 37, 5); |
| 109 | card->erase_size = (a + 1) * (b + 1); |
| 110 | card->erase_size <<= csd->wr_blk_len - 9; |
| 111 | } |
| 112 | |
| 113 | return 0; |
| 114 | } |
| 115 | |
| 116 | /* |
| 117 | * Read extended CSD. |
no test coverage detected