diff --git a/drivers/mmcsd/mmcsd_sdio.c b/drivers/mmcsd/mmcsd_sdio.c
index a38521fff72c52938d30e60508a82869915837fc..2748b682d8ab3d9e058b3c496abf8767ec39d53d 100644
--- a/drivers/mmcsd/mmcsd_sdio.c
+++ b/drivers/mmcsd/mmcsd_sdio.c
@@ -69,10 +69,12 @@
 
 #define MAX_CREFS               0xff
 
-/* Timing */
+/* Timing (all in units of microseconds) */
 
-#define MMCSD_POWERUP_DELAY     250     /* 74 clock cycles @ 400KHz = 185uS */
-#define MMCSD_IDLE_DELAY        50      /* Short delay to allow change to IDLE state */
+#define MMCSD_POWERUP_DELAY     250        /* 74 clock cycles @ 400KHz = 185uS */
+#define MMCSD_IDLE_DELAY        (50*1000)  /* Short delay to allow change to IDLE state */
+#define MMCSD_DSR_DELAY         (100*1000) /* Time to wait after setting DSR */
+#define MMCSD_CLK_DELAY         (500*1000) /* Delay after changing clock speeds */
 
 #define IS_EMPTY(priv) (priv->type == MMCSD_CARDTYPE_UNKNOWN)
 
@@ -100,12 +102,13 @@ struct mmcsd_state_s
   ubyte mediachanged:1;            /* TRUE: Media changed since last check */
   ubyte wrprotect:1;               /* TRUE: Media is write protected */
   ubyte selected:1;                /* TRUE: card is selected */
+  ubyte dsrimp:1;                  /* TRUE: card supports CMD4/DSR setting (from CSD) */
 #ifdef CONFIG_SDIO_DMA
   ubyte dma:1;                     /* TRUE: hardware supports DMA */
 #endif
 
-  ubyte type;                      /* Card type (See MMCSD_CARDTYPE_* definitions) */
-  ubyte mode;                      /* (See MMCSDMODE_* definitions) */
+  ubyte mode:2;                    /* (See MMCSDMODE_* definitions) */
+  ubyte type:4;                    /* Card type (See MMCSD_CARDTYPE_* definitions) */
   uint16 selblocklen;              /* The currently selected block length */
   uint16 rca;                      /* Relative Card Address (RCS) register */
 
@@ -131,6 +134,16 @@ struct mmcsd_state_s
 
 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]);
+#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
+static void    mmcsd_decodecid(uint32 cid[4]);
+#else
+#  define mmcsd_decodecid(cid)
+#endif
+
+static int     mmcsd_verifystandby(struct mmcsd_state_s *priv);
+
 /* Transfer helpers *********************************************************/
 
 static ssize_t mmcsd_doread(FAR void *dev, FAR ubyte *buffer,
@@ -197,7 +210,7 @@ static const struct block_operations g_bops =
  * Name: mmcsd_sendcmdpoll
  *
  * Description:
- *   send a command and poll-wait for the response.
+ *   Send a command and poll-wait for the response.
  *
  ****************************************************************************/
 
@@ -219,6 +232,175 @@ static int mmcsd_sendcmdpoll(struct mmcsd_state_s *priv, uint32 cmd, uint32 arg)
   return ret;
 }
 
