sdiodrv.h

#ifndef __DOOROOS_DEV_SDIODRV_H__

#define __DOOROOS_DEV_SDIODRV_H__

#include <types.h>

#include <thread.h>

#include <time.h>

#include <dev/blockapi.h>

#define SDIO_IRQ_THREAD_ENABLED

//==================================================================================================

//==================================================================================================

//==================================================================================================

/* SDIO commands                         type  argument     response */

#define SD_IO_SEND_OP_COND          5 /* bcr  [23:0] OCR         R4  */

#define SD_IO_RW_DIRECT            52 /* ac   [31:0] See below   R5  */

#define SD_IO_RW_EXTENDED          53 /* adtc [31:0] See below   R5  */

/*

 * SD_IO_RW_DIRECT argument format:

 *

 *      [31] R/W flag

 *      [30:28] Function number

 *      [27] RAW flag

 *      [25:9] Register address

 *      [7:0] Data

 */

/*

 * SD_IO_RW_EXTENDED argument format:

 *

 *      [31] R/W flag

 *      [30:28] Function number

 *      [27] Block mode

 *      [26] Increment address

 *      [25:9] Register address

 *      [8:0] Byte/block count

 */

#define R4_MEMORY_PRESENT       (1 << 27)

/*

  SDIO status in R5

  Type

    e : error bit

    s : status bit

    r : detected and set for the actual command response

    x : detected and set during command execution. the host must poll

            the card by sending status command in order to read these bits.

  Clear condition

    a : according to the card state

    b : always related to the previous command. Reception of

            a valid command will clear it (with a delay of one command)

    c : clear by read

 */

#define R5_COM_CRC_ERROR            (1 << 15)    /* er, b */

#define R5_ILLEGAL_COMMAND          (1 << 14)    /* er, b */

#define R5_ERROR                    (1 << 11)    /* erx, c */

#define R5_FUNCTION_NUMBER          (1 << 9)    /* er, c */

#define R5_OUT_OF_RANGE             (1 << 8)    /* er, c */

#define R5_STATUS(x)                (x & 0xCB00)

#define R5_IO_CURRENT_STATE(x)      ((x & 0x3000) >> 12) /* s, b */

/*

 * Card Common Control Registers (CCCR)

 */

#define SDIO_CCCR_CCCR              0x00

#define SDIO_CCCR_REV_1_00          0    /* CCCR/FBR Version 1.00 */

#define SDIO_CCCR_REV_1_10          1    /* CCCR/FBR Version 1.10 */

#define SDIO_CCCR_REV_1_20          2    /* CCCR/FBR Version 1.20 */

#define SDIO_SDIO_REV_1_00          0    /* SDIO Spec Version 1.00 */

#define SDIO_SDIO_REV_1_10          1    /* SDIO Spec Version 1.10 */

#define SDIO_SDIO_REV_1_20          2    /* SDIO Spec Version 1.20 */

#define SDIO_SDIO_REV_2_00          3    /* SDIO Spec Version 2.00 */

#define SDIO_CCCR_SD                0x01

#define SDIO_SD_REV_1_01            0    /* SD Physical Spec Version 1.01 */

#define SDIO_SD_REV_1_10            1    /* SD Physical Spec Version 1.10 */

#define SDIO_SD_REV_2_00            2    /* SD Physical Spec Version 2.00 */

#define SDIO_CCCR_IOEx              0x02

#define SDIO_CCCR_IORx              0x03

#define SDIO_CCCR_IENx              0x04    /* Function/Master Interrupt Enable */

#define SDIO_CCCR_INTx              0x05    /* Function Interrupt Pending */

#define SDIO_CCCR_ABORT             0x06    /* function abort/card reset */

#define SDIO_CCCR_IF                0x07    /* bus interface controls */

#define SDIO_BUS_WIDTH_1BIT         0x00

#define SDIO_BUS_WIDTH_4BIT         0x02

#define SDIO_BUS_ECSI               0x20    /* Enable continuous SPI interrupt */

#define SDIO_BUS_SCSI               0x40    /* Support continuous SPI interrupt */

#define SDIO_BUS_ASYNC_INT         0x20

#define SDIO_BUS_CD_DISABLE        0x80    /* disable pull-up on DAT3 (pin 1) */

#define SDIO_CCCR_CAPS              0x08

#define SDIO_CCCR_CAP_SDC           0x01    /* can do CMD52 while data transfer */

#define SDIO_CCCR_CAP_SMB           0x02    /* can do multi-block xfers (CMD53) */

#define SDIO_CCCR_CAP_SRW           0x04    /* supports read-wait protocol */

#define SDIO_CCCR_CAP_SBS           0x08    /* supports suspend/resume */

#define SDIO_CCCR_CAP_S4MI          0x10    /* interrupt during 4-bit CMD53 */

#define SDIO_CCCR_CAP_E4MI          0x20    /* enable ints during 4-bit CMD53 */

#define SDIO_CCCR_CAP_LSC           0x40    /* low speed card */

#define SDIO_CCCR_CAP_4BLS          0x80    /* 4 bit low speed card */

#define SDIO_CCCR_CIS               0x09    /* common CIS pointer (3 bytes) */

/* Following 4 regs are valid only if SBS is set */

#define SDIO_CCCR_SUSPEND           0x0c

#define SDIO_CCCR_SELx              0x0d

#define SDIO_CCCR_EXECx             0x0e

#define SDIO_CCCR_READYx            0x0f

#define SDIO_CCCR_BLKSIZE           0x10

#define SDIO_CCCR_POWER             0x12

#define SDIO_POWER_SMPC             0x01    /* Supports Master Power Control */

#define SDIO_POWER_EMPC             0x02    /* Enable Master Power Control */

#define SDIO_CCCR_SPEED             0x13

#define SDIO_SPEED_SHS              0x01    /* Supports High-Speed mode */

#define SDIO_SPEED_EHS              0x02    /* Enable High-Speed mode */

/*

 * Function Basic Registers (FBR)

 */

#define SDIO_FBR_BASE(f)            ((f) * 0x100) /* base of function f's FBRs */

#define SDIO_FBR_STD_IF             0x00

#define  SDIO_FBR_SUPPORTS_CSA      0x40    /* supports Code Storage Area */

#define  SDIO_FBR_ENABLE_CSA        0x80    /* enable Code Storage Area */

#define SDIO_FBR_STD_IF_EXT         0x01

#define SDIO_FBR_POWER              0x02

#define  SDIO_FBR_POWER_SPS         0x01    /* Supports Power Selection */

#define  SDIO_FBR_POWER_EPS         0x02    /* Enable (low) Power Selection */

#define SDIO_FBR_CIS                0x09    /* CIS pointer (3 bytes) */

#define SDIO_FBR_CSA                0x0C    /* CSA pointer (3 bytes) */

#define SDIO_FBR_CSA_DATA           0x0F

#define SDIO_FBR_BLKSIZE            0x10    /* block size (2 bytes) */

///*

// * SDIO Classes, Interface Types, Manufacturer IDs, etc.

// */

//

//#ifndef MMC_SDIO_IDS_H

//#define MMC_SDIO_IDS_H

/*

 * Standard SDIO Function Interfaces

 */

#define SDIO_CLASS_NONE             0x00    /* Not a SDIO standard interface */

#define SDIO_CLASS_UART             0x01    /* standard UART interface */

#define SDIO_CLASS_BT_A             0x02    /* Type-A BlueTooth std interface */

#define SDIO_CLASS_BT_B             0x03    /* Type-B BlueTooth std interface */

#define SDIO_CLASS_GPS              0x04    /* GPS standard interface */

#define SDIO_CLASS_CAMERA           0x05    /* Camera standard interface */

#define SDIO_CLASS_PHS              0x06    /* PHS standard interface */

#define SDIO_CLASS_WLAN             0x07    /* WLAN interface */

#define SDIO_CLASS_ATA              0x08    /* Embedded SDIO-ATA std interface */

#define SDIO_CLASS_BT_AMP           0x09    /* Type-A Bluetooth AMP interface */

/*

 * Vendors and devices.  Sort key: vendor first, device next.

 */

#define SDIO_VENDOR_ID_INTEL                    0x0089

#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX      0x1402

#define SDIO_DEVICE_ID_INTEL_IWMC3200WIFI       0x1403

#define SDIO_DEVICE_ID_INTEL_IWMC3200TOP        0x1404

#define SDIO_DEVICE_ID_INTEL_IWMC3200GPS        0x1405

#define SDIO_DEVICE_ID_INTEL_IWMC3200BT         0x1406

#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX_2G5  0x1407

#define SDIO_VENDOR_ID_MARVELL                  0x02df

#define SDIO_DEVICE_ID_MARVELL_LIBERTAS         0x9103

#define SDIO_DEVICE_ID_MARVELL_8688WLAN         0x9104

#define SDIO_DEVICE_ID_MARVELL_8688BT           0x9105

#define SDIO_VENDOR_ID_SIANO                    0x039a

#define SDIO_DEVICE_ID_SIANO_NOVA_B0            0x0201

#define SDIO_DEVICE_ID_SIANO_NICE               0x0202

#define SDIO_DEVICE_ID_SIANO_VEGA_A0            0x0300

#define SDIO_DEVICE_ID_SIANO_VENICE             0x0301

#define SDIO_DEVICE_ID_SIANO_NOVA_A0            0x1100

#define SDIO_DEVICE_ID_SIANO_STELLAR            0x5347

//#endif

//#ifndef MMC_SDIO_FUNC_H

//#define MMC_SDIO_FUNC_H

//#include <linux/device.h>

//#include <linux/mod_devicetable.h>

//

//#include <linux/mmc/pm.h>

//struct mmc_card;

struct sdio_func;

typedef void (sdio_irq_handler_t)(struct sdio_func *);

/*

 * SDIO function CIS tuple (unknown to the core)

 */

struct sdio_func_tuple {

    struct sdio_func_tuple *next;

    unsigned char code;

    unsigned char size;

    unsigned char data[0];

};

/*

 * SDIO function devices

 */

struct _PDISK_;

typedef struct sdio_func

{

    struct _DISK_          *pSdio;         /* the card this device belongs to */

    //struct device        dev;             /* the device */

    PVOID                   pPriv;

    sdio_irq_handler_t      *IrqHandler;    /* IRQ callback */

    UINT32                  Num;            /* function number */

    BYTE                    Class;          /* standard interface class */

    UINT16                  Vendor;         /* vendor id */

    UINT16                  Device;         /* device id */

    UINT32                  MaxBlkSize;     /* maximum block size */

    UINT32                  CurBlkSize;     /* current block size */

    UINT32                  EnableTimeout;  /* max enable timeout in msec */

    UINT32                  State;          /* function state */

        #define SDIO_STATE_PRESENT    (1<<0)        /* present in sysfs */

    BYTE                    TmpBuf[4];      /* DMA:able scratch buffer */

    UINT32                  nInfo;          /* number of info strings */

    const char              **ppInfo;       /* info strings */

    struct sdio_func_tuple  *pTuples;

}SDIO_FUNC, *PSDIO_FUNC;

#define IS_SDIO_FUNC_PRESENT(f)         ((f)->State & SDIO_STATE_PRESENT)

#define SET_SDIO_FUNC_PRESENT(f)        ((f)->State |= SDIO_STATE_PRESENT)

//#define sdio_func_id(f)             (dev_name(&(f)->dev))

//

#define SDIO_GET_DRVDATA(f)             (f)->pPriv              //dev_get_drvdata(&(f)->dev)

#define SDIO_SET_DRVDATA(f,d)           (f)->pPriv = (PVOID)(d) //dev_set_drvdata(&(f)->dev, d)

//#define dev_to_sdio_func(d)         container_of(d, struct sdio_func, dev)

/*

 * SDIO function device driver

 */

struct sdio_driver

{

    char *name;

    const struct sdio_device_id *id_table;

    int (*probe)(struct sdio_func *, const struct sdio_device_id *);

    void (*remove)(struct sdio_func *);

//    struct device_driver drv;

};

#define to_sdio_driver(d)    container_of(d, struct sdio_driver, drv)

/**

 * SDIO_DEVICE - macro used to describe a specific SDIO device

 * @vend: the 16 bit manufacturer code

 * @dev: the 16 bit function id

 *

 * This macro is used to create a struct sdio_device_id that matches a

 * specific device. The class field will be set to SDIO_ANY_ID.

 */

#define SDIO_DEVICE(vend,dev) \

    .class = SDIO_ANY_ID, \

    .vendor = (vend), .device = (dev)

/**

 * SDIO_DEVICE_CLASS - macro used to describe a specific SDIO device class

 * @dev_class: the 8 bit standard interface code

 *

 * This macro is used to create a struct sdio_device_id that matches a

 * specific standard SDIO function type.  The vendor and device fields will

 * be set to SDIO_ANY_ID.

 */

#define SDIO_DEVICE_CLASS(dev_class) \

    .class = (dev_class), \

    .vendor = SDIO_ANY_ID, .device = SDIO_ANY_ID

extern int sdio_register_driver(struct sdio_driver *);

extern void sdio_unregister_driver(struct sdio_driver *);

///*

// * SDIO I/O operations

// */

//extern void sdio_claim_host(struct sdio_func *func);

//extern void sdio_release_host(struct sdio_func *func);

//

//extern int sdio_enable_func(struct sdio_func *func);

//extern int sdio_disable_func(struct sdio_func *func);

//

//extern int sdio_set_block_size(struct sdio_func *func, unsigned blksz);

//

//extern int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler);

//extern int sdio_release_irq(struct sdio_func *func);

//

//extern unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz);

//

//extern BYTE sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret);

//extern u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret);

//extern u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret);

//

//extern int sdio_memcpy_fromio(struct sdio_func *func, void *dst,

//    unsigned int addr, int count);

//extern int sdio_readsb(struct sdio_func *func, void *dst,

//    unsigned int addr, int count);

//

//extern void sdio_writeb(struct sdio_func *func, BYTE b,

//    unsigned int addr, int *err_ret);

