You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by bt...@apache.org on 2020/12/05 06:41:56 UTC

[incubator-nuttx] branch master updated: Added: MT29F2G Nand Flash block driver for sam4s-xplained-pro. Fixed: SDIO Interface hanging after inserted SD Card.

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6aba444  Added: MT29F2G Nand Flash block driver for sam4s-xplained-pro. Fixed: SDIO Interface hanging after inserted SD Card.
6aba444 is described below

commit 6aba444359bd0624263d6eae74941f1f6161a10e
Author: yjdwbj <yj...@gmail.com>
AuthorDate: Wed Dec 2 23:03:31 2020 +0800

    Added: MT29F2G Nand Flash block driver for sam4s-xplained-pro.
    Fixed: SDIO Interface hanging after inserted SD Card.
    
    Disabled the CONFIG_SYSTEMTICK_EXTCLK, using nxsig_usleep instead of usleep
---
 arch/arm/src/sam34/Kconfig                         |  11 +
 arch/arm/src/sam34/Make.defs                       |   4 +
 arch/arm/src/sam34/hardware/sam_matrix.h           |   8 +-
 arch/arm/src/sam34/sam4s_nand.c                    | 593 +++++++++++++++++++++
 arch/arm/src/sam34/sam4s_nand.h                    | 179 +++++++
 boards/arm/sam34/sam4s-xplained-pro/Kconfig        |  39 ++
 .../configs/{nsh => fs}/defconfig                  |  24 +-
 .../sam34/sam4s-xplained-pro/configs/nsh/defconfig |   8 +-
 .../arm/sam34/sam4s-xplained-pro/include/board.h   |  16 +
 boards/arm/sam34/sam4s-xplained-pro/src/Makefile   |  10 +
 .../sam4s-xplained-pro/src/sam4s-xplained-pro.h    |  42 +-
 .../arm/sam34/sam4s-xplained-pro/src/sam_appinit.c |  23 +
 .../sam34/sam4s-xplained-pro/src/sam_nandflash.c   | 245 +++++++++
 boards/arm/sam34/sam4s-xplained-pro/src/sam_spi.c  | 195 +++++++
 drivers/mmcsd/mmcsd_sdio.c                         |   5 +-
 drivers/mtd/mtd_nand.c                             |  35 +-
 drivers/mtd/mtd_onfi.c                             |  12 +-
 17 files changed, 1399 insertions(+), 50 deletions(-)

diff --git a/arch/arm/src/sam34/Kconfig b/arch/arm/src/sam34/Kconfig
index 8ea5bb9..62144d3 100644
--- a/arch/arm/src/sam34/Kconfig
+++ b/arch/arm/src/sam34/Kconfig
@@ -814,6 +814,17 @@ config SAM34_EXTNANDSIZE
 	default 0
 	---help---
 		Size of the external NAND in bytes.
+	config SAM34_HAVE_NAND
+	bool
+	default n
+
+config SAM34_NAND_DUMP
+	bool "NAND data dump"
+	default n
+	depends on DEBUG_FEATURES && DEBUG_FS
+	---help---
+		Dump the contents of all data read and written to FLASH.  Depends on
+		CONFIG_DEBUG_FEATURES and DEBUG_FS.
 
 endif # SAM34_EXTNAND
 
diff --git a/arch/arm/src/sam34/Make.defs b/arch/arm/src/sam34/Make.defs
index c131183..c53866a 100644
--- a/arch/arm/src/sam34/Make.defs
+++ b/arch/arm/src/sam34/Make.defs
@@ -149,6 +149,10 @@ ifeq ($(CONFIG_SAM34_HSMCI),y)
 CHIP_CSRCS += sam_hsmci.c
 endif
 
+ifeq ($(CONFIG_SAM34_EXTNAND),y)
+CHIP_CSRCS += sam4s_nand.c
+endif
+
 ifeq ($(CONFIG_SAM34_SPI0),y)
 CHIP_CSRCS += sam_spi.c
 else
diff --git a/arch/arm/src/sam34/hardware/sam_matrix.h b/arch/arm/src/sam34/hardware/sam_matrix.h
index 975803b..3ac4e4d 100644
--- a/arch/arm/src/sam34/hardware/sam_matrix.h
+++ b/arch/arm/src/sam34/hardware/sam_matrix.h
@@ -128,7 +128,7 @@
 
 /* MATRIX register addresses ************************************************************/
 
-#define SAM_MATRIX_MCFG(n))              (SAM_MATRIX_BASE+SAM_MATRIX_MCFG_OFFSET(n))
+#define SAM_MATRIX_MCFG(n)               (SAM_MATRIX_BASE+SAM_MATRIX_MCFG_OFFSET(n))
 #define SAM_MATRIX_MCFG0                 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG0_OFFSET)
 #define SAM_MATRIX_MCFG1                 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG1_OFFSET)
 #define SAM_MATRIX_MCFG2                 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG2_OFFSET)
@@ -200,6 +200,7 @@
 #define SAM_MATRIX_WPSR                  (SAM_MATRIX_BASE+SAM_MATRIX_WPSR_OFFSET)
 
 /* MATRIX register bit definitions ******************************************************/
+
 /* Master Configuration Registers */
 
 #define MATRIX_MCFG_ULBT_SHIFT           (0)       /* Bits 0-2:  Undefined Length Burst Type */
@@ -309,6 +310,7 @@
 /* SMC Chip Select NAND Flash Assignment Register */
 
 #if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E)
+#define MATRIX_CCFG_SMCNFCS_SMC_NFCS(n)  (1<<(n))  /* Bit n:  SMC NAND Flash Chip Select n Assignment */
 #  define MATRIX_CCFG_SMCNFCS_SMC_NFCS0  (1 << 0)  /* Bit 0:  SMC NAND Flash Chip Select 0 Assignment */
 #  define MATRIX_CCFG_SMCNFCS_SMC_NFCS1  (1 << 1)  /* Bit 1:  SMC NAND Flash Chip Select 2 Assignment */
 #  define MATRIX_CCFG_SMCNFCS_SMC_NFCS2  (1 << 2)  /* Bit 2:  SMC NAND Flash Chip Select 2 Assignment */
@@ -364,8 +366,4 @@
  * Public Data
  ****************************************************************************************/
 
-/****************************************************************************************
- * Public Functions
- ****************************************************************************************/
-
 #endif /* __ARCH_ARM_SRC_SAM34_HARDWARE_SAM_MATRIX_H */
