- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

# include/sdmmc/sdmmc.h

Go to the documentation of this file.

    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 /* Combinations of the above */
    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)        /* open drain mode */
    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         /* Data read timeout (ns) */
    00189         uint32_t                read_timeout_ns;
    00190         /* Data read timeout (clks) */
    00191         uint32_t                read_timeout_clks;
    00192         /* Data write timeout (ns) */
    00193         uint32_t                write_timeout_ns;
    00194         /* Data write timeout (clks) */
    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 /* SDMMC_SDMMC_H_INCLUDED */
    00649