//extern void sdio_writew(struct sdio_func *func, u16 b,

//    unsigned int addr, int *err_ret);

//extern void sdio_writel(struct sdio_func *func, u32 b,

//    unsigned int addr, int *err_ret);

//

//extern BYTE sdio_writeb_readb(struct sdio_func *func, BYTE write_byte,

//    unsigned int addr, int *err_ret);

//

//extern int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,

//    void *src, int count);

//extern int sdio_writesb(struct sdio_func *func, unsigned int addr,

//    void *src, int count);

//

//extern unsigned char sdio_f0_readb(struct sdio_func *func,

//    unsigned int addr, int *err_ret);

//extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b,

//    unsigned int addr, int *err_ret);

//

//extern mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func);

//extern int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags);

//

//#endif

//==================================================================================================

//==================================================================================================

/* Standard MMC commands (4.1)           type  argument     response */

   /* class 1 */

#define MMC_GO_IDLE_STATE         0   /* bc                          */

#define MMC_SEND_OP_COND          1   /* bcr  [31:0] OCR         R3  */

#define MMC_ALL_SEND_CID          2   /* bcr                     R2  */

#define MMC_SET_RELATIVE_ADDR     3   /* ac   [31:16] RCA        R1  */

#define MMC_SET_DSR               4   /* bc   [31:16] RCA            */

#define MMC_SWITCH                6   /* ac   [31:0] See below   R1b */

#define MMC_SELECT_CARD           7   /* ac   [31:16] RCA        R1  */

#define MMC_SEND_EXT_CSD          8   /* adtc                    R1  */

#define MMC_SEND_CSD              9   /* ac   [31:16] RCA        R2  */

#define MMC_SEND_CID             10   /* ac   [31:16] RCA        R2  */

#define MMC_READ_DAT_UNTIL_STOP  11   /* adtc [31:0] dadr        R1  */

#define MMC_STOP_TRANSMISSION    12   /* ac                      R1b */

#define MMC_SEND_STATUS          13   /* ac   [31:16] RCA        R1  */

#define MMC_BUS_TEST_R           14   /* adtc                    R1  */

#define MMC_GO_INACTIVE_STATE    15   /* ac   [31:16] RCA            */

#define MMC_BUS_TEST_W           19   /* adtc                    R1  */

#define MMC_SPI_READ_OCR         58   /* spi                  spi_R3 */

#define MMC_SPI_CRC_ON_OFF       59   /* spi  [0:0] flag      spi_R1 */

  /* class 2 */

#define MMC_SET_BLOCKLEN         16   /* ac   [31:0] block len   R1  */

#define MMC_READ_SINGLE_BLOCK    17   /* adtc [31:0] data addr   R1  */

#define MMC_READ_MULTIPLE_BLOCK  18   /* adtc [31:0] data addr   R1  */

#define MMC_SEND_TUNING_BLOCK    19   /* adtc                    R1  */

#define MMC_SEND_TUNING_BLOCK_HS200     21      /* adtc R1  */

  /* class 3 */

#define MMC_WRITE_DAT_UNTIL_STOP 20   /* adtc [31:0] data addr   R1  */

  /* class 4 */

#define MMC_SET_BLOCK_COUNT      23   /* adtc [31:0] data addr   R1  */

#define MMC_WRITE_BLOCK          24   /* adtc [31:0] data addr   R1  */

#define MMC_WRITE_MULTIPLE_BLOCK 25   /* adtc                    R1  */

#define MMC_PROGRAM_CID          26   /* adtc                    R1  */

#define MMC_PROGRAM_CSD          27   /* adtc                    R1  */

  /* class 6 */

#define MMC_SET_WRITE_PROT       28   /* ac   [31:0] data addr   R1b */

#define MMC_CLR_WRITE_PROT       29   /* ac   [31:0] data addr   R1b */

#define MMC_SEND_WRITE_PROT      30   /* adtc [31:0] wpdata addr R1  */

  /* class 5 */

#define MMC_ERASE_GROUP_START    35   /* ac   [31:0] data addr   R1  */

#define MMC_ERASE_GROUP_END      36   /* ac   [31:0] data addr   R1  */

#define MMC_ERASE                38   /* ac                      R1b */

  /* class 9 */

#define MMC_FAST_IO              39   /* ac   <Complex>          R4  */

#define MMC_GO_IRQ_STATE         40   /* bcr                     R5  */

  /* class 7 */

#define MMC_LOCK_UNLOCK          42   /* adtc                    R1b */

  /* class 8 */

#define MMC_APP_CMD              55   /* ac   [31:16] RCA        R1  */

#define MMC_GEN_CMD              56   /* adtc [0] RD/WR          R1  */

/*

 * MMC_SWITCH argument format:

 *

 *    [31:26] Always 0

 *    [25:24] Access Mode

 *    [23:16] Location of target Byte in EXT_CSD

 *    [15:08] Value Byte

 *    [07:03] Always 0

 *    [02:00] Command Set

 */

/*

  MMC status in R1

  Type

      e : error bit

    s : status bit

    r : detected and set for the actual command response

    x : detected and set during command execution. the pHost must poll

            the pCard by sending status command in order to read these bits.

  Clear condition

      a : according to the pCard state

    b : always related to the previous command. Reception of

            a valid command will clear it (with a delay of one command)

    c : clear by read

 */

#define R1_OUT_OF_RANGE         (1 << 31)    /* er, c */

#define R1_ADDRESS_ERROR        (1 << 30)    /* erx, c */

#define R1_BLOCK_LEN_ERROR      (1 << 29)    /* er, c */

#define R1_ERASE_SEQ_ERROR      (1 << 28)    /* er, c */

#define R1_ERASE_PARAM          (1 << 27)    /* ex, c */

#define R1_WP_VIOLATION         (1 << 26)    /* erx, c */

#define R1_CARD_IS_LOCKED       (1 << 25)    /* sx, a */

#define R1_LOCK_UNLOCK_FAILED   (1 << 24)    /* erx, c */

#define R1_COM_CRC_ERROR        (1 << 23)    /* er, b */

#define R1_ILLEGAL_COMMAND      (1 << 22)    /* er, b */

#define R1_CARD_ECC_FAILED      (1 << 21)    /* ex, c */

#define R1_CC_ERROR             (1 << 20)    /* erx, c */

#define R1_ERROR                (1 << 19)    /* erx, c */

#define R1_UNDERRUN             (1 << 18)    /* ex, c */

#define R1_OVERRUN              (1 << 17)    /* ex, c */

#define R1_CID_CSD_OVERWRITE    (1 << 16)    /* erx, c, CID/CSD overwrite */

#define R1_WP_ERASE_SKIP        (1 << 15)    /* sx, c */

#define R1_CARD_ECC_DISABLED    (1 << 14)    /* sx, a */

#define R1_ERASE_RESET          (1 << 13)    /* sr, c */

#define R1_STATUS(x)            (x & 0xFFFFE000)

#define R1_CURRENT_STATE(x)     ((x & 0x00001E00) >> 9)    /* sx, b (4 bits) */

