00001
00044 #ifndef SDMMC_SDMMC_H_INCLUDED
00045 #define SDMMC_SDMMC_H_INCLUDED
00046
00047 #include <types.h>
00048 #include <bitops.h>
00049 #include <slist.h>
00050 #include <buffer.h>
00051 #include <chip/portmux.h>
00052 #include <dmac/dma_controller.h>
00053
00055 struct sdmmc_cid {
00056 uint8_t manufacturer_id;
00057 uint16_t application_id;
00058 char name[6];
00059 uint8_t revision;
00060 uint32_t serial;
00061 uint16_t manu_year;
00062 uint8_t manu_month;
00063 uint8_t checksum;
00064 };
00065
00067 struct sdmmc_csd {
00068 uint8_t mmc_version;
00069 uint16_t command_classes;
00070 uint16_t read_access_time_clks;
00071 uint32_t read_access_time_ns;
00072 uint32_t write_speed_factor;
00073 uint32_t max_transfer_rate;
00074 uint32_t read_block_length;
00075 uint32_t write_block_length;
00076 uint32_t capacity;
00077 uint32_t can_read_partial:1,
00078 can_read_misaligned:1,
00079 can_write_partial:1,
00080 can_write_misaligned:1;
00081 };
00082
00084 struct sdmmc_command {
00086 uint32_t opcode;
00088 uint32_t arg;
00090 uint32_t resp[4];
00092 unsigned long flags;
00093 #define SDMMC_RSP_PRESENT (1 << 0)
00094 #define SDMMC_RSP_136 (1 << 1)
00095 #define SDMMC_RSP_CRC (1 << 2)
00096 #define SDMMC_RSP_BUSY (1 << 3)
00097 #define SDMMC_RSP_MASK (15)
00098
00099
00100 #define SDMMC_RSP_NONE (0)
00101 #define SDMMC_RSP_R1 (SDMMC_RSP_PRESENT | SDMMC_RSP_CRC)
00102 #define SDMMC_RSP_R1B (SDMMC_RSP_PRESENT | SDMMC_RSP_CRC | SDMMC_RSP_BUSY)
00103 #define SDMMC_RSP_R2 (SDMMC_RSP_PRESENT | SDMMC_RSP_136 | SDMMC_RSP_CRC)
00104 #define SDMMC_RSP_R3 (SDMMC_RSP_PRESENT)
00105 #define SDMMC_RSP_R4 (SDMMC_RSP_PRESENT)
00106 #define SDMMC_RSP_R5 (SDMMC_RSP_PRESENT | SDMMC_RSP_CRC)
00107 #define SDMMC_RSP_R6 (SDMMC_RSP_PRESENT | SDMMC_RSP_CRC)
00108 #define SDMMC_RSP_R7 (SDMMC_RSP_PRESENT | SDMMC_RSP_CRC)
00109
00110 #define SDMMC_CMD_OPD (1 << 4)
00111
00113 int status;
00114 };
00115
00119 enum sdmmc_req_flag {
00120 SDMMC_REQ_WRITE,
00121 SDMMC_REQ_STOP,
00122 SDMMC_REQ_INITSEQ,
00123 };
00124
00128 struct sdmmc_request {
00130 struct slist buf_list;
00132 struct slist_node node;
00134 struct sdmmc_command cmd;
00136 struct sdmmc_slot *slot;
00138 uint32_t blocks;
00140 uint32_t block_size;
00142 unsigned long flags;
00147 void (*req_started)(struct sdmmc_request *req);
00152 void (*req_done)(struct sdmmc_request *req);
00159 void (*buf_list_done)(struct sdmmc_request *req,
00160 struct slist *buf_list);
00162 void *context;
00164 int status;
00166 size_t bytes_xfered;
00167 };
00168
00169 enum sdmmc_card_type {
00170 SDMMC_CARD_TYPE_SD,
00171 SDMMC_CARD_TYPE_SDHC,
00172 SDMMC_CARD_TYPE_MMC,
00173 SDMMC_CARD_TYPE_SDIO
00174 };
00175
00177 struct sdmmc_card {
00179 enum sdmmc_card_type type;
00181 uint32_t rca;
00183 struct sdmmc_cid cid;
00185 struct sdmmc_csd csd;
00187 uint32_t block_size;
00188
00189 uint32_t read_timeout_ns;
00190
00191 uint32_t read_timeout_clks;
00192
00193 uint32_t write_timeout_ns;
00194
00195 uint32_t write_timeout_clks;
00196 };
00197
00199 enum sdmmc_slot_flags {
00200 SDMMC_SLOT_CARD_DETECT,
00201 SDMMC_SLOT_CARD_PRESENT,
00203 SDMMC_SLOT_HCS,
00204 SDMMC_SLOT_HIGH_SPEED,
00205 SDMMC_SLOT_PROBING,
00206 };
00207
00208 struct sdmmc_cd;
00209
00211 struct sdmmc_slot {
00213 int id;
00215 struct sdmmc_host *host;
00217 unsigned long flags;
00219 struct sdmmc_card card;
00221 uint32_t bcr;
00223 uint32_t ocr;
00225 int bus_width;
00227 int bus_width_max;
00229 int32_t f_max;
00231 void (*notify_card_detect)(void *context);
00233 void *context;
00235 struct sdmmc_cd *cd;
00236 };
00237
00239 struct sdmmc_host {
00241 void (*enable)(struct sdmmc_host *host);
00243 void (*power_up)(struct sdmmc_host *host,
00244 struct sdmmc_slot *slot);
00246 void (*power_down)(struct sdmmc_host *host,
00247 struct sdmmc_slot *slot);
00249 void (*set_voltage)(struct sdmmc_host *host,
00250 uint32_t ocr);
00252 void (*set_bus_params)(struct sdmmc_host *host,
00253 struct sdmmc_slot *slot);
00255 int slot_count;
00257 struct sdmmc_slot *(*get_slot)(struct sdmmc_host *host,
00258 int slot_id);
00260 bool (*wp_is_active)(struct sdmmc_host *host,
00261 struct sdmmc_slot *slot);
00263 void (*submit_req)(struct sdmmc_host *host,
00264 struct sdmmc_request *req);
00266 int (*submit_buf_list)(struct sdmmc_host *host,
00267 struct sdmmc_request *req,
00268 struct slist *buf_list);
00270 unsigned int f_max;
00272 unsigned int f_min;
00274 unsigned int f_cur;
00276 uint32_t ocr_avail;
00277 };
00278
00282 static inline struct sdmmc_slot *sdmmc_card_get_slot(struct sdmmc_card *card)
00283 {
00284 return container_of(card, struct sdmmc_slot, card);
00285 }
00286
00296 extern void sdmmc_req_prep_transfer(struct sdmmc_slot *slot,
00297 struct sdmmc_request *req,
00298 uint32_t lba, uint32_t nr_blocks, bool write);
00299
00305 static inline void sdmmc_req_init(struct sdmmc_request *req)
00306 {
00307 req->flags = 0;
00308 slist_init(&req->buf_list);
00309 req->blocks = 0;
00310 req->block_size = 0;
00311 }
00312
00321 static inline void sdmmc_req_prep_cmd(struct sdmmc_request *req,
00322 uint32_t opcode, uint32_t arg, unsigned long flags)
00323 {
00324 req->cmd.opcode = opcode;
00325 req->cmd.arg = arg;
00326 req->cmd.flags = flags;
00327 }
00328
00335 static inline void sdmmc_req_prep_data(struct sdmmc_request *req,
00336 struct buffer *buf)
00337 {
00338 slist_insert_tail(&req->buf_list, &buf->node);
00339 req->blocks = 1;
00340 req->block_size = buf->len;
00341 }
00342
00350 static inline void sdmmc_req_prep_callback(struct sdmmc_request *req,
00351 void (*callback)(struct sdmmc_request *req),
00352 void *data)
00353 {
00354 req->req_done = callback;
00355 req->context = data;
00356 }
00357
00367 static inline void sdmmc_slot_update(struct sdmmc_slot *slot)
00368 {
00369 struct sdmmc_host *host = slot->host;
00370
00371 host->set_bus_params(host, slot);
00372 }
00373
00380 extern void sdmmc_decode_sd_cid(struct sdmmc_card *card, const be32_t *raw_cid);
00381
00391 extern int sdmmc_decode_mmc_cid(struct sdmmc_card *card, const be32_t *raw_cid);
00392
00402 extern int sdmmc_decode_sd_csd(struct sdmmc_card *card, const be32_t *raw_csd);
00403
00413 extern int sdmmc_decode_mmc_csd(struct sdmmc_card *card,
00414 const be32_t *raw_csd);
00415
00422 static inline void sdmmc_card_set_type(struct sdmmc_card *card,
00423 enum sdmmc_card_type type)
00424 {
00425 card->type = type;
00426 sdmmc_slot_update(sdmmc_card_get_slot(card));
00427 }
00428
00435 extern void sdmmc_card_update_timeouts(struct sdmmc_card *card,
00436 uint32_t mmc_hz);
00437
00445 static inline uint32_t sdmmc_card_get_rca(struct sdmmc_card *card)
00446 {
00447 return card->rca >> 16;
00448 }
00449
00458 static inline uint32_t sdmmc_card_block2addr(struct sdmmc_card *card,
00459 uint32_t lba)
00460 {
00461 if (card->type == SDMMC_CARD_TYPE_SDHC)
00462 return lba;
00463
00464 return lba * card->block_size;
00465 }
00466
00473 extern void sdmmc_slot_submit_req(struct sdmmc_slot *slot,
00474 struct sdmmc_request *req);
00475
00490 static inline int sdmmc_req_submit_buf_list(struct sdmmc_host *host,
00491 struct sdmmc_request *req, struct slist *buf_list)
00492 {
00493 assert(host && req && buf_list);
00494
00495 return host->submit_buf_list(host, req, buf_list);
00496 }
00497
00506 static inline bool sdmmc_slot_is_card_present(struct sdmmc_slot *slot)
00507 {
00508 return test_bit(SDMMC_SLOT_CARD_PRESENT, &slot->flags);
00509 }
00510
00521 static inline bool sdmmc_slot_is_card_write_protected(struct sdmmc_slot *slot)
00522 {
00523 return slot->host->wp_is_active(slot->host, slot);
00524 }
00525
00533 extern void sdmmc_slot_power_up(struct sdmmc_slot *slot);
00534
00544 extern void sdmmc_slot_power_down(struct sdmmc_slot *slot);
00545
00554 extern uint32_t sdmmc_slot_set_voltage(struct sdmmc_slot *slot, uint32_t ocr);
00555
00568 extern void sdmmc_slot_set_f_max(struct sdmmc_slot *slot, int32_t f_max);
00569
00576 extern void sdmmc_slot_set_bus_width(struct sdmmc_slot *slot,
00577 unsigned int bits);
00578
00588 extern void sdmmc_slot_notify_card_detect(struct sdmmc_slot *slot, int value);
00589
00597 extern void sdmmc_slot_init(struct sdmmc_slot *slot, struct sdmmc_host *host,
00598 int slot_id);
00599
00605 extern void sdmmc_probe_notify_card_detect(void *data);
00606
00616 extern void *sdmmc_probe_init(struct sdmmc_slot *slot,
00617 void (*event)(struct sdmmc_slot *slot, void *context),
00618 void *context);
00619
00626 extern struct sdmmc_cd *sdmmc_cd_init(struct sdmmc_slot *slot, gpio_pin_t pin);
00627
00633 extern void sdmmc_cd_enable(struct sdmmc_cd *cd);
00634
00640 static inline void sdmmc_host_enable(struct sdmmc_host *host)
00641 {
00642 assert(host);
00643 assert(host->enable);
00644
00645 host->enable(host);
00646 }
00647
00648 #endif
00649