+/****************************************************************************
+ * Name: mmcsd_sendcmdpoll
+ *
+ * Description:
+ *   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.
+ *
+ ****************************************************************************/
+
+static inline int mmcsd_sendcmd4(struct mmcsd_state_s *priv)
+{
+  int ret = OK;
+
+#ifdef CONFIG_MMCSD_DSR
+  /* The dsr_imp bit from the CSD will tell us if the card supports setting
+   * the DSR via CMD4 or not.
+   */
+
+  if (priv->dsrimp != FALSE)
+    {
+      /* CMD4 = SET_DSR will set the cards DSR register. The DSR and CMD4
+       * support are optional.  However, since this is a broadcast command
+       * with no response (like CMD0), we will never know if the DSR was
+       * set correctly or not
+       */
+
+      mmcsd_sendcmdpoll(priv, MMCSD_CMD4, CONFIG_MMCSD_DSR << 16);
+      up_udelay(MMCSD_DSR_DELAY);
+
+      /* Send it again to have more confidence */
+
+      mmcsd_sendcmdpoll(priv, MMCSD_CMD4, CONFIG_MMCSD_DSR << 16);
+      up_udelay(MMCSD_DSR_DELAY);
+    }
+#endif
+  return ret;
+}
+
+/****************************************************************************
+ * Name: mmcsd_recvR1
+ *
+ * Description:
+ *   Receive R1 response and check for errors.
+ *
+ ****************************************************************************/
+
+static int mmcsd_recvR1(struct mmcsd_state_s *priv, uint32 cmd)
+{
+  uint32 r1;
+  int ret;
+
+  /* Get the R1 response from the hardware */
+
+  ret = SDIO_RECVR1(priv->dev, cmd, &r1);
+  if (ret == OK)
+    {
+      /* Check if R1 reports an error */
+
+      if ((r1 & MMCSD_R1_ERRORMASK) != 0)
+        {
+          ret = -EIO;
+        }
+    }
+  return ret;
+}
+
+/****************************************************************************
+ * Name: mmcsd_decodecsd
+ *
+ * Description:
+ *   Decode and extract necessary information from the CSD. If debug is
+ *   enabled, then decode and show the full contents of the CSD.
+ *
+ * Returned Value:
+ *   OK on success; a negated ernno on failure.  On success, the following
+ *   values will be set in the driver state structure:
+ *
+ *   priv->dsrimp      TRUE: card supports CMD4/DSR setting (from CSD)
+ *   priv->rdblocklen  Read block length (== block size)
+ *   priv->wrblocklen  Write block length
+ *   priv->nblocks     Number of blocks
+ *   priv->capacity    Total capacity of volume
+ *
+ ****************************************************************************/
+
+static void mmcsd_decodecsd(struct mmcsd_state_s *priv, uint32 csd[4])
+{
+#warning "Not Implemented"
+  return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: mmcsd_decodecid
+ *
+ * Description:
+ *   Show the contents of the CID (for debug purposes only)
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
+static void mmcsd_decodecid(uint32 cid[4])
+{
+  struct mmcsd_cid_s decoded;
+
+  /* Word 1: Bits 127-96:
+   *   mid - 127-120  8-bit Manufacturer ID
+   *   oid - 119-104 16-bit OEM/Application ID (ascii)
+   *   pnm - 103-64  40-bit Product Name (ascii) + null terminator
+   *         pnm[0] 103:96
+   */
+
+  decoded.mid    =  cid[0] >> 24;
+  decoded.oid    = (cid[0] >> 8) & 0xffff;
+  decoded.pnm[0] =  cid[0] & 0xff;
+
+  /* Word 2: Bits 64:95
+   *   pnm - 103-64  40-bit Product Name (ascii) + null terminator
+   *         pnm[1] 95:88
+   *         pnm[2] 87:80
+   *         pnm[3] 79:72
+   *         pnm[4] 71:64
+   */
+
+  decoded.pnm[1] =  cid[1] >> 24;
+  decoded.pnm[2] = (cid[1] >> 16) & 0xff;
+  decoded.pnm[3] = (cid[1] >> 8) & 0xff;
+  decoded.pnm[4] =  cid[1] & 0xff;
+  decoded.pnm[5] = '\0';
+
+  /* Word 3: Bits 32-63
+   *   prv -  63-56   8-bit Product revision
+   *   psn -  55-24  32-bit Product serial number
+   */
+
+  decoded.prv    = cid[2] >> 24;
+  decoded.psn    = cid[2] << 8;
+
+  /* Word 4: Bits 0-31
+   *   psn -  55-24  32-bit Product serial number
+   *          23-20   4-bit (reserved)
+   *   mdt -  19:8   12-bit Manufacturing date
+   *   crc -   7:1    7-bit CRC7
+   */
+
+  decoded.psn   |= cid[3] >> 24;
+  decoded.mdt    = (cid[3] >> 8) & 0x0fff;
+  decoded.crc    = (cid[3] >> 1) & 0x7f;
+
+  fvdbg("mid=%02x oid=%04x pnm=%s prv=%d psn=%d mdt=%02x crc=%02x\n",
+      priv->cid.mid, priv->cid.oid, priv->cid.pnm, priv->cid.prv,
+      priv->cid.psn, priv->cid.mdt, priv->cid.crc);
+}
+#endif
+
+/****************************************************************************
+ * Name: mmcsd_verifystandby
+ *
+ * Description:
+ *   Verify that the card is in standby state
+ *
+ ****************************************************************************/
+
+static int mmcsd_verifystandby(struct mmcsd_state_s *priv)
+{
+#warning "Not implemented"
+  return -ENOSYS;
+}
+
 /****************************************************************************
  * Transfer Helpers
  ****************************************************************************/
@@ -482,7 +664,89 @@ static int mmcsd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
 
 static inline int mmcsd_mmcinitialize(struct mmcsd_state_s *priv)
 {
-  return -ENOSYS;
+  uint32 cid[4];
+  uint32 csd[4];
+  int ret;
+
+  /* At this point, slow, ID mode clocking has been supplied to the card
+   * and CMD0 has been sent successfully. CMD1 succeeded and ACMD41 failed
+   * 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.
+   * 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
+   * ALL_SEND_CID is received. CMD2 causes transition to 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 MMC CID failed: %d\n", ret);
+      return ret;
+    }
+  mmcsd_decodecid(cid);
+
+  /* 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
+   */
+
+  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)
+    {
+      fdbg("ERROR: mmcsd_recvR1(CMD3) failed: %d\n", ret);
+      return ret;
+    }
+
+  /* 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 != 0)
+    {
+      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, 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)
+    {
+      fdbg("ERROR: Could not get SD CSD register: %d\n", ret);
+      return ret;
+    }
+  mmcsd_decodecsd(priv, csd);
+
+  fvdbg("Capacity: %dKb, Block size: %db, nblocks=%d\n",
+         priv->capacity / 1024, priv->rdblocklen, priv->nblocks);
+
+  /* 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 MMC clocking (which may depend on the DSR setting) */
+
+  SDIO_CLOCK(priv->dev, CLOCK_MMC_TRANSFER);
+  up_udelay( MMCSD_CLK_DELAY);
+
+  return OK;
 }
 
 /****************************************************************************
@@ -513,9 +777,7 @@ static inline int mmcsd_cardidentify(struct mmcsd_state_s *priv)
   uint32  response;
   uint32  start;
   uint32  elapsed;
-  uint32  state;
   uint32  sdcapacity = MMCD_ACMD41_STDCAPACITY;
-  boolean cardbusy;
   int     ret;
 
   /* Assume failure to identify the card */