diff --git a/arch/arm/src/sam34/sam4s_nand.c b/arch/arm/src/sam34/sam4s_nand.c
new file mode 100644
index 0000000..6a49f64
--- /dev/null
+++ b/arch/arm/src/sam34/sam4s_nand.c
@@ -0,0 +1,593 @@
+/****************************************************************************
+ * arch/arm/src/sam34/sam4s_nand.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/mtd/nand_config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/mtd/mtd.h>
+#include <nuttx/mtd/nand.h>
+#include <nuttx/mtd/nand_raw.h>
+#include <nuttx/mtd/nand_model.h>
+
+#include <nuttx/irq.h>
+#include <arch/board/board.h>
+#include "hardware/sam4s_pinmap.h"
+#include "arm_arch.h"
+#include "sam4s_nand.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Nand flash chip status codes */
+
+#define STATUS_ERROR         (1 << 0)
+#define STATUS_READY         (1 << 6)
+
+/* Number of tries for erasing or writing block */
+
+#define NAND_ERASE_NRETRIES  2
+#define NAND_WRITE_NRETRIES  2
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Low-level HSMC Helpers */
+
+#ifdef CONFIG_SAM34_NAND_DUMP
+#  define nand_dump(m,b,s) lib_dumpbuffer(m,b,s)
+#else
+#  define nand_dump(m,b,s)
+#endif
+
+/* Raw Data Transfer Helpers */
+
+static int      nand_write(struct sam_nandcs_s *priv, uint32_t rowaddr,
+                      uint32_t coladdr, uint8_t *buffer, uint16_t buflen,
+                      uint16_t offset);
+static int      nand_read(struct sam_nandcs_s *priv, uint32_t rowaddr,
+                     uint32_t coladdr, uint8_t *buffer, uint16_t buflen,
+                     uint16_t offset);
+
+/* MTD driver methods */
+
+static int      nand_eraseblock(struct nand_raw_s *raw, off_t block);
+static int      nand_rawread(struct nand_raw_s *raw, off_t block,
+                  unsigned int page, void *data, void *spare);
+static int      nand_rawwrite(struct nand_raw_s *raw, off_t block,
+                  unsigned int page, const void *data, const void *spare);
+
+/* Initialization */
+
+static void     nand_reset(struct sam_nandcs_s *priv);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* These pre-allocated structures hold the state of the MTD driver for NAND
+ * on CS0..3 as configured.
+ */
+
+#ifdef CONFIG_SAM34_NCS0_NAND
+static struct sam_nandcs_s g_cs0nand;
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void  nand_reset(struct sam_nandcs_s *priv)
+{
+  WRITE_COMMAND8(&priv->raw, COMMAND_RESET);
+
+  /* The device will be busy for a maximum of 1ms. */
+
+  up_mdelay(1);
+}
+
+/****************************************************************************
+ * Name: nand_wait_ready
+ *
+ * Description:
+ *   Waiting for the completion of a page program, erase and random read
+ *   completion.
+ *
+ * Input Parameters:
+ *   priv  Pointer to a sam_nandcs_s instance.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static int nand_wait_ready(struct sam_nandcs_s *priv)
+{
+  uint32_t timeout;
+  uint8_t status;
+  up_udelay(10);
+
+  /* The ready/busy (R/nB) signal of the NAND Flash  */
+
+  while (!sam_gpioread(priv->rb));
+  WRITE_COMMAND8(&priv->raw, COMMAND_STATUS);
+
+  /* Issue command */
+
+  timeout = 0;
+  while (timeout < MAX_READ_STATUS_COUNT)
+    {
+      /* Read status byte */
+
+      status = READ_DATA8(&priv->raw);
+
+      /* Check status. If status bit 6 = 1 device is ready */
+
+      if ((status & STATUS_READY) == STATUS_READY)
+        {
+          /* If status bit 0 = 0 the last operation was successful */
+
+          if ((status & STATUS_ERROR) == 0)
+            {
+              return OK;
+            }
+          else
+            {
+              return -EIO;
+            }
+        }
+
+      timeout++;
+    }
+
+  return -ETIMEDOUT;
+}
+
+/****************************************************************************
+ * Name: nand_eraseblock
+ *
+ * Description:
+ *   Erases the specified block of the device.
+ *
+ * Input Parameters:
+ *   raw    - Lower-half, raw NAND FLASH interface
+ *   block  - Number of the physical block to erase.
+ *
+ * Returned Value:
+ *   OK is returned in success; a negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+static inline int nand_tryeraseblock(struct sam_nandcs_s *priv, off_t block)
+{
+  uint32_t rowaddr;
+  int ret = OK;
+
+  /* Calculate address used for erase */
+
+  rowaddr = block * nandmodel_pagesperblock(&priv->raw.model);
+
+  WRITE_COMMAND8(&priv->raw, COMMAND_ERASE_1);
+  WRITE_ADDRESS8(&priv->raw, rowaddr);          /* 3rd cycle row addr */
+  WRITE_ADDRESS8(&priv->raw, rowaddr >> 8);     /* 4th cycle row addr */
+  WRITE_ADDRESS8(&priv->raw, rowaddr >> 16);    /* 5st cycle row addr */
+  WRITE_COMMAND8(&priv->raw, COMMAND_ERASE_2);
+
+  ret = nand_wait_ready(priv);
+  if (ret < 0)
+    {
+      ferr("ERROR: Block %d Could not erase: %d\n", block, ret);
+    }
+
+  return ret;
+}
+
+static int nand_eraseblock(struct nand_raw_s *raw, off_t block)
+{
+  struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw;
+  int retries = NAND_ERASE_NRETRIES;
+  int ret = OK;
+
+  DEBUGASSERT(priv);
+
+  finfo("block=%d\n", (int)block);
+
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  /* Try up to NAND_ERASE_NRETRIES times to erase the FLASH */
+
+  while (retries > 0)
+    {
+      ret = nand_tryeraseblock(priv, block);
+      if (ret == OK)
+        {
+          return OK;
+        }
+
+      retries--;
+    }
+
+  ferr("ERROR: Block %d Failed to erase after %d tries\n",
+       (int)block, NAND_ERASE_NRETRIES);
+
+  return -EAGAIN;
+}
+
+/****************************************************************************
+ * Name: nand_write
+ *
+ * Description:
+ *   Write data to NAND using the NAND data address.
+ *
+ * Input Parameters:
+ *   priv     - Lower-half, private NAND FLASH device state
+ *   buffer   - Buffer that provides the data for the write
+ *   offset   - Data offset in bytes
+ *
+ * Returned Value:
+ *   OK on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int nand_write(struct sam_nandcs_s *priv, uint32_t rowaddr,
+                      uint32_t coladdr, uint8_t *buffer,
+                      uint16_t buflen, uint16_t offset)
+{
+  uintptr_t dest;
+  int ret = OK;
+
+  nand_dump("NAND Write", buffer, buflen);
+
+  dest =  priv->raw.dataaddr + offset;
+
+  /* Apply the offset to the destination address */
+
+  WRITE_COMMAND8(&priv->raw, COMMAND_WRITE_1);
+  WRITE_ADDRESS8(&priv->raw, coladdr);         /* 1st cycle column addr */
+  WRITE_ADDRESS8(&priv->raw, coladdr >> 8);    /* 2nt cycle column addr */
+  WRITE_ADDRESS8(&priv->raw, rowaddr);         /* 3rd cycle row addr */
+  WRITE_ADDRESS8(&priv->raw, rowaddr >> 8);    /* 4th cycle row addr */
+  WRITE_ADDRESS8(&priv->raw, rowaddr >> 16);   /* 5st cycle row addr */
+
+  volatile uint8_t *dest8  = (volatile uint8_t *)dest;
+  for (; buflen > 0; buflen--)
+    {
+      *dest8 = *buffer++;
+    }
+
+  WRITE_COMMAND8(&priv->raw, COMMAND_WRITE_2);
+
+  ret = nand_wait_ready(priv);
+
+  return ret;
+}
+
+static int nand_read(struct sam_nandcs_s *priv, uint32_t rowaddr,
+                     uint32_t coladdr, uint8_t *buffer,
+                     uint16_t buflen, uint16_t offset)
+{
+  volatile uint8_t *src8  = (volatile uint8_t *)priv->raw.dataaddr + offset;
+  uint8_t *dest8 = (uint8_t *)buffer;
+  int remaining;
+  int ret = OK;
+
+  WRITE_COMMAND8(&priv->raw, COMMAND_READ_1);
+  WRITE_ADDRESS8(&priv->raw, coladdr);           /* 1st cycle column addr */
+  WRITE_ADDRESS8(&priv->raw, coladdr >> 8);      /* 2nt cycle column addr */
+  WRITE_ADDRESS8(&priv->raw, rowaddr);           /* 3rd cycle row addr */
+  WRITE_ADDRESS8(&priv->raw, rowaddr >> 8);      /* 4th cycle row addr */
+  WRITE_ADDRESS8(&priv->raw, rowaddr >> 16);     /* 5st cycle row addr */
+  WRITE_COMMAND8(&priv->raw, COMMAND_READ_2);
+  up_udelay(10);
+  while (!sam_gpioread(priv->rb));
+
+  remaining = buflen;
+  for (; remaining > 0; remaining--)
+    {
+      *dest8++ = *src8;
+    }
+
+  nand_dump("NAND Read", buffer, buflen);
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nand_rawread
+ *
+ * Description:
+ *   Reads the data and/or the spare areas of a page of a NAND FLASH into the
+ *   provided buffers.  This is a raw read of the flash contents.
+ *
+ * Input Parameters:
+ *   raw   - Lower-half, raw NAND FLASH interface
+ *   block - Number of the block where the page to read resides.
+ *   page  - Number of the page to read inside the given block.
+ *   data  - Buffer where the data area will be stored.
+ *   spare - Buffer where the spare area will be stored.
+ *
+ * Returned Value:
+ *   OK is returned in success; a negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+static int nand_rawread(struct nand_raw_s *raw, off_t block,
+                        unsigned int page, void *data, void *spare)
+{
+  struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw;
+  uint16_t pagesize;
+  uint16_t sparesize;
+  off_t rowaddr;
+  off_t coladdr;
+  int ret = OK;
+
+  DEBUGASSERT(priv && (data || spare));
+
+  /* Get page and spare sizes */
+
+  pagesize  = nandmodel_getpagesize(&priv->raw.model);
+  sparesize = nandmodel_getsparesize(&priv->raw.model);
+
+  /* Calculate actual address of the page */
+
+  rowaddr = block * nandmodel_pagesperblock(&priv->raw.model) + page;
+  coladdr = data ? 0 : pagesize;
+  fwarn("block=%d page=%d rowaddr=%d coladdr %d data=%p spare=%p\n",
+        (int)block, page, rowaddr, coladdr , data, spare);
+  coladdr = (coladdr >> 8) & 0x4 ? coladdr & 0x83f : coladdr;
+  if (data)
+    {
+      ret = nand_read(priv, rowaddr, coladdr, (uint8_t *)data, pagesize, 0);
+      if (ret < 0)
+        {
+          ferr("ERROR: nand_nfcsram_read for data region failed: %d\n", ret);
+          return ret;
+        }
+    }
+
+  if (spare)
+    {
+      uint16_t offset = data ? pagesize : 0;
+      ret = nand_read(priv, rowaddr, coladdr, (uint8_t *)spare, sparesize,
+                                                               offset);
+      if (ret < 0)
+        {
+          ferr("ERROR: nand_nfcsram_read for spare region failed: %d\n",
+               ret);
+          return ret;
+        }
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nand_rawwrite
+ *
+ * Description:
+ *   Writes the data and/or the spare area of a page on a NAND FLASH chip.
+ *   This is a raw write of the flash contents.
+ *
+ * Input Parameters:
+ *   raw   - Lower-half, raw NAND FLASH interface
+ *   block - Number of the block where the page to write resides.
+ *   page  - Number of the page to write inside the given block.
+ *   data  - Buffer containing the data to be writing
+ *   spare - Buffer containing the spare data to be written.
+ *
+ * Returned Value:
+ *   OK is returned in success; a negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+static int nand_rawwrite(struct nand_raw_s *raw, off_t block,
+                         unsigned int page, const void *data,
+                         const void *spare)
+{
+  struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw;
+  uint16_t pagesize;
+  uint16_t sparesize;
+  off_t rowaddr;
+  int ret = OK;
+
+  DEBUGASSERT(raw);
+  finfo("block=%d page=%d data=%p spare=%p\n",
+        (int)block, page, data, spare);
+
+  /* Get page and spare sizes */
+
+  pagesize  = nandmodel_getpagesize(&priv->raw.model);
+  sparesize = nandmodel_getsparesize(&priv->raw.model);
+
+  rowaddr = block * nandmodel_pagesperblock(&priv->raw.model) + page;
+
+  if (data)
+    {
+      ret = nand_write(priv, rowaddr, 0, (uint8_t *)data, pagesize, 0);
+      if (ret < 0)
+        {
+          ferr("ERROR: Failed writing data area: %d\n", ret);
+        }
+    }
+
+  if (spare)
+    {
+      ret = nand_write(priv, rowaddr, 0, (uint8_t *)spare, sparesize,
+                                                           pagesize);
+      if (ret < 0)
+        {
+          ferr("ERROR: Failed writing data spare: %d\n", ret);
+        }
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam_nand_initialize
+ *
+ * Description:
+ *   Create and initialize an raw NAND device instance.  This driver
+ *   implements the RAW NAND interface:  No software ECC or sparing is
+ *   performed here.  Those necessary NAND features are provided by common,
+ *   higher level NAND MTD layers found in drivers/mtd.
+ *
+ * Input Parameters:
+ *   cs - Chip select number (in the event that multiple NAND devices
+ *        are connected on-board).
+ *
+ * Returned Value:
+ *   On success a non-NULL pointer to an MTD device structure is returned;
+ *   NULL is returned on a failure.
+ *
+ ****************************************************************************/
+
+struct mtd_dev_s *sam_nand_initialize(int cs)
+{
+  struct sam_nandcs_s *priv;
+  struct mtd_dev_s *mtd;
+  uintptr_t cmdaddr;
+  uintptr_t addraddr;
+  uintptr_t dataaddr;
+  uint8_t ecctype;
+  int ret;
+
+  finfo("CS%d\n", cs);
+
+  if (SAM_SMCCS_BASE(cs) == SAM_SMC_CS0_BASE)
+    {
+      /* Refer to the pre-allocated NAND device structure */
+
+      priv = &g_cs0nand;
+
+      /* Set up the NAND addresses.  These must be provided in the board.h
+       * header file.
+       */
+
+      cmdaddr  = BOARD_NCS0_NAND_CMDADDR;
+      addraddr = BOARD_NCS0_NAND_ADDRADDR;
+      dataaddr = BOARD_NCS0_NAND_DATAADDR;
+
+      /* Pass on the configured ECC type */
+
+      ecctype = SAM34_NCS0_ECCTYPE;
+    }
+  else
+    {
+      ferr("ERROR: CS%d unsupported or invalid\n", cs);
+      return NULL;
+    }
+
+  /* Initialize the device structure */
+
+  memset(priv, 0, sizeof(struct sam_nandcs_s));
+  priv->raw.cmdaddr    = cmdaddr;
+  priv->raw.addraddr   = addraddr;
+  priv->raw.dataaddr   = dataaddr;
+  priv->raw.ecctype    = ecctype;
+  priv->raw.eraseblock = nand_eraseblock;
+  priv->raw.rawread    = nand_rawread;
+  priv->raw.rawwrite   = nand_rawwrite;
+
+  priv->cs             = cs;
+  priv->rb             = GPIO_SMC_RB;
+
+  /* Initialize the NAND hardware for this CS */
+
+  /**
+   * Note: The initialization is shown for the reference purpose only, and
+   * for other MCUs, refer to the Package and Pinout chapter of the
+   * respective data sheet.
+   *
+   * The I/O pin initialization for the 8-bit NAND is connected to the NCS0:
+   *
+   * To initialize the 8-bit D0-D7 data bus, configure the Port C, PC0 to
+   * PC7 in Peripheral-A mode
+   *
+   * To initialize the NANDOE,configure the Port C,PC9 in Peripheral-A mode
+   *
+   * To initialize the NANDWE,configure the Port C,PC10 in Peripheral-A mode
+   *
+   * To initialize the NANDCLE,configure the Port C,PC17 in Peripheral-A mode
+   *
+   * To initialize the NANDALE,configure the Port C,PC16 in Peripheral-A mode
+   *
+   * To initialize the R/nB, configure any PIO as an input pin with pull-up
+   * enabled
+   *
+   * To initialize the nCE, configure any PIO as an output pin (refer to Tips
+   * and Tricks for the supported nCE connection types)
+   **/
+
+  ret = board_nandflash_config(cs);
+  if (ret < 0)
+    {
+      ferr("ERROR: board_nandflash_config failed for CS%d: %d\n",
+           cs, ret);
+      return NULL;
+    }
+
+  /* Reset the NAND FLASH part */
+
+  nand_reset(priv);
+
+  /* Probe the NAND part.  On success, an MTD interface that wraps
+   * our raw NAND interface is returned.
+   **/
+
+  mtd = nand_initialize(&priv->raw);
+  if (!mtd)
+    {
+      ferr("ERROR: CS%d nand_initialize failed %d\n", cs);
+      return NULL;
+    }
+
+  /* Return the MTD wrapper interface as the MTD device */
+
+  return mtd;
+}
diff --git a/arch/arm/src/sam34/sam4s_nand.h b/arch/arm/src/sam34/sam4s_nand.h
new file mode 100644
index 0000000..253a664
--- /dev/null
+++ b/arch/arm/src/sam34/sam4s_nand.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+ * arch/arm/src/sam34/sam4s_nand.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAM4S_SAM_NAND_H
+#define __ARCH_ARM_SRC_SAM4S_SAM_NAND_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/mtd/nand_config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <debug.h>
+
+#include <nuttx/mtd/nand_raw.h>
+#include <nuttx/semaphore.h>
+
+#include "arm_arch.h"
+#include "chip.h"
+#include "sam_gpio.h"
+#include "hardware/sam_smc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Only NCS0 can support NAND.  The rest is a fantasy */
+
+#if defined(CONFIG_SAM34_EXTNAND)
+  # define CONFIG_SAM34_NCS0_NAND 1
+#else
+  # undef CONFIG_SAM34_NCS0_NAND
+#endif
+
+/* On-Die ECC, Requires Micron Flash to support on-die */
+
+#define SAM34_NCS0_ECCTYPE NANDECC_NONE
+
+#if defined(CONFIG_SAM34_NCS0_NAND)
+#  if defined(CONFIG_SAM34_NCS0_ECCNONE) ||\
+      defined(CONFIG_MTD_NAND_EMBEDDEDECC)
+#    define SAM34_NCS0_ECCTYPE NANDECC_NONE
+#  elif defined(CONFIG_MTD_NAND_SWECC)
+#    define SAM34_NCS0_ECCTYPE NANDECC_SWECC
+#  endif
+#endif /* CONFIG_SAM34_NCS0_NAND */
+
+/* Count the number of banks that configured for NAND with PMECC support
+ * enabled.
+ */
+
+#ifdef CONFIG_SAM34_NCS0_NAND
+#  define CONFIG_SAM34_HAVE_NAND 1
+#  define NAND_HAVE_NCS0 1
+#else
+#  define NAND_HAVE_NCS0 0
+#endif
+
+#define MAX_READ_STATUS_COUNT    100000 /* Read status timeout */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* This type represents the state of a raw NAND MTD device on a single chip
+ * select.  The struct nand_raw_s must appear at the beginning of the
+ * definition so that you can freely cast between pointers to struct
+ * nand_raw_s and struct sam_nandcs_s.
+ *
+ * NOTE: Currently, only SAM4S CS0 can support NAND.  The logic here would
+ * support NAND on any CS, but that capability is not needed.
+ */
+
+struct sam_nandcs_s
+{
+  struct nand_raw_s raw;     /* Externally visible part of the driver */
+
+  /* Static configuration */
+
+  uint8_t cs;                /* Chip select number (0..3) */
+  gpio_pinset_t rb;          /* NAND Ready/Busy detect GPIO pin */
+#endif
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/* NAND global state */
+
+EXTERN struct sam_nand_s g_nand;
+
+/****************************************************************************
+ * Name: sam_nand_initialize
+ *
+ * Description:
+ *   Create and initialize an raw NAND device instance.  This driver
+ *   implements the RAW NAND interface:  No software ECC or sparing is
+ *   performed here.  Those necessary NAND features are provided by common,
+ *   higher level NAND MTD layers found in drivers/mtd.
+ *
+ * Input Parameters:
+ *   cs - Chip select number (in the event that multiple NAND devices
+ *        are connected on-board).
+ *
+ * Returned Value:
+ *   On success a non-NULL pointer to an MTD device structure is returned;
+ *   NULL is returned on a failure.
+ *
+ ****************************************************************************/
+
+struct mtd_dev_s;
+struct mtd_dev_s *sam_nand_initialize(int cs);
+
+/****************************************************************************
+ * Name: board_nandflash_config
+ *
+ * Description:
+ *   If CONFIG_SAM34_BOOT_CS3FLASH is defined, then NAND FLASH support is
+ *   enabled.  This function provides the board-specific implementation of
+ *   the logic to reprogram the SMC to support NAND FLASH on the specified
+ *   CS.  As a minimum, this board-specific initialization should do the
+ *   following:
+ *
+ *     1. Enable clocking to the HSMC
+ *     2. Configure timing for the HSMC CS
+ *     3. Configure NAND PIO pins
+ *
+ * Input Parameters:
+ *   cs - Chip select number (in the event that multiple NAND devices
+ *        are connected on-board).
+ *
+ * Returned Value:
+ *   OK if the HSMC was successfully configured for this CS.  A negated
+ *   errno value is returned on a failure.  This would fail with -ENODEV,
+ *   for example, if the board does not support NAND FLASH on the requested
+ *   CS.
+ *
+ ****************************************************************************/
+
+int board_nandflash_config(int cs);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
diff --git a/boards/arm/sam34/sam4s-xplained-pro/Kconfig b/boards/arm/sam34/sam4s-xplained-pro/Kconfig
index 86a649d..f8150d2 100644
--- a/boards/arm/sam34/sam4s-xplained-pro/Kconfig
+++ b/boards/arm/sam34/sam4s-xplained-pro/Kconfig
@@ -20,4 +20,43 @@ config SAM4S_XPLAINED_PRO_CPULOAD_TIMER_DEVPATH
 	default "/dev/tc0"
 	depends on TIMER && SCHED_CPULOAD && SCHED_CPULOAD_EXTCLK
 
+config SAM34_NAND_BLOCKMOUNT
+	bool "NAND FLASH auto-mount"
+	default n
+	depends on NSH_ARCHINIT && SAM34_EXTNAND
+	---help---
+		Automatically initialize the NAND FLASH driver when NSH starts.
+
+choice
+	prompt "NAND FLASH configuration"
+	default SAM34_NAND_NXFFS
+	depends on SAM34_NAND_BLOCKMOUNT
+
+config SAM34_NAND_FTL
+	bool "Create NAND FLASH block driver"
+	depends on MTD && MTD_NAND
+	---help---
+		Create the MTD driver for the NAND and "wrap" the NAND as a standard
+		block driver that could then, for example, be mounted using FAT or
+		any other file system.  Any file system may be used, but there will
+		be no wear-leveling.
+
+		NOTE: This options is not currently recommended.  There is not now
+		NuttX file system that can handle the NAND back blocks or performs
+		wear-leveling other than NXFFS and NXFFS does not use a block driver
+		but, rather, operates directly upon the NAND MTD device.
+
+config SAM34_NAND_NXFFS
+	bool "Create NAND FLASH NXFFS file system"
+	depends on MTD && MTD_NAND && FS_NXFFS && NXFFS_NAND
+	---help---
+		Create the MTD driver for the NAND and mount the NAND device as
+		a wear-leveling, NuttX FLASH file system (NXFFS).  The downside of
+		NXFFS is that it can be very slow.
+
+		NOTE: NXFFS is recommended because (1) it can handle the NAND back
+		blocks and (1) performs wear-leveling.
+
+endchoice # NAND FLASH configuration
+
 endif
diff --git a/boards/arm/sam34/sam4s-xplained-pro/configs/nsh/defconfig b/boards/arm/sam34/sam4s-xplained-pro/configs/fs/defconfig
similarity index 85%
copy from boards/arm/sam34/sam4s-xplained-pro/configs/nsh/defconfig
copy to boards/arm/sam34/sam4s-xplained-pro/configs/fs/defconfig
index 35c2b36..c997be0 100644
--- a/boards/arm/sam34/sam4s-xplained-pro/configs/nsh/defconfig
+++ b/boards/arm/sam34/sam4s-xplained-pro/configs/fs/defconfig
@@ -6,6 +6,8 @@
 # modifications.
 #
 # CONFIG_ARCH_RAMFUNCS is not set
+# CONFIG_MTD_NAND_BLOCKCHECK is not set
+# CONFIG_MTD_NAND_SWECC is not set
 CONFIG_ARCH="arm"
 CONFIG_ARCH_BOARD="sam4s-xplained-pro"
 CONFIG_ARCH_BOARD_SAM4S_XPLAINED_PRO=y
@@ -15,12 +17,11 @@ CONFIG_ARCH_CHIP_SAM34=y
 CONFIG_ARCH_CHIP_SAM4S=y
 CONFIG_ARCH_INTERRUPTSTACK=1024
 CONFIG_ARCH_STACKDUMP=y
-CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT=y
 CONFIG_ARMV7M_USEBASEPRI=y
 CONFIG_ARM_MPU=y
 CONFIG_BOARDCTL_USBDEVCTRL=y
 CONFIG_BOARD_LATE_INITIALIZE=y
-CONFIG_BOARD_LOOPSPERMSEC=9186
+CONFIG_BOARD_LOOPSPERMSEC=11401
 CONFIG_BUILTIN=y
 CONFIG_CDCACM=y
 CONFIG_CDCACM_BULKIN_REQLEN=250
@@ -29,12 +30,6 @@ CONFIG_CDCACM_TXBUFSIZE=1024
 CONFIG_DEBUG_FULLOPT=y
 CONFIG_DEBUG_SYMBOLS=y
 CONFIG_DEV_ZERO=y
-CONFIG_DISABLE_ENVIRON=y
-CONFIG_EXAMPLES_CPUHOG=y
-CONFIG_EXAMPLES_SERIALBLASTER=y
-CONFIG_EXAMPLES_SERIALRX=y
-CONFIG_EXAMPLES_SERIALRX_BUFSIZE=4096
-CONFIG_EXAMPLES_SERIALRX_PRINTHEX=y
 CONFIG_FS_FAT=y
 CONFIG_FS_PROCFS=y
 CONFIG_HAVE_CXX=y
@@ -46,6 +41,14 @@ CONFIG_LIBC_STRERROR=y
 CONFIG_LIBC_STRERROR_SHORT=y
 CONFIG_MAX_TASKS=16
 CONFIG_MMCSD_SDIO=y
+CONFIG_MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_EMBEDDEDECC=y
+CONFIG_MTD_NAND_MAXNUMBLOCKS=2048
+CONFIG_MTD_NAND_MAXNUMPAGESPERBLOCK=64
+CONFIG_MTD_NAND_MAXPAGEDATASIZE=2048
+CONFIG_MTD_NAND_MAXPAGESPARESIZE=64
+CONFIG_MTD_NAND_MAXSPAREECCBYTES=64
 CONFIG_NSH_ARCHINIT=y
 CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_DISABLE_IFCONFIG=y
@@ -71,6 +74,7 @@ CONFIG_SAM34_EXTNANDSIZE=268435456
 CONFIG_SAM34_GPIOC_IRQ=y
 CONFIG_SAM34_GPIO_IRQ=y
 CONFIG_SAM34_HSMCI=y
+CONFIG_SAM34_NAND_BLOCKMOUNT=y
 CONFIG_SAM34_PDCA=y
 CONFIG_SAM34_RTC=y
 CONFIG_SAM34_RTT=y
@@ -81,15 +85,11 @@ CONFIG_SAM34_UART1=y
 CONFIG_SAM34_UDP=y
 CONFIG_SAM34_USART1=y
 CONFIG_SAM34_WDT=y
-CONFIG_SCHED_CPULOAD=y
-CONFIG_SCHED_CPULOAD_EXTCLK=y
-CONFIG_SCHED_CPULOAD_TICKSPERSEC=222
 CONFIG_SCHED_HPWORK=y
 CONFIG_SCHED_WAITPID=y
 CONFIG_SDCLONE_DISABLE=y
 CONFIG_SDIO_BLOCKSETUP=y
 CONFIG_STDIO_BUFFER_SIZE=256
-CONFIG_SYSTEMTICK_EXTCLK=y
 CONFIG_SYSTEM_NSH=y
 CONFIG_TASK_NAME_SIZE=15
 CONFIG_UART1_SERIAL_CONSOLE=y
diff --git a/boards/arm/sam34/sam4s-xplained-pro/configs/nsh/defconfig b/boards/arm/sam34/sam4s-xplained-pro/configs/nsh/defconfig
index 35c2b36..4e15807 100644
--- a/boards/arm/sam34/sam4s-xplained-pro/configs/nsh/defconfig
+++ b/boards/arm/sam34/sam4s-xplained-pro/configs/nsh/defconfig
@@ -15,12 +15,11 @@ CONFIG_ARCH_CHIP_SAM34=y
 CONFIG_ARCH_CHIP_SAM4S=y
 CONFIG_ARCH_INTERRUPTSTACK=1024
 CONFIG_ARCH_STACKDUMP=y
-CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT=y
 CONFIG_ARMV7M_USEBASEPRI=y
 CONFIG_ARM_MPU=y
 CONFIG_BOARDCTL_USBDEVCTRL=y
 CONFIG_BOARD_LATE_INITIALIZE=y
-CONFIG_BOARD_LOOPSPERMSEC=9186
+CONFIG_BOARD_LOOPSPERMSEC=11401
 CONFIG_BUILTIN=y
 CONFIG_CDCACM=y
 CONFIG_CDCACM_BULKIN_REQLEN=250
@@ -29,7 +28,6 @@ CONFIG_CDCACM_TXBUFSIZE=1024
 CONFIG_DEBUG_FULLOPT=y
 CONFIG_DEBUG_SYMBOLS=y
 CONFIG_DEV_ZERO=y
-CONFIG_DISABLE_ENVIRON=y
 CONFIG_EXAMPLES_CPUHOG=y
 CONFIG_EXAMPLES_SERIALBLASTER=y
 CONFIG_EXAMPLES_SERIALRX=y
@@ -81,15 +79,11 @@ CONFIG_SAM34_UART1=y
 CONFIG_SAM34_UDP=y
 CONFIG_SAM34_USART1=y
 CONFIG_SAM34_WDT=y
-CONFIG_SCHED_CPULOAD=y
-CONFIG_SCHED_CPULOAD_EXTCLK=y
-CONFIG_SCHED_CPULOAD_TICKSPERSEC=222
 CONFIG_SCHED_HPWORK=y
 CONFIG_SCHED_WAITPID=y
 CONFIG_SDCLONE_DISABLE=y
 CONFIG_SDIO_BLOCKSETUP=y
 CONFIG_STDIO_BUFFER_SIZE=256
-CONFIG_SYSTEMTICK_EXTCLK=y
 CONFIG_SYSTEM_NSH=y
 CONFIG_TASK_NAME_SIZE=15
 CONFIG_UART1_SERIAL_CONSOLE=y
diff --git a/boards/arm/sam34/sam4s-xplained-pro/include/board.h b/boards/arm/sam34/sam4s-xplained-pro/include/board.h
index d98c2e5..cf873e6 100644
--- a/boards/arm/sam34/sam4s-xplained-pro/include/board.h
+++ b/boards/arm/sam34/sam4s-xplained-pro/include/board.h
@@ -261,4 +261,20 @@
 
 #define BUTTON_SW0_BIT       (1 << BUTTON_SW0)
 
+/* NAND *********************************************************************/
+
+#define GPIO_SMC_RB   (GPIO_INPUT | GPIO_SMC_NWAIT)
+
+/* Address for transferring command bytes to the nandflash, CLE A22 */
+
+#define BOARD_NCS0_NAND_CMDADDR   0x60400000
+
+/* Address for transferring address bytes to the nandflash, ALE A21 */
+
+#define BOARD_NCS0_NAND_ADDRADDR  0x60200000
+
+/* Address for transferring data bytes to the nandflash. */
+
+#define BOARD_NCS0_NAND_DATAADDR  0x60000000
+
 #endif /* __BOARDS_ARM_SAM34_SAM4S_XPLAINED_PRO_INCLUDE_BOARD_H */
diff --git a/boards/arm/sam34/sam4s-xplained-pro/src/Makefile b/boards/arm/sam34/sam4s-xplained-pro/src/Makefile
index f2830ee..c31353c 100644
--- a/boards/arm/sam34/sam4s-xplained-pro/src/Makefile
+++ b/boards/arm/sam34/sam4s-xplained-pro/src/Makefile
@@ -37,10 +37,20 @@ include $(TOPDIR)/Make.defs
 
 CSRCS = sam_boot.c
 
+ifeq ($(CONFIG_MMCSD_SPI),y)
+CSRCS += sam_spi.c
+endif
+
 ifeq ($(CONFIG_LIB_BOARDCTL),y)
 CSRCS += sam_appinit.c
 endif
 
+ifeq ($(CONFIG_SAM34_EXTNAND),y)
+ifeq ($(CONFIG_MTD_NAND),y)
+CSRCS += sam_nandflash.c
+endif
+endif
+
 ifeq ($(CONFIG_SAM34_HSMCI),y)
 CSRCS += sam_hsmci.c
 endif
diff --git a/boards/arm/sam34/sam4s-xplained-pro/src/sam4s-xplained-pro.h b/boards/arm/sam34/sam4s-xplained-pro/src/sam4s-xplained-pro.h
index a4895d1..0437d54 100644
--- a/boards/arm/sam34/sam4s-xplained-pro/src/sam4s-xplained-pro.h
+++ b/boards/arm/sam34/sam4s-xplained-pro/src/sam4s-xplained-pro.h
@@ -60,8 +60,16 @@
 #define HAVE_HSMCI      1
 #define HAVE_PROC       1
 #define HAVE_USBDEV     1
+
+#if defined(CONFIG_MTD_NAND) && defined(CONFIG_SAM34_EXTNAND)
+#define HAVE_NAND       1
+#endif
 #undef  HAVE_USBMONITOR
 
+#if defined(CONFIG_MMCSD_SPI)
+# define HAVE_MMCSD_SPI 1
+#endif
+
 /* HSMCI */
 
 /* Can't support MMC/SD if the card interface is not enabled */
@@ -93,6 +101,16 @@
 #  undef HAVE_HSMCI
 #endif
 
+/* MMC/SD minor numbers */
+
+#ifndef CONFIG_NSH_MMCSDMINOR
+#  define CONFIG_NSH_MMCSDMINOR 0
+#endif
+
+#ifndef CONFIG_NSH_MMCSDSLOTNO
+#  define CONFIG_NSH_MMCSDSLOTNO 0
+#endif
+
 /* USB Device */
 
 /* CONFIG_SAM34_UDP and CONFIG_USBDEV must be defined, or there is no USB
@@ -173,11 +191,24 @@
  * Public data
  ****************************************************************************/
 
-#ifndef __ASSEMBLY__
+/* SPI0 */
 
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
+#ifdef HAVE_MMCSD_SPI
+#define GPIO_SPISD_NPCS0 (GPIO_OUTPUT | GPIO_CFG_PULLUP | GPIO_OUTPUT_SET | \
+                        GPIO_PORT_PIOA | GPIO_PIN11)
+#define SPISD_PORT      SPI0_CS0
+
+#define GPIO_SPI_CD   (GPIO_INPUT | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN19)
+#define SD_SPI_IRQ    SAM_IRQ_PC19
+#endif /* HAVE_MMCSD_SPI */
+
+/* NAND */
+
+#ifdef HAVE_NAND
+# define NAND_MINOR 0
+# define SAM_SMC_CS0 0 /* GPIO_SMC_NCS0  connect SAM_SMC_CS0_BASE */
+int sam_nand_automount(int minor);
+#endif /* HAVE_NAND */
 
 /****************************************************************************
  * Name: sam_hsmci_initialize
@@ -193,6 +224,8 @@ int sam_hsmci_initialize(void);
 # define sam_hsmci_initialize()
 #endif
 
+int sam_sdinitialize(int port, int minor);
+
 /****************************************************************************
  * Name: sam_cardinserted
  *
@@ -235,5 +268,4 @@ bool sam_writeprotected(int slotno);
 
 int sam_watchdog_initialize(void);
 
-#endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_ARM_SAM34_SAM4S_XPLAINED_SRC_SAM4S_XPLAINED_H */
diff --git a/boards/arm/sam34/sam4s-xplained-pro/src/sam_appinit.c b/boards/arm/sam34/sam4s-xplained-pro/src/sam_appinit.c
index 6253472..031590c 100644
--- a/boards/arm/sam34/sam4s-xplained-pro/src/sam_appinit.c
+++ b/boards/arm/sam34/sam4s-xplained-pro/src/sam_appinit.c
@@ -114,6 +114,17 @@ int board_app_initialize(uintptr_t arg)
     }
 #endif
 
+#ifdef HAVE_NAND
+  ret = sam_nand_automount(SAM_SMC_CS0);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR,
+             "ERROR: Failed to initialize the NAND: %d (%d)\n",
+             ret, errno);
+      return ret;
+    }
+#endif
+
 #ifdef HAVE_HSMCI
   /* Initialize the HSMCI driver */
 
@@ -157,6 +168,18 @@ int board_app_initialize(uintptr_t arg)
     }
 #endif
 
+  /* SPI */
+
+#ifdef HAVE_MMCSD_SPI
+  ret = sam_sdinitialize(0, 0);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize MMC/SD slot: %d\n",
+             ret);
+      return ret;
+    }
+#endif
+
 #ifdef HAVE_USBMONITOR
   /* Start the USB Monitor */
 