#define R1_READY_FOR_DATA       (1 << 8)    /* sx, a */

#define R1_APP_CMD              (1 << 5)    /* sr, c */

/* These are unpacked versions of the actual responses */

typedef struct _MMC_RAW_CSD_

{

    BYTE        CSD_Structure;

    BYTE        SpecVers;

    BYTE        taac;

    BYTE        nsac;

    BYTE        Tran_Speed;

    UINT16      ccc;

    BYTE        ReadBlockLen;

    BYTE        ReadBlockPartial;

    BYTE        WriteBlockMisalign;

    BYTE        ReadBlockMisalign;

    BYTE        DsrImp;

    UINT16      c_Size;

    BYTE        Vdd_Read_CurrMin;

    BYTE        Vdd_Read_CurrMax;

    BYTE        Vdd_Write_CurrMin;

    BYTE        Vdd_Write_CurrMax;

    BYTE        c_SizeMult;

    union

    {

        struct

        { /* MMC system specification version 3.1 */

            BYTE        EraseGrpSize;

            BYTE        EraseGrpMult;

        } v31;

        struct

        { /* MMC system specification version 2.2 */

            BYTE        SectorSize;

            BYTE        EraseGrpSize;

        } v22;

    } erase;

    BYTE        WpGrpSize;

    BYTE        WpGrpEnable;

    BYTE        DefaultEcc;

    BYTE        R2WFactor;

    BYTE        WriteBlockLen;

    BYTE        WriteBlockPartial;

    BYTE        FileFormatGrp;

    BYTE        Copy;

    BYTE        PermWriteProtect;

    BYTE        TmpWriteProtect;

    BYTE        FileFormat;

    BYTE        Ecc;

}MMC_RAW_CSD, *PMMC_RAW_CSD;

/*

 * OCR bits are mostly

 */

#define MMC_CARD_BUSY           0x80000000    /* Card Power up status bit */

#define MMC_CARD_HCS            0x40000000    /* Card is high capacity */

#define SD_HIGHSPEED_BUSY       0x00020000

#define SD_HIGHSPEED_SUPPORTED  0x00020000

#define MMC_HS_TIMING           0x00000100

#define MMC_HS_52MHZ            0x2

/*

 * Card Command Classes (CCC)

 */

#define CCC_BASIC               (1<<0)      /* (0) Basic protocol functions */

                                            /* (CMD0,1,2,3,4,7,9,10,12,13,15) */

#define CCC_STREAM_READ         (1<<1)      /* (1) Stream read commands */

                                            /* (CMD11) */

#define CCC_BLOCK_READ          (1<<2)      /* (2) Block read commands */

                                            /* (CMD16,17,18) */

#define CCC_STREAM_WRITE        (1<<3)      /* (3) Stream write commands */

                                            /* (CMD20) */

#define CCC_BLOCK_WRITE         (1<<4)      /* (4) Block write commands */

                                            /* (CMD16,24,25,26,27) */

#define CCC_ERASE               (1<<5)      /* (5) Ability to erase Blocks */

                                            /* (CMD32,33,34,35,36,37,38,39) */

#define CCC_WRITE_PROT          (1<<6)      /* (6) Able to write protect Blocks */

                                            /* (CMD28,29,30) */

#define CCC_LOCK_CARD           (1<<7)      /* (7) Able to lock down pCard */

                                            /* (CMD16,CMD42) */

#define CCC_APP_SPEC            (1<<8)      /* (8) Application specific */

                                            /* (CMD55,56,57,ACMD*) */

#define CCC_IO_MODE             (1<<9)      /* (9) I/O mode */

                                            /* (CMD5,39,40,52,53) */

#define CCC_SWITCH              (1<<10)     /* (10) High speed switch */

                                            /* (CMD6,34,35,36,37,50) */

                                            /* (11) Reserved */

                                            /* (CMD?) */

/*

 * CSD field definitions

 */

#define CSD_STRUCT_VER_1_0      0           /* Valid for system specification 1.0 - 1.2 */

#define CSD_STRUCT_VER_1_1      1           /* Valid for system specification 1.4 - 2.2 */

#define CSD_STRUCT_VER_1_2      2           /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */

#define CSD_STRUCT_EXT_CSD      3           /* Version is coded in CSD_STRUCTURE in EXT_CSD */

#define CSD_SPEC_VER_0          0           /* Implements system specification 1.0 - 1.2 */

#define CSD_SPEC_VER_1          1           /* Implements system specification 1.4 */

#define CSD_SPEC_VER_2          2           /* Implements system specification 2.0 - 2.2 */

#define CSD_SPEC_VER_3          3           /* Implements system specification 3.1 - 3.2 - 3.31 */

#define CSD_SPEC_VER_4          4           /* Implements system specification 4.0 - 4.1 */

/*

 * EXT_CSD fields

 */

#define EXT_CSD_BUS_WIDTH       183         /* R/W */

#define EXT_CSD_HS_TIMING       185         /* R/W */

#define EXT_CSD_REV             192         /* RO */

#define EXT_CSD_CARD_TYPE       196         /* RO */

#define EXT_CSD_SEC_CNT         212         /* RO, 4 bytes */

/*

 * EXT_CSD field definitions

 */

#define EXT_CSD_CMD_SET_NORMAL      (1<<0)

#define EXT_CSD_CMD_SET_SECURE      (1<<1)

#define EXT_CSD_CMD_SET_CPSECURE    (1<<2)

#define EXT_CSD_CARD_TYPE_26        (1<<0)      /* Card can run at 26MHz */

#define EXT_CSD_CARD_TYPE_52        (1<<1)      /* Card can run at 52MHz */

#define EXT_CSD_BUS_WIDTH_1         0           /* Card is in 1 bit mode */

#define EXT_CSD_BUS_WIDTH_4         1           /* Card is in 4 bit mode */

#define EXT_CSD_BUS_WIDTH_8         2           /* Card is in 8 bit mode */

/*

 * MMC_SWITCH access modes

 */

#define MMC_SWITCH_MODE_CMD_SET         0x00    /* Change the command set */

#define MMC_SWITCH_MODE_SET_BITS        0x01    /* Set bits which are 1 in value */

#define MMC_SWITCH_MODE_CLEAR_BITS      0x02    /* Clear bits which are 1 in value */

#define MMC_SWITCH_MODE_WRITE_BYTE      0x03    /* Set target to value */

#endif  /* _SD_MMC_H_ */

//==================================================================================================

//==================================================================================================

//==================================================================================================

//==================================================================================================

//==================================================================================================

#ifndef _MMC_SD_H_

#define _MMC_SD_H_

/* SD commands                           type  argument     response */

  /* class 0 */

/* This is basically the same command as for MMC with some quirks. */

#define SD_SEND_RELATIVE_ADDR       3   /* bcr                     R6  */

#define SD_SEND_IF_COND             8   /* bcr  [11:0] See below   R7  */

  /* class 10 */

#define SD_SWITCH                   6   /* adtc [31:0] See below   R1  */

  /* Application commands */

#define SD_APP_SET_BUS_WIDTH        6   /* ac   [1:0] bus width    R1  */

#define SD_APP_SEND_NUM_WR_BLKS     22   /* adtc                    R1  */

#define SD_APP_OP_COND              41   /* bcr  [31:0] OCR         R3  */

#define SD_APP_SEND_SCR             51   /* adtc                    R1  */

/*

 * SD_SWITCH argument format:

 *

 *      [31] Check (0) or switch (1)

 *      [30:24] Reserved (0)

 *      [23:20] Function group 6

 *      [19:16] Function group 5

 *      [15:12] Function group 4

 *      [11:8] Function group 3

 *      [7:4] Function group 2

 *      [3:0] Function group 1

 */

/*

 * SD_SEND_IF_COND argument format:

 *

 *    [31:12] Reserved (0)

 *    [11:8] Host Voltage Supply Flags

 *    [7:0] Check Pattern (0xAA)

 */

/*

 * SCR field definitions

 */

#define SCR_SPEC_VER_0          0    /* Implements system specification 1.0 - 1.01 */

#define SCR_SPEC_VER_1          1    /* Implements system specification 1.10 */

#define SCR_SPEC_VER_2          2    /* Implements system specification 2.00 */

/*

 * SD bus widths

 */

#define SD_BUS_WIDTH_1          0

#define SD_BUS_WIDTH_4          2

/*

 * SD_SWITCH mode

 */

#define SD_SWITCH_CHECK         0

#define SD_SWITCH_SET           1

/*

 * SD_SWITCH function groups

 */

#define SD_SWITCH_GRP_ACCESS    0

/*

 * SD_SWITCH access modes

 */

#define SD_SWITCH_ACCESS_DEF    0

#define SD_SWITCH_ACCESS_HS     1

//==================================================================================================

//==================================================================================================

//==================================================================================================

//==================================================================================================

//==================================================================================================

typedef struct _MMC_CID_

{

    UINT32          ManfId;

    char            ProdName[8];

    UINT32          Serial;

    UINT16          OemId;

    UINT16          Year;

    BYTE            HwRev;

    BYTE            FwRev;

    BYTE            Month;

}MMC_CID, *PMMC_CID;

typedef struct _MMC_CSD_

{

    BYTE            MmcaVsn;

    UINT16          CmdClass;

    UINT16          TaccClks;

    UINT32          TaccNs;

    UINT32          R2WFactor;

    UINT32          MaxDtr;

    UINT32          ReadBlkBits;

    UINT32          WriteBlkBits;

    UINT32          Capacity;

    UINT32          ReadPartial:1,

                    ReadMisalign:1,

                    WritePartial:1,

                    WriteMisalign:1;

}MMC_CSD, *PMMC_CSD;

typedef struct _MMC_EXT_CSD_

{

    UINT32          HsMaxDtr;

    UINT32          Sectors;

}MMC_EXT_CSD, *PMMC_EXT_CSD;

typedef struct _SD_CSR_

{

    BYTE            SdaVsn;

    BYTE            BusWidths;

        #define SD_SCR_BUS_WIDTH_1    (1<<0)

        #define SD_SCR_BUS_WIDTH_4    (1<<2)

}SD_CSR, *PSD_CSR;

typedef struct _SD_SWITCH_CAPS_

{

    UINT32          HsMaxDtr;

}SD_SWITCH_CAPS, *PSD_SWITCH_CAPS;

typedef struct _SDIO_CCCR_

{

    UINT32      SdioVsn;

    UINT32      SdVsn;

    UINT32      MultiBlock:1,

                LowSpeed:1,

                WideBus:1,

                HighPower:1,

                HighSpeed:1,

                DisableCd:1;

}SDIO_CCCR, *PSDIO_CCCR;

typedef struct _SDIO_CIS_

{

    UINT16      Vendor;

    UINT16      Device;

    UINT16      BlkSize;

    UINT32      MaxDtr;

}SDIO_CIS, *PSDIO_CIS;

struct _MMC_HOST_;

/*

 * MMC device

 */

#define SDIO_MAX_FUNCS 7

typedef struct _MMC_CARD_

{

    UINT32          Rca;                    /* relative pCard address of device */

    UINT32          Type;                   /* pCard type */

        #define MMC_TYPE_MMC        0       /* MMC pCard */

        #define MMC_TYPE_SD         1       /* SD pCard */

        #define MMC_TYPE_SDIO       2       /* SDIO card */

        #define MMC_TYPE_SD_COMBO   3       /* SD combo (IO+mem) card */

    UINT32          State;                  /* (our) pCard state */

        #define MMC_STATE_PRESENT       (1<<0)        /* present */

        #define MMC_STATE_READONLY      (1<<1)        /* pCard is read-only */

        #define MMC_STATE_HIGHSPEED     (1<<2)        /* pCard is in high speed mode */

        #define MMC_STATE_BLOCKADDR     (1<<3)        /* pCard uses block-addressing */

        #define MMC_STATE_MOVINAND      (1<<7)        /* is a moviNAND Card */

        #define MMC_STATE_HIGHSPEED_DDR (1<<4)        /* card is in high speed mode */

    UINT32          Quirks;                 /* card quirks */

        #define MMC_QUIRK_LENIENT_FN0           (1<<0)  /* allow SDIO FN0 writes outside of the VS CCCR range */

        #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE   (1<<1)  /* use func->cur_blksize */

                                                /* for byte mode */

        #define MMC_QUIRK_NONSTD_SDIO           (1<<2)  /* non-standard SDIO card attached */

                                                        /* (missing CIA registers) */

    UINT32          RawCID[4];      /* raw card CID */

    UINT32          RawCSD[4];      /* raw card CSD */

    UINT32          RawSCR[2];      /* raw card SCR */

    MMC_CID         Cid;            /* card identification */

    MMC_CSD         Csd;            /* card specific */

    MMC_EXT_CSD     ExtCsd;         /* mmc v4 extended pCard specific */

    SD_CSR          Scr;            /* extra SD information */

    SD_SWITCH_CAPS  SwCaps;         /* switch (CMD6) Caps */

    // for SDIO

UINT32     nSdioFunc;                  /* number of SDIO functions */

SDIO_CCCR       Cccr;                       /* common card info */

SDIO_CIS        Cis;                        /* common tuple info */

PSDIO_FUNC      SdioFunc[SDIO_MAX_FUNCS];   /* SDIO functions (devices) */

UINT32          nInfo;                      /* number of info strings */

const char **ppInfo;                   /* info strings */

struct sdio_func_tuple *pTuples;            /* unknown common tuples */

}MMC_CARD, *PMMC_CARD;

#define IS_MMC_CARD_MMC(c)          ((c)->Type == MMC_TYPE_MMC)

#define IS_MMC_CARD_SD(c)           ((c)->Type == MMC_TYPE_SD)

#define IS_SDIO_CARD(c)             ((c)->Type == MMC_TYPE_SDIO)

#define IS_MMC_CARD_PRESENT(c)      ((c)->State & MMC_STATE_PRESENT)

#define IS_MMC_CARD_READONLY(c)     ((c)->State & MMC_STATE_READONLY)