@@ -595,79 +857,146 @@ static inline int mmcsd_cardidentify(struct mmcsd_state_s *priv)
   elapsed = 0;
   do
     {
-      /* Send CMD55 */
+      /* We may have already determined that his card is an MMC card from
+       * an earlier pass through through this loop.  In that case, we should
+       * skip the SD-specific commands.
+       */
 
-      mmcsd_sendcmdpoll(priv, SD_CMD55, 0);
-      ret = SDIO_RECVR1(priv->dev, SD_CMD55, &response);
-      if (ret != OK)
+      if (priv->type != MMCSD_CARDTYPE_MMC)
         {
-          /* If the error is a timeout, then it is an MMC card */
+          /* Send CMD55 */
 
-          if (ret == -ETIMEDOUT)
+          mmcsd_sendcmdpoll(priv, SD_CMD55, 0);
+          ret = mmcsd_recvR1(priv, SD_CMD55);
+          if (ret != OK)
             {
-              fvdbg("ERROR: CMD55 timeout, assuming MMC card\n");
-              priv->type = MMCSD_CARDTYPE_MMC;
-              break;        
+              /* I am a little confused.. I think both SD and MMC cards support
+               * CMD55 (but maybe only SD cards support CMD55).  We'll make the
+               * the MMC vs. SD decision based on CMD1 and ACMD41.
+               */
+
+              fdbg("ERROR: mmcsd_recvR1(CMD55) failed: %d\n", ret);
             }
           else
             {
-              fdbg("ERROR: CMD55 RECVR1: %d\n", ret);
-              return -EIO;
+              /* Send ACMD41 */
+
+              mmcsd_sendcmdpoll(priv, SD_ACMD41, MMCD_ACMD41_VOLTAGEWINDOW|sdcapacity);
+              ret = SDIO_RECVR3(priv->dev, SD_CMD55, &response);
+              if (ret != OK)
+                {
+                  /* If the error is a timeout, then it is probably an MMC card,
+                   * but we will make the decision based on CMD1 below
+                   */
+
+                  fdbg("ERROR: ACMD41 RECVR3: %d\n", ret);
+                }
+              else
+                {
+                  /* ACMD41 succeeded.  ACMD41 is supported by SD V1.x and SD V2.x,
+                   * but not MMC.  If we did not previously determine that this is
+                   * an SD V2.x (via CMD8), then this must be SD V1.x
+                   */
+
+                  if (priv->type == MMCSD_CARDTYPE_UNKNOWN)
+                    {
+                      fvdbg("SD V1.x card\n");
+                      priv->type = MMCSD_CARDTYPE_SDV1;
+                    }
+
+                  /* Check if the card is busy */
+
+                  if ((response &  MMCSD_CARD_BUSY) == 0)
+                    {
+                      /* No.. We really should check the current state to see if
+                       * the SD card successfully made it to the IDLE state, but
+                       * at least for now, we will simply assume that that is the
+                       * case.
+                       *
+                       * Now, check if this is a SD V2.x card that supports block
+                       * addressing
+                       */
+
+                      if ((response & MMCD_R3_HIGHCAPACITY) != 0)
+                        {
+                          fvdbg("SD V2.x card with block addressing\n");
+                          DEBUGASSERT(priv->type == MMCSD_CARDTYPE_SDV2);
+                          priv->type |= MMCSD_CARDTYPE_BLOCK;
+                        }
+
+                      /* And break out of the loop with an SD card identified */
+
+                      break;
+                    }
+                }
             }
         }
-      else
-        {
-          /* CMD55 succeeded.  CMD55 is supported by SD V1.x and SD V2.x,
-           * but not MMC.  If we did not previoulsy determine that this is
-           * an SD V2.x (via CMD8), then this must be SD V1.x
-           */
 
-          if (priv->type == MMCSD_CARDTYPE_UNKNOWN)
-            {
-              fvdbg("SD V1.x card\n");
-              priv->type = MMCSD_CARDTYPE_SDV1;
-            }
+      /* If we get here then either (1) CMD55 failed, (2) CMD41 failed, or (3)
+       * and SD or MMC card has been identified, but it is not yet in the IDLE state.
+       * If SD card has not been identified, then we might be looking at an
+       * MMC card.  We can send the CMD1 to find out for sure.  CMD1 is supported
+       * by MMC cards, but not by SD cards.
+       */
 
-          /* Save the state from CMD55 R1 response */
+      if (priv->type == MMCSD_CARDTYPE_UNKNOWN || priv->type == MMCSD_CARDTYPE_MMC)
+        {
+          /* Send the MMC CMD1 to specify the operating voltage. CMD1 causes
+           * transition to ready state/ card-identification mode.  NOTE: If the
+           * card does not support this voltage range, it will go the inactive
+           * state.
+           *
+           * NOTE: An MMC card will only respond once to CMD1 (unless it is busy).
+           * This is part of the logic used to determine how  many MMC cards are
+           * connected (This implementation supports only a single MMC card).  So
+           * we cannot re-send CMD1 without first placing the card back into
+           * stand-by state (if the card is busy, it will automatically
+           * go back to the the standby state).
+           */
 
-          state = response & MMCSD_R1_STATE_MASK;
-          fvdbg("CMD55 R1: %08x\n", response);
+          mmcsd_sendcmdpoll(priv, MMC_CMD1, MMCSD_VDD_33_34);
+          ret = SDIO_RECVR3(priv->dev, MMC_CMD1, &response);
 
-          /* Send ACMD41 */
+          /* Was the operating range set successfully */
 
-          mmcsd_sendcmdpoll(priv, SD_ACMD41, MMCD_ACMD41_VOLTAGEWINDOW|sdcapacity);
-          ret = SDIO_RECVR3(priv->dev, SD_CMD55, &response);
           if (ret != OK)
             {
-              fdbg("ERROR: ACMD41 RECVR1: %d\n", ret);
-              return -EIO;
+              fdbg("ERROR: CMD1 RECVR3: %d\n", ret);
             }
           else
             {
+              /* CMD1 succeeded... this must be an MMC card */
+
+              fdbg("CMD1 succeeded, assuming MMC card\n");
+              priv->type = MMCSD_CARDTYPE_MMC;
+
               /* Check if the card is busy */
 
-              cardbusy = ((response >> 31) == 1);
-              if (!cardbusy)
+              if ((response &  MMCSD_CARD_BUSY) == 0)
                 {
-                  /* Check if this is a SD V2.x card that supports block addressing */
-
-                  if ((response & MMCD_R3_HIGHCAPACITY) != 0)
-                    {
-                      fvdbg("SD V2.x card with block addressing\n");
-                      DEBUGASSERT(priv->type == MMCSD_CARDTYPE_SDV2);
-                      priv->type |= MMCSD_CARDTYPE_BLOCK;
-                    }
-                }
-            }
+                  /* NO.. We really should check the current state to see if the
+                   * MMC successfully made it to the IDLE state, but at least for now,
+                   * we will simply assume that that is the case.
+                   *
+                   * Then break out of the look with an MMC card identified
+                   */
+
+                  break;
+                }
+            }
         }