diff --git a/boards/arm/sam34/sam4s-xplained-pro/src/sam_nandflash.c b/boards/arm/sam34/sam4s-xplained-pro/src/sam_nandflash.c
new file mode 100644
index 0000000..0374369
--- /dev/null
+++ b/boards/arm/sam34/sam4s-xplained-pro/src/sam_nandflash.c
@@ -0,0 +1,245 @@
+/****************************************************************************
+ *  boards/arm/sam34/sam4s-xplained-pro/src/sam_nandflash.c
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.  The
+ *  ASF licenses this file to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance with the
+ *  License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ *  License for the specific language governing permissions and limitations
+ *  under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/mount.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/mtd/mtd.h>
+#include <nuttx/fs/nxffs.h>
+#include <arch/board/board.h>
+
+#include "arm_arch.h"
+#include "sam_periphclks.h"
+#include "sam4s_nand.h"
+#include "hardware/sam_smc.h"
+#include "hardware/sam4s_pinmap.h"
+#include "hardware/sam_matrix.h"
+
+#include "sam4s-xplained-pro.h"
+
+#ifdef  HAVE_NAND
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+static const gpio_pinset_t g_nandpins[] =
+{
+  GPIO_SMC_NCS0, GPIO_SMC_NANDALE, GPIO_SMC_NANDCLE,
+  GPIO_SMC_NANDOE, GPIO_SMC_NANDWE, GPIO_SMC_RB,
+
+  GPIO_SMC_D0,   GPIO_SMC_D1,  GPIO_SMC_D2,  GPIO_SMC_D3,
+  GPIO_SMC_D4,   GPIO_SMC_D5,  GPIO_SMC_D6,  GPIO_SMC_D7
+};
+
+#define NAND_NPINS (sizeof(g_nandpins) / sizeof(gpio_pinset_t))
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_nandflash_config
+ *
+ * Description:
+ *   If CONFIG_SAM34_EXTNAND is defined, then NAND FLASH support is
+ *   enabled.  This function provides the board-specific implementation of
+ *   the logic to reprogram the SMC to support NAND FLASH on the specified
+ *   CS.
+ *
+ * Input Parameters:
+ *   cs - Chip select number (in the event that multiple NAND devices
+ *        are connected on-board).
+ *
+ * Returned Value:
+ *   OK if the HSMC was successfully configured for this CS.  A negated
+ *   errno value is returned on a failure.  This would fail with -ENODEV,
+ *   for example, if the board does not support NAND FLASH on the requested
+ *   CS.
+ *
+ ****************************************************************************/
+
+int board_nandflash_config(int cs)
+{
+  /* The Embest and Ronetix CM boards and one Hynix NAND HY27UF(08/16)2G2B
+   * Series NAND (MT29F2G08ABAEAWP).
+   * This part has a capacity of 256Mx8bit () with spare 8Mx8 bit capacity.
+   * The device contains 2048 blocks, composed by 64 x 2112 byte pages.
+   * The effective size is approximately 256MiB.
+   *
+   * NAND is available on NCS0.
+   */
+
+  int i;
+
+  /* Configure GPIO pins (leaving SRAM in the disabled state) */
+
+  for (i = 0; i < NAND_NPINS; i++)
+    {
+      sam_configgpio(g_nandpins[i]);
+    }
+
+  /* SMC NAND Flash Chip Select Configuration Register */
+
+  putreg32(MATRIX_CCFG_SMCNFCS_SMC_NFCS(cs), SAM_MATRIX_CCFG_SMCNFCS);
+
+  /* below from sam4s-xplained */
+
+  sam_smc_enableclk();
+
+  /* Configure SMC setup timing */
+
+  putreg32(SMCCS_SETUP_NWESETUP(3) | SMCCS_SETUP_NCSWRSETUP(1) |
+           SMCCS_SETUP_NRDSETUP(2) | SMCCS_SETUP_NCSRDSETUP(1),
+           SAM_SMCCS_SETUP(cs));
+
+  /* Configure the SMC pulse timing */
+
+  putreg32(SMCCS_PULSE_NWEPULSE(5) | SMCCS_PULSE_NCSWRPULSE(5) |
+           SMCCS_PULSE_NRDPULSE(5) | SMCCS_PULSE_NCSRDPULSE(5),
+           SAM_SMCCS_PULSE(cs));
+
+  /* Configure the SMC cycle timing */
+
+  /**
+   * Select 0. Chip Select 0 has been programmed with:
+   * NRD_HOLD = 4; READ_MODE = 1 (NRD controlled)
+   * NWE_SETUP = 3; WRITE_MODE = 1 (NWE controlled)
+   * TDF_CYCLES = 6; TDF_MODE = 1 (optimization enabled).
+   */
+
+  putreg32(SMCCS_CYCLE_NWECYCLE(12) | SMCCS_CYCLE_NRDCYCLE(11),
+           SAM_SMCCS_CYCLE(cs));
+
+  /* Configure the SMC mode */
+
+  /**
+   *
+   * READ_MODE:
+   *    0: The read operation is controlled by the NCS signal.
+   *    1: The read operation is controlled by the NRD signal.
+   *
+   **/
+
+  putreg32(SMCCS_MODE_TDFCYCLES(6) | SMCCS_MODE_TDFMODE |
+           SMCCS_MODE_WRITEMODE | SMCCS_MODE_READMODE,
+           SAM_SMCCS_MODE(cs));
+
+  /* Configure NAND PIO pins
+   *
+   * NAND Interface  NAND     DESC
+   *
+   *   NCS0           CE    - Dedicated pin; no configuration needed
+   *   NANDCLE        CLE   - Dedicated pin; no configuration needed
+   *   NANDALE        ALE   - Dedicated pin; no configuration needed
+   *   NANDOE         RE    - Dedicated pin; no configuration needed
+   *   NANDWE         WE    - Dedicated pin; no configuration needed
+   *   NAND_RB        RB    - PC13
+   *   IO_D0-7        IO0-7 - Dedicated pins; no configuration needed
+   */
+
+  sam_configgpio(GPIO_SMC_NANDALE);
+  sam_configgpio(GPIO_SMC_NANDCLE);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: sam_nand_automount
+ *
+ * Description:
+ *   Initialize and configure the NAND on CS3
+ *
+ ****************************************************************************/
+
+int sam_nand_automount(int minor)
+{
+  FAR struct mtd_dev_s *mtd;
+  static bool initialized = false;
+
+  /* Have we already initialized? */
+
+  if (!initialized)
+    {
+      /* Create and initialize an NAND MATD device */
+
+      mtd = sam_nand_initialize(SAM_SMC_CS0);
+
+      if (!mtd)
+        {
+          ferr("ERROR: Failed to create the NAND driver on CS%d\n",
+                  SAM_SMC_CS0);
+          return -ENODEV;
+        }
+
+#if defined(CONFIG_SAM34_NAND_FTL)
+      /* Use the FTL layer to wrap the MTD driver as a block driver */
+
+      int ret = OK;
+      ret = ftl_initialize(NAND_MINOR, mtd);
+      if (ret < 0)
+        {
+          ferr("ERROR: Failed to initialize the FTL layer: %d\n", ret);
+          return ret;
+        }
+
+#elif defined(CONFIG_SAM34_NAND_NXFFS)
+      /* Initialize to provide NXFFS on the MTD interface */
+
+      int ret = OK;
+      ret = nxffs_initialize(mtd);
+      if (ret < 0)
+        {
+          ferr("ERROR: NXFFS initialization failed: %d\n", ret);
+          return ret;
+        }
+
+      /* Mount the file system at /mnt/nand */
+
+      ret = mount(NULL, "/mnt/nand", "nxffs", 0, NULL);
+      if (ret < 0)
+        {
+          ferr("ERROR: Failed to mount the NXFFS volume: %d\n", errno);
+          return ret;
+        }
+#endif
+
+      /* Now we are initialized */
+
+      initialized = true;
+    }
+
+  return OK;
+}
+
+#endif /* HAVE_NAND */
diff --git a/boards/arm/sam34/sam4s-xplained-pro/src/sam_spi.c b/boards/arm/sam34/sam4s-xplained-pro/src/sam_spi.c
new file mode 100644
index 0000000..73f44c5
--- /dev/null
+++ b/boards/arm/sam34/sam4s-xplained-pro/src/sam_spi.c
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * boards/arm/sam34/sam4s-xplained-pro/src/sam_spi.c
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.  The
+ *  ASF licenses this file to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance with the
+ *  License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ *  License for the specific language governing permissions and limitations
+ *  under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/spi/spi.h>
+#include <arch/board/board.h>
+
+#include "arm_arch.h"
+#include "chip.h"
+#include "sam_gpio.h"
+#include "sam_spi.h"
+#include "sam4s-xplained-pro.h"
+
+#if defined(CONFIG_SAM34_SPI0)
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam_spidev_initialize
+ *
+ * Description:
+ *   Called to configure SPI chip select PIO pins for the SAM4S-Xplained-Pro
+ *   board.
+ *
+ ****************************************************************************/
+
+void weak_function sam_spidev_initialize(void)
+{
+#ifdef CONFIG_SAM34_SPI0
+  sam_configgpio(GPIO_SPI0_NPCS0);
+#endif
+}
+
+/****************************************************************************
+ * Name:  sam_spi[0|1]select, sam_spi[0|1]status, and sam_spi[0|1]cmddata
+ *
+ * Description:
+ *   These external functions must be provided by board-specific logic.
+ *   They include:
+ *
+ *   o sam_spi[0|1]select is a functions tomanage the board-specific chip
+ *           selects
+ *   o sam_spi[0|1]status and sam_spi[0|1]cmddata:
+ *     Implementations of the status and cmddata methods of the SPI interface
+ *     defined by struct spi_ops_(see include/nuttx/spi/spi.h).
+ *     All other methods including sam_spibus_initialize()) are provided by
+ *     common SAM3/4 logic.
+ *
+ *  To use this common SPI logic on your board:
+ *
+ *   1. Provide logic in sam_boardinitialize() to configure SPI chip select
+ *      pins.
+ *   2. Provide sam_spi[0|1]select() and sam_spi[0|1]status() functions in
+ *      your board-specific logic.
+ *      These functions will perform chip selection and status operations
+ *      using PIOs in the way your board is configured.
+ *   2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide
+ *      sam_spi[0|1]cmddata() functions in your board-specific logic.  This
+ *      function will perform cmd/data selection operations using PIOs in
+ *      the way your board is configured.
+ *   3. Add a call to sam_spibus_initialize() in your low level application
+ *      initialization logic
+ *   4. The handle returned by sam_spibus_initialize() may then be used to
+ *      bind the SPI driver to higher level logic (e.g., calling
+ *      mmcsd_spislotinitialize(), for example, will bind the SPI driver to
+ *      the SPI MMC/SD driver).
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam_spi[0|1]select
+ *
+ * Description:
+ *   PIO chip select pins may be programmed by the board specific logic in
+ *   one of two different ways.  First, the pins may be programmed as SPI
+ *   peripherals.  In that case, the pins are completely controlled by the
+ *   SPI driver.  This method still needs to be provided, but it may be only
+ *   a stub.
+ *
+ *   An alternative way to program the PIO chip select pins is as a normal
+ *   PIO output.  In that case, the automatic control of the CS pins is
+ *   bypassed and this function must provide control of the chip select.
+ *   NOTE:  In this case, the PIO output pin does *not* have to be the
+ *   same as the NPCS pin normal associated with the chip select number.
+ *
+ * Input Parameters:
+ *   devid - Identifies the (logical) device
+ *   selected - TRUE:Select the device, FALSE:De-select the device
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SAM34_SPI0
+void sam_spi0select(uint32_t devid, bool selected)
+{
+#ifdef CONFIG_MMCSD_SPI
+  /* The AT25 serial FLASH connects using NPCS0 */
+
+  if (devid == SPIDEV_MMCSD(0))
+    {
+      sam_gpiowrite(GPIO_SPI0_NPCS0, !selected);
+    }
+#endif
+}
+#endif
+
+/****************************************************************************
+ * Name: sam_spi[0|1]status
+ *
+ * Description:
+ *   Return status information associated with the SPI device.
+ *
+ * Input Parameters:
+ *   devid - Identifies the (logical) device
+ *
+ * Returned Value:
+ *   Bit-encoded SPI status (see include/nuttx/spi/spi.h.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SAM34_SPI0
+uint8_t sam_spi0status(FAR struct spi_dev_s *dev, uint32_t devid)
+{
+  return SPI_STATUS_PRESENT;
+}
+#endif
+
+int sam_sdinitialize(int port, int minor)
+{
+  FAR struct spi_dev_s *spi;
+  int ret;
+
+  /* Get the SPI driver instance for the SD chip select */
+
+  finfo("Initializing SERCOM SPI%d\n", port);
+
+  spi = sam_spibus_initialize(port);
+  if (!spi)
+    {
+      ferr("ERROR: Failed to initialize SPI%d\n", port);
+      return -ENODEV;
+    }
+
+  finfo("Successfully initialized SPI%d\n", port);
+
+  /* Bind the SPI device for the chip select to the slot */
+
+  finfo("Binding SPI%d to MMC/SD slot %d\n", port, 0);
+
+  ret = mmcsd_spislotinitialize(minor, 0, spi);
+  if (ret < 0)
+    {
+      ferr("ERROR: Failed to bind SPI%d to MMC/SD slot %d: %d\n",
+            port, 0, ret);
+      return ret;
+    }
+
+  finfo("Successfully bound SPI%d to MMC/SD slot %d\n",
+        port, 0);
+
+  return OK;
+}
+
+#endif /* CONFIG_SAM34_SPI0 */
diff --git a/drivers/mmcsd/mmcsd_sdio.c b/drivers/mmcsd/mmcsd_sdio.c
index 600144c..dce104b 100644
--- a/drivers/mmcsd/mmcsd_sdio.c
+++ b/drivers/mmcsd/mmcsd_sdio.c
@@ -42,6 +42,7 @@
 #include <errno.h>
 
 #include <nuttx/kmalloc.h>
