summaryrefslogtreecommitdiff
path: root/nuttx/drivers/mmcsd/mmcsd_sdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/drivers/mmcsd/mmcsd_sdio.c')
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_sdio.c268
1 files changed, 135 insertions, 133 deletions
diff --git a/nuttx/drivers/mmcsd/mmcsd_sdio.c b/nuttx/drivers/mmcsd/mmcsd_sdio.c
index 1a3016e88..97c2a6dc0 100644
--- a/nuttx/drivers/mmcsd/mmcsd_sdio.c
+++ b/nuttx/drivers/mmcsd/mmcsd_sdio.c
@@ -944,13 +944,13 @@ static int mmcsd_verifystate(FAR struct mmcsd_state_s *priv, uint32 state)
* Transfer Helpers
****************************************************************************/
-/****************************************************************************
- * Name: mmcsd_wrprotected
- *
- * Description:
+/****************************************************************************
+ * Name: mmcsd_wrprotected
+ *
+ * Description:
* Return true if the the card is unlocked an not write protected. The
- *
- *
+ *
+ *
****************************************************************************/
static boolean mmcsd_wrprotected(FAR struct mmcsd_state_s *priv)
@@ -964,12 +964,12 @@ static boolean mmcsd_wrprotected(FAR struct mmcsd_state_s *priv)
return (priv->wrprotect || priv->locked || SDIO_WRPROTECTED(priv->dev));
}
-/****************************************************************************
- * Name: mmcsd_eventwait
- *
- * Description:
- * Wait for the specified events to occur. Check for wakeup on error events.
- *
+/****************************************************************************
+ * Name: mmcsd_eventwait
+ *
+ * Description:
+ * Wait for the specified events to occur. Check for wakeup on error events.
+ *
****************************************************************************/
static int mmcsd_eventwait(FAR struct mmcsd_state_s *priv,
@@ -1001,14 +1001,14 @@ static int mmcsd_eventwait(FAR struct mmcsd_state_s *priv,
return OK;
}
-/****************************************************************************
- * Name: mmcsd_transferready
- *
- * Description:
+/****************************************************************************
+ * Name: mmcsd_transferready
+ *
+ * Description:
* Check if the MMC/SD card is ready for the next read or write transfer.
* Ready means: (1) card still in the slot, and (2) if the last transfer
- * was a write transfer, the card is no longer busy from that transfer.
- *
+ * was a write transfer, the card is no longer busy from that transfer.
+ *
****************************************************************************/
static int mmcsd_transferready(FAR struct mmcsd_state_s *priv)
@@ -1095,27 +1095,27 @@ static int mmcsd_transferready(FAR struct mmcsd_state_s *priv)
return -ETIMEDOUT;
}
-/****************************************************************************
- * Name: mmcsd_stoptransmission
- *
- * Description:
- * Send STOP_TRANSMISSION
- *
+/****************************************************************************
+ * Name: mmcsd_stoptransmission
+ *
+ * Description:
+ * Send STOP_TRANSMISSION
+ *
****************************************************************************/
-
+
static int mmcsd_stoptransmission(FAR struct mmcsd_state_s *priv)
{
- int ret;
-
- /* Send CMD12, STOP_TRANSMISSION, and verify good R1 return status */
+ int ret;
+
+ /* Send CMD12, STOP_TRANSMISSION, and verify good R1 return status */
- mmcsd_sendcmdpoll(priv, MMCSD_CMD12, 0);
+ mmcsd_sendcmdpoll(priv, MMCSD_CMD12, 0);
ret = mmcsd_recvR1(priv, MMCSD_CMD12);
if (ret != OK)
{
fdbg("ERROR: mmcsd_recvR1 for CMD12 failed: %d\n", ret);
- }
- return ret;
+ }
+ return ret;
}
/****************************************************************************
@@ -1139,16 +1139,16 @@ static int mmcsd_setblocklen(FAR struct mmcsd_state_s *priv, uint32 blocklen)
* block length is specified in the CSD.
*/
- mmcsd_sendcmdpoll(priv, MMCSD_CMD16, priv->blocksize);
- ret = mmcsd_recvR1(priv, MMCSD_CMD16);
- if (ret == OK)
+ mmcsd_sendcmdpoll(priv, MMCSD_CMD16, priv->blocksize);
+ ret = mmcsd_recvR1(priv, MMCSD_CMD16);
+ if (ret == OK)
{
priv->selblocklen = blocklen;
}
else
{
- fdbg("ERROR: mmcsd_recvR1 for CMD16 failed: %d\n", ret);
- }
+ fdbg("ERROR: mmcsd_recvR1 for CMD16 failed: %d\n", ret);
+ }
}
return ret;
@@ -1172,12 +1172,12 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv,
DEBUGASSERT(priv != NULL && buffer != NULL);
/* Check if the card is locked */
-
- if (priv->locked)
+
+ if (priv->locked)
{
- fdbg("ERROR: Card is locked\n");
- return -EPERM;
- }
+ fdbg("ERROR: Card is locked\n");
+ return -EPERM;
+ }
/* Verify that the card is ready for the transfer. The card may still be
* busy from the preceding write transfer. It would be simpler to check
@@ -1207,28 +1207,28 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv,
}
fvdbg("offset=%d\n", offset);
- /* Select the block size for the card */
+ /* Select the block size for the card */
ret = mmcsd_setblocklen(priv, priv->blocksize);
- if (ret != OK)
+ if (ret != OK)
{
- fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
- return ret;
- }
+ fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
+ return ret;
+ }
/* Configure SDIO controller hardware for the read transfer */
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
-#ifdef CONFIG_SDIO_DMA
+#ifdef CONFIG_SDIO_DMA
if (priv->dma)
- {
+ {
SDIO_DMARECVSETUP(priv->dev, buffer, priv->blocksize);
}
else
-#endif
- {
+#endif
+ {
SDIO_RECVSETUP(priv->dev, buffer, priv->blocksize);
- }
+ }
/* Send CMD17, READ_SINGLE_BLOCK: Read a block of the size selected
* by the mmcsd_setblocklen() and verify that good R1 status is
@@ -1236,19 +1236,19 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv,
* state.
*/
- mmcsd_sendcmdpoll(priv, MMCSD_CMD17, offset);
- ret = mmcsd_recvR1(priv, MMCSD_CMD17);
- if (ret != OK)
- {
+ mmcsd_sendcmdpoll(priv, MMCSD_CMD17, offset);
+ ret = mmcsd_recvR1(priv, MMCSD_CMD17);
+ if (ret != OK)
+ {
fdbg("ERROR: mmcsd_recvR1 for CMD17 failed: %d\n", ret);
- return ret;
+ return ret;
}
/* Then wait for the data transfer to complete */
- ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, MMCSD_BLOCK_DATADELAY);
- if (ret != OK)
- {
+ ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, MMCSD_BLOCK_DATADELAY);
+ if (ret != OK)
+ {
fdbg("ERROR: CMD17 transfer failed: %d\n", ret);
}
return ret;
@@ -1274,12 +1274,12 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv,
DEBUGASSERT(priv != NULL && buffer != NULL && nblocks > 1);
/* Check if the card is locked */
-
- if (priv->locked)
+
+ if (priv->locked)
{
- fdbg("ERROR: Card is locked\n");
- return -EPERM;
- }
+ fdbg("ERROR: Card is locked\n");
+ return -EPERM;
+ }
/* Verify that the card is ready for the transfer. The card may still be
* busy from the preceding write transfer. It would be simpler to check
@@ -1310,48 +1310,48 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv,
}
fvdbg("nbytes=%d byte offset=%d\n", nbytes, offset);
- /* Select the block size for the card */
+ /* Select the block size for the card */
ret = mmcsd_setblocklen(priv, priv->blocksize);
- if (ret != OK)
+ if (ret != OK)
{
- fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
- return ret;
- }
+ fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
+ return ret;
+ }
/* Configure SDIO controller hardware for the read transfer */
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
-#ifdef CONFIG_SDIO_DMA
+#ifdef CONFIG_SDIO_DMA
if (priv->dma)
- {
+ {
SDIO_DMARECVSETUP(priv->dev, buffer, nbytes);
}
else
-#endif
- {
+#endif
+ {
SDIO_RECVSETUP(priv->dev, buffer, nbytes);
- }
-
+ }
+
/* Send CMD18, READ_MULT_BLOCK: Read a block of the size selected by
* the mmcsd_setblocklen() and verify that good R1 status is returned
*/
mmcsd_sendcmdpoll(priv, MMCSD_CMD18, offset);
ret = mmcsd_recvR1(priv, MMCSD_CMD18);
- if (ret != OK)
- {
+ if (ret != OK)
+ {
fdbg("ERROR: mmcsd_recvR1 for CMD18 failed: %d\n", ret);
- return ret;
+ return ret;
}
/* Wait for the transfer to complete */
ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, nblocks * MMCSD_BLOCK_DATADELAY);
- if (ret != OK)
- {
+ if (ret != OK)
+ {
fdbg("ERROR: CMD18 transfer failed: %d\n", ret);
- return ret;
+ return ret;
}
/* Send STOP_TRANSMISSION */
@@ -1414,12 +1414,12 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv,
/* Check if the card is locked or write protected (either via software or
* via the mechanical write protect on the card)
*/
-
- if (mmcsd_wrprotected(priv))
+
+ if (mmcsd_wrprotected(priv))
{
- fdbg("ERROR: Card is locked or write protected\n");
- return -EPERM;
- }
+ fdbg("ERROR: Card is locked or write protected\n");
+ return -EPERM;
+ }
/* Verify that the card is ready for the transfer. The card may still be
* busy from the preceding write transfer. It would be simpler to check
@@ -1449,13 +1449,13 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv,
}
fvdbg("offset=%d\n", offset);
- /* Select the block size for the card */
+ /* Select the block size for the card */
ret = mmcsd_setblocklen(priv, priv->blocksize);
- if (ret != OK)
+ if (ret != OK)
{
- fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
- return ret;
+ fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
+ return ret;
}
/* Send CMD24, WRITE_BLOCK, and verify that good R1 status is returned */
@@ -1464,29 +1464,29 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv,
ret = mmcsd_recvR1(priv, MMCSD_CMD24);
if (ret != OK)
{
- fdbg("ERROR: mmcsd_recvR1 for CMD24 failed: %d\n", ret);
- return ret;
+ fdbg("ERROR: mmcsd_recvR1 for CMD24 failed: %d\n", ret);
+ return ret;
}
-
+
/* Configure SDIO controller hardware for the write transfer */
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
-#ifdef CONFIG_SDIO_DMA
+#ifdef CONFIG_SDIO_DMA
if (priv->dma)
- {
- SDIO_DMASENDSETUP(priv->dev, buffer, priv->blocksize);
+ {
+ SDIO_DMASENDSETUP(priv->dev, buffer, priv->blocksize);
}
else
-#endif
- {
- SDIO_SENDSETUP(priv->dev, buffer, priv->blocksize);
- }
+#endif
+ {
+ SDIO_SENDSETUP(priv->dev, buffer, priv->blocksize);
+ }
/* Wait for the transfer to complete */
- ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, MMCSD_BLOCK_DATADELAY);
- if (ret != OK)
- {
+ ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, MMCSD_BLOCK_DATADELAY);
+ if (ret != OK)
+ {
fdbg("ERROR: CMD24 transfer failed: %d\n", ret);
}
@@ -1520,12 +1520,12 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
/* Check if the card is locked or write protected (either via software or
* via the mechanical write protect on the card)
*/
-
- if (mmcsd_wrprotected(priv))
+
+ if (mmcsd_wrprotected(priv))
{
- fdbg("ERROR: Card is locked or write protected\n");
- return -EPERM;
- }
+ fdbg("ERROR: Card is locked or write protected\n");
+ return -EPERM;
+ }
/* Verify that the card is ready for the transfer. The card may still be
* busy from the preceding write transfer. It would be simpler to check
@@ -1556,13 +1556,13 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
}
fvdbg("nbytes=%d byte offset=%d\n", nbytes, offset);
- /* Select the block size for the card */
+ /* Select the block size for the card */
ret = mmcsd_setblocklen(priv, priv->blocksize);
- if (ret != OK)
+ if (ret != OK)
{
- fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
- return ret;
+ fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
+ return ret;
}
/* If this is an SD card, then send ACMD23 (SET_WR_BLK_COUNT) just before
@@ -1573,14 +1573,14 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
if (IS_SD(priv->type))
{
- /* Send CMD55, APP_CMD, a verify that good R1 status is retured */
-
+ /* Send CMD55, APP_CMD, a verify that good R1 status is retured */
+
mmcsd_sendcmdpoll(priv, SD_CMD55, 0);
ret = mmcsd_recvR1(priv, SD_CMD55);
if (ret != OK)
{
- fdbg("ERROR: mmcsd_recvR1 for CMD55 (ACMD23) failed: %d\n", ret);
- return ret;
+ fdbg("ERROR: mmcsd_recvR1 for CMD55 (ACMD23) failed: %d\n", ret);
+ return ret;
}
/* Send CMD23, SET_WR_BLK_COUNT, and verify that good R1 status is returned */
@@ -1589,8 +1589,8 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
ret = mmcsd_recvR1(priv, SD_ACMD23);
if (ret != OK)
{
- fdbg("ERROR: mmcsd_recvR1 for ACMD23 failed: %d\n", ret);
- return ret;
+ fdbg("ERROR: mmcsd_recvR1 for ACMD23 failed: %d\n", ret);
+ return ret;
}
}
@@ -1602,31 +1602,31 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
ret = mmcsd_recvR1(priv, MMCSD_CMD25);
if (ret != OK)
{
- fdbg("ERROR: mmcsd_recvR1 for CMD24 failed: %d\n", ret);
- return ret;
+ fdbg("ERROR: mmcsd_recvR1 for CMD24 failed: %d\n", ret);
+ return ret;
}
-
+
/* Configure SDIO controller hardware for the write transfer */
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
-#ifdef CONFIG_SDIO_DMA
+#ifdef CONFIG_SDIO_DMA
if (priv->dma)
- {
- SDIO_DMASENDSETUP(priv->dev, buffer, nbytes);
+ {
+ SDIO_DMASENDSETUP(priv->dev, buffer, nbytes);
}
else
-#endif
- {
- SDIO_SENDSETUP(priv->dev, buffer, nbytes);
- }
+#endif
+ {
+ SDIO_SENDSETUP(priv->dev, buffer, nbytes);
+ }
/* Wait for the transfer to complete */
ret =mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, nblocks * MMCSD_BLOCK_DATADELAY);
- if (ret != OK)
- {
+ if (ret != OK)
+ {
fdbg("ERROR: CMD18 transfer failed: %d\n", ret);
- return ret;
+ return ret;
}
/* Send STOP_TRANSMISSION */
@@ -1951,7 +1951,8 @@ static void mmcsd_mediachange(FAR void *arg)
if (SDIO_PRESENT(priv->dev))
{
/* No... process the card insertion. This could cause chaos if we think
- * that a card is already present and there are mounted filesystms!
+ * that a card is already present and there are mounted filesystems!
+ * NOTE that mmcsd_probe() will always re-enable callbacks appropriately.
*/
(void)mmcsd_probe(priv);
@@ -1959,7 +1960,8 @@ static void mmcsd_mediachange(FAR void *arg)
else
{
/* No... process the card removal. This could have very bad implications
- * for any mounted file systems!
+ * for any mounted file systems! NOTE that mmcsd_removed() does NOT
+ * re-enable callbacks so we will need to do that here.
*/
(void)mmcsd_removed(priv);