+
+      /* Check the elapsed time.  We won't keep trying this forever! */
+
       elapsed = g_system_timer - start;
     }
-  while (elapsed < TICK_PER_SEC && (ret != OK || state != MMCSD_R1_STATE_IDLE || cardbusy));
+  while (elapsed < TICK_PER_SEC && ret != OK);
 
-  /* We get here when the above loop completes, either (1) because this is 
-   * an MMC card, (2) we could not communicate properly with the card due to
-   * errors (and the loop times out), or (3) it is an SD card that has successfully
-   * transitioned to the IDLE state.
+  /* We get here when the above loop completes, either (1) we could not
+   * communicate properly with the card due to errors (and the loop times
+   * out), or (3) it is an MMC or SD card that has successfully transitioned
+   * to the IDLE state (well, at least, it provided its OCR saying that it
+   * it is no longer busy).
    */
 
   if (elapsed >= TICK_PER_SEC || priv->type == MMCSD_CARDTYPE_UNKNOWN)
diff --git a/drivers/mmcsd/mmcsd_sdio.h b/drivers/mmcsd/mmcsd_sdio.h
index 460360d3438f9de23660a557a37978f523576708..b6f618f005fc916774eaab574c5af8b47127bacb 100644
--- a/drivers/mmcsd/mmcsd_sdio.h
+++ b/drivers/mmcsd/mmcsd_sdio.h
@@ -103,7 +103,7 @@
 #define MMCSD_R1_READYFORDATA       (1 << 8)   /* Buffer empty */
 #define MMCSD_R1_APPCMD             (1 << 5)   /* Next CMD is ACMD */
 #define MMCSD_R1_AKESEQERROR        (1 << 3)   /* Authentication error */
