#include <sys/devclass.h>
#include <dev/emmc.h>

DEVCLASS_CREATE(emmc);

/* Some of these might contain incorrect flags. Please, if you are implementing
 * a driver for a new e.MMC device, check the configuration here and ensure
 * that for any commands that were not previously used, flags are set correctly.
 *
 * Also, don't mind the magical 57. It's not going to change and is irrelevant
 * for any purpouses other than expanding this particualar table if the e.MMC
 * standard ever gets a new command with an index higher than 56. */
const emmc_cmd_t default_emmc_commands[57] = {
  [EMMC_CMD_GO_IDLE] = {EMMC_CMD_GO_IDLE, 0, EMMCRESP_NONE},
  [EMMC_CMD_SEND_OP_COND] = {EMMC_CMD_SEND_OP_COND, 0, EMMCRESP_R3},
  [EMMC_CMD_ALL_SEND_CID] = {EMMC_CMD_ALL_SEND_CID, 0, EMMCRESP_R2},
  [EMMC_CMD_SET_RELATIVE_ADDR] = {EMMC_CMD_SET_RELATIVE_ADDR, 0, EMMCRESP_R1},
  [EMMC_CMD_SET_DSR] = {EMMC_CMD_SET_DSR, 0, EMMCRESP_NONE},
  [EMMC_CMD_SLEEP_AWAKE] = {EMMC_CMD_SLEEP_AWAKE, 0, EMMCRESP_R1},
  [EMMC_CMD_SWITCH] = {EMMC_CMD_SWITCH, 0, EMMCRESP_R1},
  [EMMC_CMD_SELECT_CARD] = {EMMC_CMD_SELECT_CARD, 0, EMMCRESP_R1},
  [EMMC_CMD_SEND_EXT_CSD] = {EMMC_CMD_SEND_EXT_CSD, 0, EMMCRESP_R1},
  [EMMC_CMD_SEND_CSD] = {EMMC_CMD_SEND_CSD, 0, EMMCRESP_R2},
  [EMMC_CMD_SEND_CID] = {EMMC_CMD_SEND_CID, 0, EMMCRESP_R2},
  [EMMC_CMD_READ_DAT_UNTIL_STOP] = {EMMC_CMD_READ_DAT_UNTIL_STOP, 0,
                                    EMMCRESP_R1},
  [EMMC_CMD_STOP_TRANSMISSION] = {EMMC_CMD_STOP_TRANSMISSION, 0, EMMCRESP_R1},
  [EMMC_CMD_SEND_STATUS] = {EMMC_CMD_SEND_STATUS, 0, EMMCRESP_R1},
  [EMMC_CMD_BUSTEST_R] = {EMMC_CMD_BUSTEST_R, 0, EMMCRESP_R1},
  [EMMC_CMD_GO_INACTIVE_STATE] = {EMMC_CMD_GO_INACTIVE_STATE, 0, EMMCRESP_NONE},
  [EMMC_CMD_BUSTEST_W] = {EMMC_CMD_BUSTEST_W, 0, EMMCRESP_R1},
  [EMMC_CMD_SET_BLOCKLEN] = {EMMC_CMD_SET_BLOCKLEN, 0, EMMCRESP_R1},
  [EMMC_CMD_READ_BLOCK] = {EMMC_CMD_READ_BLOCK, EMMC_F_DATA_READ, EMMCRESP_R1},
  [EMMC_CMD_READ_MULTIPLE_BLOCKS] = {EMMC_CMD_READ_MULTIPLE_BLOCKS,
                                     EMMC_F_DATA_READ | EMMC_F_DATA_MULTI,
                                     EMMCRESP_R1},
  [EMMC_CMD_WRITE_DAT_UNTIL_STOP] = {EMMC_CMD_WRITE_DAT_UNTIL_STOP, 0,
                                     EMMCRESP_R1},
  [EMMC_CMD_SET_BLOCK_COUNT] = {EMMC_CMD_SET_BLOCK_COUNT, 0, EMMCRESP_R1},
  [EMMC_CMD_WRITE_BLOCK] = {EMMC_CMD_WRITE_BLOCK, EMMC_F_DATA_WRITE,
                            EMMCRESP_R1},
  [EMMC_CMD_WRITE_MULTIPLE_BLOCKS] = {EMMC_CMD_WRITE_MULTIPLE_BLOCKS,
                                      EMMC_F_DATA_WRITE | EMMC_F_DATA_MULTI,
                                      EMMCRESP_R1},
  [EMMC_CMD_PROGRAM_CID] = {EMMC_CMD_PROGRAM_CID, 0, EMMCRESP_R1},
  [EMMC_CMD_PROGRAM_CSD] = {EMMC_CMD_PROGRAM_CSD, 0, EMMCRESP_R1},
  [EMMC_CMD_SET_WRITE_PROT] = {EMMC_CMD_SET_WRITE_PROT, 0, EMMCRESP_R1},
  [EMMC_CMD_CLR_WRITE_PROT] = {EMMC_CMD_CLR_WRITE_PROT, 0, EMMCRESP_R1},
  [EMMC_CMD_SEND_WRITE_PROT] = {EMMC_CMD_SEND_WRITE_PROT, 0, EMMCRESP_R1},
  [EMMC_CMD_SEND_WRITE_PROT_TYPE] = {EMMC_CMD_SEND_WRITE_PROT_TYPE, 0,
                                     EMMCRESP_R1},
  [EMMC_CMD_ERASE_GROUP_START] = {EMMC_CMD_ERASE_GROUP_START, 0, EMMCRESP_R1},
  [EMMC_CMD_ERASE_GROUP_END] = {EMMC_CMD_ERASE_GROUP_END, 0, EMMCRESP_R1},
  [EMMC_CMD_ERASE] = {EMMC_CMD_ERASE, 0, EMMCRESP_R1},
  [EMMC_CMD_FAST_IO] = {EMMC_CMD_FAST_IO, 0, EMMCRESP_R4},
  [EMMC_CMD_GO_IRQ_STATE] = {EMMC_CMD_GO_IRQ_STATE, 0, EMMCRESP_R5},
  [EMMC_CMD_LOCK_UNLOCK] = {EMMC_CMD_LOCK_UNLOCK, 0, EMMCRESP_R1},
  [EMMC_CMD_APP_CMD] = {EMMC_CMD_APP_CMD, 0, EMMCRESP_R1},
  [EMMC_CMD_GEN_CMD] = {EMMC_CMD_GEN_CMD, 0, EMMCRESP_R1},
};
