update SDIO protocol
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1979 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
b2d0a9c146
commit
dea9c19e5e
|
@ -681,10 +681,10 @@ static void at91_mci_irq(int irq)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (int_status & AT91_MCI_SDIOIRQA)
|
/*if (int_status & AT91_MCI_SDIOIRQA)
|
||||||
rt_mmcsd_signal_sdio_irq(host->mmc);
|
rt_mmcsd_signal_sdio_irq(host->mmc);*/
|
||||||
|
|
||||||
if (int_status & AT91_MCI_SDIOIRQB)
|
if (int_status & AT91_MCI_SDIOIRQB)
|
||||||
rt_mmcsd_signal_sdio_irq(host->mmc);*/
|
sdio_irq_wakeup(at_mci->host);
|
||||||
|
|
||||||
if (int_status & AT91_MCI_TXRDY)
|
if (int_status & AT91_MCI_TXRDY)
|
||||||
mci_dbg("Ready to transmit\n");
|
mci_dbg("Ready to transmit\n");
|
||||||
|
@ -778,10 +778,17 @@ static void at91_mci_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void at91_mci_enable_sdio_irq(struct rt_mmcsd_host *host, rt_int32_t enable)
|
||||||
|
{
|
||||||
|
at91_mci_write(enable ? AT91_MCI_IER : AT91_MCI_IDR, AT91_MCI_SDIOIRQB);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const struct rt_mmcsd_host_ops ops = {
|
static const struct rt_mmcsd_host_ops ops = {
|
||||||
at91_mci_request,
|
at91_mci_request,
|
||||||
at91_mci_set_iocfg,
|
at91_mci_set_iocfg,
|
||||||
RT_NULL,
|
RT_NULL,
|
||||||
|
at91_mci_enable_sdio_irq,
|
||||||
};
|
};
|
||||||
|
|
||||||
void at91_mci_detect(int irq)
|
void at91_mci_detect(int irq)
|
||||||
|
@ -834,6 +841,10 @@ rt_int32_t at91_mci_init(void)
|
||||||
host->freq_max = 25000000;
|
host->freq_max = 25000000;
|
||||||
host->valid_ocr = VDD_32_33 | VDD_33_34;
|
host->valid_ocr = VDD_32_33 | VDD_33_34;
|
||||||
host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE;
|
host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE;
|
||||||
|
host->max_seg_size = 65535;
|
||||||
|
host->max_dma_segs = 2;
|
||||||
|
host->max_blk_size = 512;
|
||||||
|
host->max_blk_count = 4096;
|
||||||
|
|
||||||
at_mci->host = host;
|
at_mci->host = host;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ src = Split("""
|
||||||
block_dev.c
|
block_dev.c
|
||||||
mmcsd_core.c
|
mmcsd_core.c
|
||||||
sd.c
|
sd.c
|
||||||
|
sdio.c
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# The set of source files associated with this SConscript file.
|
# The set of source files associated with this SConscript file.
|
||||||
|
|
|
@ -114,7 +114,7 @@ static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector,
|
||||||
req.data = &data;
|
req.data = &data;
|
||||||
|
|
||||||
cmd.arg = sector;
|
cmd.arg = sector;
|
||||||
if (!(card->card_type & CARD_TYPE_SDHC))
|
if (!(card->flags & CARD_FLAG_SDHC))
|
||||||
{
|
{
|
||||||
cmd.arg <<= 9;
|
cmd.arg <<= 9;
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ static rt_int32_t mmcsd_set_blksize(struct rt_mmcsd_card *card)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Block-addressed cards ignore MMC_SET_BLOCKLEN. */
|
/* Block-addressed cards ignore MMC_SET_BLOCKLEN. */
|
||||||
if (card->card_type & CARD_TYPE_SDHC)
|
if (card->flags & CARD_FLAG_SDHC)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mmcsd_host_lock(card->host);
|
mmcsd_host_lock(card->host);
|
||||||
|
@ -412,7 +412,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
|
||||||
|
|
||||||
blk_dev->geometry.bytes_per_sector = 1<<9;
|
blk_dev->geometry.bytes_per_sector = 1<<9;
|
||||||
blk_dev->geometry.block_size = card->card_blksize;
|
blk_dev->geometry.block_size = card->card_blksize;
|
||||||
if (card->card_type | CARD_TYPE_SDHC)
|
if (card->flags & CARD_FLAG_SDHC)
|
||||||
{
|
{
|
||||||
blk_dev->geometry.sector_count = (card->csd.c_size + 1) * 1024;
|
blk_dev->geometry.sector_count = (card->csd.c_size + 1) * 1024;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#define __MMCSD_CARD_H__
|
#define __MMCSD_CARD_H__
|
||||||
|
|
||||||
#include "mmcsd_host.h"
|
#include "mmcsd_host.h"
|
||||||
|
#include "sdio.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -61,6 +62,28 @@ struct rt_sd_scr {
|
||||||
rt_uint8_t sd_bus_widths;
|
rt_uint8_t sd_bus_widths;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rt_sdio_cccr {
|
||||||
|
rt_uint8_t sdio_version;
|
||||||
|
rt_uint8_t sd_version;
|
||||||
|
rt_uint8_t multi_block:1,
|
||||||
|
low_speed:1,
|
||||||
|
wide_bus:1,
|
||||||
|
high_power:1,
|
||||||
|
high_speed:1,
|
||||||
|
disable_cd:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rt_sdio_cis {
|
||||||
|
rt_uint16_t manufacturer;
|
||||||
|
rt_uint16_t product;
|
||||||
|
rt_uint16_t func0_blk_size;
|
||||||
|
rt_uint32_t max_tran_speed;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SDIO_MAX_FUNCTIONS 7
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct rt_mmcsd_card {
|
struct rt_mmcsd_card {
|
||||||
struct rt_mmcsd_host *host;
|
struct rt_mmcsd_host *host;
|
||||||
rt_uint32_t rca; /* card addr */
|
rt_uint32_t rca; /* card addr */
|
||||||
|
@ -73,16 +96,29 @@ struct rt_mmcsd_card {
|
||||||
rt_uint32_t max_data_rate; /* max data transfer rate */
|
rt_uint32_t max_data_rate; /* max data transfer rate */
|
||||||
rt_uint32_t card_capacity; /* card capacity, unit:KB */
|
rt_uint32_t card_capacity; /* card capacity, unit:KB */
|
||||||
rt_uint32_t card_blksize; /* card block size */
|
rt_uint32_t card_blksize; /* card block size */
|
||||||
rt_uint32_t card_type;
|
rt_uint16_t card_type;
|
||||||
#define CARD_TYPE_MMC (1 << 0) /* MMC card */
|
#define CARD_TYPE_MMC 0 /* MMC card */
|
||||||
#define CARD_TYPE_SD (1 << 1) /* SD card */
|
#define CARD_TYPE_SD 1 /* SD card */
|
||||||
#define CARD_TYPE_SDIO (1 << 2) /* SDIO card */
|
#define CARD_TYPE_SDIO 2 /* SDIO card */
|
||||||
#define CARD_TYPE_SDHC (1 << 3) /* SDHC card */
|
#define CARD_TYPE_SDIO_COMBO 3 /* SD combo (IO+mem) card */
|
||||||
|
|
||||||
|
rt_uint16_t flags;
|
||||||
|
#define CARD_FLAG_HIGHSPEED (1 << 0) /* SDIO bus speed 50MHz */
|
||||||
|
#define CARD_FLAG_SDHC (1 << 1) /* SDHC card */
|
||||||
|
#define CARD_FLAG_SDXC (1 << 2) /* SDXC card */
|
||||||
|
|
||||||
struct rt_sd_scr scr;
|
struct rt_sd_scr scr;
|
||||||
struct rt_mmcsd_csd csd;
|
struct rt_mmcsd_csd csd;
|
||||||
rt_uint32_t hs_max_data_rate; /* max data transfer rate in high speed mode */
|
rt_uint32_t hs_max_data_rate; /* max data transfer rate in high speed mode */
|
||||||
rt_uint32_t flags;
|
|
||||||
#define CARD_MODE_HIGHSPEED (1 << 0)
|
rt_uint8_t sdio_function_num; /* totol number of SDIO functions */
|
||||||
|
struct rt_sdio_cccr cccr; /* common card info */
|
||||||
|
struct rt_sdio_cis cis; /* common tuple info */
|
||||||
|
struct rt_sdio_function *sdio_func0;
|
||||||
|
struct rt_sdio_function *sdio_function[SDIO_MAX_FUNCTIONS]; /* SDIO functions (devices) */
|
||||||
|
|
||||||
|
//struct rt_sdio_function_tuple *tuples; /* tuples */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -93,6 +93,39 @@ extern "C" {
|
||||||
#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
|
#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
|
||||||
#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */
|
#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
|
||||||
|
|
||||||
|
/* CMD52 arguments */
|
||||||
|
#define SDIO_ARG_CMD52_READ (0<<31)
|
||||||
|
#define SDIO_ARG_CMD52_WRITE (1u<<31)
|
||||||
|
#define SDIO_ARG_CMD52_FUNC_SHIFT 28
|
||||||
|
#define SDIO_ARG_CMD52_FUNC_MASK 0x7
|
||||||
|
#define SDIO_ARG_CMD52_RAW_FLAG (1u<<27)
|
||||||
|
#define SDIO_ARG_CMD52_REG_SHIFT 9
|
||||||
|
#define SDIO_ARG_CMD52_REG_MASK 0x1ffff
|
||||||
|
#define SDIO_ARG_CMD52_DATA_SHIFT 0
|
||||||
|
#define SDIO_ARG_CMD52_DATA_MASK 0xff
|
||||||
|
#define SDIO_R5_DATA(resp) ((resp)[0] & 0xff)
|
||||||
|
|
||||||
|
/* CMD53 arguments */
|
||||||
|
#define SDIO_ARG_CMD53_READ (0<<31)
|
||||||
|
#define SDIO_ARG_CMD53_WRITE (1u<<31)
|
||||||
|
#define SDIO_ARG_CMD53_FUNC_SHIFT 28
|
||||||
|
#define SDIO_ARG_CMD53_FUNC_MASK 0x7
|
||||||
|
#define SDIO_ARG_CMD53_BLOCK_MODE (1u<<27)
|
||||||
|
#define SDIO_ARG_CMD53_INCREMENT (1u<<26)
|
||||||
|
#define SDIO_ARG_CMD53_REG_SHIFT 9
|
||||||
|
#define SDIO_ARG_CMD53_REG_MASK 0x1ffff
|
||||||
|
#define SDIO_ARG_CMD53_LENGTH_SHIFT 0
|
||||||
|
#define SDIO_ARG_CMD53_LENGTH_MASK 0x1ff
|
||||||
|
#define SDIO_ARG_CMD53_LENGTH_MAX 511
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -413,7 +413,7 @@ void mmcsd_set_data_timeout(struct rt_mmcsd_data *data, const struct rt_mmcsd_ca
|
||||||
{
|
{
|
||||||
rt_uint32_t mult;
|
rt_uint32_t mult;
|
||||||
|
|
||||||
if (card->card_type & CARD_TYPE_SDIO)
|
if (card->card_type == CARD_TYPE_SDIO)
|
||||||
{
|
{
|
||||||
data->timeout_ns = 1000000000; /* SDIO card 1s */
|
data->timeout_ns = 1000000000; /* SDIO card 1s */
|
||||||
data->timeout_clks = 0;
|
data->timeout_clks = 0;
|
||||||
|
@ -423,7 +423,7 @@ void mmcsd_set_data_timeout(struct rt_mmcsd_data *data, const struct rt_mmcsd_ca
|
||||||
/*
|
/*
|
||||||
* SD cards use a 100 multiplier rather than 10
|
* SD cards use a 100 multiplier rather than 10
|
||||||
*/
|
*/
|
||||||
mult = (card->card_type & CARD_TYPE_SD) ? 100 : 10;
|
mult = (card->card_type == CARD_TYPE_SD) ? 100 : 10;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scale up the multiplier (and therefore the timeout) by
|
* Scale up the multiplier (and therefore the timeout) by
|
||||||
|
@ -438,7 +438,7 @@ void mmcsd_set_data_timeout(struct rt_mmcsd_data *data, const struct rt_mmcsd_ca
|
||||||
/*
|
/*
|
||||||
* SD cards also have an upper limit on the timeout.
|
* SD cards also have an upper limit on the timeout.
|
||||||
*/
|
*/
|
||||||
if (card->card_type & CARD_TYPE_SD)
|
if (card->card_type == CARD_TYPE_SD)
|
||||||
{
|
{
|
||||||
rt_uint32_t timeout_us, limit_us;
|
rt_uint32_t timeout_us, limit_us;
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ void mmcsd_set_data_timeout(struct rt_mmcsd_data *data, const struct rt_mmcsd_ca
|
||||||
/*
|
/*
|
||||||
* SDHC cards always use these fixed values.
|
* SDHC cards always use these fixed values.
|
||||||
*/
|
*/
|
||||||
if (timeout_us > limit_us || card->card_type & CARD_TYPE_SDHC)
|
if (timeout_us > limit_us || card->flags & CARD_FLAG_SDHC)
|
||||||
{
|
{
|
||||||
data->timeout_ns = limit_us * 1000; /* SDHC card fixed 250ms */
|
data->timeout_ns = limit_us * 1000; /* SDHC card fixed 250ms */
|
||||||
data->timeout_clks = 0;
|
data->timeout_clks = 0;
|
||||||
|
@ -575,6 +575,8 @@ void mmcsd_detect(void *param)
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (rt_mb_recv(&mmcsd_detect_mb, (rt_uint32_t*)&host, RT_WAITING_FOREVER) == RT_EOK)
|
if (rt_mb_recv(&mmcsd_detect_mb, (rt_uint32_t*)&host, RT_WAITING_FOREVER) == RT_EOK)
|
||||||
|
{
|
||||||
|
if (host->card == RT_NULL)
|
||||||
{
|
{
|
||||||
mmcsd_host_lock(host);
|
mmcsd_host_lock(host);
|
||||||
mmcsd_power_up(host);
|
mmcsd_power_up(host);
|
||||||
|
@ -582,6 +584,14 @@ void mmcsd_detect(void *param)
|
||||||
|
|
||||||
mmcsd_send_if_cond(host, host->valid_ocr);
|
mmcsd_send_if_cond(host, host->valid_ocr);
|
||||||
|
|
||||||
|
err = sdio_io_send_op_cond(host, 0, &ocr);
|
||||||
|
if (!err) {
|
||||||
|
if (init_sdio(host, ocr))
|
||||||
|
mmcsd_power_off(host);
|
||||||
|
mmcsd_host_unlock(host);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* detect SD card
|
* detect SD card
|
||||||
*/
|
*/
|
||||||
|
@ -597,6 +607,7 @@ void mmcsd_detect(void *param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct rt_mmcsd_host *mmcsd_alloc_host(void)
|
struct rt_mmcsd_host *mmcsd_alloc_host(void)
|
||||||
{
|
{
|
||||||
|
@ -641,4 +652,6 @@ void rt_mmcsd_core_init(void)
|
||||||
{
|
{
|
||||||
rt_thread_startup(&mmcsd_detect_thread);
|
rt_thread_startup(&mmcsd_detect_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rt_sdio_init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ struct rt_mmcsd_cmd {
|
||||||
#define RESP_R4 (5 << 0)
|
#define RESP_R4 (5 << 0)
|
||||||
#define RESP_R6 (6 << 0)
|
#define RESP_R6 (6 << 0)
|
||||||
#define RESP_R7 (7 << 0)
|
#define RESP_R7 (7 << 0)
|
||||||
|
#define RESP_R5 (8 << 0) /*SDIO command response type*/
|
||||||
/*command types
|
/*command types
|
||||||
*bits:4~5
|
*bits:4~5
|
||||||
*/
|
*/
|
||||||
|
@ -155,6 +156,17 @@ struct rt_mmcsd_req {
|
||||||
|
|
||||||
#define CARD_BUSY 0x80000000 /* Card Power up status bit */
|
#define CARD_BUSY 0x80000000 /* Card Power up status bit */
|
||||||
|
|
||||||
|
/* R5 response bits */
|
||||||
|
#define R5_COM_CRC_ERROR (1 << 15)
|
||||||
|
#define R5_ILLEGAL_COMMAND (1 << 14)
|
||||||
|
#define R5_ERROR (1 << 11)
|
||||||
|
#define R5_FUNCTION_NUMBER (1 << 9)
|
||||||
|
#define R5_OUT_OF_RANGE (1 << 8)
|
||||||
|
#define R5_STATUS(x) (x & 0xCB00)
|
||||||
|
#define R5_IO_CURRENT_STATE(x) ((x & 0x3000) >> 12)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fls - find last (most-significant) bit set
|
* fls - find last (most-significant) bit set
|
||||||
* @x: the word to search
|
* @x: the word to search
|
||||||
|
|
|
@ -59,6 +59,7 @@ struct rt_mmcsd_host_ops {
|
||||||
void (*request)(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req);
|
void (*request)(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req);
|
||||||
void (*set_iocfg)(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg);
|
void (*set_iocfg)(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg);
|
||||||
rt_int32_t (*get_card_status)(struct rt_mmcsd_host *host);
|
rt_int32_t (*get_card_status)(struct rt_mmcsd_host *host);
|
||||||
|
void (*enable_sdio_irq)(struct rt_mmcsd_host *host, rt_int32_t en);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rt_mmcsd_host {
|
struct rt_mmcsd_host {
|
||||||
|
@ -91,10 +92,22 @@ struct rt_mmcsd_host {
|
||||||
#define MMCSD_MUTBLKWRITE (1 << 2)
|
#define MMCSD_MUTBLKWRITE (1 << 2)
|
||||||
#define MMCSD_HOST_IS_SPI (1 << 3)
|
#define MMCSD_HOST_IS_SPI (1 << 3)
|
||||||
#define controller_is_spi(host) (host->flags & MMCSD_HOST_IS_SPI)
|
#define controller_is_spi(host) (host->flags & MMCSD_HOST_IS_SPI)
|
||||||
|
#define MMCSD_SUP_SDIO_IRQ (1 << 4) /* support signal pending SDIO IRQs */
|
||||||
|
#define MMCSD_SUP_HIGHSPEED (1 << 5) /* support high speed */
|
||||||
|
|
||||||
|
rt_uint32_t max_seg_size; /* maximum size of one dma segment */
|
||||||
|
rt_uint32_t max_dma_segs; /* maximum number of dma segments in one request */
|
||||||
|
rt_uint32_t max_blk_size; /* maximum block size */
|
||||||
|
rt_uint32_t max_blk_count; /* maximum block count */
|
||||||
|
|
||||||
rt_uint32_t spi_use_crc;
|
rt_uint32_t spi_use_crc;
|
||||||
struct rt_semaphore bus_lock;
|
struct rt_semaphore bus_lock;
|
||||||
struct rt_semaphore sem_ack;
|
struct rt_semaphore sem_ack;
|
||||||
|
|
||||||
|
rt_uint32_t sdio_irq_num;
|
||||||
|
struct rt_semaphore *sdio_irq_sem;
|
||||||
|
struct rt_thread *sdio_irq_thread;
|
||||||
|
|
||||||
void *private_data;
|
void *private_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card)
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
card->card_type |= CARD_TYPE_SDHC;
|
card->flags |= CARD_FLAG_SDHC;
|
||||||
|
|
||||||
/*This field is fixed to 0Eh, which indicates 1 ms.
|
/*This field is fixed to 0Eh, which indicates 1 ms.
|
||||||
The host should not use TAAC, NSAC, and R2W_FACTOR
|
The host should not use TAAC, NSAC, and R2W_FACTOR
|
||||||
|
@ -187,7 +187,7 @@ static rt_int32_t mmcsd_switch(struct rt_mmcsd_card *card)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!(card->card_type & CARD_TYPE_SD))
|
if (card->card_type != CARD_TYPE_SD)
|
||||||
goto err;
|
goto err;
|
||||||
if (card->scr.sd_version < SCR_SPEC_VER_1)
|
if (card->scr.sd_version < SCR_SPEC_VER_1)
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -255,7 +255,7 @@ static rt_int32_t mmcsd_switch(struct rt_mmcsd_card *card)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
card->flags |= CARD_MODE_HIGHSPEED;
|
card->flags |= CARD_FLAG_HIGHSPEED;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
rt_free_align(buf);
|
rt_free_align(buf);
|
||||||
|
@ -629,7 +629,7 @@ static rt_int32_t mmcsd_sd_init_card(struct rt_mmcsd_host *host, rt_uint32_t ocr
|
||||||
/* set bus speed */
|
/* set bus speed */
|
||||||
max_data_rate = (unsigned int)-1;
|
max_data_rate = (unsigned int)-1;
|
||||||
|
|
||||||
if (card->flags & CARD_MODE_HIGHSPEED)
|
if (card->flags & CARD_FLAG_HIGHSPEED)
|
||||||
{
|
{
|
||||||
if (max_data_rate > card->hs_max_data_rate)
|
if (max_data_rate > card->hs_max_data_rate)
|
||||||
max_data_rate = card->hs_max_data_rate;
|
max_data_rate = card->hs_max_data_rate;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,227 @@
|
||||||
|
/*
|
||||||
|
* File : sdio.h
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rt-thread.org/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2012-01-15 weety first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __SDIO_H__
|
||||||
|
#define __SDIO_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include "mmcsd_host.h"
|
||||||
|
#include "mmcsd_card.h"
|
||||||
|
#include "sdio_func_ids.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct rt_sdio_function;
|
||||||
|
|
||||||
|
typedef void (rt_sdio_irq_handler_t)(struct rt_sdio_function *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SDIO function CIS tuple (unknown to the core)
|
||||||
|
*/
|
||||||
|
struct rt_sdio_function_tuple {
|
||||||
|
struct rt_sdio_function_tuple *next;
|
||||||
|
rt_uint8_t code;
|
||||||
|
rt_uint8_t size;
|
||||||
|
rt_uint8_t *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SDIO function devices
|
||||||
|
*/
|
||||||
|
struct rt_sdio_function {
|
||||||
|
struct rt_mmcsd_card *card; /* the card this device belongs to */
|
||||||
|
rt_sdio_irq_handler_t *irq_handler; /* IRQ callback */
|
||||||
|
rt_uint8_t num; /* function number */
|
||||||
|
|
||||||
|
rt_uint8_t func_code; /* Standard SDIO Function interface code */
|
||||||
|
rt_uint16_t manufacturer; /* manufacturer id */
|
||||||
|
rt_uint16_t product; /* product id */
|
||||||
|
|
||||||
|
rt_uint32_t max_blk_size; /* maximum block size */
|
||||||
|
rt_uint32_t cur_blk_size; /* current block size */
|
||||||
|
|
||||||
|
rt_uint32_t enable_timeout_val; /* max enable timeout in msec */
|
||||||
|
|
||||||
|
struct rt_sdio_function_tuple *tuples;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Card Common Control Registers (CCCR)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SDIO_REG_CCCR_CCCR_REV 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_REG_CCCR_SD_REV 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_REG_CCCR_IO_EN 0x02
|
||||||
|
#define SDIO_REG_CCCR_IO_RDY 0x03
|
||||||
|
|
||||||
|
#define SDIO_REG_CCCR_INT_EN 0x04 /* Function/Master Interrupt Enable */
|
||||||
|
#define SDIO_REG_CCCR_INT_PEND 0x05 /* Function Interrupt Pending */
|
||||||
|
|
||||||
|
#define SDIO_REG_CCCR_IO_ABORT 0x06 /* function abort/card reset */
|
||||||
|
|
||||||
|
#define SDIO_REG_CCCR_BUS_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_REG_CCCR_CARD_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_REG_CCCR_CIS_PTR 0x09 /* common CIS pointer (3 bytes) */
|
||||||
|
|
||||||
|
/* Following 4 regs are valid only if SBS is set */
|
||||||
|
#define SDIO_REG_CCCR_BUS_SUSPEND 0x0c
|
||||||
|
#define SDIO_REG_CCCR_FUNC_SEL 0x0d
|
||||||
|
#define SDIO_REG_CCCR_EXEC_FLAG 0x0e
|
||||||
|
#define SDIO_REG_CCCR_READY_FLAG 0x0f
|
||||||
|
|
||||||
|
#define SDIO_REG_CCCR_FN0_BLKSIZE 0x10 /* 2bytes, 0x10~0x11 */
|
||||||
|
|
||||||
|
#define SDIO_REG_CCCR_POWER_CTRL 0x12
|
||||||
|
|
||||||
|
#define SDIO_POWER_SMPC 0x01 /* Supports Master Power Control */
|
||||||
|
#define SDIO_POWER_EMPC 0x02 /* Enable Master Power Control */
|
||||||
|
|
||||||
|
#define SDIO_REG_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_REG_FBR_BASE(f) ((f) * 0x100) /* base of function f's FBRs */
|
||||||
|
|
||||||
|
#define SDIO_REG_FBR_STD_FUNC_IF 0x00
|
||||||
|
|
||||||
|
#define SDIO_FBR_SUPPORTS_CSA 0x40 /* supports Code Storage Area */
|
||||||
|
#define SDIO_FBR_ENABLE_CSA 0x80 /* enable Code Storage Area */
|
||||||
|
|
||||||
|
#define SDIO_REG_FBR_STD_IF_EXT 0x01
|
||||||
|
|
||||||
|
#define SDIO_REG_FBR_POWER 0x02
|
||||||
|
|
||||||
|
#define SDIO_FBR_POWER_SPS 0x01 /* Supports Power Selection */
|
||||||
|
#define SDIO_FBR_POWER_EPS 0x02 /* Enable (low) Power Selection */
|
||||||
|
|
||||||
|
#define SDIO_REG_FBR_CIS 0x09 /* CIS pointer (3 bytes) */
|
||||||
|
|
||||||
|
|
||||||
|
#define SDIO_REG_FBR_CSA 0x0C /* CSA pointer (3 bytes) */
|
||||||
|
|
||||||
|
#define SDIO_REG_FBR_CSA_DATA 0x0F
|
||||||
|
|
||||||
|
#define SDIO_REG_FBR_BLKSIZE 0x10 /* block size (2 bytes) */
|
||||||
|
|
||||||
|
|
||||||
|
/* SDIO CIS Tuple code */
|
||||||
|
#define CISTPL_NULL 0x00
|
||||||
|
#define CISTPL_CHECKSUM 0x10
|
||||||
|
#define CISTPL_VERS_1 0x15
|
||||||
|
#define CISTPL_ALTSTR 0x16
|
||||||
|
#define CISTPL_MANFID 0x20
|
||||||
|
#define CISTPL_FUNCID 0x21
|
||||||
|
#define CISTPL_FUNCE 0x22
|
||||||
|
#define CISTPL_SDIO_STD 0x91
|
||||||
|
#define CISTPL_SDIO_EXT 0x92
|
||||||
|
#define CISTPL_END 0xff
|
||||||
|
|
||||||
|
/* SDIO device id */
|
||||||
|
#define SDIO_ANY_FUNC_ID 0xff
|
||||||
|
#define SDIO_ANY_MAN_ID 0xffff
|
||||||
|
#define SDIO_ANY_PROD_ID 0xffff
|
||||||
|
|
||||||
|
struct rt_sdio_device_id {
|
||||||
|
rt_uint8_t func_code;
|
||||||
|
rt_uint16_t manufacturer;
|
||||||
|
rt_uint16_t product;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rt_sdio_driver {
|
||||||
|
char *name;
|
||||||
|
rt_int32_t (*probe)(struct rt_sdio_function *func);
|
||||||
|
rt_int32_t (*remove)(struct rt_sdio_function *func);
|
||||||
|
struct rt_sdio_device_id *id;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rt_int32_t sdio_io_send_op_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr, rt_uint32_t
|
||||||
|
*cmd5_resp);
|
||||||
|
rt_int32_t sdio_io_rw_direct(struct rt_mmcsd_card *card, rt_int32_t rw, rt_uint32_t fn,
|
||||||
|
rt_uint32_t reg_addr, rt_uint8_t *pdata, rt_uint8_t raw);
|
||||||
|
rt_int32_t sdio_io_rw_extended(struct rt_mmcsd_card *card, rt_int32_t rw, rt_uint32_t fn,
|
||||||
|
rt_uint32_t addr, rt_int32_t op_code, rt_uint8_t *buf, rt_uint32_t blocks, rt_uint32_t blksize);
|
||||||
|
rt_uint8_t sdio_io_readb(struct rt_sdio_function *func,
|
||||||
|
rt_uint32_t reg, rt_int32_t *err);
|
||||||
|
rt_int32_t sdio_io_writeb(struct rt_sdio_function *func,
|
||||||
|
rt_uint32_t reg, rt_uint8_t data);
|
||||||
|
rt_uint16_t sdio_io_readw(struct rt_sdio_function *func, rt_uint32_t addr, rt_int32_t *err);
|
||||||
|
rt_int32_t sdio_io_writew(struct rt_sdio_function *func, rt_uint16_t data, rt_uint32_t addr);
|
||||||
|
rt_int32_t sdio_io_read_multi_fifo_1(struct rt_sdio_function *func,
|
||||||
|
rt_uint32_t addr, rt_uint8_t *buf, rt_uint32_t len);
|
||||||
|
rt_int32_t sdio_io_write_multi_fifo_1(struct rt_sdio_function *func,
|
||||||
|
rt_uint32_t addr, rt_uint8_t *buf, rt_uint32_t len);
|
||||||
|
rt_int32_t init_sdio(struct rt_mmcsd_host *host, rt_uint32_t ocr);
|
||||||
|
rt_int32_t sdio_attach_irq(struct rt_sdio_function *func, rt_sdio_irq_handler_t *handler);
|
||||||
|
rt_int32_t sdio_detach_irq(struct rt_sdio_function *func);
|
||||||
|
void sdio_irq_wakeup(struct rt_mmcsd_host *host);
|
||||||
|
rt_int32_t sdio_enable_func(struct rt_sdio_function *func);
|
||||||
|
rt_int32_t sdio_disable_func(struct rt_sdio_function *func);
|
||||||
|
rt_int32_t sdio_set_block_size(struct rt_sdio_function *func, rt_uint32_t blksize);
|
||||||
|
rt_int32_t sdio_register_driver(struct rt_sdio_driver *driver);
|
||||||
|
rt_int32_t sdio_unregister_driver(struct rt_sdio_driver *driver);
|
||||||
|
void rt_sdio_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* File : sdio_func_ids.h
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rt-thread.org/license/LICENSE
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2012-02-26 weety first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SDIO_FUNC_IDS_H__
|
||||||
|
#define __SDIO_FUNC_IDS_H__
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Standard SDIO Function Interfaces */
|
||||||
|
|
||||||
|
#define SDIO_FUNC_CODE_NONE 0x00 /* Not a SDIO standard interface */
|
||||||
|
#define SDIO_FUNC_CODE_UART 0x01 /* SDIO Standard UART */
|
||||||
|
#define SDIO_FUNC_CODE_BT_A 0x02 /* SDIO Type-A for Bluetooth standard interface */
|
||||||
|
#define SDIO_FUNC_CODE_BT_B 0x03 /* SDIO Type-B for Bluetooth standard interface */
|
||||||
|
#define SDIO_FUNC_CODE_GPS 0x04 /* SDIO GPS standard interface */
|
||||||
|
#define SDIO_FUNC_CODE_CAMERA 0x05 /* SDIO Camera standard interface */
|
||||||
|
#define SDIO_FUNC_CODE_PHS 0x06 /* SDIO PHS standard interface */
|
||||||
|
#define SDIO_FUNC_CODE_WLAN 0x07 /* SDIO WLAN interface */
|
||||||
|
#define SDIO_FUNC_CODE_ATA 0x08 /* Embedded SDIO-ATA standard interface */
|
||||||
|
|
||||||
|
/* manufacturer id, product io */
|
||||||
|
|
||||||
|
#define SDIO_MANUFACTURER_ID_MARVELL 0x02df
|
||||||
|
#define SDIO_PRODUCT_ID_MARVELL_LIBERTAS 0x9103
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue