This is an automated email from the ASF dual-hosted git repository.

davids5 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 50a8ec62c4 Add eMMC driver support
50a8ec62c4 is described below

commit 50a8ec62c45dc12512cbbd5dce7f1e885b003849
Author: Radek Pesina <[email protected]>
AuthorDate: Wed Mar 29 11:04:50 2023 +1100

    Add eMMC driver support
    
    - Fix DMA addressing issues within litex_sendsetup/litex_recvsetup
    - Extend with handling specific to eMMC commands during init & use.
    - Cleanup of 4-bit BUS handling for SD and eMMC
    - For eMMC, Send CMD0 during init as per JEDEC v4.41 for pre-idle
---
 arch/risc-v/src/litex/litex_sdio.c                 |   8 +-
 boards/risc-v/litex/arty_a7/Kconfig                |  38 ++++
 .../risc-v/litex/arty_a7/configs/sdmmc/defconfig   |  75 ++++++++
 drivers/mmcsd/mmcsd_sdio.c                         | 200 ++++++++++++++++++---
 drivers/mmcsd/mmcsd_sdio.h                         |  26 +++
 5 files changed, 316 insertions(+), 31 deletions(-)

diff --git a/arch/risc-v/src/litex/litex_sdio.c 
b/arch/risc-v/src/litex/litex_sdio.c
index 13359662a3..eec66ed295 100644
--- a/arch/risc-v/src/litex/litex_sdio.c
+++ b/arch/risc-v/src/litex/litex_sdio.c
@@ -860,10 +860,12 @@ static int litex_recvsetup(struct sdio_dev_s *dev, 
uint8_t *buffer,
 
   /* flush CPU d-cache */
 
+#ifndef CONFIG_LITEX_COHERENT_DMA
   up_invalidate_dcache_all();
+#endif
 
   putreg32(0, LITEX_SDBLOCK2MEM_DMA_ENABLE);
-  putreg32((uintptr_t)buffer >> 32, LITEX_SDBLOCK2MEM_DMA_BASE);
+  putreg32((uintptr_t)(&buffer[4]), LITEX_SDBLOCK2MEM_DMA_BASE);
   putreg32((uintptr_t)buffer, LITEX_SDBLOCK2MEM_DMA_BASE + 0x04);
   putreg32(nbytes, LITEX_SDBLOCK2MEM_DMA_LENGTH);
   putreg32(1, LITEX_SDBLOCK2MEM_DMA_ENABLE);
@@ -903,10 +905,12 @@ static int litex_sendsetup(struct sdio_dev_s *dev,
 
   /* flush CPU d-cache */
 
+#ifndef CONFIG_LITEX_COHERENT_DMA
   up_invalidate_dcache_all();
+#endif
 
   putreg32(0, LITEX_SDMEM2BLOCK_DMA_ENABLE);
-  putreg32((uintptr_t)buffer >> 32, LITEX_SDMEM2BLOCK_DMA_BASE);
+  putreg32((uintptr_t)(&buffer[4]), LITEX_SDMEM2BLOCK_DMA_BASE);
   putreg32((uintptr_t)buffer, LITEX_SDMEM2BLOCK_DMA_BASE + 0x04);
   putreg32(nbytes, LITEX_SDMEM2BLOCK_DMA_LENGTH);
   putreg32(1, LITEX_SDMEM2BLOCK_DMA_ENABLE);
diff --git a/boards/risc-v/litex/arty_a7/Kconfig 
b/boards/risc-v/litex/arty_a7/Kconfig
index 92df0ad54c..b64aa2d566 100644
--- a/boards/risc-v/litex/arty_a7/Kconfig
+++ b/boards/risc-v/litex/arty_a7/Kconfig
@@ -5,6 +5,44 @@
 
 if ARCH_BOARD_ARTY_A7
 
+
+config LITEX_SDIO
+       bool "SDIO"
+       default n
+       select SCHED_HPWORK
+       select MMCSD
+       select MMCSD_SDIO
+       select SDIO_BLOCKSETUP
+       select ARCH_HAVE_SDIO
+       select SDIO_DMA
+
+config LITEX_SDIO1
+       bool "Enable SDIO1"
+       default y if LITEX_SDIO
+       select LITEX_SDIO_DMA
+       depends on LITEX_SDIO
+
+config LITEX_IDMODE_FREQ
+       int "ID mode frequency"
+       default 400000
+       depends on LITEX_SDIO
+       ---help---
+               Initial, ID mode SD frequency
+
+config LITEX_MMCXFR_FREQ
+       int "MMC transfer frequency"
+       default 25000000
+       depends on LITEX_SDIO
+       ---help---
+               Frequency to use for transferring data to/from an MMC card
+
+config LITEX_SD4BIT_FREQ
+       int "SD 4-bit transfer frequency"
+       default 50000000
+       depends on LITEX_SDIO
+       ---help---
+               Frequency to use for transferring data to/from an SD card using 
all four data lines.
+
 config LITEX_SDIO_MOUNT
        bool "Mount SDIO at startup"
        default n
diff --git a/boards/risc-v/litex/arty_a7/configs/sdmmc/defconfig 
b/boards/risc-v/litex/arty_a7/configs/sdmmc/defconfig
new file mode 100644
index 0000000000..3b4d385526
--- /dev/null
+++ b/boards/risc-v/litex/arty_a7/configs/sdmmc/defconfig
@@ -0,0 +1,75 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed 
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that 
includes your
+# modifications.
+#
+# CONFIG_DISABLE_PTHREAD is not set
+# CONFIG_FS_PROCFS_EXCLUDE_BLOCKS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_ENVIRON is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MEMDUMP is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MEMINFO is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MOUNT is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MOUNTS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set
+# CONFIG_FS_PROCFS_EXCLUDE_USAGE is not set
+# CONFIG_FS_PROCFS_EXCLUDE_VERSION is not set
+# CONFIG_NSH_DISABLEBG is not set
+# CONFIG_NSH_DISABLE_LOSMART is not set
+# CONFIG_NSH_DISABLE_UNAME is not set
+# CONFIG_STANDARD_SERIAL is not set
+CONFIG_ARCH="risc-v"
+CONFIG_ARCH_BOARD="arty_a7"
+CONFIG_ARCH_BOARD_ARTY_A7=y
+CONFIG_ARCH_CHIP="litex"
+CONFIG_ARCH_CHIP_LITEX=y
+CONFIG_ARCH_INTERRUPTSTACK=8192
+CONFIG_ARCH_RISCV=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BINFMT_DISABLE=y
+CONFIG_BOARD_LOOPSPERMSEC=10000
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_SMALL=y
+CONFIG_DEV_ZERO=y
+CONFIG_EXAMPLES_HELLO=y
+CONFIG_EXAMPLES_HELLO_STACKSIZE=8192
+CONFIG_FAT_DMAMEMORY=y
+CONFIG_FAT_FORCE_INDIRECT=y
+CONFIG_FAT_LFN=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FATTIME=y
+CONFIG_FS_PROCFS=y
+CONFIG_GRAN=y
+CONFIG_IDLETHREAD_STACKSIZE=8192
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_STACKSIZE=8192
+CONFIG_INTELHEX_BINARY=y
+CONFIG_LIBC_PERROR_STDOUT=y
+CONFIG_LIBC_STRERROR=y
+CONFIG_LITEX_SDIO=y
+CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=64
+CONFIG_NSH_STRERROR=y
+CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE=8192
+CONFIG_PTHREAD_STACK_DEFAULT=8192
+CONFIG_RAM_SIZE=268435456
+CONFIG_RAM_START=0x40000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_STACK_COLORATION=y
+CONFIG_START_DAY=20
+CONFIG_START_MONTH=3
+CONFIG_START_YEAR=2020
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=12
+CONFIG_TESTING_GETPRIME=y
+CONFIG_UART0_RXBUFSIZE=128
+CONFIG_UART0_SERIAL_CONSOLE=y
+CONFIG_UART0_TXBUFSIZE=128
diff --git a/drivers/mmcsd/mmcsd_sdio.c b/drivers/mmcsd/mmcsd_sdio.c
index 5465ab781e..8569ee6d86 100644
--- a/drivers/mmcsd/mmcsd_sdio.c
+++ b/drivers/mmcsd/mmcsd_sdio.c
@@ -355,6 +355,7 @@ static inline int mmcsd_sendcmd4(FAR struct mmcsd_state_s 
*priv)
 
   if (priv->dsrimp != false)
     {
+      finfo("Card supports DSR - send DSR.\n");
       /* 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
@@ -369,6 +370,10 @@ static inline int mmcsd_sendcmd4(FAR struct mmcsd_state_s 
*priv)
       mmcsd_sendcmdpoll(priv, MMCSD_CMD4, CONFIG_MMCSD_DSR << 16);
       nxsig_usleep(MMCSD_DSR_DELAY);
     }
+  else
+    {
+      finfo("Card does not support DSR.\n");
+    }
 #endif
 
   return ret;
@@ -2472,9 +2477,14 @@ static int mmcsd_widebus(FAR struct mmcsd_state_s *priv)
    * SCR or in the SDIO driver capabililities)
    */
 
-  if ((priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0 &&
+  if (IS_SD(priv->type) &&
+      (priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0 &&
       (priv->caps & SDIO_CAPS_1BIT_ONLY) == 0)
     {
+      /* SD card supports 4-bit BUS and host settings is not 1-bit only. */
+
+      finfo("Setting SD BUS width to 4-bit. Card type: %d\n", priv->type);
+
       /* Disconnect any CD/DAT3 pull up using ACMD42.  ACMD42 is optional and
        * need not be supported by all SD calls.
        *
@@ -2504,7 +2514,7 @@ static int mmcsd_widebus(FAR struct mmcsd_state_s *priv)
           return ret;
         }
 
-      /* Now send ACMD6 to select wide, 4-bit bus operation, beginning
+      /* Now send ACMD6 to select bus width operation, beginning
        * with CMD55, APP_CMD:
        */
 
@@ -2519,27 +2529,82 @@ static int mmcsd_widebus(FAR struct mmcsd_state_s *priv)
       /* Then send ACMD6 */
 
       mmcsd_sendcmdpoll(priv, SD_ACMD6, MMCSD_ACMD6_BUSWIDTH_4);
+
       ret = mmcsd_recv_r1(priv, SD_ACMD6);
       if (ret != OK)
         {
           return ret;
         }
+    }
+#ifdef CONFIG_MMCSD_MMCSUPPORT
+  else if (IS_MMC(priv->type) &&
+           ((priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0 &&
+           (priv->caps & SDIO_CAPS_1BIT_ONLY) == 0))
+    {
+      /* SD card supports 4-bit BUS and host settings is not 1-bit only.
+       * Configuring MMC - Use MMC_SWITCH access modes.
+       */
 
-      /* Configure the SDIO peripheral */
+      uint32_t arg = MMCSD_CMD6_MODE_WRITE_BYTE | MMCSD_CMD6_BUSWIDTH_RW;
 
-      finfo("Wide bus operation selected\n");
-      SDIO_WIDEBUS(priv->dev, true);
-      priv->widebus = true;
+      arg |= MMCSD_CMD6_BUS_WIDTH_4;
 
-      SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_4BIT);
+      mmcsd_sendcmdpoll(priv, MMCSD_CMD6, arg);
+      ret = mmcsd_recv_r1(priv, MMCSD_CMD6);
+
+      if (ret != OK)
+        {
+          ferr("ERROR: (MMCSD_CMD6) Setting MMC BUS width: %d\n", ret);
+          return ret;
+        }
+    }
+#endif /* #ifdef CONFIG_MMCSD_MMCSUPPORT */
+  else
+    {
+      fwarn("No card inserted.\n");
+      SDIO_WIDEBUS(priv->dev, false);
+      priv->widebus = false;
+      SDIO_CLOCK(priv->dev, CLOCK_SDIO_DISABLED);
       nxsig_usleep(MMCSD_CLK_DELAY);
+
       return OK;
     }
 
-  /* Wide bus operation not supported */
+  /* Configure the SDIO peripheral */
 
-  fwarn("WARNING: Card does not support wide-bus operation\n");
-  return -ENOSYS;
+  if ((priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0)
+    {
+      finfo("Wide bus operation selected\n");
+      SDIO_WIDEBUS(priv->dev, true);
+      priv->widebus = true;
+    }
+  else
+    {
+      finfo("Narrow bus operation selected\n");
+      SDIO_WIDEBUS(priv->dev, false);
+      priv->widebus = false;
+    }
+
+  if (IS_SD(priv->type))
+    {
+      if ((priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0)
+        {
+          SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_4BIT);
+        }
+      else
+        {
+          SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_1BIT);
+        }
+    }
+#ifdef CONFIG_MMCSD_MMCSUPPORT
+  else
+    {
+      SDIO_CLOCK(priv->dev, CLOCK_MMC_TRANSFER);
+    }
+#endif /* #ifdef CONFIG_MMCSD_MMCSUPPORT */
+
+  nxsig_usleep(MMCSD_CLK_DELAY);
+  return OK;
 }
 
 /****************************************************************************
@@ -2571,6 +2636,8 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s 
*priv)
    * identification state / card-identification mode.
    */
 
+  finfo("Initialising MMC card.\n");
+
   mmcsd_sendcmdpoll(priv, MMCSD_CMD2, 0);
   ret = SDIO_RECVR2(priv->dev, MMCSD_CMD2, cid);
   if (ret != OK)
@@ -2587,7 +2654,7 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s 
*priv)
    */
 
   priv->rca = 1;  /* There is only one card */
-  mmcsd_sendcmdpoll(priv, MMC_CMD3, priv->rca << 16);
+  mmcsd_sendcmdpoll(priv, MMC_CMD3, (uint32_t)priv->rca << 16);
   ret = mmcsd_recv_r1(priv, MMC_CMD3);
   if (ret != OK)
     {
@@ -2597,8 +2664,8 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s 
*priv)
 
   /* This should have caused a transition to standby state. However, this
    * will not be reflected in the present R1/6 status.  R1/6 contains the
-   * state of the card when the command was received, not when it completed
-   * execution.
+   * state of the card when the command was received, not when it
+   * completed execution.
    *
    * Verify that we are in standby state/data-transfer mode
    */
@@ -2612,10 +2679,18 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s 
*priv)
 
   /* 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 standby state/data-transfer mode)
+   * capacity, etc. (Stays in standby state/data-transfer mode).
+   * NOTE in v2.0 high capacity cards, the following values are always
+   * returned:
+   *  - write block length = 9 = 2^9 = 512
+   *  - read block length = 9 = 512
+   *  - rw2 factor = 0x2 (010b)
+   *  - size_mult = 0
+   * We can't decode the CSD register yet as we also need to read the
+   * extended CSD register.
    */
 
-  mmcsd_sendcmdpoll(priv, MMCSD_CMD9, priv->rca << 16);
+  mmcsd_sendcmdpoll(priv, MMCSD_CMD9, (uint32_t) priv->rca << 16);
   ret = SDIO_RECVR2(priv->dev, MMCSD_CMD9, csd);
   if (ret != OK)
     {
@@ -2623,6 +2698,13 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s 
*priv)
       return ret;
     }
 
+  /* Decode the CSD register to obtain version.  We will need to
+   * decode further if card is v4.0 or higher as it supports
+   * ext_csd commands.
+   */
+
+  mmcsd_decode_csd(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.
@@ -2630,7 +2712,8 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s 
*priv)
 
   mmcsd_sendcmd4(priv);
 
-  /* Send CMD7 with the argument == RCA in order to select the card
+  /* Select the card.
+   * Send CMD7 with the argument == RCA in order to select the card
    * and send it in data-trasfer mode. Since we are supporting
    * only a single card, we just leave the card selected all of the time.
    */
@@ -2643,14 +2726,33 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s 
*priv)
       return ret;
     }
 