#define IS_MMC_CARD_HIGHSPEED(c)    ((c)->State & MMC_STATE_HIGHSPEED)

#define IS_MMC_CARD_BLOCKADDR(c)    ((c)->State & MMC_STATE_BLOCKADDR)

#define IS_MMC_CARD_MOVINAND(c)     ((c)->State & MMC_STATE_MOVINAND)

#define IS_MMC_CARD_DDRMODE(c)      ((c)->State & MMC_STATE_HIGHSPEED_DDR)

#define MMC_CARD_SET_PRESENT(c)     ((c)->State |= MMC_STATE_PRESENT)

#define MMC_CARD_SET_READONLY(c)    ((c)->State |= MMC_STATE_READONLY)

#define MMC_CARD_SET_HIGHSPEED(c)   ((c)->State |= MMC_STATE_HIGHSPEED)

#define MMC_CARD_SET_BLOCKADDR(c)   ((c)->State |= MMC_STATE_BLOCKADDR)

#define MMC_CARD_SET_MOVINAND(c)    ((c)->State |= MMC_STATE_MOVINAND)

#define MMC_CARD_SET_DDRMODE(c)     ((c)->State |= MMC_STATE_HIGHSPEED_DDR)

#define MMC_CARD_NAME(c)            ((c)->Cid.ProdName)

STATIC INLINE INT32

MMC_CardLenientFn0 (PMMC_CARD pCard)

{

return pCard->Quirks & MMC_QUIRK_LENIENT_FN0;

}

STATIC INLINE INT32

MMC_BlkSzForByteMode (PMMC_CARD pCard)

{

return pCard->Quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;

}

//==================================================================================================

//==================================================================================================

//==================================================================================================

//==================================================================================================

//==================================================================================================

struct _MMC_DATA_;

struct _MMC_REQUEST_;

typedef struct _MMC_COMMAND_

{

    UINT32          Opcode;

    UINT32          Arg;

    UINT32          Resp[4];

    UINT32          Flags;                          /* expected response type */

        #define MMC_RSP_PRESENT     (1 << 0)

        #define MMC_RSP_136         (1 << 1)        /* 136 bit response */

        #define MMC_RSP_CRC         (1 << 2)        /* expect valid crc */

        #define MMC_RSP_BUSY        (1 << 3)        /* pCard may send busy */

        #define MMC_RSP_OPCODE      (1 << 4)        /* response contains Opcode */

        #define MMC_CMD_MASK        (3 << 5)        /* command type */

        #define MMC_CMD_AC          (0 << 5)

        #define MMC_CMD_ADTC        (1 << 5)

        #define MMC_CMD_BC          (2 << 5)

        #define MMC_CMD_BCR         (3 << 5)

        #define MMC_RSP_SPI_S1      (1 << 7)        /* one status byte */

        #define MMC_RSP_SPI_S2      (1 << 8)        /* second byte */

        #define MMC_RSP_SPI_B4      (1 << 9)        /* four data bytes */

        #define MMC_RSP_SPI_BUSY    (1 << 10)       /* card may send busy */

        /*

         * These are the response types, and correspond to valid bit

         * patterns of the above flags.  One additional valid pattern

         * is all zeros, which means we don't expect a response.

         */

        #define MMC_RSP_NONE        (0)

        #define MMC_RSP_R1          (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)

        #define MMC_RSP_R1B         (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)

        #define MMC_RSP_R2          (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)

        #define MMC_RSP_R3          (MMC_RSP_PRESENT)

        #define MMC_RSP_R4          (MMC_RSP_PRESENT)

        #define MMC_RSP_R5          (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)

        #define MMC_RSP_R6          (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)

        #define MMC_RSP_R7          (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)

        #define MmcRespType(pCmd)   ((pCmd)->Flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))

        /*

         * These are the SPI response types for MMC, SD, and SDIO cards.

         * Commands return R1, with maybe more info.  Zero is an error type;

         * callers must always provide the appropriate MMC_RSP_SPI_Rx flags.

         */

        #define MMC_RSP_SPI_R1      (MMC_RSP_SPI_S1)

        #define MMC_RSP_SPI_R1B     (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)

        #define MMC_RSP_SPI_R2      (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)

        #define MMC_RSP_SPI_R3      (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)

        #define MMC_RSP_SPI_R4      (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)

        #define MMC_RSP_SPI_R5      (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)

        #define MMC_RSP_SPI_R7      (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)

        #define MmcSpiRespType(Cmd)    ((Cmd)->Flags & (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY|MMC_RSP_SPI_S2|MMC_RSP_SPI_B4))

        /*

         * These are the command types.

         */

        #define MmcCmdType(pCmd)    ((pCmd)->Flags & MMC_CMD_MASK)

    UINT32        Retries;    /* max number of retries */

    UINT32        Error;        /* command error */

        #define MMC_ERR_NONE        0

        #define MMC_ERR_TIMEOUT     1

        #define MMC_ERR_BADCRC      2

        #define MMC_ERR_FIFO        3

        #define MMC_ERR_FAILED      4

        #define MMC_ERR_INVALID     5

        #define MMC_ERR_NOMEDIUM    6

        #define MMC_ERR_IO          7

        #define MMC_ERR_NODEV       8

        #define MMC_ERR_ILSEQ       9

        #define MMC_ERR_AGAIN       10

    struct _MMC_DATA_           *pData;          /* data segment associated with pCmd */

    struct _MMC_REQUEST_        *pMMCRequest;           /* associated request */

}MMC_COMMAND, *PMMC_COMMAND;

typedef struct _MMC_DATA_

{

    UINT32                  TimeoutNs;    /* data timeout (in ns, max 80ms) */

    UINT32                  TimeoutClks;    /* data timeout (in clocks) */

    UINT32                  BlkSz;        /* data block size */

    UINT32                  Blocks;        /* number of Blocks */

    UINT32                  Error;        /* data error */

    UINT32                  Flags;

        #define MMC_DATA_WRITE      (1 << 8)

        #define MMC_DATA_READ       (1 << 9)

        #define MMC_DATA_STREAM     (1 << 10)

        #define MMC_DATA_MULTI      (1 << 11)

    UINT32                  nTransferedLength;

    PMMC_COMMAND            pStopCmd;        /* stop command */

    struct _MMC_REQUEST_    *pMMCRequest;        /* associated request */

//    DISK_PREQUEST       pRequest;

    DISK_PREQUESTBUF        *ppReqBuf;

//    UINT32              RequestLength;

}MMC_DATA, *PMMC_DATA;

typedef struct _MMC_REQUEST_

{

    PMMC_COMMAND        pCmd;

    PMMC_DATA           pData;

    PMMC_COMMAND        pStopCmd;

    PMMC_COMMAND        pSetBlockCountedCmd;

}MMC_REQUEST, *PMMC_REQUEST;

//==================================================================================================

//==================================================================================================

//==================================================================================================

//==================================================================================================

//==================================================================================================

typedef struct _MMC_IOSET_