+#include <nuttx/signal.h>
 #include <nuttx/fs/fs.h>
 #include <nuttx/fs/ioctl.h>
 #include <nuttx/clock.h>
@@ -2645,7 +2646,7 @@ static int mmcsd_widebus(FAR struct mmcsd_state_s *priv)
       priv->widebus = true;
 
       SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_4BIT);
-      usleep(MMCSD_CLK_DELAY);
+      nxsig_usleep(MMCSD_CLK_DELAY);
       return OK;
     }
 
@@ -2777,7 +2778,7 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv)
   /* Select high speed MMC clocking (which may depend on the DSR setting) */
 
   SDIO_CLOCK(priv->dev, CLOCK_MMC_TRANSFER);
-  usleep(MMCSD_CLK_DELAY);
+  nxsig_usleep(MMCSD_CLK_DELAY);
   return OK;
 }
 
diff --git a/drivers/mtd/mtd_nand.c b/drivers/mtd/mtd_nand.c
index 01d87b1..008420d 100644
--- a/drivers/mtd/mtd_nand.c
+++ b/drivers/mtd/mtd_nand.c
@@ -66,6 +66,7 @@
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
+
 /* Success Values returned by the nand_checkblock function */
 
 #define GOODBLOCK            254
@@ -82,6 +83,7 @@
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
+
 /* NAND locking */
 
 static int      nand_lock(FAR struct nand_dev_s *nand);