+  /* If the hardware only supports 4-bit transfer mode then we forced to
+   * attempt to setup the card in this mode before checking the ext CSD
+   * register.
+   */
+
+  if ((priv->caps & SDIO_CAPS_4BIT_ONLY) != 0)
+    {
+      /* Select width (4-bit) bus operation */
+
+      priv->buswidth = MMCSD_SCR_BUSWIDTH_4BIT;
+      ret = mmcsd_widebus(priv);
+
+      if (ret != OK)
+        {
+          ferr("ERROR: Failed to set wide bus operation: %d\n", ret);
+        }
+    }
+
   /* CSD Decoding for MMC should be done after entering in data-transfer mode
    * because if the card has block addressing then extended CSD register
    * must be read in order to get the right number of blocks and capacity,
-   * but it has to be done in data-transfer mode.
+   * and BUS width but it has to be done in data-transfer mode.
    */
 
   if (IS_BLOCK(priv->type))
     {
+      finfo("Card supports eMMC spec 4.0 (or greater). Reading ext_csd.\n");
       ret = mmcsd_read_csd(priv);
       if (ret != OK)
         {
@@ -2661,10 +2763,17 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s 
*priv)
 
   mmcsd_decode_csd(priv, csd);
 
-  /* Select high speed MMC clocking (which may depend on the DSR setting) */
+  if ((priv->caps & SDIO_CAPS_4BIT_ONLY) != 0)
+    {
+      /* Select width (4-bit) bus operation (if the card supports it) */
+
+      ret = mmcsd_widebus(priv);
+      if (ret != OK)
+        {
+          ferr("ERROR: Failed to set wide bus operation: %d\n", ret);
+        }
+    }
 
-  SDIO_CLOCK(priv->dev, CLOCK_MMC_TRANSFER);
-  nxsig_usleep(MMCSD_CLK_DELAY);
   return OK;
 }
 
