blob: ea53a81f7cdd643cf57332a19e1c3a5630531e10 [file] [log] [blame] [edit]
/*
* Copyright 2017, Data61
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
* ABN 41 687 119 230.
*
* This software may be distributed and modified according to the terms of
* the BSD 2-Clause license. Note that NO WARRANTY is provided.
* See "LICENSE_BSD2.txt" for details.
*
* @TAG(DATA61_BSD)
*/
#pragma once
#include <sdhc/mmc.h>
#include "sdhc.h"
/* MMC Standard Command Index, Response Type */
#define MMC_GO_IDLE_STATE 0 //NONE
#define MMC_SEND_OP_COND 1 //R3
#define MMC_ALL_SEND_CID 2 //R2
#define MMC_SEND_RELATIVE_ADDR 3 //R1
#define MMC_SET_DSR 4 //NONE
#define MMC_IO_SEND_OP_COND 5 //R4
#define MMC_SWITCH 6 //R1
#define MMC_SELECT_CARD 7 //R1b
#define MMC_SEND_EXT_CSD 8 //R1
#define MMC_SEND_CSD 9 //R2
#define MMC_SEND_CID 10 //R2
#define MMC_READ_DAT_UNTIL_STOP 11 //R1
#define MMC_STOP_TRANSMISSION 12 //R1b
#define MMC_SEND_STATUS 13 //R1
#define MMC_GO_INACTIVE_STATE 15 //NONE
#define MMC_SET_BLOCKLEN 16 //R1
#define MMC_READ_SINGLE_BLOCK 17 //R1
#define MMC_READ_MULTIPLE_BLOCK 18 //R1
#define MMC_WRITE_DAT_UNTIL_STOP 20 //R1
#define MMC_WRITE_BLOCK 24 //R1
#define MMC_WRITE_MULTIPLE_BLOCK 25 //R1
#define MMC_PROGRAM_CID 26 //R1
#define MMC_PROGRAM_CSD 27 //R1
#define MMC_SET_WRITE_PROT 28 //R1b
#define MMC_CLR_WRITE_PROT 29 //R1b
#define MMC_SEND_WRITE_PROT 30 //R1
#define MMC_TAG_SECTOR_START 32 //R1
#define MMC_TAG_SECTOR_END 33 //R1
#define MMC_UNTAG_SECTOR 34 //R1
#define MMC_TAG_ERASE_GROUP_START 35 //R1
#define MMC_TAG_ERASE_GROUP_END 36 //R1
#define MMC_UNTAG_ERASE_GROUP 37 //R1
#define MMC_ERASE 38 //R1b
#define MMC_FAST_IO 39 //R4
#define MMC_GO_IRQ_STATE 40 //R5
#define MMC_LOCK_UNLOCK 42 //R1b
#define MMC_IO_RW_DIRECT 52 //R5
#define MMC_IO_RW_EXTENDED 53 //R5
#define MMC_APP_CMD 55 //R1
#define MMC_GEN_CMD 56 //R1b
#define MMC_RW_MULTIPLE_REGISTER 60 //R1b
#define MMC_RW_MULTIPLE_BLOCK 61 //R1b
/* Application Specific Command(ACMD). */
#define SD_SET_BUS_WIDTH 6 //R1
#define SD_SD_STATUS 13 //R1
#define SD_SEND_NUM_WR_SECTORS 22 //R1
#define SD_SET_WR_BLK_ERASE_COUNT 23 //R1
#define SD_SD_APP_OP_COND 41 //R1
#define SD_SET_CLR_CARD_DETECT 42 //R1
#define SD_SEND_SCR 51 //R1
/* MMC Voltage Level */
#define MMC_VDD_33_34 (1 << 21)
#define MMC_VDD_32_33 (1 << 20)
#define MMC_VDD_31_32 (1 << 19)
#define MMC_VDD_30_31 (1 << 18)
#define MMC_VDD_29_30 (1 << 17)
/* Bus width */
#define MMC_MODE_8BIT 0x04
#define MMC_MODE_4BIT 0x02
enum mmc_rsp_type {
MMC_RSP_TYPE_NONE = 0,
MMC_RSP_TYPE_R1,
MMC_RSP_TYPE_R1b,
MMC_RSP_TYPE_R2,
MMC_RSP_TYPE_R3,
MMC_RSP_TYPE_R4,
MMC_RSP_TYPE_R5,
MMC_RSP_TYPE_R5b,
MMC_RSP_TYPE_R6,
};
enum mmc_card_type {
CARD_TYPE_UNKNOWN = 0,
CARD_TYPE_MMC,
CARD_TYPE_SD,
CARD_TYPE_SDIO,
};
enum mmc_card_status {
CARD_STS_ACTIVE = 0,
CARD_STS_INACTIVE,
CARD_STS_BUSY,
};
struct mmc_data {
uintptr_t pbuf;
void *vbuf;
uint32_t data_addr;
uint32_t block_size;
uint32_t blocks;
};
struct mmc_cmd {
/* Data */
uint32_t index;
uint32_t arg;
uint32_t response[4];
struct mmc_data *data;
/* Type */
enum mmc_rsp_type rsp_type;
/* For async handling */
sdio_cb cb;
void *token;
/* For queueing */
struct mmc_cmd *next;
int complete;
};
struct cid {
uint8_t reserved;
uint8_t manfid;
union {
struct {
uint8_t bga;
uint8_t oemid;
char name[6];
uint8_t rev;
uint32_t serial;
uint8_t date;
} mmc_cid;
struct {
uint16_t oemid;
char name[5];
uint8_t rev;
uint32_t serial;
uint16_t date;
} sd_cid;
};
} __attribute__((packed));
struct csd {
uint8_t structure;
uint8_t tran_speed;
uint8_t read_bl_len;
uint32_t c_size;
uint8_t c_size_mult;
};
struct mmc_card {
uint32_t ocr;
uint32_t raw_cid[4];
uint32_t raw_csd[4];
uint16_t raw_rca;
uint32_t raw_scr[2];
uint32_t type;
uint32_t voltage;
uint32_t version;
uint32_t high_capacity;
uint32_t status;
ps_dma_man_t *dalloc;
sdio_host_dev_t *sdio;
};
static inline int host_send_command(struct mmc_card *card, struct mmc_cmd *cmd, sdio_cb cb, void *token)
{
return sdio_send_command(card->sdio, cmd, cb, token);
}
static inline int host_nth_irq(mmc_card_t card, int n)
{
return sdio_nth_irq(card->sdio, n);
}
static inline int host_handle_irq(struct mmc_card *card, int irq)
{
return sdio_handle_irq(card->sdio, irq);
}
static inline int host_is_voltage_compatible(struct mmc_card *card, int mv)
{
return sdio_is_voltage_compatible(card->sdio, mv);
}
static inline int host_reset(struct mmc_card *card)
{
return sdio_reset(card->sdio);
}
/* void card_data(...) */