diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-11-15 18:23:46 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-11-15 18:23:46 +0000 |
commit | dac960ed920e8108e8156c44ccea2245808fa18f (patch) | |
tree | 2990aa20ee64beae5ab422b2cffe49b302de6347 | |
parent | 6e1a54263dbed5291417bc780ef422dc31fb9156 (diff) | |
download | nuttx-dac960ed920e8108e8156c44ccea2245808fa18f.tar.gz nuttx-dac960ed920e8108e8156c44ccea2245808fa18f.tar.bz2 nuttx-dac960ed920e8108e8156c44ccea2245808fa18f.zip |
Add SD card initialization logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2258 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | nuttx/arch/arm/src/stm32/stm32_sdio.c | 155 | ||||
-rw-r--r-- | nuttx/drivers/mmcsd/mmcsd_sdio.c | 429 | ||||
-rw-r--r-- | nuttx/drivers/mmcsd/mmcsd_sdio.h | 40 | ||||
-rwxr-xr-x | nuttx/include/nuttx/sdio.h | 109 |
4 files changed, 604 insertions, 129 deletions
diff --git a/nuttx/arch/arm/src/stm32/stm32_sdio.c b/nuttx/arch/arm/src/stm32/stm32_sdio.c index 102127e57..a7fe28c7d 100644 --- a/nuttx/arch/arm/src/stm32/stm32_sdio.c +++ b/nuttx/arch/arm/src/stm32/stm32_sdio.c @@ -123,6 +123,7 @@ static inline void stm32_dmaenable(void); /* Data Transfer Helpers ****************************************************/
+static ubyte stm32_log2(uint16 value);
static void stm32_dataconfig(uint32 timeout, uint32 dlen, uint32 dctrl);
static void stm32_datadisable(void);
@@ -135,13 +136,12 @@ static ubyte stm32_status(FAR struct sdio_dev_s *dev); static void stm32_widebus(FAR struct sdio_dev_s *dev, boolean enable);
static void stm32_clock(FAR struct sdio_dev_s *dev,
enum sdio_clock_e rate);
-static int stm32_setblocklen(FAR struct sdio_dev_s *dev, int blocklen,
- int nblocks);
static int stm32_attach(FAR struct sdio_dev_s *dev);
/* Command/Status/Data Transfer */
-static void stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 arg);
+static void stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 arg); +static int stm32_sendsetup(FAR struct sdio_dev_s *dev, uint32 nbytes);
static int stm32_senddata(FAR struct sdio_dev_s *dev,
FAR const ubyte *buffer);
@@ -150,11 +150,12 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 * static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 rlong[4]);
static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rshort);
static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rnotimpl);
+static int stm32_recvsetup(FAR struct sdio_dev_s *dev, uint32 nbytes); static int stm32_recvdata(FAR struct sdio_dev_s *dev, FAR ubyte *buffer);
/* EVENT handler */
-static void stm32_eventenable(FAR struct sdio_dev_s *dev, ubyte eventset,
+static void stm32_eventenable(FAR struct sdio_dev_s *dev, sdio_event_t eventset,
boolean enable);
static ubyte stm32_eventwait(FAR struct sdio_dev_s *dev, uint32 timeout);
static ubyte stm32_events(FAR struct sdio_dev_s *dev);
@@ -194,9 +195,9 @@ struct stm32_dev_s g_mmcsd = .status = stm32_status,
.widebus = stm32_widebus,
.clock = stm32_clock,
- .setblocklen = stm32_setblocklen,
.attach = stm32_attach,
- .sendcmd = stm32_sendcmd,
+ .sendcmd = stm32_sendcmd, + .sendsetup = stm32_sendsetup,
.senddata = stm32_senddata, .waitresponse = stm32_waitresponse,
.recvR1 = stm32_recvshortcrc,
@@ -205,7 +206,8 @@ struct stm32_dev_s g_mmcsd = .recvR4 = stm32_recvnotimpl,
.recvR5 = stm32_recvnotimpl,
.recvR6 = stm32_recvshortcrc,
- .recvR7 = stm32_recvshort,
+ .recvR7 = stm32_recvshort, + .recvsetup = stm32_recvsetup,
.recvdata = stm32_recvdata,
.eventenable = stm32_eventenable,
.eventwait = stm32_eventwait,
@@ -378,6 +380,37 @@ static inline void stm32_dmaenable(void) /****************************************************************************
* Data Transfer Helpers
****************************************************************************/
+ +/****************************************************************************
+ * Name: stm32_log2 + * + * Description: + * Take (approximate) log base 2 of the provided number (Only works if the + * provided number is a power of 2). + * + ****************************************************************************/ +
+static ubyte stm32_log2(uint16 value)
+{
+ ubyte log2 = 0; + + /* 0000 0000 0000 0001 -> return 0, + * 0000 0000 0000 001x -> return 1,
+ * 0000 0000 0000 01xx -> return 2,
+ * 0000 0000 0000 1xxx -> return 3, + * ...
+ * 1xxx xxxx xxxx xxxx -> return 15, + */
+ + DEBUGASSERT(value > 0);
+ while (value != 1)
+ {
+ value >>= 1;
+ log2++;
+ }
+ return log2;
+}
+ /****************************************************************************
* Name: stm32_dataconfig * @@ -490,7 +523,11 @@ static ubyte stm32_status(FAR struct sdio_dev_s *dev) ****************************************************************************/
static void stm32_widebus(FAR struct sdio_dev_s *dev, boolean wide)
-{
+{ + if (wide) + {
+ priv->mode = MMCSDMODE_DMA;
+ }
}
/****************************************************************************
@@ -513,27 +550,6 @@ static void stm32_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) }
/****************************************************************************
- * Name: stm32_setblocklen
- *
- * Description:
- * Set the MMC/SD block length and block count
- *
- * Input Parameters:
- * dev - An instance of the MMC/SD device interface
- * blocklen - The block length
- * nblocks - The block count
- *
- * Returned Value:
- * OK on success; negated errno on failure
- *
- ****************************************************************************/
-
-static int stm32_setblocklen(FAR struct sdio_dev_s *dev, int blocklen, int nblocks)
-{
- return -ENOSYS;
-}
-
-/****************************************************************************
* Name: stm32_attach
*
* Description:
@@ -616,6 +632,31 @@ static void stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 arg) putreg32(regval, STM32_SDIO_CMD);
}
+/**************************************************************************** + * Name: stm32_sendsetup + * + * Description: + * Setup hardware in preparation for data trasfer from the card. This method + * will do whatever controller setup is necessary. This would be called + * for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25 + * (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called. + * + * Input Parameters: + * dev - An instance of the MMC/SD device interface + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_sendsetup(FAR struct sdio_dev_s *dev, uint32 nbytes) +{ + uint32 dctrl = stm32_log2(nbytes) << SDIO_DCTRL_DBLOCKSIZE_SHIFT); + stm32_dataconfig(SD_DATATIMEOUT, nbytes, dctrl); + return OK; +}
+ /****************************************************************************
* Name: stm32_senddata
*
@@ -627,7 +668,7 @@ static void stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 arg) * data - Data to be sent
*
* Returned Value:
- * Number of bytes sent on succes; a negated errno on failure
+ * Number of bytes sent on success; a negated errno on failure
*
****************************************************************************/
@@ -918,6 +959,32 @@ static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rno return -ENOSYS;
}
+/**************************************************************************** + * Name: stm32_recvsetup + * + * Description: + * Setup hardware in preparation for data trasfer from the card. This method + * will do whatever controller setup is necessary. This would be called + * for SD memory just BEFORE sending CMD13 (SEND_STATUS), CMD17 + * (READ_SINGLE_BLOCK), CMD18 (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), ... + * and before SDIO_RECVDATA is called. + * + * Input Parameters: + * dev - An instance of the MMC/SD device interface + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_recvsetup(FAR struct sdio_dev_s *dev, uint32 nbytes) +{
+ uint32 dctrl = (stm32_log2(nbytes) << SDIO_DCTRL_DBLOCKSIZE_SHIFT)) | SDIO_DCTRL_DTDIR; + stm32_dataconfig(SD_DATATIMEOUT, nbytes, dctrl); + return OK; +}
+ /****************************************************************************
* Name: stm32_recvdata
*
@@ -929,7 +996,7 @@ static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rno * buffer - Buffer in which to receive the data
*
* Returned Value:
- * Number of bytes sent on succes; a negated errno on failure
+ * Number of bytes sent on success; a negated errno on failure
*
****************************************************************************/
@@ -947,16 +1014,14 @@ static int stm32_recvdata(FAR struct sdio_dev_s *dev, FAR ubyte *buffer) * Input Parameters:
* dev - An instance of the MMC/SD device interface
* eventset - A bitset of events to enable or disable (see MMCSDEVENT_*
- * definitions
- * enable - TRUE: enable event; FALSE: disable events
+ * definitions). 0=disable; 1=enable.
*
* Returned Value:
* None
*
****************************************************************************/
-static void stm32_eventenable(FAR struct sdio_dev_s *dev, ubyte eventset,
- boolean enable)
+static void stm32_eventenable(FAR struct sdio_dev_s *dev, sdio_event_t eventset)
{
}
@@ -972,7 +1037,8 @@ static void stm32_eventenable(FAR struct sdio_dev_s *dev, ubyte eventset, *
* Returned Value:
* Event set containing the event(s) that ended the wait. If no events the
- * returned event set is zero, then the wait was terminated by the timeout.
+ * returned event set is zero, then the wait was terminated by the timeout. + * All events are cleared disabled after the wait concludes.
*
****************************************************************************/
@@ -986,13 +1052,14 @@ static ubyte stm32_eventwait(FAR struct sdio_dev_s *dev, uint32 timeout) *
* Description:
* Return the current event set. This supports polling for MMC/SD (vs.
- * waiting).
+ * waiting). Only enabled events need be reported.
*
* Input Parameters:
- * dev - An instance of the MMC/SD device interface
+ * dev - An instance of the MMC/SD device interface
*
* Returned Value:
- * Event set containing the current events (cleared after reading).
+ * Event set containing the current events (All pending events are cleared + * after reading).
*
****************************************************************************/
@@ -1062,7 +1129,7 @@ static void stm32_coherent(FAR struct sdio_dev_s *dev, FAR void *addr, * buffer - The memory to DMA from
*
* Returned Value:
- * OK on succes; a negated errno on failure
+ * OK on success; a negated errno on failure
*
****************************************************************************/
@@ -1084,7 +1151,7 @@ static int tm32_dmareadsetup(FAR struct sdio_dev_s *dev, FAR ubyte *buffer) * buffer - The memory to DMA into
*
* Returned Value:
- * OK on succes; a negated errno on failure
+ * OK on success; a negated errno on failure
*
****************************************************************************/
@@ -1106,7 +1173,7 @@ static int stm32_dmawritesetup(FAR struct sdio_dev_s *dev, * dev - An instance of the MMC/SD device interface
*
* Returned Value:
- * OK on succes; a negated errno on failure
+ * OK on success; a negated errno on failure
*
****************************************************************************/
@@ -1127,7 +1194,7 @@ static int stm32_dmastart(FAR struct sdio_dev_s *dev) * dev - An instance of the MMC/SD device interface
*
* Returned Value:
- * OK on succes; a negated errno on failure
+ * OK on success; a negated errno on failure
*
****************************************************************************/
@@ -1150,7 +1217,7 @@ static int stm32_dmastop(FAR struct sdio_dev_s *dev) * remaining in the transfer.
*
* Returned Value:
- * OK on succes; a negated errno on failure
+ * OK on success; a negated errno on failure
*
****************************************************************************/
diff --git a/nuttx/drivers/mmcsd/mmcsd_sdio.c b/nuttx/drivers/mmcsd/mmcsd_sdio.c index 6a60ab3c0..65abe645f 100644 --- a/nuttx/drivers/mmcsd/mmcsd_sdio.c +++ b/nuttx/drivers/mmcsd/mmcsd_sdio.c @@ -76,6 +76,10 @@ #define MMCSD_DSR_DELAY (100*1000) /* Time to wait after setting DSR */ #define MMCSD_CLK_DELAY (500*1000) /* Delay after changing clock speeds */ +/* Event delays (all in units of milliseconds) */ + +#define MMCSD_SCR_DATADELAY (100) /* Wait up to 100MS to get SCR */ + #define IS_EMPTY(priv) (priv->type == MMCSD_CARDTYPE_UNKNOWN) /* Transfer mode */ @@ -109,6 +113,7 @@ struct mmcsd_state_s ubyte mode:2; /* (See MMCSDMODE_* definitions) */ ubyte type:4; /* Card type (See MMCSD_CARDTYPE_* definitions) */ + ubyte buswidth:4; /* Bus widthes supported (SD only) */ uint16 selblocklen; /* The currently selected block length */ uint16 rca; /* Relative Card Address (RCS) register */ @@ -131,17 +136,21 @@ struct mmcsd_state_s /* Command/response helpers *************************************************/ -static int mmcsd_sendcmdpoll(struct mmcsd_state_s *priv, uint32 cmd, uint32 arg); - +static int mmcsd_sendcmdpoll(struct mmcsd_state_s *priv, uint32 cmd, + uint32 arg); static int mmcsd_recvR1(struct mmcsd_state_s *priv, uint32 cmd); -static void mmcsd_decodecsd(struct mmcsd_state_s *priv, uint32 csd[4]); +static int mmcsd_getSCR(struct mmcsd_state_s *priv, uint32 scr[2]); + +static void mmcsd_decodeCSD(struct mmcsd_state_s *priv, uint32 csd[4]); #if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS) -static void mmcsd_decodecid(struct mmcsd_state_s *priv, uint32 cid[4]); +static void mmcsd_decodeCID(struct mmcsd_state_s *priv, uint32 cid[4]); #else -# define mmcsd_decodecid(priv,cid) +# define mmcsd_decodeCID(priv,cid) #endif +static void mmcsd_decodeSCR(struct mmcsd_state_s *priv, uint32 scr[2]); static int mmcsd_verifystandby(struct mmcsd_state_s *priv); +static int mmcsd_verifyidle(struct mmcsd_state_s *priv); /* Transfer helpers *********************************************************/ @@ -167,17 +176,14 @@ static int mmcsd_ioctl(FAR struct inode *inode, int cmd, /* Initialization/uninitialization/reset ************************************/ -static inline int - mmcsd_mmcinitialize(struct mmcsd_state_s *priv); -static inline int - mmcsd_sdinitialize(struct mmcsd_state_s *priv); -static inline int - mmcsd_cardidentify(struct mmcsd_state_s *priv); +static int mmcsd_widebus(struct mmcsd_state_s *priv); +static int mmcsd_mmcinitialize(struct mmcsd_state_s *priv); +static int mmcsd_sdinitialize(struct mmcsd_state_s *priv); +static int mmcsd_cardidentify(struct mmcsd_state_s *priv); static int mmcsd_probe(struct mmcsd_state_s *priv); static int mmcsd_removed(struct mmcsd_state_s *priv); static int mmcsd_hwinitialize(struct mmcsd_state_s *priv); -static inline void - mmcsd_hwuninitialize(struct mmcsd_state_s *priv); +static void mmcsd_hwuninitialize(struct mmcsd_state_s *priv); /**************************************************************************** * Private Data @@ -299,7 +305,75 @@ static int mmcsd_recvR1(struct mmcsd_state_s *priv, uint32 cmd) } /**************************************************************************** - * Name: mmcsd_decodecsd + * Name: mmcsd_getSCR + * + * Description: + * Obtain the SD card's Configuration Register (SCR) + * + * Returned Value: + * OK on success; a negated ernno on failure. + * + ****************************************************************************/ + +static int mmcsd_getSCR(struct mmcsd_state_s *priv, uint32 scr[2]) +{ + int ret; +
+ /* Set Block Size To 8 Bytes */
+ /* Send CMD55 APP_CMD with argument as card's RCA */
+
+ mmcsd_sendcmdpoll(priv, MMCSD_CMD16, 8);
+ ret = mmcsd_recvR1(priv, MMCSD_CMD16);
+ if (ret != OK)
+ { + fdbg("ERROR: RECVR1 for CMD16 failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Send CMD55 APP_CMD with argument as card's RCA */
+
+ mmcsd_sendcmdpoll(priv, SD_CMD55, (uint32)priv->rca << 16);
+ ret = mmcsd_recvR1(priv, SD_CMD55);
+ if (ret != OK)
+ {
+ fdbg("ERROR: RECVR1 for CMD55 failed: %d\n", ret); + return ret;
+ }
+ + /* Setup up to receive data */ + + SDIO_RECVSETUP(priv->dev, 8);
+
+ /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 to start data receipt */
+
+ (void)SDIO_EVENTENABLE(priv->dev, SDIOEVENT_READDATADONE); + mmcsd_sendcmdpoll(priv, SD_ACMD51, 0);
+ ret = mmcsd_recvR1(priv, SD_ACMD51);
+ if (ret != OK)
+ {
+ fdbg("ERROR: RECVR1 for ACMD51 failed: %d\n", ret); + return ret;
+ } + + /* Wait for data available */ + + ret = SDIO_EVENTWAIT(priv->dev, MMCSD_SCR_DATADELAY); + if (ret != OK) + { + fdbg("ERROR: WAITEVENT for READ DATA failed: %d\n", ret); + return ret; + }
+ + /* Receive the SCR data from the SD card. Card data is sent big-endian; + * if we are running on a little-endian machine, then we need to swap + * some bytes (should this be a configuration option?) + */ + + return SDIO_RECVDATA(priv->dev, (FAR ubyte *)scr); +} + +/**************************************************************************** + * Name: mmcsd_decodeCSD * * Description: * Decode and extract necessary information from the CSD. If debug is @@ -316,7 +390,7 @@ static int mmcsd_recvR1(struct mmcsd_state_s *priv, uint32 cmd) * ****************************************************************************/ -static void mmcsd_decodecsd(struct mmcsd_state_s *priv, uint32 csd[4]) +static void mmcsd_decodeCSD(struct mmcsd_state_s *priv, uint32 csd[4]) { #if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS) struct mmcsd_csd_s decoded; @@ -563,15 +637,16 @@ static void mmcsd_decodecsd(struct mmcsd_state_s *priv, uint32 csd[4]) } /**************************************************************************** - * Name: mmcsd_decodecid + * Name: mmcsd_decodeCID * * Description: - * Show the contents of the CID (for debug purposes only) + * Show the contents of the Card Indentification Data (CID) (for debug + * purposes only) * ****************************************************************************/ #if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS) -static void mmcsd_decodecid(struct mmcsd_state_s *priv, uint32 cid[4]) +static void mmcsd_decodeCID(struct mmcsd_state_s *priv, uint32 cid[4]) { struct mmcsd_cid_s decoded; @@ -626,10 +701,65 @@ static void mmcsd_decodecid(struct mmcsd_state_s *priv, uint32 cid[4]) #endif /**************************************************************************** + * Name: mmcsd_decodeSCR + * + * Description: + * Show the contents of the SD Configuration Register (SCR). The only + * value retained is: priv->buswidth; + * + ****************************************************************************/ + +static void mmcsd_decodeSCR(struct mmcsd_state_s *priv, uint32 scr[2]) +{ +#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS) +struct mmcsd_scr_s decoded; +#endif + + /* Word 1, bits 63:32 + * SCR_STRUCTURE 63:60 4-bit SCR structure version + * SD_VERSION 59:56 4-bit SD memory spec. version + * DATA_STATE_AFTER_ERASE 55:55 1-bit erase status + * SD_SECURITY 54:52 3-bit SD security support level + * SD_BUS_WIDTHS 51:48 4-bit bus width indicator + * Reserved 47:32 16-bit SD reserved space + * usage. + * + */ + + priv->buswidth = (scr[0] >> 16) & 15; + +#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS) + decoded.scrversion = scr[0] >> 28; + decoded.sdversion = (scr[0] >> 24) & 15; + decoded.erasestate = (scr[0] >> 23) & 1; + decoded.security = (scr[0] >> 20) & 7; + decoded.buswidth = priv->buswidth; +#endif + + /* Word 1, bits 63:32 + * Reserved 31:0 32-bits reserved for manufacturing + * usage. + * + */ + +#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS) + decoded.mfgdata = scr[1]; + + fvdbg("SCR:\n"); + fvdbg(" SCR_STRUCTURE: %d SD_VERSION: %d\n", + decoded.scrversion,decoded.sdversion); + fvdbg(" DATA_STATE_AFTER_ERASE: %d SD_SECURITY: %d SD_BUS_WIDTHS: %x\n", + decoded.erasestate, decoded.security, decoded.buswidth); + fvdbg(" Manufacturing data: %08x\n", + decoded.mfgdata); +#endif +} + +/**************************************************************************** * Name: mmcsd_verifystandby * * Description: - * Verify that the card is in standby state + * Verify that the card is in STANDBY state * ****************************************************************************/ @@ -640,6 +770,20 @@ static int mmcsd_verifystandby(struct mmcsd_state_s *priv) } /**************************************************************************** + * Name: mmcsd_verifystandby + * + * Description: + * Verify that the card is in IDLE state + * + ****************************************************************************/ + +static int mmcsd_verifyidle(struct mmcsd_state_s *priv) +{ +#warning "Not implemented" + return -ENOSYS; +} + +/**************************************************************************** * Transfer Helpers ****************************************************************************/ /**************************************************************************** @@ -892,6 +1036,93 @@ static int mmcsd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg) ****************************************************************************/ /**************************************************************************** + * Name: mmcsd_widebus + * + * Description: + * An SD card has been inserted and its SCR has been obtained. Select wide + * (4-bit) bus operation if the card supports it. + * + * Assumptions: + * This function is called only once per card insertion as part of the SD + * card initialization sequence. It is not necessary to reselect the card + * there is not need to check if wide bus operation has already been + * selected. + * + ****************************************************************************/ + +static int mmcsd_widebus(struct mmcsd_state_s *priv) +{ + int ret; + + /* Check if the SD card supports this feature (as reported in the SCR) */ + + if ((priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0)
+ { + /* Disconnect any CD/DAT3 pull up using ACMD42. ACMD42 is optional and + * need not be supported by all SD calls. + * + * First end CMD55 APP_CMD with argument as card's RCA. + */
+ + mmcsd_sendcmdpoll(priv, SD_CMD55, (uint32)priv->rca << 16);
+ ret = mmcsd_recvR1(priv, SD_CMD55);
+ if (ret != OK)
+ { + fdbg("ERROR: RECVR1 for CMD55 of ACMD42: %d\n", ret);
+ return ret;
+ }
+ + /* Then send ACMD42 with the argument to disconnect the CD/DAT3 + * pullup + */ + + mmcsd_sendcmdpoll(priv, SD_ACMD42, MMCSD_ACMD42_CD_DISCONNECT);
+ ret = mmcsd_recvR1(priv, SD_ACMD42);
+ if (ret != OK)
+ { + fvdbg("WARNING: SD card does not support ACMD42: %d\n", ret);
+ return ret;
+ } + + /* Now send ACMD6 to select wide, 4-bit bus operation, beginning + * with CMD55, APP_CMD: + */ +
+ mmcsd_sendcmdpoll(priv, SD_CMD55, (uint32)priv->rca << 16);
+ ret = mmcsd_recvR1(priv, SD_CMD55);
+ if (ret != OK)
+ { + fdbg("ERROR: RECVR1 for CMD55 of ACMD6: %d\n", ret);
+ return ret;
+ } + + /* Then send ACMD6 */ + + mmcsd_sendcmdpoll(priv, SD_ACMD6, MMCSD_ACMD6_BUSWIDTH_4);
+ ret = mmcsd_recvR1(priv, SD_ACMD6);
+ if (ret != OK)
+ {
+ return ret;
+ }
+
+ /* Configure the SDIO peripheral */
+ + fvdbg("Wide bus operation selected\n"); + SDIO_WIDEBUS(priv->dev, TRUE); + priv->widebus = TRUE; + + SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_4BIT);
+ up_udelay(MMCSD_CLK_DELAY); + return OK; + } + + /* Wide bus operation not supported */ + + fdbg("WARNING: Card does not support wide-bus operation\n"); + return -ENOSYS; +} + +/**************************************************************************** * Name: mmcsd_mmcinitialize * * Description: @@ -900,7 +1131,7 @@ static int mmcsd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg) * ****************************************************************************/ -static inline int mmcsd_mmcinitialize(struct mmcsd_state_s *priv) +static int mmcsd_mmcinitialize(struct mmcsd_state_s *priv) { #ifdef CONFIG_MMCSD_MMCSUPPORT uint32 cid[4]; @@ -912,7 +1143,7 @@ static inline int mmcsd_mmcinitialize(struct mmcsd_state_s *priv) * so there is good evidence that we have an MMC card inserted into the * slot. * - * Send CMD2 = ALL_SEND_CID. This implementation supports only one MMC slot. + * Send CMD2, ALL_SEND_CID. This implementation supports only one MMC slot. * If mulitple cards were installed, each card would respond to CMD2 by * sending its CID (only one card completes the response at a time). The * driver should send CMD2 and assign an RCAs until no response to @@ -926,9 +1157,9 @@ static inline int mmcsd_mmcinitialize(struct mmcsd_state_s *priv) fdbg("ERROR: SDIO_RECVR2 for MMC CID failed: %d\n", ret); return ret; } - mmcsd_decodecid(priv, cid); + mmcsd_decodeCID(priv, cid); - /* Send CMD3 = SET_RELATIVE_ADDR. This command is used to assign a logical + /* Send CMD3, SET_RELATIVE_ADDR. This command is used to assign a logical * address to the card. For MMC, the host assigns the address. CMD3 causes * transition to standby state/data-transfer mode */ @@ -936,7 +1167,7 @@ static inline int mmcsd_mmcinitialize(struct mmcsd_state_s *priv) priv->rca = 1; /* There is only one card */ mmcsd_sendcmdpoll(priv, MMC_CMD3, priv->rca << 16); ret = mmcsd_recvR1(priv, MMC_CMD3); - if (ret != 0) + if (ret != OK) { fdbg("ERROR: mmcsd_recvR1(CMD3) failed: %d\n", ret); return ret; @@ -950,25 +1181,25 @@ static inline int mmcsd_mmcinitialize(struct mmcsd_state_s *priv) */ ret = mmcsd_verifystandby(priv); - if (ret != 0) + if (ret != OK) { fdbg("ERROR: Failed to enter standby state\n"); return ret; } - /* Send CMD9 = SEND_CSD in standby state/data-transfer mode to obtain the + /* Send CMD9, SEND_CSD in standby state/data-transfer mode to obtain the * Card Specific Data (CSD) register, e.g., block length, card storage * capacity, etc. (Stays in standy state/data-transfer mode) */ mmcsd_sendcmdpoll(priv, MMCSD_CMD9, priv->rca << 16); ret = SDIO_RECVR2(priv->dev, MMCSD_CMD9, csd); - if (ret != 0) + if (ret != OK) { fdbg("ERROR: Could not get SD CSD register: %d\n", ret); return ret; } - mmcsd_decodecsd(priv, csd); + mmcsd_decodeCSD(priv, csd); /* Set the Driver Stage Register (DSR) if (1) a CONFIG_MMCSD_DSR has been * provided and (2) the card supports a DSR register. If no DSR value @@ -994,9 +1225,120 @@ static inline int mmcsd_mmcinitialize(struct mmcsd_state_s *priv) * ****************************************************************************/ -static inline int mmcsd_sdinitialize(struct mmcsd_state_s *priv) +static int mmcsd_sdinitialize(struct mmcsd_state_s *priv) { - return -ENOSYS; + uint32 cid[4]; + uint32 csd[4]; + uint32 scr[2]; + uint32 rca; + int ret; + + /* At this point, clocking has been supplied to the card, both CMD0 and + * ACMD41 (with OCR=0) have been sent successfully, the card is no longer + * busy and (presumably) in the IDLE state so there is good evidence + * that we have an SD card inserted into the slot. + * + * Send CMD2, ALL_SEND_CID. The SD CMD2 is similar to the MMC CMD2 except + * that the buffer type used to transmit to response of the card (SD Memory + * Card: Push-Pull, MMC: Open-Drain). This implementation supports only a + * single SD card. If multiple cards were installed in the slot, each card + * would respond to CMD2 by sending its CID (only one card completes the + * response at a time). The driver should send CMD2 and obtain RCAs until + * no response to ALL_SEND_CID is received. + * + * When an SD card receives the CMD2 command it should transition to the + * identification state/card-identification mode + */ + + mmcsd_sendcmdpoll(priv, MMCSD_CMD2, 0); + ret = SDIO_RECVR2(priv->dev, MMCSD_CMD2, cid); + if (ret != OK) + { + fdbg("ERROR: SDIO_RECVR2 for SD CID failed: %d\n", ret); + return ret; + } + mmcsd_decodeCID(priv, cid); + + /* Send CMD3, SET_RELATIVE_ADDR. In both protocols, this command is used + * to assign a logical address to the card. For MMC, the host assigns the + * address; for SD, the memory card has this responsibility. CMD3 causes + * transition to standby state/data-transfer mode + * + * Send CMD3 with argument 0, SD card publishes its RCA in the response. + */ + + mmcsd_sendcmdpoll(priv, SD_CMD3, 0);
+ ret = SDIO_RECVR6(priv->dev, SD_CMD3, &rca);
+ if (ret != OK)
+ {
+ return ret;
+ } + + priv->rca = (uint16)rca; + fvdbg("RCA: %04x\n", priv->rca);
+ + /* This should have caused a transition to standby state. However, this will + * not be reflected in the present R1 status. R1/6 contains the state of + * the card when the command was received, not when it completed execution. + * + * Verify that we are in standby state/data-transfer mode + */ + + ret = mmcsd_verifystandby(priv); + if (ret != OK) + { + fdbg("ERROR: Failed to enter standby state\n"); + return ret; + } + + /* Send CMD9, SEND_CSD, in standby state/data-transfer mode to obtain the + * Card Specific Data (CSD) register. The argument is the RCA that we + * just obtained from CMD3. The card stays in standy state/data-transfer + * mode. + */ + + mmcsd_sendcmdpoll(priv, MMCSD_CMD9, priv->rca << 16); + ret = SDIO_RECVR2(priv->dev, MMCSD_CMD9, csd); + if (ret != OK) + { + fdbg("ERROR: Could not get SD CSD register(%d)\n", ret); + return ret; + } + mmcsd_decodeCSD(priv, csd); + + /* Set the Driver Stage Register (DSR) if (1) a CONFIG_MMCSD_DSR has been + * provided and (2) the card supports a DSR register. If no DSR value + * the card default value (0x0404) will be used. + */ + + (void)mmcsd_sendcmd4(priv); + + /* Select high speed SD clocking (which may depend on the DSR setting) */ + + SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_1BIT); + up_udelay(MMCSD_CLK_DELAY); + + /* Get the SD card Configuration Register (SCR). We need this now because + * that configuration register contains the indication whether or not + * this card supports wide bus operation.\ + */ + + ret = mmcsd_getSCR(priv, scr); + if (ret != OK) + { + fdbg("ERROR: Could not get SD SCR register(%d)\n", ret); + return ret; + } + mmcsd_decodeSCR(priv, scr); + + /* Select width (4-bit) bus operation (if the card supports it) */ + + ret = mmcsd_widebus(priv); + if (ret != OK) + { + fdbg("WARN: Failed to set wide bus operation: %d\n", ret); + } + return OK; } /**************************************************************************** @@ -1008,12 +1350,12 @@ static inline int mmcsd_sdinitialize(struct mmcsd_state_s *priv) * ****************************************************************************/ -static inline int mmcsd_cardidentify(struct mmcsd_state_s *priv) +static int mmcsd_cardidentify(struct mmcsd_state_s *priv) { uint32 response; uint32 start; uint32 elapsed; - uint32 sdcapacity = MMCD_ACMD41_STDCAPACITY; + uint32 sdcapacity = MMCSD_ACMD41_STDCAPACITY; int ret; /* Assume failure to identify the card */ @@ -1074,7 +1416,7 @@ static inline int mmcsd_cardidentify(struct mmcsd_state_s *priv) {
fvdbg("SD V2.x card\n"); priv->type = MMCSD_CARDTYPE_SDV2;
- sdcapacity = MMCD_ACMD41_HIGHCAPACITY; + sdcapacity = MMCSD_ACMD41_HIGHCAPACITY; } else { @@ -1119,7 +1461,7 @@ static inline int mmcsd_cardidentify(struct mmcsd_state_s *priv) { /* Send ACMD41 */ - mmcsd_sendcmdpoll(priv, SD_ACMD41, MMCD_ACMD41_VOLTAGEWINDOW|sdcapacity); + mmcsd_sendcmdpoll(priv, SD_ACMD41, MMCSD_ACMD41_VOLTAGEWINDOW|sdcapacity); ret = SDIO_RECVR3(priv->dev, SD_CMD55, &response); if (ret != OK) { @@ -1155,7 +1497,7 @@ static inline int mmcsd_cardidentify(struct mmcsd_state_s *priv) * addressing */ - if ((response & MMCD_R3_HIGHCAPACITY) != 0) + if ((response & MMCSD_R3_HIGHCAPACITY) != 0) { fvdbg("SD V2.x card with block addressing\n"); DEBUGASSERT(priv->type == MMCSD_CARDTYPE_SDV2); @@ -1243,6 +1585,15 @@ static inline int mmcsd_cardidentify(struct mmcsd_state_s *priv) return -EIO; } + /* Verify that we are in IDLE state */ + + ret = mmcsd_verifyidle(priv); + if (ret != OK) + { + fdbg("ERROR: Failed to enter IDLE state\n"); + return ret; + } + return OK; } @@ -1417,7 +1768,7 @@ static int mmcsd_hwinitialize(struct mmcsd_state_s *priv) * ****************************************************************************/ -static inline void mmcsd_hwuninitialize(struct mmcsd_state_s *priv) +static void mmcsd_hwuninitialize(struct mmcsd_state_s *priv) { if (priv) { @@ -1498,7 +1849,7 @@ int mmcsd_slotinitialize(int minor, int slotno, FAR struct sdio_dev_s *dev) else { fdbg("ERROR: Failed to initialize MMC/SD slot %d: %d\n", - slotno, -ret); + slotno, ret); goto errout_with_alloc; } } @@ -1510,7 +1861,7 @@ int mmcsd_slotinitialize(int minor, int slotno, FAR struct sdio_dev_s *dev) ret = rwb_initialize(&priv->rwbuffer); if (ret < 0) { - fdbg("ERROR: Buffer setup failed: %d\n", -ret); + fdbg("ERROR: Buffer setup failed: %d\n", ret); goto errout_with_hwinit; } #endif @@ -1524,7 +1875,7 @@ int mmcsd_slotinitialize(int minor, int slotno, FAR struct sdio_dev_s *dev) ret = register_blockdriver(devname, &g_bops, 0, priv); if (ret < 0) { - fdbg("ERROR: register_blockdriver failed: %d\n", -ret); + fdbg("ERROR: register_blockdriver failed: %d\n", ret); goto errout_with_buffers; } } diff --git a/nuttx/drivers/mmcsd/mmcsd_sdio.h b/nuttx/drivers/mmcsd/mmcsd_sdio.h index 43997f2f6..e005af212 100644 --- a/nuttx/drivers/mmcsd/mmcsd_sdio.h +++ b/nuttx/drivers/mmcsd/mmcsd_sdio.h @@ -60,11 +60,21 @@ #define MMCSD_CMD8ECHO_MASK (0xff << MMCSD_CMD8ECHO_SHIFT) # define MMCSD_CMD8CHECKPATTERN (0xaa << MMCSD_CMD8ECHO_SHIFT) +/* ACMD6 argument */ + +#define MMCSD_ACMD6_BUSWIDTH_1 (0) /* Bus width = 1-bit */ +#define MMCSD_ACMD6_BUSWIDTH_4 (2) /* Bus width = 4-bit */ + /* ACMD41 argument */ -#define MMCD_ACMD41_VOLTAGEWINDOW 0x80100000
-#define MMCD_ACMD41_HIGHCAPACITY (1 << 30)
-#define MMCD_ACMD41_STDCAPACITY (0)
+#define MMCSD_ACMD41_VOLTAGEWINDOW 0x80100000
+#define MMCSD_ACMD41_HIGHCAPACITY (1 << 30)
+#define MMCSD_ACMD41_STDCAPACITY (0)
+ +/* ACMD42 argument */ + +#define MMCSD_ACMD42_CD_DISCONNECT (0) /* Disconnect card detection logic */ +#define MMCSD_ACMD42_CD_CONNECT (1) /* Connect card detection logic */ /* R1 Card Status bit definitions */ @@ -135,9 +145,16 @@ #define MMCSD_VDD_33_34 (1 << 21) /* VDD voltage 3.3-3.4 */ #define MMCSD_VDD_34_35 (1 << 22) /* VDD voltage 3.4-3.5 */ #define MMCSD_VDD_35_36 (1 << 23) /* VDD voltage 3.5-3.6 */ -#define MMCD_R3_HIGHCAPACITY (1 << 30) /* TRUE: Card supports block addressing */
+#define MMCSD_R3_HIGHCAPACITY (1 << 30) /* TRUE: Card supports block addressing */
#define MMCSD_CARD_BUSY (1 << 31) /* Card power-up busy bit */ +/* SD Configuration Register (SCR) encoding */ + +#define MMCSD_SCR_BUSWIDTH_1BIT (1) +#define MMCSD_SCR_BUSWIDTH_2BIT (2) +#define MMCSD_SCR_BUSWIDTH_4BIT (4) +#define MMCSD_SCR_BUSWIDTH_8BIT (8) + /* Last 4 bytes of the 48-bit R7 response */ #define MMCSD_R7VERSION_SHIFT 28 /* Bits 28-31: Command version number */ @@ -153,7 +170,7 @@ * Public Types ********************************************************************************************/ -/* Decoded CID register */ +/* Decoded Card Identification (CID) register */ struct mmcsd_cid_s { @@ -168,7 +185,7 @@ struct mmcsd_cid_s /* 0:0 1-bit (not used) */ }; -/* Decoded CSD register */ +/* Decoded Card Specific Data (CSD) register */ struct mmcsd_csd_s { @@ -264,6 +281,17 @@ struct mmcsd_csd_s /* 0:0 Not used */ }; +struct mmcsd_scr_s +{ + ubyte scrversion; /* 63:60 Version of SCR structure */ + ubyte sdversion; /* 59:56 SD memory card physical layer version */ + ubyte erasestate; /* 55:55 Data state after erase (1 or 0) */ + ubyte security; /* 54:52 SD security support */ + ubyte buswidth; /* 51:48 DAT bus widthes supported */ + /* 47:32 SD reserved space */ + uint32 mfgdata; /* 31:0 Reserved for manufacturing data */ +}; + /******************************************************************************************** * Public Data ********************************************************************************************/ diff --git a/nuttx/include/nuttx/sdio.h b/nuttx/include/nuttx/sdio.h index 0e4d77c62..ebecc5923 100755 --- a/nuttx/include/nuttx/sdio.h +++ b/nuttx/include/nuttx/sdio.h @@ -360,25 +360,6 @@ #define SDIO_CLOCK(dev,rate) ((dev)->clock(dev,rate)) /**************************************************************************** - * Name: SDIO_SETBLOCKLEN - * - * Description: - * Set the MMC/SD block length and block count - * - * Input Parameters: - * dev - An instance of the MMC/SD device interface - * blocklen - The block length - * nblocks - The block count - * - * Returned Value: - * OK on success; negated errno on failure - * - ****************************************************************************/ - -#define SDIO_SETBLOCKLEN(dev,blocklen,nblocks) \ - ((dev)->setblocklen(dev,blocklen,nblocks)) - -/**************************************************************************** * Name: SDIO_ATTACH * * Description: @@ -414,6 +395,26 @@ #define SDIO_SENDCMD(dev,cmd,arg) ((dev)->sendcmd(dev,cmd,arg)) /**************************************************************************** + * Name: SDIO_SENDSETUP + * + * Description: + * Setup hardware in preparation for data trasfer from the card. This method + * will do whatever controller setup is necessary. This would be called + * for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25 + * (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called. + * + * Input Parameters: + * dev - An instance of the MMC/SD device interface + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +#define SDIO_SENDSETUP(dev,nbytes) ((dev)->sendsetup(dev,nbytes)) + +/**************************************************************************** * Name: SDIO_SENDDATA * * Description: @@ -424,7 +425,7 @@ * data - Data to be sent * * Returned Value: - * Number of bytes sent on succes; a negated errno on failure + * Number of bytes sent on success; a negated errno on failure * ****************************************************************************/ @@ -475,7 +476,28 @@ #define SDIO_RECVR4(dev,cmd,R4) ((dev)->recvR4(dev,cmd,R4)) /* 48-bit */ #define SDIO_RECVR5(dev,cmd,R5) ((dev)->recvR5(dev,cmd,R5)) /* 48-bit */ #define SDIO_RECVR6(dev,cmd,R6) ((dev)->recvR6(dev,cmd,R6)) /* 48-bit */ -#define SDIO_RECVR7(dev,cmd,R7) ((dev)->recvR6(dev,cmd,R7)) /* 48-bit */ +#define SDIO_RECVR7(dev,cmd,R7) ((dev)->recvR7(dev,cmd,R7)) /* 48-bit */ + +/**************************************************************************** + * Name: SDIO_RECVSETUP + * + * Description: + * Setup hardware in preparation for data trasfer from the card. This method + * will do whatever controller setup is necessary. This would be called + * for SD memory just BEFORE sending CMD13 (SEND_STATUS), CMD17 + * (READ_SINGLE_BLOCK), CMD18 (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), ... + * and before SDIO_RECVDATA is called. + * + * Input Parameters: + * dev - An instance of the MMC/SD device interface + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +#define SDIO_RECVSETUP(dev,nbytes) ((dev)->recvsetup(dev,nbytes)) /**************************************************************************** * Name: SDIO_RECVDATA @@ -488,7 +510,7 @@ * buffer - Buffer in which to receive the data * * Returned Value: - * Number of bytes sent on succes; a negated errno on failure + * Number of bytes sent on success; a negated errno on failure * ****************************************************************************/ @@ -502,18 +524,15 @@ * * Input Parameters: * dev - An instance of the MMC/SD device interface - * eventset - A bitset of events to enable or disable (see SDIOEVENT_* - * definitions - * enable - TRUE: enable event; FALSE: disable events + * eventset - A bitset of events to enable or disable (see MMCSDEVENT_*
+ * definitions). 0=disable; 1=enable.
* * Returned Value: * None * ****************************************************************************/ -#define SDIO_EVENTENABLE(dev,eventset) ((dev)->eventenable(dev,eventset,TRUE)) -#define SDIO_EVENTDISABLE(dev,eventset) ((dev)->eventenable(dev,eventset,FALSE)) -#define SDIO_EVENTDISABLEALL(dev) ((dev)->eventenable(dev,SDIOEVENT_ALLEVENTS,FALSE)) +#define SDIO_EVENTENABLE(dev,eventset) ((dev)->eventenable(dev,eventset)) /**************************************************************************** * Name: SDIO_EVENTWAIT @@ -526,8 +545,9 @@ * timeout - Maximum time in milliseconds to wait. Zero means no timeout. * * Returned Value: - * Event set containing the event(s) that ended the wait. If no events the + * Event set containing the event(s) that ended the wait. If no events the
* returned event set is zero, then the wait was terminated by the timeout. + * All events are cleared disabled after the wait concludes.
* ****************************************************************************/ @@ -538,13 +558,14 @@ * * Description: * Return the current event set. This supports polling for MMC/SD (vs. - * waiting). + * waiting). Only enabled events need be reported. * * Input Parameters: - * dev - An instance of the MMC/SD device interface + * dev - An instance of the MMC/SD device interface * * Returned Value: - * Event set containing the current events (cleared after reading). + * Event set containing the current events (All pending events are cleared + * after reading).
* ****************************************************************************/ @@ -609,7 +630,7 @@ * buffer - The memory to DMA from * * Returned Value: - * OK on succes; a negated errno on failure + * OK on success; a negated errno on failure * ****************************************************************************/ @@ -630,7 +651,7 @@ * buffer - The memory to DMA into * * Returned Value: - * OK on succes; a negated errno on failure + * OK on success; a negated errno on failure * ****************************************************************************/ @@ -650,7 +671,7 @@ * dev - An instance of the MMC/SD device interface * * Returned Value: - * OK on succes; a negated errno on failure + * OK on success; a negated errno on failure * ****************************************************************************/ @@ -670,7 +691,7 @@ * dev - An instance of the MMC/SD device interface * * Returned Value: - * OK on succes; a negated errno on failure + * OK on success; a negated errno on failure * ****************************************************************************/ @@ -692,7 +713,7 @@ * remaining in the transfer. * * Returned Value: - * OK on succes; a negated errno on failure + * OK on success; a negated errno on failure * ****************************************************************************/ @@ -713,9 +734,16 @@ enum sdio_clock_e CLOCK_SDIO_DISABLED = 0, /* Clock is disabled */ CLOCK_IDMODE, /* Initial ID mode clocking (<400KHz) */ CLOCK_MMC_TRANSFER, /* MMC normal operation clocking */ - CLOCK_SD_TRANSFER /* SD normal operation clocking */ + CLOCK_SD_TRANSFER_1BIT, /* SD normal operation clocking (narrow 1-bit mode) */ + CLOCK_SD_TRANSFER_4BIT /* SD normal operation clocking (wide 4-bit mode) */ }; +/* Event set. A ubyte is big enough to hold a set of 8-events. If more are + * needed, change this to a uint16. + */ + +typedef ubyte sdio_eventset_t; + /* This structure defines the interface between the NuttX MMC/SD * driver and the chip- or board-specific MMC/SD interface. This * interface is only used in architectures that support SDIO @@ -736,12 +764,12 @@ struct sdio_dev_s ubyte (*status)(FAR struct sdio_dev_s *dev); void (*widebus)(FAR struct sdio_dev_s *dev, boolean enable); void (*clock)(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate); - int (*setblocklen)(FAR struct sdio_dev_s *dev, int blocklen, int nblocks); int (*attach)(FAR struct sdio_dev_s *dev); /* Command/Status/Data Transfer */ void (*sendcmd)(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 arg); + int (*sendsetup)(FAR struct sdio_dev_s *dev, uint32 nbytes); int (*senddata)(FAR struct sdio_dev_s *dev, FAR const ubyte *buffer); int (*waitresponse)(FAR struct sdio_dev_s *dev, uint32 cmd); @@ -752,11 +780,12 @@ struct sdio_dev_s int (*recvR5)(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *R5); int (*recvR6)(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *R6); int (*recvR7)(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *R7); + int (*recvsetup)(FAR struct sdio_dev_s *dev, uint32 nbytes); int (*recvdata)(FAR struct sdio_dev_s *dev, FAR ubyte *buffer); /* EVENT handler */ - void (*eventenable)(FAR struct sdio_dev_s *dev, ubyte eventset, boolean enable); + void (*eventenable)(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset); ubyte (*eventwait)(FAR struct sdio_dev_s *dev, uint32 timeout); ubyte (*events)(FAR struct sdio_dev_s *dev); |