{

    UINT32      Clock;              /* clock rate */

    UINT16      Vdd;

/* vdd stores the bit number of the selected voltage range from below. */

    BYTE        BusMode;            /* command output mode */

        #define MMC_BUSMODE_OPENDRAIN   1

        #define MMC_BUSMODE_PUSHPULL    2

    BYTE        ChipSelect;         /* SPI chip select */

        #define MMC_CS_DONTCARE         0

        #define MMC_CS_HIGH             1

        #define MMC_CS_LOW              2

    BYTE        PowerMode;          /* power supply mode */

        #define MMC_POWER_OFF           0

        #define MMC_POWER_UP            1

        #define MMC_POWER_ON            2

    BYTE        BusWidth;           /* data bus width */

        #define MMC_BUS_WIDTH_1         0

        #define MMC_BUS_WIDTH_4         2

        #define MMC_BUS_WIDTH_8         3

    BYTE        Timing;             /* Timing specification used */

        #define MMC_TIMING_LEGACY       0

        #define MMC_TIMING_MMC_HS       1

        #define MMC_TIMING_SD_HS        2

}MMC_IOSET, *PMMC_IOSET;

struct _DEVICESDMMC_OPS_ ;

typedef struct _MMC_HOST_

{

//    int                         index;

    struct _DEVICESDMMC_OPS_    *pOps;

    UINT32          fMin;

    UINT32          fMax;

    UINT32          OcrAvail;

        #define MMC_VDD_165_195      0x00000080    /* VDD voltage 1.65 - 1.95 */

        #define MMC_VDD_20_21        0x00000100    /* VDD voltage 2.0 ~ 2.1 */

        #define MMC_VDD_21_22        0x00000200    /* VDD voltage 2.1 ~ 2.2 */

        #define MMC_VDD_22_23        0x00000400    /* VDD voltage 2.2 ~ 2.3 */

        #define MMC_VDD_23_24        0x00000800    /* VDD voltage 2.3 ~ 2.4 */

        #define MMC_VDD_24_25        0x00001000    /* VDD voltage 2.4 ~ 2.5 */

        #define MMC_VDD_25_26        0x00002000    /* VDD voltage 2.5 ~ 2.6 */

        #define MMC_VDD_26_27        0x00004000    /* VDD voltage 2.6 ~ 2.7 */

        #define MMC_VDD_27_28        0x00008000    /* VDD voltage 2.7 ~ 2.8 */

        #define MMC_VDD_28_29        0x00010000    /* VDD voltage 2.8 ~ 2.9 */

        #define MMC_VDD_29_30        0x00020000    /* VDD voltage 2.9 ~ 3.0 */

        #define MMC_VDD_30_31        0x00040000    /* VDD voltage 3.0 ~ 3.1 */

        #define MMC_VDD_31_32        0x00080000    /* VDD voltage 3.1 ~ 3.2 */

        #define MMC_VDD_32_33        0x00100000    /* VDD voltage 3.2 ~ 3.3 */

        #define MMC_VDD_33_34        0x00200000    /* VDD voltage 3.3 ~ 3.4 */

        #define MMC_VDD_34_35        0x00400000    /* VDD voltage 3.4 ~ 3.5 */

        #define MMC_VDD_35_36        0x00800000    /* VDD voltage 3.5 ~ 3.6 */

    UINT32          Caps;        /* Host capabilities 0*/

    UINT32          Caps1;       /* Host capabilities 1*/

        #define MMC_CAP_4_BIT_DATA      (1 << 0)    /* Can the pHost do 4 bit transfers */

        #define MMC_CAP_MULTIWRITE      (1 << 1)    /* Can accurately report bytes sent to pCard on error */

        #define MMC_CAP_MMC_HIGHSPEED   (1 << 2)    /* Can do MMC high-speed Timing */

        #define MMC_CAP_SD_HIGHSPEED    (1 << 3)    /* Can do SD high-speed Timing */

        #define MMC_CAP_SDIO_IRQ        (1 << 4)    /* Can signal pending SDIO IRQs */

        #define MMC_CAP_SPI             (1 << 5)    /* Talks only SPI protocols */

        #define MMC_CAP_NEEDS_POLL      (1 << 6)    /* Needs polling for card-detection */

        #define MMC_CAP_8_BIT_DATA      (1 << 7)    /* Can the host do 8 bit transfers */

        #define MMC_CAP_NONREMOVABLE    (1 << 8)    /* Nonremovable e.g. eMMC */

        #define MMC_CAP_WAIT_WHILE_BUSY (1 << 9)    /* Waits while card is busy */

        #define MMC_CAP_ON_BOARD        (1 << 8)    /* Do not need to rescan after bootup */

//        #define MMC_CAP_BOOT_ONTHEFLY   (1 << 9)    /* Can detect device at boot time */

        #define MMC_CAP_ERASE           (1 << 10)   /* Allow erase/trim commands */

        #define MMC_CAP_1_8V_DDR        (1 << 11)   /* DDR mode at 1.8V */

        #define MMC_CAP_1_2V_DDR        (1 << 12)   /* DDR mode at 1.2V */

        #define MMC_CAP_POWER_OFF_CARD  (1 << 13)   /* Can power off after boot */

        #define MMC_CAP_BUS_WIDTH_TEST  (1 << 14)       /* CMD14/CMD19 bus width ok */

        #define MMC_CAP_UHS_SDR12       (1 << 15)       /* Host supports UHS SDR12 mode */

        #define MMC_CAP_UHS_SDR25       (1 << 16)       /* Host supports UHS SDR25 mode */

        #define MMC_CAP_UHS_SDR50       (1 << 17)       /* Host supports UHS SDR50 mode */

        #define MMC_CAP_UHS_SDR104      (1 << 18)       /* Host supports UHS SDR104 mode */

        #define MMC_CAP_UHS_DDR50       (1 << 19)       /* Host supports UHS DDR50 mode */

        #define MMC_CAP_DRIVER_TYPE_A   (1 << 23)       /* Host supports Driver Type A */

        #define MMC_CAP_DRIVER_TYPE_C   (1 << 24)       /* Host supports Driver Type C */

        #define MMC_CAP_DRIVER_TYPE_D   (1 << 25)       /* Host supports Driver Type D */

        #define MMC_CAP_CMD23           (1 << 30)       /* CMD23 supported. */

        #define MMC_CAP_HW_RESET        (1 << 31)       /* Hardware reset */

    UINT32      Caps2;

        #define MMC_CAP2_BOOTPART_NOACC (1 << 0)        /* Boot partition no access */

        #define MMC_CAP2_CACHE_CTRL     (1 << 1)        /* Allow cache control */

        #define MMC_CAP2_POWEROFF_NOTIFY (1 << 2)       /* Notify poweroff supported */

        #define MMC_CAP2_NO_MULTI_READ  (1 << 3)        /* Multiblock reads don't work */

        #define MMC_CAP2_NO_SLEEP_CMD   (1 << 4)        /* Don't allow sleep command */

        #define MMC_CAP2_HS200_1_8V_SDR (1 << 5)        /* can support */

        #define MMC_CAP2_HS200_1_2V_SDR (1 << 6)        /* can support */

        #define MMC_CAP2_HS200          (MMC_CAP2_HS200_1_8V_SDR | \

                                         MMC_CAP2_HS200_1_2V_SDR)

        #define MMC_CAP2_BROKEN_VOLTAGE (1 << 7)        /* Use the broken voltage */

        #define MMC_CAP2_DETECT_ON_ERR  (1 << 8)        /* On I/O err check card removal */

        #define MMC_CAP2_HC_ERASE_SZ    (1 << 9)        /* High-capacity erase size */

        #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10)       /* Card-detect signal active high */

        #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11)       /* Write-protect signal active high */

        #define MMC_CAP2_PACKED_RD      (1 << 12)       /* Allow packed read */

        #define MMC_CAP2_PACKED_WR      (1 << 13)       /* Allow packed write */

        #define MMC_CAP2_PACKED_CMD     (MMC_CAP2_PACKED_RD | \

                                         MMC_CAP2_PACKED_WR)

    /* host specific block data */

    UINT32          MaxSegSize;     /* see blk_queue_max_segment_size */

    UINT16          MaxHwSegs;      /* see blk_queue_max_hw_segments */

    UINT16          MaxPhysSegs;    /* see blk_queue_max_phys_segments */

    UINT16          unused;

    UINT32          MaxReqSize;     /* maximum number of bytes in one req */

    UINT32          MaxBlkSize;     /* maximum size of one mmc block */

    UINT32          MaxBlkCount;    /* maximum number of Blocks in one req */

    MMC_IOSET       IOSet;          /* current io bus settings */

    UINT32          Ocr;            /* the current OCR setting */

    UINT32          Mode;           /* current pCard mode of pHost */

        #define MMC_MODE_MMC        0

        #define MMC_MODE_SD         1

    MMC_CARD        Card;           /* device attached to this pHost */

    UINT32          UseSpiCRC:1;

    UINT32          Claimed:1;      /* host exclusively claimed */

    UINT32          CardBus;

    UINT32          BusRefs;        /* reference counter */

    UINT32          BusDead:1;      /* bus has been released */

}MMC_HOST, *PMMC_HOST;

