357 lines
14 KiB
C
357 lines
14 KiB
C
|
/*
|
||
|
* Copyright (C) 2017 ALLWINNERTECH TECHNOLOGY CO., LTD. All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions
|
||
|
* are met:
|
||
|
* 1. Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the
|
||
|
* distribution.
|
||
|
* 3. Neither the name of ALLWINNERTECH TECHNOLOGY CO., LTD. nor the names of
|
||
|
* its contributors may be used to endorse or promote products derived
|
||
|
* from this software without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*/
|
||
|
|
||
|
#ifndef _DRIVER_CHIP_SDMMC_CARD_H_
|
||
|
#define _DRIVER_CHIP_SDMMC_CARD_H_
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
#include "osal/os_mutex.h"
|
||
|
|
||
|
#define CONFIG_SDIO_USE_FUNS
|
||
|
//#define CONFIG_USE_SDIO_COMBO
|
||
|
|
||
|
//#define SD_SUPPORT_VERSION3 /* not support for not support 1V8 */ #error !!
|
||
|
//#define CONFIG_USE_MMC_QUIRK /* not support now */ #error !!
|
||
|
//#define CONFIG_SDIO_USE_FUNS /* close to save code. and not support now */ #error !!
|
||
|
|
||
|
#define SYSTEM_SIMULATION
|
||
|
|
||
|
#ifdef CONFIG_USE_SDIO
|
||
|
struct sdio_func;
|
||
|
typedef void (sdio_irq_handler_t)(struct sdio_func *);
|
||
|
|
||
|
/*
|
||
|
* SDIO function devices
|
||
|
*/
|
||
|
struct sdio_func {
|
||
|
struct mmc_card *card; /* the card this device belongs to */
|
||
|
sdio_irq_handler_t *irq_handler; /* IRQ callback */
|
||
|
uint32_t num; /* function number */
|
||
|
|
||
|
unsigned char class; /* standard interface class */
|
||
|
unsigned short vendor; /* vendor id */
|
||
|
unsigned short device; /* device id */
|
||
|
|
||
|
uint32_t max_blksize; /* maximum block size */
|
||
|
uint32_t cur_blksize; /* current block size */
|
||
|
|
||
|
uint32_t enable_timeout; /* max enable timeout in msec */
|
||
|
|
||
|
uint32_t state; /* function state */
|
||
|
#define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */
|
||
|
|
||
|
uint8_t tmpbuf[4]; /* DMA:able scratch buffer */
|
||
|
|
||
|
unsigned num_info; /* number of info strings */
|
||
|
const char **info; /* info strings */
|
||
|
|
||
|
struct sdio_func_tuple *tuples;
|
||
|
/*for rtl*/
|
||
|
void *drv_prv;
|
||
|
};
|
||
|
|
||
|
#define sdio_func_present(f) ((f)->state & SDIO_STATE_PRESENT)
|
||
|
#define sdio_func_set_present(f) ((f)->state |= SDIO_STATE_PRESENT)
|
||
|
|
||
|
#endif
|
||
|
|
||
|
struct mmc_ocr {
|
||
|
union {
|
||
|
uint32_t vol_window : 24,
|
||
|
to_1v8_acpt : 1,
|
||
|
: 5,
|
||
|
high_capacity : 1,
|
||
|
: 1;
|
||
|
uint32_t ocr;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
struct mmc_cid {
|
||
|
uint16_t oemid;
|
||
|
uint8_t manfid;
|
||
|
uint32_t serial;
|
||
|
uint16_t year;
|
||
|
uint8_t month;
|
||
|
uint8_t hwrev;
|
||
|
uint8_t fwrev;
|
||
|
uint8_t prod_name[6];
|
||
|
};
|
||
|
|
||
|
struct mmc_csd {
|
||
|
uint8_t csd_ver;
|
||
|
//uint8_t c_size_mult;
|
||
|
//uint16_t c_size;
|
||
|
uint32_t max_dtr; /* max transfer speed */
|
||
|
uint16_t read_blk_len;
|
||
|
uint16_t cmdclass;
|
||
|
uint32_t capacity;
|
||
|
};
|
||
|
|
||
|
struct sd_scr {
|
||
|
uint8_t sda_vsn;
|
||
|
uint8_t sda_spec3;
|
||
|
uint8_t sda_spec4;
|
||
|
uint8_t sda_spec5;
|
||
|
uint8_t bus_widths;
|
||
|
uint8_t security_sup;
|
||
|
#define SD_SCR_BUS_WIDTH_1 (1<<0)
|
||
|
#define SD_SCR_BUS_WIDTH_4 (1<<2)
|
||
|
uint8_t cmds;
|
||
|
#define SD_SCR_CMD20_SUPPORT (1<<0)
|
||
|
#define SD_SCR_CMD23_SUPPORT (1<<1)
|
||
|
};
|
||
|
|
||
|
struct sd_ssr {
|
||
|
uint32_t au; /* In sectors */
|
||
|
uint32_t erase_timeout; /* In milliseconds */
|
||
|
uint32_t erase_offset; /* In milliseconds */
|
||
|
};
|
||
|
|
||
|
struct sd_switch_caps {
|
||
|
uint32_t hs_max_dtr;
|
||
|
uint32_t uhs_max_dtr;
|
||
|
#define HIGH_SPEED_MAX_DTR 50000000
|
||
|
#define UHS_SDR104_MAX_DTR 208000000
|
||
|
#define UHS_SDR50_MAX_DTR 100000000
|
||
|
#define UHS_DDR50_MAX_DTR 50000000
|
||
|
#define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR
|
||
|
#define UHS_SDR12_MAX_DTR 25000000
|
||
|
uint32_t sd3_bus_mode;
|
||
|
#define UHS_SDR12_BUS_SPEED 0
|
||
|
#define HIGH_SPEED_BUS_SPEED 1
|
||
|
#define UHS_SDR25_BUS_SPEED 1
|
||
|
#define UHS_SDR50_BUS_SPEED 2
|
||
|
#define UHS_SDR104_BUS_SPEED 3
|
||
|
#define UHS_DDR50_BUS_SPEED 4
|
||
|
|
||
|
#define SD_MODE_HIGH_SPEED (1 << HIGH_SPEED_BUS_SPEED)
|
||
|
#define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED)
|
||
|
#define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED)
|
||
|
#define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED)
|
||
|
#define SD_MODE_UHS_SDR104 (1 << UHS_SDR104_BUS_SPEED)
|
||
|
#define SD_MODE_UHS_DDR50 (1 << UHS_DDR50_BUS_SPEED)
|
||
|
uint32_t sd3_drv_type;
|
||
|
#define SD_DRIVER_TYPE_B 0x01
|
||
|
#define SD_DRIVER_TYPE_A 0x02
|
||
|
#define SD_DRIVER_TYPE_C 0x04
|
||
|
#define SD_DRIVER_TYPE_D 0x08
|
||
|
uint32_t sd3_curr_limit;
|
||
|
#define SD_SET_CURRENT_LIMIT_200 0
|
||
|
#define SD_SET_CURRENT_LIMIT_400 1
|
||
|
#define SD_SET_CURRENT_LIMIT_600 2
|
||
|
#define SD_SET_CURRENT_LIMIT_800 3
|
||
|
|
||
|
#define SD_MAX_CURRENT_200 (1 << SD_SET_CURRENT_LIMIT_200)
|
||
|
#define SD_MAX_CURRENT_400 (1 << SD_SET_CURRENT_LIMIT_400)
|
||
|
#define SD_MAX_CURRENT_600 (1 << SD_SET_CURRENT_LIMIT_600)
|
||
|
#define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800)
|
||
|
};
|
||
|
|
||
|
struct mmc_ext_csd {
|
||
|
uint8_t version;
|
||
|
uint8_t card_type;
|
||
|
uint8_t csd_struc;
|
||
|
uint8_t hs_timing;
|
||
|
uint8_t bus_width;
|
||
|
uint8_t part_config;
|
||
|
uint8_t boot_bus_cond;
|
||
|
};
|
||
|
|
||
|
struct sdio_cccr {
|
||
|
uint32_t sdio_vsn;
|
||
|
uint32_t sd_vsn;
|
||
|
uint32_t multi_block:1,
|
||
|
low_speed:1,
|
||
|
wide_bus:1,
|
||
|
high_power:1,
|
||
|
high_speed:1,
|
||
|
disable_cd:1;
|
||
|
};
|
||
|
|
||
|
struct sdio_cis {
|
||
|
uint16_t vendor;
|
||
|
uint16_t device;
|
||
|
uint16_t blksize;
|
||
|
uint32_t max_dtr;
|
||
|
};
|
||
|
|
||
|
struct mmc_host;
|
||
|
|
||
|
#define SDIO_MAX_FUNCS 7
|
||
|
|
||
|
/** @bried SD Card Init Structure definition. */
|
||
|
typedef struct {
|
||
|
uint16_t debug_mask;
|
||
|
uint16_t type; /* set card type if we know to speed up scan card, MMC_TYPE_xx */
|
||
|
} SDCard_InitTypeDef;
|
||
|
|
||
|
struct mmc_card {
|
||
|
uint16_t debug_mask;
|
||
|
uint16_t suspend;
|
||
|
//#if ((defined CONFIG_USE_SD) || (defined CONFIG_USE_MMC))
|
||
|
/* register info. */
|
||
|
struct mmc_cid cid;
|
||
|
struct mmc_csd csd;
|
||
|
struct sd_scr scr;
|
||
|
struct sd_ssr ssr;
|
||
|
struct mmc_ext_csd extcsd;
|
||
|
struct sd_switch_caps sw_caps; /* switch (CMD6) caps */
|
||
|
//#endif
|
||
|
/* card information */
|
||
|
uint32_t id;
|
||
|
uint32_t type; /* card type */
|
||
|
#define MMC_TYPE_MMC 1 /* MMC card */
|
||
|
#define MMC_TYPE_SD 2 /* SD card */
|
||
|
#define MMC_TYPE_SDIO 3 /* SDIO card */
|
||
|
#define MMC_TYPE_SD_COMBO 4 /* SD combo (IO+mem) card */
|
||
|
#define MMC_TYPE_MAX 5
|
||
|
|
||
|
uint32_t sd_bus_speed; /* Bus Speed Mode set for the card */
|
||
|
uint32_t state; /* (our) card state */
|
||
|
#define MMC_STATE_PRESENT (1 << 0) /* present */
|
||
|
#define MMC_STATE_READONLY (1 << 1) /* card is read-only */
|
||
|
#define MMC_STATE_HIGHSPEED (1 << 2) /* card is in high speed mode */
|
||
|
#define MMC_STATE_BLOCKADDR (1 << 3) /* card uses block-addressing */
|
||
|
#define MMC_STATE_HIGHSPEED_DDR (1 << 4) /* card is in high speed mode */
|
||
|
|
||
|
#define MMC_STATE_ULTRAHIGHSPEED (1<<5) /* card is in ultra high speed mode */
|
||
|
#define MMC_CARD_SDXC (1<<6) /* card is SDXC */
|
||
|
#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
|
||
|
#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
|
||
|
#define MMC_STATE_SLEEP (1<<9) /* card is in sleep state */
|
||
|
//#ifdef CONFIG_USE_MMC_QUIRK
|
||
|
uint32_t 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) */
|
||
|
#define MMC_QUIRK_BROKEN_CLK_GATING (1<<3) /* clock gating the sdio bus will make card fail */
|
||
|
#define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */
|
||
|
#define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */
|
||
|
#define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */
|
||
|
#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */
|
||
|
#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */
|
||
|
#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */
|
||
|
#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */
|
||
|
//#endif
|
||
|
/* missing CIA registers */
|
||
|
|
||
|
//#ifdef CONFIG_SDIO_USE_FUNS
|
||
|
uint32_t erase_size; /* erase size in sectors */
|
||
|
uint32_t erase_shift; /* if erase unit is power 2 */
|
||
|
uint32_t pref_erase; /* in sectors */
|
||
|
uint8_t erased_byte; /* value of erased bytes */
|
||
|
|
||
|
uint32_t raw_cid[4]; /* raw card CID */
|
||
|
uint32_t raw_csd[4]; /* raw card CSD */
|
||
|
uint32_t raw_scr[2]; /* raw card SCR */
|
||
|
uint32_t sdio_funcs; /* number of SDIO functions */
|
||
|
struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
|
||
|
uint32_t num_info; /* number of info strings */
|
||
|
const int8_t **info; /* info strings */
|
||
|
//#ifdef CONFIG_SDIO_IRQ_SUPPORT
|
||
|
// sdio_irq_handler_t *sdio_single_irq; /* IRQ callback, all funs only support one for efficiency! */
|
||
|
struct sdio_func *sdio_single_irq; /* SDIO function when only one IRQ active */
|
||
|
//#endif
|
||
|
//#endif
|
||
|
#ifdef CONFIG_USE_SDIO
|
||
|
uint32_t manfid;
|
||
|
uint32_t cisptr[8];
|
||
|
uint16_t fn_bsize[8];
|
||
|
void *mem_info_p; //if with memory, to store information about memory portion
|
||
|
//struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
|
||
|
struct sdio_cccr cccr; /* common card info */
|
||
|
struct sdio_cis cis; /* common tuple info */
|
||
|
|
||
|
struct sdio_func_tuple *tuples; /* unknown common tuples */
|
||
|
#endif
|
||
|
uint8_t bus_width;
|
||
|
uint8_t speed_class;
|
||
|
uint16_t ref;
|
||
|
OS_Mutex_t mutex;
|
||
|
uint32_t cidno[4];
|
||
|
|
||
|
uint32_t rca; /* relative card address of device */
|
||
|
struct mmc_ocr ocr;
|
||
|
struct mmc_host *host; /* the host this device belongs to */
|
||
|
};
|
||
|
|
||
|
struct mmc_card_info {
|
||
|
struct mmc_card card;
|
||
|
struct sdio_func sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
|
||
|
//const int8_t **info; /* info strings */
|
||
|
//struct sdio_func *sdio_single_irq; /* SDIO function when only one IRQ active */
|
||
|
//void *mem_info_p; //if with memory, to store information about memory portion
|
||
|
#ifdef CONFIG_USE_SDIO
|
||
|
//struct sdio_func_tuple *tuples; /* unknown common tuples */
|
||
|
#endif
|
||
|
uint32_t sdc_id;
|
||
|
};
|
||
|
|
||
|
#define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC)
|
||
|
#define mmc_card_sd(c) ((c)->type == MMC_TYPE_SD)
|
||
|
#define mmc_card_sdio(c) ((c)->type == MMC_TYPE_SDIO)
|
||
|
#define mmc_card_sd_combo(c) ((c)->type == MMC_TYPE_SD_COMBO)
|
||
|
|
||
|
#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
|
||
|
#define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY)
|
||
|
#define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED)
|
||
|
#define mmc_card_hs200(c) ((c)->state & MMC_STATE_HIGHSPEED_200)
|
||
|
#define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR)
|
||
|
#define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR)
|
||
|
#define mmc_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
|
||
|
#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
|
||
|
#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
|
||
|
#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED))
|
||
|
#define mmc_card_is_sleep(c) ((c)->state & MMC_STATE_SLEEP)
|
||
|
|
||
|
#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_hs200(c) ((c)->state |= MMC_STATE_HIGHSPEED_200)
|
||
|
#define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
|
||
|
#define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR)
|
||
|
#define mmc_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
|
||
|
#define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
|
||
|
#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
|
||
|
#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
|
||
|
#define mmc_card_set_sleep(c) ((c)->state |= MMC_STATE_SLEEP)
|
||
|
|
||
|
#define mmc_card_clr_sleep(c) ((c)->state &= ~MMC_STATE_SLEEP)
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif /* _DRIVER_CHIP_SDMMC_CARD_H_ */
|