@@ -2698,6 +2807,7 @@ static int mmcsd_read_csd(FAR struct mmcsd_state_s *priv)
   memset(buffer, 0, sizeof(buffer));
 
 #if defined(CONFIG_SDIO_DMA) && defined(CONFIG_ARCH_HAVE_SDIO_PREFLIGHT)
+
   /* If we think we are going to perform a DMA transfer, make sure that we
    * will be able to before we commit the card to the operation.
    */
@@ -2726,7 +2836,7 @@ static int mmcsd_read_csd(FAR struct mmcsd_state_s *priv)
       return ret;
     }
 
-  /* Select the block size for the card */
+  /* Select the block size for the card (CMD16) */
 
   ret = mmcsd_setblocklen(priv, 512);
   if (ret != OK)
@@ -2745,6 +2855,7 @@ static int mmcsd_read_csd(FAR struct mmcsd_state_s *priv)
 #ifdef CONFIG_SDIO_DMA
   if ((priv->caps & SDIO_CAPS_DMASUPPORTED) != 0)
     {
+      finfo("Setting up for DMA transfer.\n");
       ret = SDIO_DMARECVSETUP(priv->dev, buffer, 512);
       if (ret != OK)
         {
@@ -3274,8 +3385,9 @@ static int mmcsd_sdinitialize(FAR struct mmcsd_state_s 
*priv)
     {
       /* Select width (4-bit) bus operation */
 
-      priv->buswidth = 4;
+      priv->buswidth = MMCSD_SCR_BUSWIDTH_4BIT;
       ret = mmcsd_widebus(priv);
+
       if (ret != OK)
         {
           ferr("ERROR: Failed to set wide bus operation: %d\n", ret);
@@ -3296,7 +3408,7 @@ static int mmcsd_sdinitialize(FAR struct mmcsd_state_s 
*priv)
 
   mmcsd_decode_scr(priv, scr);
 
-  if ((priv->caps & SDIO_CAPS_4BIT_ONLY) == 0)
+  if ((priv->caps & SDIO_CAPS_4BIT_ONLY) != 0)
     {
       /* Select width (4-bit) bus operation (if the card supports it) */
 
@@ -3335,6 +3447,8 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s 
*priv)
   clock_t elapsed;
   int ret;
 
+  finfo("Identifying card...\n");
+
   /* Assume failure to identify the card */
 
   priv->type = MMCSD_CARDTYPE_UNKNOWN;
@@ -3349,6 +3463,13 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s 
*priv)
       return -ENODEV;
     }
 
+  /* For eMMC, Send CMD0 with argument 0xf0f0f0f0 as per JEDEC v4.41
+   * for pre-idle. No effect for SD.
+   */
+
+  mmcsd_sendcmdpoll(priv, MMCSD_CMD0, 0xf0f0f0f0);
+  nxsig_usleep(MMCSD_IDLE_DELAY);
+
   /* Set ID mode clocking (<400KHz) */
 
   SDIO_CLOCK(priv->dev, CLOCK_IDMODE);
@@ -3376,12 +3497,14 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s 
*priv)
 
   if (ret != OK)
     {
-      ferr("ERROR: CMD1 RECVR3: %d\n", ret);
+      fwarn("WARNING: CMD1 RECVR3: %d.  \
+             NOTE: This is expected for SD cards.\n", ret);
 
-      /* CMD1 did not succeed, card is not MMC. This sleep let
-       * the communication to recover before another send.
+      /* CMD1 did not succeed, card is not MMC. Return to idle
+       * to allow the communication to recover before another send.
        */
 
+      mmcsd_sendcmdpoll(priv, MMCSD_CMD0, 0);
       nxsig_usleep(MMCSD_IDLE_DELAY);
     }
   else
@@ -3471,7 +3594,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s 
*priv)
         }
     }
 