#define IS_MMC_HOST_SPI(pHost)    ((pHost)->Caps & MMC_CAP_SPI)

typedef struct _DEVICESDMMC_OPS_

{

    HANDLE          (*DevInit)          (UINT32);

    BOOL            (*DevDeInit)          (HANDLE Handle, UINT32);

    VOID            (*DevRequest)       ( HANDLE Handle, PMMC_REQUEST pRequest );

    VOID            (*DevSetIOSet)      ( HANDLE Handle, PMMC_IOSET pIos );

    INT32           (*DevInterrupt)     ( HANDLE Handle );

    INT32           (*DevGetReadOnly)   ( HANDLE Handle );

    UINT32          (*DevGetCardBus)    ( HANDLE Handle );

    UINT32          (*DevTimeOut)       ( HANDLE Handle );

    VOID            (*DevSignal)        ( HANDLE Handle, UINT32 Mask );

    VOID            (*EnableSDIOIrq)    ( HANDLE Handle, BOOL Enable );

    INT32           (*SecondInterrupt)  ( HANDLE Handle );

}DEVICESDMMC_OPS, *PDEVICESDMMC_OPS;

#define INTERRUPTTHREADSTACK_SIZE       1024

typedef struct _DEVICECONFIGSDMMC_

{

    BYTE                Name[4];

    UINT32              Minor;

    UINT32              Channel;

    VOID                (*DevPowerOff)( VOID );

    VOID                (*DevPowerOn)( VOID );

    UINT32              nInterrupt;

    PDEVICESDMMC_OPS    pDeviceOps;

    THREADCONFIG        ThreadConfig;

    THREADCONFIG        InterruptThreadConfig;

    UINT32              InterruptThreadStack[INTERRUPTTHREADSTACK_SIZE>>2];

}DEVICECONFIGSDMMC, *PDEVICECONFIGSDMMC;

#define STATE_INITING           1

#define STATE_CLOSED            2

#define STATE_OPENED            3

#define STATE_DEAD              4    // Power down

#define STATE_REMOVED           5

#define DISK_DEAD_ERROR         ERROR_NOT_READY

#define DISK_REMOVED_ERROR      ERROR_BAD_UNIT

#define DISK_MAGICNUMBER         0xDD115533

typedef struct _DISK_

{

    struct _DISK_*              pNext;

    UINT32                      d_DiskCardState;

    DISK_INFO                   d_DiskInfo;

    UINT32                      d_OpenCount;

    UINT32                      dwMagicNumber;

    UINT32                      dwSysIntr;

    HANDLE                      hInterruptEvent;

    UINT32                      dwSlotNumber;

    // user definition

    HANDLE                      hCond;

    UINT32                      nChannel;

    UINT32                      BlockBits;

    MMC_HOST                    Host;

    UINT32                      flags;

    HANDLE                      hTimer;

    UINT32                      nISRChannel;

    PVOID                       pPriv;

#ifdef SDIO_IRQ_THREAD_ENABLED

    INT32                       SdioIrqs;

    HANDLE                      hThreadSDIOIrq;

    BOOL                        bSdioIrqThreadAbort;

    HANDLE                      hCondSdioIrq;

#endif

} DISK, * PDISK, /*SDIO,*/ * PSDIO;

#define SDIO_MAGICNUMBER         0x2D105533

//typedef struct _SDIO_

//{

//    struct _SDIO_*              pNext;

////    struct _DISK_*              pNext;

//

//    UINT32                      d_DiskCardState;

//    DISK_INFO                   d_DiskInfo;

//    UINT32                      d_OpenCount;

//

//    UINT32                      dwMagicNumber;

//    UINT32                      dwSysIntr;

//    HANDLE                      hInterruptEvent;

//    UINT32                      dwSlotNumber;

//

//    // user definition

//    HANDLE                      hCond;

//    UINT32                      nChannel;

//    UINT32                      BlockBits;

//

//    MMC_HOST                    Host;

//    UINT32                      flags;

//    HANDLE                      hTimer;

//

//    UINT32                      nISRChannel;

//

//    PVOID                       pPriv;

//

////    // only for SDIO

////    INT32                       SdioIrqs;

////    UINT32                      IrqPriority;

//// HANDLE                      hThreadSDIOIrq;

////    BOOL                        bSdioIrqThreadAbort;

////    

//

//} SDIO, * PSDIO;

//

EXTERN BOOL MMC_AllocHost( PDISK pDisk );

EXTERN VOID MMC_RequestDone(PDISK pDisk, PMMC_REQUEST pMMCRequest);

EXTERN VOID MMC_TimerStart( PDISK pDisk );

EXTERN VOID MMC_TimerStop( PDISK pDisk );

EXTERN VOID MMC_TimerModify( PDISK pDisk, UINT32 Timeout );

EXTERN VOID MMC_DetectChange( PDISK pDisk );

EXTERN HANDLE DeviceRegisterSDMMC( PDEVICECONFIGSDMMC pSDMMCDeviceConfig, PBYTE pStack, UINT32 StackSize, UINT32 Priority);

#endif //__DOOROOS_DEV_SDIODRV_H__