@@ -94,7 +96,6 @@ static int     nand_checkblock(FAR struct nand_dev_s *nand, off_t block);
 static int     nand_devscan(FAR struct nand_dev_s *nand);
 #else
 #  define      nand_checkblock(n,b) (GOODBLOCK)
-#  define      nand_devscan(n) (0)
 #endif
 
 /* Misc. NAND helpers */
@@ -282,6 +283,7 @@ static int nand_devscan(FAR struct nand_dev_s *nand)
               finfo("Good blocks: %u - %u\n", good, good + ngood);
               ngood = 0;
             }
+
 #endif
           if (ret == BADBLOCK)
             {
@@ -296,12 +298,12 @@ static int nand_devscan(FAR struct nand_dev_s *nand)
 #if defined(CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
       else
         {
-           if (ngood == 0)
-             {
-               good = block;
-             }
+          if (ngood == 0)
+            {
+              good = block;
+            }
 
-           ngood++;
+          ngood++;
         }
 #endif
     }
@@ -381,6 +383,7 @@ static int nand_eraseblock(FAR struct nand_dev_s *nand, off_t block,
   int ret;
 
   /* finfo("Block %d\n", block); */
+
   DEBUGASSERT(nand && nand->raw);
 
 #ifdef CONFIG_MTD_NAND_BLOCKCHECK
@@ -455,7 +458,7 @@ static int nand_readpage(FAR struct nand_dev_s *nand, off_t block,
     {
       ferr("ERROR: Block is BAD\n");
       return -EAGAIN;
-   }
+    }
 #endif
 
 #ifdef CONFIG_MTD_NAND_SWECC
@@ -787,8 +790,8 @@ static int nand_ioctl(struct mtd_dev_s *dev, int cmd, unsigned long arg)
           struct mtd_geometry_s *geo = (struct mtd_geometry_s *)arg;
           if (geo)
             {
-              /* Populate the geometry structure with information needed to know
-               * the capacity and how to access the device.  Returns:
+              /* Populate the geometry structure with information needed to
+               * know the capacity and how to access the device.  Returns:
                *
                *   blocksize    Size of one read/write block in bytes
                *   erasesize    Size of one erase block in bytes
@@ -880,7 +883,7 @@ FAR struct mtd_dev_s *nand_initialize(FAR struct nand_raw_s *raw)
       chipid = nand_chipid(raw);
       if (nandmodel_find(g_nandmodels, NAND_NMODELS, chipid,
                          &raw->model))
-       {
+        {
           ferr("ERROR: Could not determine NAND model\n");
           return NULL;
         }
@@ -895,7 +898,8 @@ FAR struct mtd_dev_s *nand_initialize(FAR struct nand_raw_s *raw)
       /* Construct the NAND model structure */
 
       model->devid     = onfi.manufacturer;
-      model->options   = onfi.buswidth ? NANDMODEL_DATAWIDTH16 : NANDMODEL_DATAWIDTH8;
+      model->options   = onfi.buswidth ? NANDMODEL_DATAWIDTH16 :
+                                         NANDMODEL_DATAWIDTH8;
       model->pagesize  = onfi.pagesize;
       model->sparesize = onfi.sparesize;
 
@@ -933,7 +937,8 @@ FAR struct mtd_dev_s *nand_initialize(FAR struct nand_raw_s *raw)
 
       /* Disable any internal, embedded ECC function */
 
-      onfi_embeddedecc(&onfi, cmdaddr, addraddr, dataaddr, false);
+      onfi_embeddedecc(&onfi, raw->cmdaddr, raw->addraddr, raw->dataaddr,
+                                                           true);
     }
 
   /* Allocate an NAND MTD device structure */
@@ -955,9 +960,13 @@ FAR struct mtd_dev_s *nand_initialize(FAR struct nand_raw_s *raw)
 
   nxsem_init(&nand->exclsem, 0, 1);
 
-  /* Scan the device for bad blocks */
+#if defined(CONFIG_MTD_NAND_BLOCKCHECK) && defined(CONFIG_DEBUG_INFO) && \
+    defined(CONFIG_DEBUG_FS)
+
+    /* Scan the device for bad blocks */
 
   nand_devscan(nand);
+#endif
 
   /* Return the implementation-specific state structure as the MTD device */
 
diff --git a/drivers/mtd/mtd_onfi.c b/drivers/mtd/mtd_onfi.c
index 29efdf4..14bc282 100644
--- a/drivers/mtd/mtd_onfi.c
+++ b/drivers/mtd/mtd_onfi.c
@@ -189,7 +189,7 @@ static int onfi_readstatus(uintptr_t cmdaddr, uintptr_t dataaddr)
  ****************************************************************************/
 
 #ifdef CONFIG_MTD_NAND_EMBEDDEDECC
-bool onfi_have_embeddedecc(FAR struct onfi_pgparam_s *onfi)
+bool onfi_have_embeddedecc(FAR const struct onfi_pgparam_s *onfi)
 {
   /* Check if the Nandflash has an embedded ECC controller.  Known memories
    * with this feature:
@@ -243,8 +243,8 @@ bool onfi_compatible(uintptr_t cmdaddr, uintptr_t addraddr,
   parmtab[3] = READ_NAND(dataaddr);
 
   return
-   (parmtab[0] == 'O' && parmtab[1] == 'N' &&
-    parmtab[2] == 'F' && parmtab[3] == 'I');
+      (parmtab[0] == 'O' && parmtab[1] == 'N' &&
+      parmtab[2] == 'F' && parmtab[3] == 'I');
 }
 
 /****************************************************************************
@@ -318,7 +318,7 @@ int onfi_read(uintptr_t cmdaddr, uintptr_t addraddr, uintptr_t dataaddr,
     {
       ferr("ERROR: Failed to read ONFI parameter table\n");
       return -EIO;
-   }
+    }
 
   /* JEDEC manufacturer ID */
 
@@ -398,6 +398,7 @@ bool onfi_embeddedecc(FAR const struct onfi_pgparam_s *onfi,
   if (onfi_have_embeddedecc(onfi))
     {
       /* Yes... enable or disable it */
+
       /* Perform common setup */
 
       WRITE_NAND_COMMAND(NAND_CMD_SET_FEATURE, cmdaddr);
@@ -411,7 +412,6 @@ bool onfi_embeddedecc(FAR const struct onfi_pgparam_s *onfi,
           WRITE_NAND(0x00, dataaddr);
           WRITE_NAND(0x00, dataaddr);
           WRITE_NAND(0x00, dataaddr);
-          setSmcOpEccType(SMC_ECC_INTERNAL);
         }
       else
         {
@@ -499,7 +499,7 @@ bool onfi_ebidetect(uintptr_t cmdaddr, uintptr_t addraddr,
            */
 
           found = true;
-       }
+        }
     }
 
   return found;