#ifndef _SYS_SDCARD_SDA_H
#define _SYS_SDCARD_SDA_H
#include <sys/types.h>
#include <sys/note.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
CMD_GO_IDLE = 0,
CMD_SEND_OCR = 1,
CMD_BCAST_CID = 2,
CMD_SEND_RCA = 3,
CMD_SET_DSR = 4,
CMD_IO_SEND_OCR = 5,
CMD_SWITCH_FUNC = 6,
CMD_SELECT_CARD = 7,
CMD_SEND_IF_COND = 8,
CMD_SEND_CSD = 9,
CMD_SEND_CID = 10,
CMD_STOP_TRANSMIT = 12,
CMD_SEND_STATUS = 13,
CMD_GO_INACTIVE = 15,
CMD_SET_BLOCKLEN = 16,
CMD_READ_SINGLE = 17,
CMD_READ_MULTI = 18,
CMD_WRITE_SINGLE = 24,
CMD_WRITE_MULTI = 25,
CMD_PROGRAM_CSD = 27,
CMD_SET_WRITE_PROT = 28,
CMD_CLR_WRITE_PROT = 29,
CMD_SEND_WRITE_PROT = 30,
CMD_ERASE_START = 32,
CMD_ERASE_END = 33,
CMD_ERASE = 38,
CMD_LOCK = 42,
CMD_IO_RW_DIRECT = 52,
CMD_IO_RW_EXTENDED = 53,
CMD_APP_CMD = 55,
CMD_GEN_CMD = 56,
ACMD_SET_BUS_WIDTH = 6,
ACMD_SD_STATUS = 13,
ACMD_SEND_NUM_WR_BLKS = 22,
ACMD_SET_WR_BLK_ERASE_COUNT = 23,
ACMD_SD_SEND_OCR = 41,
ACMD_SET_CLR_CARD_DETECT = 42,
ACMD_SEND_SCR = 51
} sda_index_t;
typedef enum {
R0 = 0,
R1 = 1,
R2 = 2,
R3 = 3,
R4 = 4,
R5 = 5,
R6 = 6,
R7 = 7,
Rb = 0x10,
R1b = 0x11,
R5b = 0x15
} sda_rtype_t;
#define R1_OUT_OF_RANGE (1U << 31)
#define R1_ADDRESS_ERROR (1U << 30)
#define R1_BLOCK_LEN_ERROR (1U << 29)
#define R1_ERASE_SEQ_ERROR (1U << 28)
#define R1_ERASE_PARAM (1U << 27)
#define R1_WP_VIOLATION (1U << 26)
#define R1_CARD_IS_LOCKED (1U << 25)
#define R1_LOCK_FAILED (1U << 24)
#define R1_COM_CRC_ERROR (1U << 23)
#define R1_ILLEGAL_COMMAND (1U << 22)
#define R1_CARD_ECC_FAILED (1U << 21)
#define R1_CC_ERROR (1U << 20)
#define R1_ERROR (1U << 19)
#define R1_CSD_OVERWRITE (1U << 16)
#define R1_WP_ERASE_SKIP (1U << 15)
#define R1_CARD_ECC_DIS (1U << 14)
#define R1_ERASE_RESET (1U << 13)
#define R1_READY_FOR_DATA (1U << 8)
#define R1_APP_CMD (1U << 5)
#define R1_AKE_SEQ_ERROR (1U << 3)
#define R1_ERRS (\
R1_ERROR | R1_OUT_OF_RANGE | R1_ADDRESS_ERROR | R1_BLOCK_LEN_ERROR | \
R1_ERASE_PARAM | R1_WP_VIOLATION | R1_LOCK_FAILED | \
R1_CARD_ECC_FAILED | R1_CC_ERROR | R1_CSD_OVERWRITE | \
R1_WP_ERASE_SKIP)
#define R1_STATE(x) (((x) & 0xf) >> 9)
#define R5_COM_CRC_ERROR (1U << 7)
#define R5_ILLEGAL_COMMAND (1U << 6)
#define R5_ERROR (1U << 3)
#define R5_RFU (1U << 2)
#define R5_FUNCTION_NUMBER (1U << 1)
#define R5_OUT_OF_RANGE (1U << 0)
#define R5_ERRS (R5_ERROR | R5_FUNCTION_NUMBER | R5_OUT_OF_RANGE)
#define R5_IO_STATE(x) (((x) & 0x3) >> 4)
#define R7_VHS_27_36V (1U << 8)
#define R7_PATTERN (0xAA)
#define OCR_POWER_UP (1U << 31)
#define OCR_CCS (1U << 30)
#define OCR_FUNCS(x) (((x) & 7) >> 28)
#define OCR_MEM_PRESENT (1U << 27)
#define OCR_VOLTAGE_MASK (0xffffffU)
#define OCR_HI_MASK (0xff8000U)
#define OCR_35_36V (1U << 23)
#define OCR_34_35V (1U << 22)
#define OCR_33_34V (1U << 21)
#define OCR_32_33V (1U << 20)
#define OCR_31_32V (1U << 19)
#define OCR_30_31V (1U << 18)
#define OCR_29_30V (1U << 17)
#define OCR_28_29V (1U << 16)
#define OCR_27_28V (1U << 15)
#define OCR_26_27V (1U << 14)
#define OCR_25_26V (1U << 14)
#define OCR_24_25V (1U << 13)
#define OCR_23_24V (1U << 12)
#define OCR_22_23V (1U << 11)
#define OCR_21_22V (1U << 10)
#define OCR_20_21V (1U << 9)
#define OCR_19_20V (1U << 8)
#define OCR_18_19V (1U << 7)
#define OCR_17_18V (1U << 6)
typedef struct sda_cmd sda_cmd_t;
struct sda_cmd {
sda_index_t sc_index;
sda_rtype_t sc_rtype;
uint16_t sc_flags;
uint32_t sc_argument;
uint32_t sc_response[4];
uint16_t sc_nblks;
uint16_t sc_blksz;
uint32_t sc_resid;
ddi_dma_handle_t sc_dmah;
uint_t sc_ndmac;
ddi_dma_cookie_t sc_dmac;
caddr_t sc_kvaddr;
#define SDA_CMDF_READ 0x0001
#define SDA_CMDF_WRITE 0x0002
#define SDA_CMDF_AUTO_CMD12 0x0004
#define SDA_CMDF_DAT 0x0100
#define SDA_CMDF_BUSY 0x0200
#define SDA_CMDF_INIT 0x0400
#define SDA_CMDF_MEM 0x0800
};
typedef struct sda_host sda_host_t;
typedef enum {
SDA_PROP_INSERTED = 1,
SDA_PROP_WPROTECT = 2,
SDA_PROP_LED = 3,
SDA_PROP_CLOCK = 4,
SDA_PROP_BUSWIDTH = 5,
SDA_PROP_OCR = 6,
SDA_PROP_CAP_4BITS = 7,
SDA_PROP_CAP_8BITS = 8,
SDA_PROP_CAP_HISPEED = 9,
SDA_PROP_CAP_INTR = 10,
SDA_PROP_CAP_NOPIO = 11,
SDA_PROP_HISPEED = 12
} sda_prop_t;
typedef enum {
SDA_FAULT_NONE = 0,
SDA_FAULT_ACMD12 = 1,
SDA_FAULT_CRC7 = 2,
SDA_FAULT_PROTO = 3,
SDA_FAULT_CURRENT = 4,
SDA_FAULT_INIT = 5,
SDA_FAULT_TIMEOUT = 6,
SDA_FAULT_HOST = 7,
SDA_FAULT_RESET = 8,
} sda_fault_t;
typedef enum {
SDA_EOK = 0,
SDA_ECRC7 = 1,
SDA_EPROTO = 2,
SDA_EINVAL = 3,
SDA_ETIME = 4,
SDA_ECMD12 = 5,
SDA_ENOTSUP = 6,
SDA_ERESID = 7,
SDA_EFAULT = 8,
SDA_ENOMEM = 9,
SDA_EWPROTECT = 10,
SDA_ENODEV = 11,
SDA_ERESET = 12,
SDA_EABORT = 13,
SDA_EIO = 14,
SDA_ESUSPENDED = 15,
} sda_err_t;
typedef struct sda_ops {
int so_version;
#define SDA_OPS_VERSION 1
sda_err_t (*so_cmd)(void *, sda_cmd_t *);
sda_err_t (*so_getprop)(void *, sda_prop_t, uint32_t *);
sda_err_t (*so_setprop)(void *, sda_prop_t, uint32_t);
sda_err_t (*so_poll)(void *);
sda_err_t (*so_reset)(void *);
sda_err_t (*so_halt)(void *);
} sda_ops_t;
void sda_host_init_ops(struct dev_ops *);
void sda_host_fini_ops(struct dev_ops *);
sda_host_t *sda_host_alloc(dev_info_t *, int, sda_ops_t *, ddi_dma_attr_t *);
void sda_host_free(sda_host_t *);
void sda_host_set_private(sda_host_t *, int, void *);
int sda_host_attach(sda_host_t *);
void sda_host_detach(sda_host_t *);
void sda_host_suspend(sda_host_t *);
void sda_host_resume(sda_host_t *);
void sda_host_detect(sda_host_t *, int);
void sda_host_fault(sda_host_t *, int, sda_fault_t);
void sda_host_transfer(sda_host_t *, int, sda_err_t);
void sda_host_log(sda_host_t *, int, const char *, ...);
#ifdef __cplusplus
}
#endif
#endif