-#define MMCSD_R1_ERRORMASK          0xfdff0008 /* Error mask */
+#define MMCSD_R1_ERRORMASK          0xfdffe008 /* Error mask */
 
 #define IS_STATE(v,s)               (((v)&MMCSD_R1_CURRENTSTATE_MASK)==(s))
 
@@ -153,6 +153,25 @@
  * Public Types
  ********************************************************************************************/
 
+/* Decoded CID register */
+
+struct mmcsd_cid_s
+{
+  ubyte  mid;       /* 127:120  8-bit Manufacturer ID */
+  uint16 oid;       /* 119:104 16-bit OEM/Application ID (ascii) */
+  ubyte  pnm[6];    /* 103:64  40-bit Product Name (ascii) + null terminator */
+  ubyte  prv;       /*  63:56   8-bit Product revision */
+  uint32 psn;       /*  55:24  32-bit Product serial number */
+                    /*  23:20   4-bit (reserved) */
+  uint16 mdt;       /*  19:8   12-bit Manufacturing date */
+  ubyte  crc;       /*   7:1    7-bit CRC7 */
+                    /*   0:0    1-bit (not used) */
+};
+
+/********************************************************************************************
+ * Public Data
+ ********************************************************************************************/
+
 #undef EXTERN
 #if defined(__cplusplus)
 #define EXTERN extern "C"
diff --git a/include/nuttx/sdio.h b/include/nuttx/sdio.h
index 5255e69a5aae7c53260b93cd0aea3a49bb3974f1..0e4d77c62ee057f1de36c4c5a8937e81732dd3fd 100755
--- a/include/nuttx/sdio.h
+++ b/include/nuttx/sdio.h
@@ -712,10 +712,8 @@ enum sdio_clock_e
 {
   CLOCK_SDIO_DISABLED = 0, /* Clock is disabled */
   CLOCK_IDMODE,            /* Initial ID mode clocking (<400KHz) */
-  CLOCK_MMC_SLOW,          /* MMC initialization clocking */
-  CLOCK_SD_SLOW,           /* SD initialization clocking */
-  CLOCK_MMC_FAST,          /* MMC normal operation clocking */
-  CLOCK_SD_FAST            /* SD normal operation clocking */
+  CLOCK_MMC_TRANSFER,      /* MMC normal operation clocking */
+  CLOCK_SD_TRANSFER        /* SD normal operation clocking */
 };
 
 /* This structure defines the interface between the NuttX MMC/SD