-  /* At this point, type is either UNKNOWN or SDV2.  Try sending
+  /* At this point, type is either UNKNOWN, eMMC or SDV2.  Try sending
    * CMD55 and (maybe) ACMD41 for up to 1 second or until the card
    * exits the IDLE state.  CMD55 is supported by SD V1.x and SD V2.x,
    * but not MMC
@@ -3481,7 +3604,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s 
*priv)
   elapsed = 0;
   do
     {
-      /* We may have already determined that his card is an MMC card from
+      /* We may have already determined that this card is an MMC card from
        * an earlier pass through this loop.  In that case, we should
        * skip the SD-specific commands.
        */
@@ -3602,6 +3725,8 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s 
*priv)
             {
               /* CMD1 succeeded... this must be an MMC card */
 
+              finfo("Confirmed MMC card present.\n");
+
               priv->type = MMCSD_CARDTYPE_MMC;
 
               /* Now, check if this is a MMC card/chip that supports block
@@ -3633,9 +3758,13 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s 
*priv)
                    * Then break out of the look with an MMC card identified
                    */
 
-                  finfo("MMC card/chip ready!\n");
+                  finfo("MMC card/chip is ready!\n");
                   break;
                 }
+              else
+                {
+                  finfo("MMC card/chip is busy.  Waiting for reply...\n");
+                }
             }
         }
 #endif
