summaryrefslogtreecommitdiff
path: root/components/drivers/include
diff options
context:
space:
mode:
author[email protected] <[email protected]>2012-07-08 14:43:08 +0000
committer[email protected] <[email protected]>2012-07-08 14:43:08 +0000
commit7729b4a1e4fa0cda20ba5b8ff21701f9bc89e78c (patch)
treede36e1bef32ad2afa4be0e71c8e7ce9f25e08934 /components/drivers/include
parent6ae04deffba86e326764ae74b2f8e95119a727ab (diff)
move SDIO driver header files to the drivers/include directory and update rtdevice.h
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2209 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/drivers/include')
-rw-r--r--components/drivers/include/drivers/mmcsd_card.h172
-rw-r--r--components/drivers/include/drivers/mmcsd_cmd.h133
-rw-r--r--components/drivers/include/drivers/mmcsd_core.h278
-rw-r--r--components/drivers/include/drivers/mmcsd_host.h130
-rw-r--r--components/drivers/include/drivers/sd.h32
-rw-r--r--components/drivers/include/drivers/sdio.h199
-rw-r--r--components/drivers/include/drivers/sdio_func_ids.h44
-rw-r--r--components/drivers/include/rtdevice.h6
8 files changed, 994 insertions, 0 deletions
diff --git a/components/drivers/include/drivers/mmcsd_card.h b/components/drivers/include/drivers/mmcsd_card.h
new file mode 100644
index 0000000000..20bb7dca7a
--- /dev/null
+++ b/components/drivers/include/drivers/mmcsd_card.h
@@ -0,0 +1,172 @@
+/*
+ * File : mmcsd_card.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
+ * 2011-07-25 weety first version
+ */
+
+#ifndef __MMCSD_CARD_H__
+#define __MMCSD_CARD_H__
+
+#include <drivers/mmcsd_host.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SD_SCR_BUS_WIDTH_1 (1 << 0)
+#define SD_SCR_BUS_WIDTH_4 (1 << 2)
+
+struct rt_mmcsd_cid {
+ rt_uint8_t mid; /* ManufacturerID */
+ rt_uint8_t prv; /* Product Revision */
+ rt_uint16_t oid; /* OEM/Application ID */
+ rt_uint32_t psn; /* Product Serial Number */
+ rt_uint8_t pnm[5]; /* Product Name */
+ rt_uint8_t reserved1;/* reserved */
+ rt_uint16_t mdt; /* Manufacturing Date */
+ rt_uint8_t crc; /* CID CRC */
+ rt_uint8_t reserved2;/* not used, always 1 */
+};
+
+struct rt_mmcsd_csd {
+ rt_uint8_t csd_structure; /* CSD register version */
+ rt_uint8_t taac;
+ rt_uint8_t nsac;
+ rt_uint8_t tran_speed; /* max data transfer rate */
+ rt_uint16_t card_cmd_class; /* card command classes */
+ rt_uint8_t rd_blk_len; /* max read data block length */
+ rt_uint8_t rd_blk_part;
+ rt_uint8_t wr_blk_misalign;
+ rt_uint8_t rd_blk_misalign;
+ rt_uint8_t dsr_imp; /* DSR implemented */
+ rt_uint8_t c_size_mult; /* CSD 1.0 , device size multiplier */
+ rt_uint32_t c_size; /* device size */
+ rt_uint8_t r2w_factor;
+ rt_uint8_t wr_blk_len; /* max wtire data block length */
+ rt_uint8_t wr_blk_partial;
+ rt_uint8_t csd_crc;
+
+};
+
+struct rt_sd_scr {
+ rt_uint8_t sd_version;
+ rt_uint8_t sd_bus_widths;
+};
+
+struct rt_sdio_cccr {
+ rt_uint8_t sdio_version;
+ rt_uint8_t sd_version;
+ rt_uint8_t direct_cmd:1, /* Card Supports Direct Commands during data transfer
+ only SD mode, not used for SPI mode */
+ multi_block:1, /* Card Supports Multi-Block */
+ read_wait:1, /* Card Supports Read Wait
+ only SD mode, not used for SPI mode */
+ suspend_resume:1, /* Card supports Suspend/Resume
+ only SD mode, not used for SPI mode */
+ s4mi:1, /* generate interrupts during a 4-bit
+ multi-block data transfer */
+ e4mi:1, /* Enable the multi-block IRQ during
+ 4-bit transfer for the SDIO card */
+ low_speed:1, /* Card is a Low-Speed card */
+ low_speed_4:1; /* 4-bit support for Low-Speed cards */
+
+ rt_uint8_t bus_width:1, /* Support SDIO bus width, 1:4bit, 0:1bit */
+ cd_disable:1, /* Connect[0]/Disconnect[1] the 10K-90K ohm pull-up
+ resistor on CD/DAT[3] (pin 1) of the card */
+ power_ctrl:1, /* Support Master Power Control */
+ high_speed:1; /* Support High-Speed */
+
+
+};
+
+struct rt_sdio_cis {
+ rt_uint16_t manufacturer;
+ rt_uint16_t product;
+ rt_uint16_t func0_blk_size;
+ rt_uint32_t max_tran_speed;
+};
+
+/*
+ * 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;
+};
+
+struct rt_sdio_function;
+typedef void (rt_sdio_irq_handler_t)(struct rt_sdio_function *);
+
+/*
+ * 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;
+};
+
+#define SDIO_MAX_FUNCTIONS 7
+
+
+
+struct rt_mmcsd_card {
+ struct rt_mmcsd_host *host;
+ rt_uint32_t rca; /* card addr */
+ rt_uint32_t resp_cid[4]; /* card CID register */
+ rt_uint32_t resp_csd[4]; /* card CSD register */
+ rt_uint32_t resp_scr[2]; /* card SCR register */
+
+ rt_uint16_t tacc_clks; /* data access time by ns */
+ rt_uint32_t tacc_ns; /* data access time by clk cycles */
+ rt_uint32_t max_data_rate; /* max data transfer rate */
+ rt_uint32_t card_capacity; /* card capacity, unit:KB */
+ rt_uint32_t card_blksize; /* card block size */
+ rt_uint16_t card_type;
+#define CARD_TYPE_MMC 0 /* MMC card */
+#define CARD_TYPE_SD 1 /* SD card */
+#define CARD_TYPE_SDIO 2 /* SDIO 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_mmcsd_csd csd;
+ rt_uint32_t hs_max_data_rate; /* max data transfer rate in high speed mode */
+
+ 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_function[SDIO_MAX_FUNCTIONS + 1]; /* SDIO functions (devices) */
+
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/include/drivers/mmcsd_cmd.h b/components/drivers/include/drivers/mmcsd_cmd.h
new file mode 100644
index 0000000000..1b12f6b448
--- /dev/null
+++ b/components/drivers/include/drivers/mmcsd_cmd.h
@@ -0,0 +1,133 @@
+/*
+ * File : mmcsd_cmd.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
+ * 2011-07-25 weety first version
+ */
+
+#ifndef __CMD_H__
+#define __CMD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* class 1 */
+#define GO_IDLE_STATE 0 /* bc */
+#define SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
+#define ALL_SEND_CID 2 /* bcr R2 */
+#define SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
+#define SET_DSR 4 /* bc [31:16] RCA */
+#define SWITCH 6 /* ac [31:0] See below R1b */
+#define SELECT_CARD 7 /* ac [31:16] RCA R1 */
+#define SEND_EXT_CSD 8 /* adtc R1 */
+#define SEND_CSD 9 /* ac [31:16] RCA R2 */
+#define SEND_CID 10 /* ac [31:16] RCA R2 */
+#define READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
+#define STOP_TRANSMISSION 12 /* ac R1b */
+#define SEND_STATUS 13 /* ac [31:16] RCA R1 */
+#define GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
+#define SPI_READ_OCR 58 /* spi spi_R3 */
+#define SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
+
+ /* class 2 */
+#define SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
+#define READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
+#define READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
+
+ /* class 3 */
+#define WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
+
+ /* class 4 */
+#define SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
+#define WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
+#define WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
+#define PROGRAM_CID 26 /* adtc R1 */
+#define PROGRAM_CSD 27 /* adtc R1 */
+
+ /* class 6 */
+#define SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
+#define CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
+#define SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
+
+ /* class 5 */
+#define ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
+#define ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
+#define ERASE 38 /* ac R1b */
+
+ /* class 9 */
+#define FAST_IO 39 /* ac <Complex> R4 */
+#define GO_IRQ_STATE 40 /* bcr R5 */
+
+ /* class 7 */
+#define LOCK_UNLOCK 42 /* adtc R1b */
+
+ /* class 8 */
+#define APP_CMD 55 /* ac [31:16] RCA R1 */
+#define GEN_CMD 56 /* adtc [0] RD/WR R1 */
+
+
+/* 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 */
+
+#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 */
+
+
+/* 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
+}
+#endif
+
+#endif
diff --git a/components/drivers/include/drivers/mmcsd_core.h b/components/drivers/include/drivers/mmcsd_core.h
new file mode 100644
index 0000000000..1f7b38795c
--- /dev/null
+++ b/components/drivers/include/drivers/mmcsd_core.h
@@ -0,0 +1,278 @@
+/*
+ * File : mmcsd_core.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
+ * 2011-07-25 weety first version
+ */
+
+#ifndef __CORE_H__
+#define __CORE_H__
+
+#include <rtthread.h>
+#include <drivers/mmcsd_host.h>
+#include <drivers/mmcsd_card.h>
+#include <drivers/mmcsd_cmd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef RT_MMCSD_DBG
+#define mmcsd_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__)
+#else
+#define mmcsd_dbg(fmt, ...)
+#endif
+
+struct rt_mmcsd_data {
+ rt_uint32_t blksize;
+ rt_uint32_t blks;
+ rt_uint32_t *buf;
+ rt_int32_t err;
+ rt_uint32_t flags;
+#define DATA_DIR_WRITE (1 << 0)
+#define DATA_DIR_READ (1 << 1)
+#define DATA_STREAM (1 << 2)
+
+ unsigned int bytes_xfered;
+
+ struct rt_mmcsd_cmd *stop; /* stop command */
+ struct rt_mmcsd_req *mrq; /* associated request */
+
+ rt_uint32_t timeout_ns;
+ rt_uint32_t timeout_clks;
+};
+
+struct rt_mmcsd_cmd {
+ rt_uint32_t cmd_code;
+ rt_uint32_t arg;
+ rt_uint32_t resp[4];
+ rt_uint32_t flags;
+/*rsponse types
+ *bits:0~3
+ */
+#define RESP_MASK (0xF)
+#define RESP_NONE (0)
+#define RESP_R1 (1 << 0)
+#define RESP_R1B (2 << 0)
+#define RESP_R2 (3 << 0)
+#define RESP_R3 (4 << 0)
+#define RESP_R4 (5 << 0)
+#define RESP_R6 (6 << 0)
+#define RESP_R7 (7 << 0)
+#define RESP_R5 (8 << 0) /*SDIO command response type*/
+/*command types
+ *bits:4~5
+ */
+#define CMD_MASK (3 << 4) /* command type */
+#define CMD_AC (0 << 4)
+#define CMD_ADTC (1 << 4)
+#define CMD_BC (2 << 4)
+#define CMD_BCR (3 << 4)
+
+#define resp_type(cmd) ((cmd)->flags & RESP_MASK)
+
+/*spi rsponse types
+ *bits:6~8
+ */
+#define RESP_SPI_MASK (0x7 << 6)
+#define RESP_SPI_R1 (1 << 6)
+#define RESP_SPI_R1B (2 << 6)
+#define RESP_SPI_R2 (3 << 6)
+#define RESP_SPI_R3 (4 << 6)
+#define RESP_SPI_R4 (5 << 6)
+#define RESP_SPI_R5 (6 << 6)
+#define RESP_SPI_R7 (7 << 6)
+
+#define spi_resp_type(cmd) ((cmd)->flags & RESP_SPI_MASK)
+/*
+ * These are the command types.
+ */
+#define cmd_type(cmd) ((cmd)->flags & CMD_MASK)
+
+ rt_int32_t retries; /* max number of retries */
+ rt_int32_t err;
+
+ struct rt_mmcsd_data *data;
+ struct rt_mmcsd_req *mrq; /* associated request */
+};
+
+struct rt_mmcsd_req {
+ struct rt_mmcsd_data *data;
+ struct rt_mmcsd_cmd *cmd;
+ struct rt_mmcsd_cmd *stop;
+};
+
+/*the following is response bit*/
+#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 */
+
+
+#define R1_SPI_IDLE (1 << 0)
+#define R1_SPI_ERASE_RESET (1 << 1)
+#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
+#define R1_SPI_COM_CRC (1 << 3)
+#define R1_SPI_ERASE_SEQ (1 << 4)
+#define R1_SPI_ADDRESS (1 << 5)
+#define R1_SPI_PARAMETER (1 << 6)
+/* R1 bit 7 is always zero */
+#define R2_SPI_CARD_LOCKED (1 << 8)
+#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */
+#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP
+#define R2_SPI_ERROR (1 << 10)
+#define R2_SPI_CC_ERROR (1 << 11)
+#define R2_SPI_CARD_ECC_ERROR (1 << 12)
+#define R2_SPI_WP_VIOLATION (1 << 13)
+#define R2_SPI_ERASE_PARAM (1 << 14)
+#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */
+#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
+
+#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
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+
+rt_inline rt_uint32_t fls(rt_uint32_t val)
+{
+ rt_uint32_t bit = 32;
+
+ if (!val)
+ return 0;
+ if (!(val & 0xffff0000u))
+ {
+ val <<= 16;
+ bit -= 16;
+ }
+ if (!(val & 0xff000000u))
+ {
+ val <<= 8;
+ bit -= 8;
+ }
+ if (!(val & 0xf0000000u))
+ {
+ val <<= 4;
+ bit -= 4;
+ }
+ if (!(val & 0xc0000000u))
+ {
+ val <<= 2;
+ bit -= 2;
+ }
+ if (!(val & 0x80000000u))
+ {
+ val <<= 1;
+ bit -= 1;
+ }
+
+ return bit;
+}
+
+#if !defined(__GNUC__) || defined(__CC_ARM)
+rt_inline rt_uint32_t ffs(rt_uint32_t x)
+{
+ int r = 1;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xffff)) {
+ x >>= 16;
+ r += 16;
+ }
+ if (!(x & 0xff)) {
+ x >>= 8;
+ r += 8;
+ }
+ if (!(x & 0xf)) {
+ x >>= 4;
+ r += 4;
+ }
+ if (!(x & 3)) {
+ x >>= 2;
+ r += 2;
+ }
+ if (!(x & 1)) {
+ x >>= 1;
+ r += 1;
+ }
+ return r;
+}
+#endif
+
+void mmcsd_host_lock(struct rt_mmcsd_host *host);
+void mmcsd_host_unlock(struct rt_mmcsd_host *host);
+void mmcsd_req_complete(struct rt_mmcsd_host *host);
+void mmcsd_send_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req);
+rt_int32_t mmcsd_send_cmd(struct rt_mmcsd_host *host, struct rt_mmcsd_cmd *cmd, int retries);
+rt_int32_t mmcsd_go_idle(struct rt_mmcsd_host *host);
+rt_int32_t mmcsd_spi_read_ocr(struct rt_mmcsd_host *host, rt_int32_t high_capacity, rt_uint32_t *ocr);
+rt_int32_t mmcsd_all_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid);
+rt_int32_t mmcsd_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid);
+rt_int32_t mmcsd_get_csd(struct rt_mmcsd_card *card, rt_uint32_t *csd);
+rt_int32_t mmcsd_select_card(struct rt_mmcsd_card *card);
+rt_int32_t mmcsd_deselect_cards(struct rt_mmcsd_card *host);
+rt_int32_t mmcsd_spi_use_crc(struct rt_mmcsd_host *host, rt_int32_t use_crc);
+void mmcsd_set_chip_select(struct rt_mmcsd_host *host, rt_int32_t mode);
+void mmcsd_set_clock(struct rt_mmcsd_host *host, rt_uint32_t clk);
+void mmcsd_set_bus_mode(struct rt_mmcsd_host *host, rt_uint32_t mode);
+void mmcsd_set_bus_width(struct rt_mmcsd_host *host, rt_uint32_t width);
+void mmcsd_set_data_timeout(struct rt_mmcsd_data *data, const struct rt_mmcsd_card *card);
+rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr);
+void mmcsd_change(struct rt_mmcsd_host *host);
+void mmcsd_detect(void *param);
+struct rt_mmcsd_host *mmcsd_alloc_host(void);
+void mmcsd_free_host(struct rt_mmcsd_host *host);
+void rt_mmcsd_core_init(void);
+
+void rt_mmcsd_blk_init(void);
+rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card);
+void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/include/drivers/mmcsd_host.h b/components/drivers/include/drivers/mmcsd_host.h
new file mode 100644
index 0000000000..9cbbb51a76
--- /dev/null
+++ b/components/drivers/include/drivers/mmcsd_host.h
@@ -0,0 +1,130 @@
+/*
+ * File : mmcsd_host.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
+ * 2011-07-25 weety first version
+ */
+
+#ifndef __HOST_H__
+#define __HOST_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct rt_mmcsd_io_cfg {
+ rt_uint32_t clock; /* clock rate */
+ rt_uint16_t vdd;
+
+/* vdd stores the bit number of the selected voltage range from below. */
+
+ rt_uint8_t bus_mode; /* command output mode */
+
+#define MMCSD_BUSMODE_OPENDRAIN 1
+#define MMCSD_BUSMODE_PUSHPULL 2
+
+ rt_uint8_t chip_select; /* SPI chip select */
+
+#define MMCSD_CS_IGNORE 0
+#define MMCSD_CS_HIGH 1
+#define MMCSD_CS_LOW 2
+
+ rt_uint8_t power_mode; /* power supply mode */
+
+#define MMCSD_POWER_OFF 0
+#define MMCSD_POWER_UP 1
+#define MMCSD_POWER_ON 2
+
+ rt_uint8_t bus_width; /* data bus width */
+
+#define MMCSD_BUS_WIDTH_1 0
+#define MMCSD_BUS_WIDTH_4 2
+#define MMCSD_BUS_WIDTH_8 3
+
+};
+
+struct rt_mmcsd_host;
+struct rt_mmcsd_req;
+
+struct rt_mmcsd_host_ops {
+ 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);
+ 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_card *card;
+ const struct rt_mmcsd_host_ops *ops;
+ rt_uint32_t freq_min;
+ rt_uint32_t freq_max;
+ struct rt_mmcsd_io_cfg io_cfg;
+ rt_uint32_t valid_ocr; /* current valid OCR */
+#define VDD_165_195 (1 << 7) /* VDD voltage 1.65 - 1.95 */
+#define VDD_20_21 (1 << 8) /* VDD voltage 2.0 ~ 2.1 */
+#define VDD_21_22 (1 << 9) /* VDD voltage 2.1 ~ 2.2 */
+#define VDD_22_23 (1 << 10) /* VDD voltage 2.2 ~ 2.3 */
+#define VDD_23_24 (1 << 11) /* VDD voltage 2.3 ~ 2.4 */
+#define VDD_24_25 (1 << 12) /* VDD voltage 2.4 ~ 2.5 */
+#define VDD_25_26 (1 << 13) /* VDD voltage 2.5 ~ 2.6 */
+#define VDD_26_27 (1 << 14) /* VDD voltage 2.6 ~ 2.7 */
+#define VDD_27_28 (1 << 15) /* VDD voltage 2.7 ~ 2.8 */
+#define VDD_28_29 (1 << 16) /* VDD voltage 2.8 ~ 2.9 */
+#define VDD_29_30 (1 << 17) /* VDD voltage 2.9 ~ 3.0 */
+#define VDD_30_31 (1 << 18) /* VDD voltage 3.0 ~ 3.1 */
+#define VDD_31_32 (1 << 19) /* VDD voltage 3.1 ~ 3.2 */
+#define VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */
+#define VDD_33_34 (1 << 21) /* VDD voltage 3.3 ~ 3.4 */
+#define VDD_34_35 (1 << 22) /* VDD voltage 3.4 ~ 3.5 */
+#define VDD_35_36 (1 << 23) /* VDD voltage 3.5 ~ 3.6 */
+ rt_uint32_t flags; /* define device capabilities */
+#define MMCSD_BUSWIDTH_4 (1 << 0)
+#define MMCSD_BUSWIDTH_8 (1 << 1)
+#define MMCSD_MUTBLKWRITE (1 << 2)
+#define MMCSD_HOST_IS_SPI (1 << 3)
+#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;
+ struct rt_semaphore bus_lock;
+ 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;
+};
+
+rt_inline void mmcsd_delay_ms(rt_uint32_t ms)
+{
+ if (ms < 1000 / RT_TICK_PER_SECOND)
+ {
+ rt_thread_delay(1);
+ }
+ else
+ {
+ rt_thread_delay(ms/(1000 / RT_TICK_PER_SECOND));
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/include/drivers/sd.h b/components/drivers/include/drivers/sd.h
new file mode 100644
index 0000000000..b2491d7528
--- /dev/null
+++ b/components/drivers/include/drivers/sd.h
@@ -0,0 +1,32 @@
+#ifndef __SD_H__
+#define __SD_H__
+/*
+ * File : sd.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
+ * 2011-07-25 weety first version
+ */
+
+#include <rtthread.h>
+#include <drivers/mmcsd_host.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+rt_err_t mmcsd_send_if_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr);
+rt_err_t mmcsd_send_app_op_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr, rt_uint32_t *rocr);
+rt_int32_t init_sd(struct rt_mmcsd_host *host, rt_uint32_t ocr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/include/drivers/sdio.h b/components/drivers/include/drivers/sdio.h
new file mode 100644
index 0000000000..5a0272bdb3
--- /dev/null
+++ b/components/drivers/include/drivers/sdio.h
@@ -0,0 +1,199 @@
+/*
+ * 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 <drivers/mmcsd_host.h>
+#include <drivers/mmcsd_card.h>
+#include <drivers/sdio_func_ids.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * 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_mmcsd_card *card);
+ rt_int32_t (*remove)(struct rt_mmcsd_card *card);
+ 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_uint32_t sdio_io_readl(struct rt_sdio_function *func, rt_uint32_t addr, rt_int32_t *err);
+rt_int32_t sdio_io_writel(struct rt_sdio_function *func, rt_uint32_t data, rt_uint32_t addr);
+rt_int32_t sdio_io_read_multi_fifo_b(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_b(struct rt_sdio_function *func,
+ rt_uint32_t addr, rt_uint8_t *buf, rt_uint32_t len);
+rt_int32_t sdio_io_read_multi_incr_b(struct rt_sdio_function *func,
+ rt_uint32_t addr, rt_uint8_t *buf, rt_uint32_t len);
+rt_int32_t sdio_io_write_multi_incr_b(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
+
diff --git a/components/drivers/include/drivers/sdio_func_ids.h b/components/drivers/include/drivers/sdio_func_ids.h
new file mode 100644
index 0000000000..4c25622463
--- /dev/null
+++ b/components/drivers/include/drivers/sdio_func_ids.h
@@ -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_88W8686 0x9103
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h
index 26c9b3aa6f..846aac6920 100644
--- a/components/drivers/include/rtdevice.h
+++ b/components/drivers/include/rtdevice.h
@@ -90,4 +90,10 @@ rt_size_t rt_ringbuffer_emptry_size(struct rt_ringbuffer* rb);
#include "drivers/pm.h"
#endif
+#ifdef RT_USING_SDIO
+#include "drivers/mmcsd_core.h"
+#include "drivers/sd.h"
+#include "drivers/sdio.h"
+#endif
+
#endif /* __RT_DEVICE_H__ */