@@ -3708,6 +3837,8 @@ static int mmcsd_probe(FAR struct mmcsd_state_s *priv)
     {
       /* Yes.. probe it.  First, what kind of card was inserted? */
 
+      finfo("Card present.  Probing....\n");
+
       ret = mmcsd_cardidentify(priv);
       if (ret != OK)
         {
@@ -3722,24 +3853,33 @@ static int mmcsd_probe(FAR struct mmcsd_state_s *priv)
               /* Bit 1: SD version 1.x */
 
               case MMCSD_CARDTYPE_SDV1:
+                finfo("SD version 1.x .\n");
+                ret = mmcsd_sdinitialize(priv);
+                break;
 
               /* SD version 2.x with byte addressing */
 
               case MMCSD_CARDTYPE_SDV2:
+                finfo("SD version 2.x with byte addressing.\n");
+                ret = mmcsd_sdinitialize(priv);
+                break;
 
               /* SD version 2.x with block addressing */
 
               case MMCSD_CARDTYPE_SDV2 | MMCSD_CARDTYPE_BLOCK:
+                finfo("SD version 2.x with block addressing.\n");
                 ret = mmcsd_sdinitialize(priv);
                 break;
 
               /* MMC card with byte addressing */
 
               case MMCSD_CARDTYPE_MMC:
+                finfo("MMC card with byte addressing.\n");
 
               /* MMC card with block addressing */
 
               case MMCSD_CARDTYPE_MMC | MMCSD_CARDTYPE_BLOCK:
+                finfo("MMC card with block addressing.\n");
 #ifdef CONFIG_MMCSD_MMCSUPPORT
                 ret = mmcsd_mmcinitialize(priv);
                 break;
@@ -3824,8 +3964,10 @@ static int mmcsd_removed(FAR struct mmcsd_state_s *priv)
 
   /* Go back to the default 1-bit data bus. */
 
+  priv->buswidth     = MMCSD_SCR_BUSWIDTH_1BIT;
   SDIO_WIDEBUS(priv->dev, false);
   priv->widebus      = false;
+  mmcsd_widebus(priv);
 
   /* Disable clocking to the card */
 
diff --git a/drivers/mmcsd/mmcsd_sdio.h b/drivers/mmcsd/mmcsd_sdio.h
index 83e1c445c8..031a81a76d 100644
--- a/drivers/mmcsd/mmcsd_sdio.h
+++ b/drivers/mmcsd/mmcsd_sdio.h
@@ -32,6 +32,32 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
+/* CMD6 (MMC_SWITCH) argument
+ * MMC_SWITCH argument format:
+ *
+ *  [31:26] Always 0
+ *  [25:24] Access Mode
+ *  [23:16] Location of target Byte in EXT_CSD
+ *  [15:08] Value Byte
+ *  [07:03] Always 0
+ *  [02:00] Command Set
+ */
+#define MMCSD_CMD6_BUSWIDTH_RWSHIFT   (16)
+#  define MMCSD_CMD6_BUSWIDTH_RW      ((uint32_t)0xb7 << 
MMCSD_CMD6_BUSWIDTH_RWSHIFT)  /* R/W */
+
+#define MMCSD_CMD6_WRITE_BYTE_SHIFT   (24)
+#  define MMCSD_CMD6_MODE_CMD_SET     ((uint32_t)0x00 << 
MMCSD_CMD6_WRITE_BYTE_SHIFT)  /* Change the command set */
+#  define MMCSD_CMD6_MODE_SET_BITS    ((uint32_t)0x01 << 
MMCSD_CMD6_WRITE_BYTE_SHIFT)  /* Set bits which are 1 in value */
+#  define MMCSD_CMD6_MODE_CLEAR_BITS  ((uint32_t)0x02 << 
MMCSD_CMD6_WRITE_BYTE_SHIFT)  /* Clear bits which are 1 in value */
+#  define MMCSD_CMD6_MODE_WRITE_BYTE  ((uint32_t)0x03 << 
MMCSD_CMD6_WRITE_BYTE_SHIFT)  /* Set target to value */
+
+#define MMCSD_CMD6_BUS_WIDTH_SHIFT    (8)
+#  define MMCSD_CMD6_BUS_WIDTH_1      ((uint32_t)0x00 << 
MMCSD_CMD6_BUS_WIDTH_SHIFT)  /* Card is in 1 bit mode */
+#  define MMCSD_CMD6_BUS_WIDTH_4      ((uint32_t)0x01 << 
MMCSD_CMD6_BUS_WIDTH_SHIFT)  /* Card is in 4 bit mode */
+#  define MMCSD_CMD6_CSD_BUS_WIDTH_8  ((uint32_t)0x02 << 
MMCSD_CMD6_BUS_WIDTH_SHIFT)  /* Card is in 8 bit mode */
+#  define MMCSD_CMD6_DDR_BUS_WIDTH_4  ((uint32_t)0x05 << 
MMCSD_CMD6_BUS_WIDTH_SHIFT)  /* Card is in 4 bit DDR mode */
+#  define MMCSD_CMD6_DDR_BUS_WIDTH_8  ((uint32_t)0x06 << 
MMCSD_CMD6_BUS_WIDTH_SHIFT)  /* Card is in 8 bit DDR mode */
+
 /* CMD8 Argument:
  *    [31:12]: Reserved (shall be set to '0')
  *    [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)

Reply via email to