You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/07/01 06:44:57 UTC

[incubator-nuttx] branch master updated (3439c40 -> e659ae8)

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

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


    from 3439c40  stm32h7:SDMMC fix reset of do_gpio
     new 78bf264  kinetis:Replace DMA
     new e5a1b2e  kinetis:SPI use eDMA
     new 78584b4  kinetis:Serial use eDMA
     new e659ae8  Kinetis:Serial No DMA Poll needed

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/arm/src/kinetis/Kconfig                       | 159 +++-
 arch/arm/src/kinetis/Make.defs                     |   4 +-
 arch/arm/src/kinetis/hardware/kinetis_dma.h        | 776 -------------------
 arch/arm/src/kinetis/hardware/kinetis_dmamux.h     |   2 +-
 arch/arm/src/kinetis/hardware/kinetis_edma.h       | 855 +++++++++++++++++++++
 arch/arm/src/kinetis/kinetis_dma.c                 | 455 -----------
 arch/arm/src/kinetis/kinetis_dma.h                 | 250 ------
 .../s32k1xx_edma.c => kinetis/kinetis_edma.c}      | 618 +++++++--------
 .../s32k1xx_edma.h => kinetis/kinetis_edma.h}      | 118 +--
 arch/arm/src/kinetis/kinetis_serial.c              | 133 ++--
 arch/arm/src/kinetis/kinetis_spi.c                 | 464 ++++++++++-
 arch/arm/src/kinetis/kinetis_uart.h                |  46 --
 12 files changed, 1895 insertions(+), 1985 deletions(-)
 delete mode 100644 arch/arm/src/kinetis/hardware/kinetis_dma.h
 create mode 100644 arch/arm/src/kinetis/hardware/kinetis_edma.h
 delete mode 100644 arch/arm/src/kinetis/kinetis_dma.c
 delete mode 100644 arch/arm/src/kinetis/kinetis_dma.h
 copy arch/arm/src/{s32k1xx/s32k1xx_edma.c => kinetis/kinetis_edma.c} (69%)
 copy arch/arm/src/{s32k1xx/s32k1xx_edma.h => kinetis/kinetis_edma.h} (81%)

[incubator-nuttx] 02/04: kinetis:SPI use eDMA

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e5a1b2e7970b48768cf078e3a7946676601f49ca
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Fri Jun 25 04:19:34 2021 -0700

    kinetis:SPI use eDMA
    
    Kinetis:SPI only allocate DMA once
---
 arch/arm/src/kinetis/Kconfig       |  55 ++++-
 arch/arm/src/kinetis/kinetis_spi.c | 464 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 506 insertions(+), 13 deletions(-)

diff --git a/arch/arm/src/kinetis/Kconfig b/arch/arm/src/kinetis/Kconfig
index 78a868f..cbda473 100644
--- a/arch/arm/src/kinetis/Kconfig
+++ b/arch/arm/src/kinetis/Kconfig
@@ -330,6 +330,11 @@ config KINETIS_HAVE_DMA
 	bool
 	default n
 
+config KINETIS_SPI
+	bool
+	default n
+	select SPI
+
 config KINETIS_HAVE_I2C1
 	bool
 	default n
@@ -536,14 +541,14 @@ config KINETIS_FLEXCAN1
 config KINETIS_SPI0
 	bool "SPI0"
 	default n
-	select SPI
+	select KINETIS_SPI
 	---help---
 		Support SPI0
 
 config KINETIS_SPI1
 	bool "SPI1"
 	default n
-	select SPI
+	select KINETIS_SPI
 	depends on KINETIS_HAVE_SPI1
 	---help---
 		Support SPI1
@@ -551,7 +556,7 @@ config KINETIS_SPI1
 config KINETIS_SPI2
 	bool "SPI2"
 	default n
-	select SPI
+	select KINETIS_SPI
 	depends on KINETIS_HAVE_SPI2
 	---help---
 		Support SPI2
@@ -752,7 +757,7 @@ config KINETIS_FTFL
 		Support FLASH
 
 config KINETIS_EDMA
-	bool "DMA"
+	bool "eDMA"
 	default n
 	depends on KINETIS_HAVE_DMA
 	select ARCH_DMA
@@ -1204,6 +1209,48 @@ config KINETIS_EDMA_EDBG
 
 endmenu # eDMA Global Configuration
 
+menu "Kinetis SPI Configuration"
+	depends on KINETIS_SPI && KINETIS_EDMA
+
+config KINETIS_SPI_DMA
+	bool "SPI DMA"
+	depends on KINETIS_EDMA
+	default n
+	---help---
+		Use DMA to improve SPI transfer performance.
+
+config KINETIS_SPI_DMATHRESHOLD
+	int "SPI DMA threshold"
+	default 4
+	depends on KINETIS_SPI_DMA
+	---help---
+		When SPI DMA is enabled, small DMA transfers will still be performed
+		by polling logic.  But we need a threshold value to determine what
+		is small.
+
+config KINETIS_SPI0_DMA
+	bool "SPI0 DMA"
+	default n
+	depends on KINETIS_SPI0 && KINETIS_SPI_DMA
+	---help---
+		Use DMA to improve SPI0 transfer performance.
+
+config KINETIS_SPI1_DMA
+	bool "SPI1 DMA"
+	default n
+	depends on KINETIS_SPI1 && KINETIS_SPI_DMA
+	---help---
+		Use DMA to improve SPI1 transfer performance.
+
+config KINETIS_SPI2_DMA
+	bool "SPI2 DMA"
+	default n
+	depends on KINETIS_SPI2 && KINETIS_SPI_DMA
+	---help---
+		Use DMA to improve SPI2 transfer performance.
+
+endmenu # Kinetis SPI Configuration
+
 if KINETIS_USBHS && USBHOST
 
 menu "USB host controller driver (HCD) options"
diff --git a/arch/arm/src/kinetis/kinetis_spi.c b/arch/arm/src/kinetis/kinetis_spi.c
index 4659ceb..c5d51a0 100644
--- a/arch/arm/src/kinetis/kinetis_spi.c
+++ b/arch/arm/src/kinetis/kinetis_spi.c
@@ -67,7 +67,9 @@
 #include "arm_arch.h"
 
 #include "kinetis.h"
+#include "kinetis_edma.h"
 #include "kinetis_spi.h"
+#include "hardware/kinetis_dmamux.h"
 #include "hardware/kinetis_memorymap.h"
 #include "hardware/kinetis_sim.h"
 #include "hardware/kinetis_dspi.h"
@@ -83,20 +85,34 @@
 #define KINETIS_SPI_CLK_MAX    (BOARD_BUS_FREQ / 2)
 #define KINETIS_SPI_CLK_INIT   400000
 
+#define  SPI_SR_CLEAR   (SPI_SR_TCF | SPI_SR_EOQF | SPI_SR_TFUF  | \
+                         SPI_SR_TFFF | SPI_SR_RFOF | SPI_SR_RFDF | \
+                         SPI_SR_TXRXS)
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
 struct kinetis_spidev_s
 {
-  struct spi_dev_s spidev;     /* Externally visible part of the SPI interface */
-  uint32_t         spibase;    /* Base address of SPI registers */
-  sem_t            exclsem;    /* Held while chip is selected for mutual exclusion */
-  uint32_t         frequency;  /* Requested clock frequency */
-  uint32_t         actual;     /* Actual clock frequency */
-  uint8_t          nbits;      /* Width of word in bits (8 to 16) */
-  uint8_t          mode;       /* Mode 0,1,2,3 */
-  uint8_t          ctarsel;    /* Which CTAR */
+  struct spi_dev_s  spidev;     /* Externally visible part of the SPI interface */
+  uint32_t          spibase;    /* Base address of SPI registers */
+  sem_t             exclsem;    /* Held while chip is selected for mutual exclusion */
+  uint32_t          frequency;  /* Requested clock frequency */
+  uint32_t          actual;     /* Actual clock frequency */
+  uint8_t           nbits;      /* Width of word in bits (8 to 16) */
+  uint8_t           mode;       /* Mode 0,1,2,3 */
+  uint8_t           ctarsel;    /* Which CTAR */
+#ifdef CONFIG_KINETIS_SPI_DMA
+  volatile uint32_t rxresult;   /* Result of the RX DMA */
+  volatile uint32_t txresult;   /* Result of the TX DMA */
+  const uint8_t     rxch;       /* The RX DMA channel number */
+  const uint8_t     txch;       /* The TX DMA channel number */
+  DMACH_HANDLE      rxdma;      /* DMA channel handle for RX transfers */
+  DMACH_HANDLE      txdma;      /* DMA channel handle for TX transfers */
+  sem_t             rxsem;      /* Wait for RX DMA to complete */
+  sem_t             txsem;      /* Wait for TX DMA to complete */
+#endif
 };
 
 /****************************************************************************
@@ -132,6 +148,21 @@ static inline void     spi_wait_status(FAR struct kinetis_spidev_s *priv,
 static uint16_t        spi_send_data(FAR struct kinetis_spidev_s *priv,
                                      uint16_t wd, bool last);
 
+/* DMA support */
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static int         spi_dmarxwait(FAR struct kinetis_spidev_s *priv);
+static int         spi_dmatxwait(FAR struct kinetis_spidev_s *priv);
+static inline void spi_dmarxwakeup(FAR struct kinetis_spidev_s *priv);
+static inline void spi_dmatxwakeup(FAR struct kinetis_spidev_s *priv);
+static void        spi_dmarxcallback(DMACH_HANDLE handle, void *arg,
+                                     bool done, int result);
+static void        spi_dmatxcallback(DMACH_HANDLE handle, void *arg,
+                                     bool done, int result);
+static inline void spi_dmarxstart(FAR struct kinetis_spidev_s *priv);
+static inline void spi_dmatxstart(FAR struct kinetis_spidev_s *priv);
+#endif
+
 /* SPI methods */
 
 static int         spi_lock(FAR struct spi_dev_s *dev, bool lock);
@@ -197,6 +228,15 @@ static struct kinetis_spidev_s g_spi0dev =
   },
   .spibase           = KINETIS_SPI0_BASE,
   .ctarsel           = KINETIS_SPI_CTAR0_OFFSET,
+#ifdef CONFIG_KINETIS_SPI_DMA
+#  ifdef CONFIG_KINETIS_SPI0_DMA
+  .rxch     = KINETIS_DMA_REQUEST_SRC_SPI0_RX,
+  .txch     = KINETIS_DMA_REQUEST_SRC_SPI0_TX,
+#  else
+  .rxch     = 0,
+  .txch     = 0,
+#  endif
+#endif
 };
 #endif
 
@@ -237,6 +277,15 @@ static struct kinetis_spidev_s g_spi1dev =
   },
   .spibase           = KINETIS_SPI1_BASE,
   .ctarsel           = KINETIS_SPI_CTAR0_OFFSET,
+#ifdef CONFIG_KINETIS_SPI_DMA
+#  ifdef CONFIG_KINETIS_SPI1_DMA
+  .rxch     = KINETIS_DMA_REQUEST_SRC_SPI1_RX,
+  .txch     = KINETIS_DMA_REQUEST_SRC_SPI1_TX,
+#  else
+  .rxch     = 0,
+  .txch     = 0,
+#  endif
+#endif
 };
 #endif
 
@@ -277,6 +326,15 @@ static struct kinetis_spidev_s g_spi2dev =
   },
   .spibase           = KINETIS_SPI2_BASE,
   .ctarsel           = KINETIS_SPI_CTAR0_OFFSET,
+#ifdef CONFIG_KINETIS_SPI_DMA
+#  ifdef CONFIG_KINETIS_SPI2_DMA
+  .rxch     = KINETIS_DMA_REQUEST_SRC_FTM3_CH6__SPI2_RX,
+  .txch     = KINETIS_DMA_REQUEST_SRC_FTM3_CH7__SPI2_TX,
+#  else
+  .rxch     = 0,
+  .txch     = 0,
+#  endif
+#endif
 };
 #endif
 
@@ -285,6 +343,32 @@ static struct kinetis_spidev_s g_spi2dev =
  ****************************************************************************/
 
 /****************************************************************************
+ * Name: spi_modifyreg
+ *
+ * Description:
+ *   Atomic modification of the 32-bit contents of the SPI register at offset
+ *
+ * Input Parameters:
+ *   priv      - private SPI device structure
+ *   offset    - offset to the register of interest
+ *   clearbits - bits to clear
+ *   clearbits - bits to set
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static inline void spi_modifyreg(FAR struct kinetis_spidev_s *priv,
+                                 uint8_t offset, uint32_t clearbits,
+                                 uint32_t setbits)
+{
+  modifyreg32(priv->spibase + offset, clearbits, setbits);
+}
+#endif
+
+/****************************************************************************
  * Name: spi_getreg
  *
  * Description:
@@ -946,7 +1030,7 @@ static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
 }
 
 /****************************************************************************
- * Name: spi_exchange
+ * Name: spi_exchange (no DMA).  aka spi_exchange_nodma
  *
  * Description:
  *   Exchange a block of data on SPI without using DMA
@@ -966,8 +1050,15 @@ static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
  *
  ****************************************************************************/
 
+#if !defined(CONFIG_STM32_SPI_DMA) || defined(CONFIG_STM32_SPI_DMATHRESHOLD)
+#  if !defined(CONFIG_KINETIS_SPI_DMA)
 static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
                          FAR void *rxbuffer, size_t nwords)
+#  else
+static void spi_exchange_nodma(FAR struct spi_dev_s *dev,
+                               FAR const void *txbuffer,
+                               FAR void *rxbuffer, size_t nwords)
+#  endif
 {
   FAR struct kinetis_spidev_s *priv = (FAR struct kinetis_spidev_s *)dev;
   uint8_t        *brxptr = (uint8_t *)rxbuffer;
@@ -1039,8 +1130,162 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
         }
     }
 }
+#endif /* !defined(CONFIG_STM32_SPI_DMA) || defined(CONFIG_STM32_SPI_DMATHRESHOLD) */
 
 /****************************************************************************
+ * Name: spi_exchange (with DMA capability)
+ *
+ * Description:
+ *   Exchange a block of data on SPI using DMA
+ *
+ * Input Parameters:
+ *   dev      - Device-specific state data
+ *   txbuffer - A pointer to the buffer of data to be sent
+ *   rxbuffer - A pointer to a buffer in which to receive data
+ *   nwords   - the length of data to be exchaned in units of words.
+ *              The wordsize is determined by the number of bits-per-word
+ *              selected for the SPI interface.  If nbits <= 8, the data is
+ *              packed into uint8_t's; if nbits > 8, the data is packed into
+ *              uint16_t's
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
+                         FAR void *rxbuffer, size_t nwords)
+{
+  int                          ret;
+  size_t                       adjust;
+  ssize_t                      nbytes;
+  static uint8_t               rxdummy[4] __attribute__((aligned(4)));
+  static const uint16_t        txdummy = 0xffff;
+  FAR struct kinetis_spidev_s *priv    = (FAR struct kinetis_spidev_s *)dev;
+
+  DEBUGASSERT(priv != NULL);
+  DEBUGASSERT(priv && priv->spibase);
+  spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords);
+
+  /* Convert the number of word to a number of bytes */
+
+  nbytes = (priv->nbits > 8) ? nwords << 1 : nwords;
+
+  /* Invalid DMA channels fall back to non-DMA method. */
+
+  if (priv->rxdma == NULL || priv->txdma == NULL
+#ifdef CONFIG_KINETIS_SPI_DMATHRESHOLD
+      /* If this is a small SPI transfer, then let spi_exchange_nodma()
+       * do the work.
+       */
+
+      || nbytes <= CONFIG_KINETIS_SPI_DMATHRESHOLD
+#endif
+      )
+    {
+      spi_exchange_nodma(dev, txbuffer, rxbuffer, nwords);
+      return;
+    }
+
+  /* Halt the SPI */
+
+  spi_run(priv, false);
+
+  /* Flush FIFOs */
+
+  spi_modifyreg(priv, KINETIS_SPI_MCR_OFFSET,
+                SPI_MCR_CLR_RXF | SPI_MCR_CLR_TXF,
+                SPI_MCR_CLR_RXF | SPI_MCR_CLR_TXF);
+
+  /* Clear all status bits */
+
+  spi_write_status(priv, SPI_SR_CLEAR);
+
+  /* disable DMA */
+
+  spi_modifyreg(priv, KINETIS_SPI_RSER_OFFSET,
+                SPI_RSER_RFDF_RE | SPI_RSER_TFFF_RE |
+                SPI_RSER_RFDF_DIRS | SPI_RSER_TFFF_DIRS,
+                0);
+
+  /* Set up the DMA */
+
+  adjust = (priv->nbits > 8) ? 2 : 1;
+
+  struct kinetis_edma_xfrconfig_s config;
+
+  config.saddr  = priv->spibase + KINETIS_SPI_POPR_OFFSET;
+  config.daddr  = (uint32_t) (rxbuffer ? rxbuffer : rxdummy);
+  config.soff   = 0;
+  config.doff   = rxbuffer ? adjust : 0;
+  config.iter   = nbytes;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = adjust == 1 ? EDMA_8BIT : EDMA_16BIT;
+  config.dsize  = adjust == 1 ? EDMA_8BIT : EDMA_16BIT;
+  config.ttype  = EDMA_PERIPH2MEM;
+  config.nbytes = adjust;
+#ifdef CONFIG_KINETIS_EDMA_ELINK
+  config.linkch = NULL;
+#endif
+  kinetis_dmach_xfrsetup(priv->rxdma, &config);
+
+  config.saddr  = (uint32_t) (txbuffer ? txbuffer : &txdummy);
+  config.daddr  = priv->spibase + KINETIS_SPI_PUSHR_OFFSET;
+  config.soff   = txbuffer ? adjust : 0;
+  config.doff   = 0;
+  config.iter   = nbytes;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = adjust == 1 ? EDMA_8BIT : EDMA_16BIT;
+  config.dsize  = adjust == 1 ? EDMA_8BIT : EDMA_16BIT;
+  config.ttype  = EDMA_MEM2PERIPH;
+  config.nbytes = adjust;
+#ifdef CONFIG_KINETIS_EDMA_ELINK
+  config.linkch = NULL;
+#endif
+  kinetis_dmach_xfrsetup(priv->txdma, &config);
+
+  spi_modifyreg(priv, KINETIS_SPI_RSER_OFFSET, 0 ,
+                SPI_RSER_RFDF_RE | SPI_RSER_TFFF_RE |
+                SPI_RSER_RFDF_DIRS | SPI_RSER_TFFF_DIRS);
+
+  /* Start the DMAs */
+
+  spi_dmarxstart(priv);
+  spi_run(priv, true);
+
+  spi_putreg(priv, KINETIS_SPI_TCR_OFFSET, 0);
+  spi_write_control(priv, SPI_PUSHR_CTAS_CTAR0);
+
+  spi_dmatxstart(priv);
+
+  /* Then wait for each to complete */
+
+  ret = spi_dmarxwait(priv);
+
+  if (ret < 0)
+    {
+      ret = spi_dmatxwait(priv);
+    }
+
+  /* Reset any status */
+
+  spi_write_status(priv, spi_getreg(priv, KINETIS_SPI_SR_OFFSET));
+
+  /* Halt SPI */
+
+  spi_run(priv, false);
+
+  /* Disable DMA */
+
+  spi_modifyreg(priv, KINETIS_SPI_RSER_OFFSET,
+                SPI_RSER_RFDF_RE | SPI_RSER_TFFF_RE |
+                SPI_RSER_RFDF_DIRS | SPI_RSER_TFFF_DIRS,
+                0);
+}
+
+#endif  /* CONFIG_KINETIS_SPI_DMA */
+/****************************************************************************
  * Name: spi_sndblock
  *
  * Description:
@@ -1100,6 +1345,174 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
 #endif
 
 /****************************************************************************
+ * Name: spi_dmarxwait
+ *
+ * Description:
+ *   Wait for DMA to complete.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static int spi_dmarxwait(FAR struct kinetis_spidev_s *priv)
+{
+  int ret;
+
+  /* Take the semaphore (perhaps waiting).  If the result is zero, then the
+   *  DMA must not really have completed.
+   */
+
+  do
+    {
+      ret = nxsem_wait_uninterruptible(&priv->rxsem);
+
+      /* The only expected error is ECANCELED which would occur if the
+       * calling thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
+    }
+  while (priv->rxresult == 0 && ret == OK);
+
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: spi_dmatxwait
+ *
+ * Description:
+ *   Wait for DMA to complete.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static int spi_dmatxwait(FAR struct kinetis_spidev_s *priv)
+{
+  int ret;
+
+  /* Take the semaphore (perhaps waiting).  If the result is zero, then the
+   * DMA must not really have completed.
+   */
+
+  do
+    {
+      ret = nxsem_wait_uninterruptible(&priv->txsem);
+
+      /* The only expected error is ECANCELED which would occur if the
+       * calling thread were canceled.
+       */
+
+      DEBUGASSERT(ret == OK || ret == -ECANCELED);
+    }
+  while (priv->txresult == 0 && ret == OK);
+
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: spi_dmarxwakeup
+ *
+ * Description:
+ *   Signal that DMA is complete
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static inline void spi_dmarxwakeup(FAR struct kinetis_spidev_s *priv)
+{
+  nxsem_post(&priv->rxsem);
+}
+#endif
+
+/****************************************************************************
+ * Name: spi_dmatxwakeup
+ *
+ * Description:
+ *   Signal that DMA is complete
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static inline void spi_dmatxwakeup(FAR struct kinetis_spidev_s *priv)
+{
+  nxsem_post(&priv->txsem);
+}
+#endif
+
+/****************************************************************************
+ * Name: spi_dmarxcallback
+ *
+ * Description:
+ *   Called when the RX DMA completes
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static void spi_dmarxcallback(DMACH_HANDLE handle, void *arg, bool done,
+                              int result)
+{
+  FAR struct kinetis_spidev_s *priv = (FAR struct kinetis_spidev_s *)arg;
+
+  priv->rxresult = result | 0x80000000;  /* assure non-zero */
+  spi_dmarxwakeup(priv);
+}
+#endif
+
+/****************************************************************************
+ * Name: spi_dmatxcallback
+ *
+ * Description:
+ *   Called when the RX DMA completes
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static void spi_dmatxcallback(DMACH_HANDLE handle, void *arg, bool done,
+                              int result)
+{
+  FAR struct kinetis_spidev_s *priv = (FAR struct kinetis_spidev_s *)arg;
+
+  /* Wake-up the SPI driver */
+
+  priv->txresult = result | 0x80000000;  /* assure non-zero */
+  spi_dmatxwakeup(priv);
+}
+#endif
+
+/****************************************************************************
+ * Name: spi_dmarxstart
+ *
+ * Description:
+ *   Start RX DMA
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static inline void spi_dmarxstart(FAR struct kinetis_spidev_s *priv)
+{
+  priv->rxresult = 0;
+  kinetis_dmach_start(priv->rxdma, spi_dmarxcallback, priv);
+}
+#endif
+
+/****************************************************************************
+ * Name: spi_dmatxstart
+ *
+ * Description:
+ *   Start TX DMA
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_SPI_DMA
+static inline void spi_dmatxstart(FAR struct kinetis_spidev_s *priv)
+{
+  priv->txresult = 0;
+  kinetis_dmach_start(priv->txdma, spi_dmatxcallback, priv);
+}
+#endif
+
+/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
@@ -1251,6 +1664,39 @@ FAR struct spi_dev_s *kinetis_spibus_initialize(int port)
   /* Initialize the SPI semaphore that enforces mutually exclusive access */
 
   nxsem_init(&priv->exclsem, 0, 1);
+#ifdef CONFIG_KINETIS_SPI_DMA
+  /* Initialize the SPI semaphores that is used to wait for DMA completion.
+   * This semaphore is used for signaling and, hence, should not have
+   * priority inheritance enabled.
+   */
+
+  if (priv->rxch && priv->txch)
+    {
+      if (priv->txdma == NULL && priv->rxdma == NULL)
+        {
+          nxsem_init(&priv->rxsem, 0, 0);
+          nxsem_init(&priv->txsem, 0, 0);
+
+          nxsem_set_protocol(&priv->rxsem, SEM_PRIO_NONE);
+          nxsem_set_protocol(&priv->txsem, SEM_PRIO_NONE);
+
+          priv->txdma = kinetis_dmach_alloc(priv->txch | DMAMUX_CHCFG_ENBL,
+                                            0);
+          priv->rxdma = kinetis_dmach_alloc(priv->rxch | DMAMUX_CHCFG_ENBL,
+                                            0);
+          DEBUGASSERT(priv->rxdma && priv->txdma);
+          spi_modifyreg(priv, KINETIS_SPI_MCR_OFFSET,
+                        0,
+                        SPI_MCR_DIS_RXF | SPI_MCR_DIS_TXF
+                        );
+        }
+    }
+  else
+    {
+      priv->rxdma = NULL;
+      priv->txdma = NULL;
+    }
+#endif
 
   return &priv->spidev;
 }

[incubator-nuttx] 04/04: Kinetis:Serial No DMA Poll needed

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e659ae83b0cc3a96fb556553b6369c556d7a28e1
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Tue Jun 29 15:13:35 2021 -0700

    Kinetis:Serial No DMA Poll needed
---
 arch/arm/src/kinetis/kinetis_serial.c | 84 ++++++++---------------------------
 arch/arm/src/kinetis/kinetis_uart.h   | 46 -------------------
 2 files changed, 19 insertions(+), 111 deletions(-)

diff --git a/arch/arm/src/kinetis/kinetis_serial.c b/arch/arm/src/kinetis/kinetis_serial.c
index 88c07b9..3047b1f 100644
--- a/arch/arm/src/kinetis/kinetis_serial.c
+++ b/arch/arm/src/kinetis/kinetis_serial.c
@@ -1038,7 +1038,6 @@ static void up_dma_shutdown(struct uart_dev_s *dev)
   kinetis_dmach_free(rxdma);
 
   priv->rxdma = NULL;
-
 }
 #endif
 
@@ -1253,6 +1252,22 @@ static int up_interrupts(int irq, void *context, FAR void *arg)
           uart_xmitchars(dev);
           handled = true;
         }
+
+#if defined(SERIAL_HAVE_DMA) && !defined(CONFIG_KINETIS_UARTFIFOS)
+      /* Check if the receiver has detected IDLE. If so
+       * then flush any partail data in the SW rx fifo.
+       */
+
+      if ((s1 & UART_S1_IDLE) != 0)
+        {
+          up_serialin(priv, KINETIS_UART_D_OFFSET);
+          up_dma_rxcallback(priv->rxdma, dev , false, 0);
+
+          /* Exit ASAP */
+
+          handled = false;
+        }
+#endif
     }
 
   return OK;
@@ -1674,6 +1689,9 @@ static void up_rxint(struct uart_dev_s *dev, bool enable)
 
 #ifndef CONFIG_SUPPRESS_SERIAL_INTS
       priv->ie |= UART_C2_RIE;
+#if defined(SERIAL_HAVE_DMA) && !defined(CONFIG_KINETIS_UARTFIFOS)
+      priv->ie |= UART_C2_RIE | UART_C2_ILIE;
+#endif
       up_setuartint(priv);
 #endif
     }
@@ -2070,70 +2088,6 @@ unsigned int kinetis_uart_serialinit(unsigned int first)
 }
 
 /****************************************************************************
- * Name: kinetis_serial_dma_poll
- *
- * Description:
- *   Checks receive DMA buffers for received bytes that have not accumulated
- *   to the point where the DMA half/full interrupt has triggered.
- *
- *   This function should be called from a timer or other periodic context.
- *
- ****************************************************************************/
-
-#ifdef SERIAL_HAVE_DMA
-void kinetis_serial_dma_poll(void)
-{
-    irqstate_t flags;
-
-    flags = enter_critical_section();
-
-#ifdef CONFIG_KINETIS_UART0_RXDMA
-  if (g_uart0priv.rxdma != NULL)
-    {
-      up_dma_rxcallback(g_uart0priv.rxdma, (void *)&g_uart0port, false, 0);
-    }
-#endif
-
-#ifdef CONFIG_KINETIS_UART1_RXDMA
-  if (g_uart1priv.rxdma != NULL)
-    {
-      up_dma_rxcallback(g_uart1priv.rxdma, (void *)&g_uart1port, false, 0);
-    }
-#endif
-
-#ifdef CONFIG_KINETIS_UART2_RXDMA
-  if (g_uart2priv.rxdma != NULL)
-    {
-      up_dma_rxcallback(g_uart2priv.rxdma, (void *)&g_uart2port, false, 0);
-    }
-#endif
-
-#ifdef CONFIG_KINETIS_UART3_RXDMA
-  if (g_uart3priv.rxdma != NULL)
-    {
-      up_dma_rxcallback(g_uart3priv.rxdma, (void *)&g_uart3port, false, 0);
-    }
-#endif
-
-#ifdef CONFIG_KINETIS_UART4_RXDMA
-  if (g_uart4priv.rxdma != NULL)
-    {
-      up_dma_rxcallback(g_uart4priv.rxdma, (void *)&g_uart4port, false, 0);
-    }
-#endif
-
-#ifdef CONFIG_KINETIS_UART5_RXDMA
-  if (g_uart5priv.rxdma != NULL)
-    {
-      up_dma_rxcallback(g_uart5priv.rxdma, (void *)&g_uart5port, false, 0);
-    }
-#endif
-
-  leave_critical_section(flags);
-}
-#endif
-
-/****************************************************************************
  * Name: up_putc
  *
  * Description:
diff --git a/arch/arm/src/kinetis/kinetis_uart.h b/arch/arm/src/kinetis/kinetis_uart.h
index f4d396b..39b9aa9 100644
--- a/arch/arm/src/kinetis/kinetis_uart.h
+++ b/arch/arm/src/kinetis/kinetis_uart.h
@@ -52,51 +52,5 @@
 #  endif
 #endif
 
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#ifndef __ASSEMBLY__
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C"
-{
-#else
-#define EXTERN extern
-#endif
-
-/****************************************************************************
- * Public Functions Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Name: kinetis_serial_dma_poll
- *
- * Description:
- *   Must be called periodically if any Kinetis UART is configured for DMA.
- *   The DMA callback is triggered for each fifo size/2 bytes, but this can
- *   result in some bytes being transferred but not collected if the incoming
- *   data is not a whole multiple of half the FIFO size.
- *
- *   May be safely called from either interrupt or thread context.
- *
- ****************************************************************************/
-
-#ifdef SERIAL_HAVE_DMA
-void kinetis_serial_dma_poll(void);
-#endif
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* __ASSEMBLY__ */
 #endif /* HAVE_UART_DEVICE && USE_SERIALDRIVER) */
 #endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_UART_H */

[incubator-nuttx] 03/04: kinetis:Serial use eDMA

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 78584b4569fae60fa5e07654a604f6d99706eefb
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Fri Jun 25 14:02:56 2021 -0700

    kinetis:Serial use eDMA
    
    kinetis:serial mark priv->rxdma after use
---
 arch/arm/src/kinetis/kinetis_serial.c | 63 ++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 26 deletions(-)

diff --git a/arch/arm/src/kinetis/kinetis_serial.c b/arch/arm/src/kinetis/kinetis_serial.c
index 459b1f2..88c07b9 100644
--- a/arch/arm/src/kinetis/kinetis_serial.c
+++ b/arch/arm/src/kinetis/kinetis_serial.c
@@ -53,7 +53,7 @@
 #include "hardware/kinetis_uart.h"
 #include "hardware/kinetis_pinmux.h"
 #include "kinetis.h"
-#include "kinetis_dma.h"
+#include "kinetis_edma.h"
 #include "kinetis_uart.h"
 
 /****************************************************************************
@@ -270,9 +270,6 @@
 #  define RXDMA_BUFFER_SIZE   ((CONFIG_KINETIS_SERIAL_RXDMA_BUFFER_SIZE \
                                 + RXDMA_BUFFER_MASK) & ~RXDMA_BUFFER_MASK)
 
-#  define SERIAL_DMA_CONTROL_WORD \
-                              (DMA_TCD_CSR_MAJORELINK | \
-                               DMA_TCD_CSR_INTHALF)
 #endif /* SERIAL_HAVE_DMA */
 
 /****************************************************************************
@@ -306,7 +303,7 @@ struct up_dev_s
 #endif
 #ifdef SERIAL_HAVE_DMA
   const uint8_t rxdma_reqsrc;
-  DMA_HANDLE        rxdma;     /* currently-open receive DMA stream */
+  DMACH_HANDLE      rxdma;     /* currently-open receive DMA stream */
   uint32_t          rxdmanext; /* Next byte in the DMA buffer to be read */
   char      *const  rxfifo;    /* Receive DMA buffer */
 #endif
@@ -347,7 +344,8 @@ static void up_dma_shutdown(struct uart_dev_s *dev);
 static int  up_dma_receive(struct uart_dev_s *dev, unsigned int *status);
 static bool up_dma_rxavailable(struct uart_dev_s *dev);
 static uint8_t get_and_clear_uart_status(struct up_dev_s *priv);
-static void up_dma_rxcallback(DMA_HANDLE handle, void *arg, int result);
+static void up_dma_rxcallback(DMACH_HANDLE handle, void *arg, bool done,
+                              int result);
 #endif
 
 /****************************************************************************
@@ -928,7 +926,7 @@ static int up_dma_setup(struct uart_dev_s *dev)
   struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
   int result;
   uint8_t regval;
-  DMA_HANDLE rxdma = NULL;
+  DMACH_HANDLE rxdma = NULL;
 
   /* Do the basic UART setup first, unless we are the console */
 
@@ -943,10 +941,7 @@ static int up_dma_setup(struct uart_dev_s *dev)
 
   /* Acquire the DMA channel. */
 
-  rxdma = kinetis_dmachannel(priv->rxdma_reqsrc,
-                             priv->uartbase + KINETIS_UART_D_OFFSET,
-                             KINETIS_DMA_DATA_SZ_8BIT,
-                             KINETIS_DMA_DIRECTION_PERIPHERAL_TO_MEMORY);
+  rxdma = kinetis_dmach_alloc(priv->rxdma_reqsrc | DMAMUX_CHCFG_ENBL, 0);
   if (rxdma == NULL)
     {
       return -EBUSY;
@@ -954,8 +949,21 @@ static int up_dma_setup(struct uart_dev_s *dev)
 
   /* Configure for circular DMA reception into the RX FIFO */
 
-  kinetis_dmasetup(rxdma, (uint32_t)priv->rxfifo, RXDMA_BUFFER_SIZE,
-                   SERIAL_DMA_CONTROL_WORD);
+  struct kinetis_edma_xfrconfig_s config;
+  config.saddr  = priv->uartbase + KINETIS_UART_D_OFFSET;
+  config.daddr  = (uint32_t) priv->rxfifo;
+  config.soff   = 0;
+  config.doff   = 1;
+  config.iter   = RXDMA_BUFFER_SIZE;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE | EDMA_CONFIG_LOOPDEST;
+  config.ssize  = EDMA_8BIT;
+  config.dsize  = EDMA_8BIT;
+  config.ttype  = EDMA_PERIPH2MEM;
+  config.nbytes = 1;
+#ifdef CONFIG_KINETIS_EDMA_ELINK
+  config.linkch = NULL;
+#endif
+  kinetis_dmach_xfrsetup(rxdma, &config);
 
   /* Reset our DMA shadow pointer to match the address just programmed
    * above.
@@ -974,7 +982,7 @@ static int up_dma_setup(struct uart_dev_s *dev)
    * worth of time to claim bytes before they are overwritten.
    */
 
-  kinetis_dmastart(rxdma, up_dma_rxcallback, (void *)dev);
+  kinetis_dmach_start(rxdma, up_dma_rxcallback, (void *)dev);
   priv->rxdma = rxdma;
   return OK;
 }
@@ -1015,8 +1023,7 @@ static void up_shutdown(struct uart_dev_s *dev)
 static void up_dma_shutdown(struct uart_dev_s *dev)
 {
   struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
-  DMA_HANDLE rxdma = priv->rxdma;
-  priv->rxdma = NULL;
+  DMACH_HANDLE rxdma = priv->rxdma;
 
   /* Perform the normal UART shutdown */
 
@@ -1024,11 +1031,14 @@ static void up_dma_shutdown(struct uart_dev_s *dev)
 
   /* Stop the DMA channel */
 
-  kinetis_dmastop(rxdma);
+  kinetis_dmach_stop(rxdma);
 
   /* Release the DMA channel */
 
-  kinetis_dmafree(rxdma);
+  kinetis_dmach_free(rxdma);
+
+  priv->rxdma = NULL;
+
 }
 #endif
 
@@ -1821,7 +1831,7 @@ static int up_dma_nextrx(struct up_dev_s *priv)
 {
   size_t dmaresidual;
 
-  dmaresidual = kinetis_dmaresidual(priv->rxdma);
+  dmaresidual = kinetis_dmach_getcount(priv->rxdma);
 
   return (RXDMA_BUFFER_SIZE - (int)dmaresidual) % RXDMA_BUFFER_SIZE;
 }
@@ -1942,7 +1952,8 @@ static bool up_txempty(struct uart_dev_s *dev)
  ****************************************************************************/
 
 #ifdef SERIAL_HAVE_DMA
-static void up_dma_rxcallback(DMA_HANDLE handle, void *arg, int result)
+static void up_dma_rxcallback(DMACH_HANDLE handle, void *arg, bool done,
+                              int result)
 {
   struct uart_dev_s *dev = (struct uart_dev_s *)arg;
 
@@ -2079,42 +2090,42 @@ void kinetis_serial_dma_poll(void)
 #ifdef CONFIG_KINETIS_UART0_RXDMA
   if (g_uart0priv.rxdma != NULL)
     {
-      up_dma_rxcallback(g_uart0priv.rxdma, (void *)&g_uart0port, 0);
+      up_dma_rxcallback(g_uart0priv.rxdma, (void *)&g_uart0port, false, 0);
     }
 #endif
 
 #ifdef CONFIG_KINETIS_UART1_RXDMA
   if (g_uart1priv.rxdma != NULL)
     {
-      up_dma_rxcallback(g_uart1priv.rxdma, (void *)&g_uart1port, 0);
+      up_dma_rxcallback(g_uart1priv.rxdma, (void *)&g_uart1port, false, 0);
     }
 #endif
 
 #ifdef CONFIG_KINETIS_UART2_RXDMA
   if (g_uart2priv.rxdma != NULL)
     {
-      up_dma_rxcallback(g_uart2priv.rxdma, (void *)&g_uart2port, 0);
+      up_dma_rxcallback(g_uart2priv.rxdma, (void *)&g_uart2port, false, 0);
     }
 #endif
 
 #ifdef CONFIG_KINETIS_UART3_RXDMA
   if (g_uart3priv.rxdma != NULL)
     {
-      up_dma_rxcallback(g_uart3priv.rxdma, (void *)&g_uart3port, 0);
+      up_dma_rxcallback(g_uart3priv.rxdma, (void *)&g_uart3port, false, 0);
     }
 #endif
 
 #ifdef CONFIG_KINETIS_UART4_RXDMA
   if (g_uart4priv.rxdma != NULL)
     {
-      up_dma_rxcallback(g_uart4priv.rxdma, (void *)&g_uart4port, 0);
+      up_dma_rxcallback(g_uart4priv.rxdma, (void *)&g_uart4port, false, 0);
     }
 #endif
 
 #ifdef CONFIG_KINETIS_UART5_RXDMA
   if (g_uart5priv.rxdma != NULL)
     {
-      up_dma_rxcallback(g_uart5priv.rxdma, (void *)&g_uart5port, 0);
+      up_dma_rxcallback(g_uart5priv.rxdma, (void *)&g_uart5port, false, 0);
     }
 #endif
 

[incubator-nuttx] 01/04: kinetis:Replace DMA

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 78bf264af0b70a0a7c0fcbcb44e1a882bb6ada0f
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Fri Jun 25 05:13:42 2021 -0700

    kinetis:Replace DMA
    
    Kinetis:DMAMUX use hex in mask
---
 arch/arm/src/kinetis/Kconfig                   |  104 +-
 arch/arm/src/kinetis/Make.defs                 |    4 +-
 arch/arm/src/kinetis/hardware/kinetis_dma.h    |  776 -------------
 arch/arm/src/kinetis/hardware/kinetis_dmamux.h |    2 +-
 arch/arm/src/kinetis/hardware/kinetis_edma.h   |  855 ++++++++++++++
 arch/arm/src/kinetis/kinetis_dma.c             |  455 --------
 arch/arm/src/kinetis/kinetis_dma.h             |  250 ----
 arch/arm/src/kinetis/kinetis_edma.c            | 1464 ++++++++++++++++++++++++
 arch/arm/src/kinetis/kinetis_edma.h            |  455 ++++++++
 9 files changed, 2874 insertions(+), 1491 deletions(-)

diff --git a/arch/arm/src/kinetis/Kconfig b/arch/arm/src/kinetis/Kconfig
index 5cdc32b..78a868f 100644
--- a/arch/arm/src/kinetis/Kconfig
+++ b/arch/arm/src/kinetis/Kconfig
@@ -751,7 +751,7 @@ config KINETIS_FTFL
 	---help---
 		Support FLASH
 
-config KINETIS_DMA
+config KINETIS_EDMA
 	bool "DMA"
 	default n
 	depends on KINETIS_HAVE_DMA
@@ -1114,6 +1114,96 @@ config KINETIS_SD4BIT_FREQ
 endif
 endmenu # Kinetis SDHC Configuration
 
+menu "eDMA Configuration"
+	depends on KINETIS_EDMA
+
+config KINETIS_EDMA_NTCD
+	int "Number of transfer descriptors"
+	default 0
+	---help---
+		Number of pre-allocated transfer descriptors.  Needed for scatter-
+		gather DMA.  Make to be set to zero to disable in-memory TCDs in
+		which case only the TCD channel registers will be used and scatter-
+		will not be supported.
+
+config KINETIS_EDMA_ELINK
+	bool "Channeling Linking"
+	default n
+	---help---
+		This option enables optional minor or major loop channel linking:
+
+		Minor loop channel linking:  As the channel completes the minor
+		loop, this flag enables linking to another channel. The link target
+		channel initiates a channel service request via an internal
+		mechanism that sets the TCDn_CSR[START] bit of the specified
+		channel.
+
+		If minor loop channel linking is disabled, this link mechanism is
+		suppressed in favor of the major loop channel linking.
+
+		Major loop channel linking:  As the channel completes the minor
+		loop, this option enables the linking to another channel. The link
+		target channel initiates a channel service request via an internal
+		mechanism that sets the TCDn_CSR[START] bit of the linked channel.
+
+config KINETIS_EDMA_ERCA
+	bool "Round Robin Channel Arbitration"
+	default n
+	---help---
+		Normally, a fixed priority arbitration is used for channel
+		selection.  If this option is selected, round robin arbitration is
+		used for channel selection.
+
+config KINETIS_EDMA_ERGA
+	bool "Round Robin Group Arbitration"
+	default n
+	---help---
+		Normally, a fixed priority arbitration is used for channel
+		selection among the groups.  If this option is selected,
+		round Round robin arbitration is used for selection among
+		the groups.
+
+config KINETIS_EDMA_HOE
+	bool "Halt On Error"
+	default y
+	---help---
+		Any error causes the HALT bit to set. Subsequently, all service
+		requests are ignored until the HALT bit is cleared.
+
+config KINETIS_EDMA_CLM
+	bool "Continuous Link Mode"
+	default n
+	---help---
+		By default, A minor loop channel link made to itself goes through
+		channel arbitration before being activated again.  If this option is
+		selected, a minor loop channel link made to itself does not go
+		through channel arbitration before being activated again. Upon minor
+		loop completion, the channel activates again if that channel has a
+		minor loop channel link enabled and the link channel is itself. This
+		effectively applies the minor loop offsets and restarts the next
+		minor loop.
+
+config KINETIS_EDMA_EMLIM
+	bool "Minor Loop Mapping"
+	default n
+	---help---
+		Normally TCD word 2 is a 32-bit NBYTES field.  When this option is
+		enabled, TCD word 2 is redefined to include individual enable fields,
+		an offset field, and the NBYTES field.  The individual enable fields
+		allow the minor loop offset to be applied to the source address, the
+		destination address, or both. The NBYTES field is reduced when either
+		offset is enabled.
+
+config KINETIS_EDMA_EDBG
+	bool "Enable Debug"
+	default n
+	---help---
+		When in debug mode, the DMA stalls the start of a new channel. Executing
+		channels are allowed to complete. Channel execution resumes when the
+		system exits debug mode or the EDBG bit is cleared
+
+endmenu # eDMA Global Configuration
+
 if KINETIS_USBHS && USBHOST
 
 menu "USB host controller driver (HCD) options"
@@ -1208,42 +1298,42 @@ config KINETIS_UARTFIFOS
 config KINETIS_UART0_RXDMA
 	bool "UART0 Rx DMA"
 	default n
-	depends on KINETIS_UART0 && KINETIS_DMA
+	depends on KINETIS_UART0 && KINETIS_EDMA
 	---help---
 		In high data rate usage, Rx DMA may eliminate Rx overrun errors
 
 config KINETIS_UART1_RXDMA
 	bool "UART1 Rx DMA"
 	default n
-	depends on KINETIS_UART1 && KINETIS_DMA
+	depends on KINETIS_UART1 && KINETIS_EDMA
 	---help---
 		In high data rate usage, Rx DMA may eliminate Rx overrun errors
 
 config KINETIS_UART2_RXDMA
 	bool "UART2 Rx DMA"
 	default n
-	depends on KINETIS_UART2 && KINETIS_DMA
+	depends on KINETIS_UART2 && KINETIS_EDMA
 	---help---
 		In high data rate usage, Rx DMA may eliminate Rx overrun errors
 
 config KINETIS_UART3_RXDMA
 	bool "UART3 Rx DMA"
 	default n
-	depends on KINETIS_UART3 && KINETIS_DMA
+	depends on KINETIS_UART3 && KINETIS_EDMA
 	---help---
 		In high data rate usage, Rx DMA may eliminate Rx overrun errors
 
 config KINETIS_UART4_RXDMA
 	bool "UART4 Rx DMA"
 	default n
-	depends on KINETIS_UART4 && KINETIS_DMA
+	depends on KINETIS_UART4 && KINETIS_EDMA
 	---help---
 		In high data rate usage, Rx DMA may eliminate Rx overrun errors
 
 config KINETIS_UART5_RXDMA
 	bool "UART5 Rx DMA"
 	default n
-	depends on KINETIS_UART5 && KINETIS_DMA
+	depends on KINETIS_UART5 && KINETIS_EDMA
 	---help---
 		In high data rate usage, Rx DMA may eliminate Rx overrun errors
 
diff --git a/arch/arm/src/kinetis/Make.defs b/arch/arm/src/kinetis/Make.defs
index 6b34266..6fd81e4 100644
--- a/arch/arm/src/kinetis/Make.defs
+++ b/arch/arm/src/kinetis/Make.defs
@@ -140,8 +140,8 @@ CHIP_CSRCS += kinetis_usbhshost.c
 endif
 endif
 
-ifeq ($(CONFIG_KINETIS_DMA),y)
-CHIP_CSRCS += kinetis_dma.c kinetis_pindma.c
+ifeq ($(CONFIG_KINETIS_EDMA),y)
+CHIP_CSRCS += kinetis_edma.c kinetis_pindma.c
 endif
 
 ifeq ($(CONFIG_PWM),y)
diff --git a/arch/arm/src/kinetis/hardware/kinetis_dma.h b/arch/arm/src/kinetis/hardware/kinetis_dma.h
deleted file mode 100644
index bd2b941..0000000
--- a/arch/arm/src/kinetis/hardware/kinetis_dma.h
+++ /dev/null
@@ -1,776 +0,0 @@
-/****************************************************************************
- * arch/arm/src/kinetis/hardware/kinetis_dma.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_KINETIS_HARDWARE_KINETIS_DMA_H
-#define __ARCH_ARM_SRC_KINETIS_HARDWARE_KINETIS_DMA_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include "chip.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Register Offsets *********************************************************/
-
-#define KINETIS_DMA_CR_OFFSET             0x0000 /* Control Register */
-#define KINETIS_DMA_ES_OFFSET             0x0004 /* Error Status Register */
-#define KINETIS_DMA_ERQ_OFFSET            0x000c /* Enable Request Register */
-#define KINETIS_DMA_EEI_OFFSET            0x0014 /* Enable Error Interrupt Register */
-#define KINETIS_DMA_CEEI_OFFSET           0x0018 /* Clear Enable Error Interrupt Register */
-#define KINETIS_DMA_SEEI_OFFSET           0x0019 /* Set Enable Error Interrupt Register */
-#define KINETIS_DMA_CERQ_OFFSET           0x001a /* Clear Enable Request Register */
-#define KINETIS_DMA_SERQ_OFFSET           0x001b /* Set Enable Request Register */
-#define KINETIS_DMA_CDNE_OFFSET           0x001c /* Clear DONE Status Bit Register */
-#define KINETIS_DMA_SSRT_OFFSET           0x001d /* Set START Bit Register */
-#define KINETIS_DMA_CERR_OFFSET           0x001e /* Clear Error Register */
-#define KINETIS_DMA_CINT_OFFSET           0x001f /* Clear Interrupt Request Register */
-#define KINETIS_DMA_INT_OFFSET            0x0024 /* Interrupt Request Register */
-#define KINETIS_DMA_ERR_OFFSET            0x002c /* Error Register */
-#define KINETIS_DMA_HRS_OFFSET            0x0034 /* Hardware Request Status Register */
-
-#define KINETIS_DMA_DCHPRI3_OFFSET        0x0100 /* Channel 3 Priority Register */
-#define KINETIS_DMA_DCHPRI2_OFFSET        0x0101 /* Channel 2 Priority Register */
-#define KINETIS_DMA_DCHPRI1_OFFSET        0x0102 /* Channel 1 Priority Register */
-#define KINETIS_DMA_DCHPRI0_OFFSET        0x0103 /* Channel 0 Priority Register */
-#define KINETIS_DMA_DCHPRI7_OFFSET        0x0104 /* Channel 7 Priority Register */
-#define KINETIS_DMA_DCHPRI6_OFFSET        0x0105 /* Channel 6 Priority Register */
-#define KINETIS_DMA_DCHPRI5_OFFSET        0x0106 /* Channel 5 Priority Register */
-#define KINETIS_DMA_DCHPRI4_OFFSET        0x0107 /* Channel 4 Priority Register */
-#define KINETIS_DMA_DCHPRI11_OFFSET       0x0108 /* Channel 11 Priority Register */
-#define KINETIS_DMA_DCHPRI10_OFFSET       0x0109 /* Channel 10 Priority Register */
-#define KINETIS_DMA_DCHPRI9_OFFSET        0x010a /* Channel 9 Priority Register */
-#define KINETIS_DMA_DCHPRI8_OFFSET        0x010b /* Channel 8 Priority Register */
-#define KINETIS_DMA_DCHPRI15_OFFSET       0x010c /* Channel 15 Priority Register */
-#define KINETIS_DMA_DCHPRI14_OFFSET       0x010d /* Channel 14 Priority Register */
-#define KINETIS_DMA_DCHPRI13_OFFSET       0x010e /* Channel 13 Priority Register */
-#define KINETIS_DMA_DCHPRI12_OFFSET       0x010f /* Channel 12 Priority Register */
-
-#define KINETIS_DMA_DCHPRI_OFFSET(n)      0x0100 + (n - (n % 4)) + (3 - (n % 4)) /* Channel n Priority Register */
-
-#define KINETIS_DMA_TCD_OFFSET(n)         (0x0000 + ((n) << 5))
-#define KINETIS_DMA_TCD_SADDR_OFFSET      0x0000 /* TCD Source Address */
-#define KINETIS_DMA_TCD_SOFF_OFFSET       0x0004 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD_ATTR_OFFSET       0x0006 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD_NBYTES_OFFSET     0x0008 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD_SLAST_OFFSET      0x000c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD_DADDR_OFFSET      0x0010 /* TCD Destination Address */
-#define KINETIS_DMA_TCD_DOFF_OFFSET       0x0014 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD_CITER_OFFSET      0x0016 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD_DLASTSGA_OFFSET   0x0018 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD_CSR_OFFSET        0x001c /* TCD Control and Status */
-#define KINETIS_DMA_TCD_BITER_OFFSET      0x001e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD0_SADDR_OFFSET     0x0000 /* TCD Source Address */
-#define KINETIS_DMA_TCD0_SOFF_OFFSET      0x0004 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD0_ATTR_OFFSET      0x0006 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD0_NBYTES_OFFSET    0x0008 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD0_SLAST_OFFSET     0x000c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD0_DADDR_OFFSET     0x0010 /* TCD Destination Address */
-#define KINETIS_DMA_TCD0_DOFF_OFFSET      0x0014 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD0_CITER_OFFSET     0x0016 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD0_DLASTSGA_OFFSET  0x0018 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD0_CSR_OFFSET       0x001c /* TCD Control and Status */
-#define KINETIS_DMA_TCD0_BITER_OFFSET     0x001e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD1_SADDR_OFFSET     0x0020 /* TCD Source Address */
-#define KINETIS_DMA_TCD1_SOFF_OFFSET      0x0024 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD1_ATTR_OFFSET      0x0026 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD1_NBYTES_OFFSET    0x0028 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD1_SLAST_OFFSET     0x002c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD1_DADDR_OFFSET     0x0030 /* TCD Destination Address */
-#define KINETIS_DMA_TCD1_DOFF_OFFSET      0x0034 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD1_CITER_OFFSET     0x0036 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD1_DLASTSGA_OFFSET  0x0038 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD1_CSR_OFFSET       0x003c /* TCD Control and Status */
-#define KINETIS_DMA_TCD1_BITER_OFFSET     0x003e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD2_SADDR_OFFSET     0x0040 /* TCD Source Address */
-#define KINETIS_DMA_TCD2_SOFF_OFFSET      0x0044 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD2_ATTR_OFFSET      0x0046 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD2_NBYTES_OFFSET    0x0048 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD2_SLAST_OFFSET     0x004c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD2_DADDR_OFFSET     0x0050 /* TCD Destination Address */
-#define KINETIS_DMA_TCD2_DOFF_OFFSET      0x0054 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD2_CITER_OFFSET     0x0056 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD2_DLASTSGA_OFFSET  0x0058 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD2_CSR_OFFSET       0x005c /* TCD Control and Status */
-#define KINETIS_DMA_TCD2_BITER_OFFSET     0x005e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD3_SADDR_OFFSET     0x0060 /* TCD Source Address */
-#define KINETIS_DMA_TCD3_SOFF_OFFSET      0x0064 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD3_ATTR_OFFSET      0x0066 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD3_NBYTES_OFFSET    0x0068 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD3_SLAST_OFFSET     0x006c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD3_DADDR_OFFSET     0x0070 /* TCD Destination Address */
-#define KINETIS_DMA_TCD3_DOFF_OFFSET      0x0074 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD3_CITER_OFFSET     0x0076 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD3_DLASTSGA_OFFSET  0x0078 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD3_CSR_OFFSET       0x007c /* TCD Control and Status */
-#define KINETIS_DMA_TCD3_BITER_OFFSET     0x007e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD4_SADDR_OFFSET     0x0080 /* TCD Source Address */
-#define KINETIS_DMA_TCD4_SOFF_OFFSET      0x0084 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD4_ATTR_OFFSET      0x0086 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD4_NBYTES_OFFSET    0x0088 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD4_SLAST_OFFSET     0x008c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD4_DADDR_OFFSET     0x0090 /* TCD Destination Address */
-#define KINETIS_DMA_TCD4_DOFF_OFFSET      0x0094 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD4_CITER_OFFSET     0x0096 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD4_DLASTSGA_OFFSET  0x0098 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD4_CSR_OFFSET       0x009c /* TCD Control and Status */
-#define KINETIS_DMA_TCD4_BITER_OFFSET     0x009e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD5_SADDR_OFFSET     0x00a0 /* TCD Source Address */
-#define KINETIS_DMA_TCD5_SOFF_OFFSET      0x00a4 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD5_ATTR_OFFSET      0x00a6 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD5_NBYTES_OFFSET    0x00a8 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD5_SLAST_OFFSET     0x00ac /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD5_DADDR_OFFSET     0x00b0 /* TCD Destination Address */
-#define KINETIS_DMA_TCD5_DOFF_OFFSET      0x00b4 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD5_CITER_OFFSET     0x00b6 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD5_DLASTSGA_OFFSET  0x00b8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD5_CSR_OFFSET       0x00bc /* TCD Control and Status */
-#define KINETIS_DMA_TCD5_BITER_OFFSET     0x00be /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD6_SADDR_OFFSET     0x00c0 /* TCD Source Address */
-#define KINETIS_DMA_TCD6_SOFF_OFFSET      0x00c4 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD6_ATTR_OFFSET      0x00c6 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD6_NBYTES_OFFSET    0x00c8 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD6_SLAST_OFFSET     0x00cc /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD6_DADDR_OFFSET     0x00d0 /* TCD Destination Address */
-#define KINETIS_DMA_TCD6_DOFF_OFFSET      0x00d4 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD6_CITER_OFFSET     0x00d6 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD6_DLASTSGA_OFFSET  0x00d8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD6_CSR_OFFSET       0x00dc /* TCD Control and Status */
-#define KINETIS_DMA_TCD6_BITER_OFFSET     0x00de /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD7_SADDR_OFFSET     0x00e0 /* TCD Source Address */
-#define KINETIS_DMA_TCD7_SOFF_OFFSET      0x00e4 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD7_ATTR_OFFSET      0x00e6 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD7_NBYTES_OFFSET    0x00e8 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD7_SLAST_OFFSET     0x00ec /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD7_DADDR_OFFSET     0x00f0 /* TCD Destination Address */
-#define KINETIS_DMA_TCD7_DOFF_OFFSET      0x00f4 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD7_CITER_OFFSET     0x00f6 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD7_DLASTSGA_OFFSET  0x00f8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD7_CSR_OFFSET       0x00fc /* TCD Control and Status */
-#define KINETIS_DMA_TCD7_BITER_OFFSET     0x00fe /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD8_SADDR_OFFSET     0x0100 /* TCD Source Address */
-#define KINETIS_DMA_TCD8_SOFF_OFFSET      0x0104 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD8_ATTR_OFFSET      0x0106 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD8_NBYTES_OFFSET    0x0108 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD8_SLAST_OFFSET     0x010c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD8_DADDR_OFFSET     0x0110 /* TCD Destination Address */
-#define KINETIS_DMA_TCD8_DOFF_OFFSET      0x0114 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD8_CITER_OFFSET     0x0116 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD8_DLASTSGA_OFFSET  0x0118 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD8_CSR_OFFSET       0x011c /* TCD Control and Status */
-#define KINETIS_DMA_TCD8_BITER_OFFSET     0x011e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD9_SADDR_OFFSET     0x0120 /* TCD Source Address */
-#define KINETIS_DMA_TCD9_SOFF_OFFSET      0x0124 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD9_ATTR_OFFSET      0x0126 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD9_NBYTES_OFFSET    0x0128 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD9_SLAST_OFFSET     0x012c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD9_DADDR_OFFSET     0x0130 /* TCD Destination Address */
-#define KINETIS_DMA_TCD9_DOFF_OFFSET      0x0134 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD9_CITER_OFFSET     0x0136 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD9_DLASTSGA_OFFSET  0x0138 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD9_CSR_OFFSET       0x013c /* TCD Control and Status */
-#define KINETIS_DMA_TCD9_BITER_OFFSET     0x013e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD10_SADDR_OFFSET    0x0140 /* TCD Source Address */
-#define KINETIS_DMA_TCD10_SOFF_OFFSET     0x0144 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD10_ATTR_OFFSET     0x0146 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD10_NBYTES_OFFSET   0x0148 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD10_SLAST_OFFSET    0x014c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD10_DADDR_OFFSET    0x0150 /* TCD Destination Address */
-#define KINETIS_DMA_TCD10_DOFF_OFFSET     0x0154 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD10_CITER_OFFSET    0x0156 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD10_DLASTSGA_OFFSET 0x0158 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD10_CSR_OFFSET      0x015c /* TCD Control and Status */
-#define KINETIS_DMA_TCD10_BITER_OFFSET    0x015e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD11_SADDR_OFFSET    0x0160 /* TCD Source Address */
-#define KINETIS_DMA_TCD11_SOFF_OFFSET     0x0164 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD11_ATTR_OFFSET     0x0166 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD11_NBYTES_OFFSET   0x0168 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD11_SLAST_OFFSET    0x016c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD11_DADDR_OFFSET    0x0170 /* TCD Destination Address */
-#define KINETIS_DMA_TCD11_DOFF_OFFSET     0x0174 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD11_CITER_OFFSET    0x0176 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD11_DLASTSGA_OFFSET 0x0178 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD11_CSR_OFFSET      0x017c /* TCD Control and Status */
-#define KINETIS_DMA_TCD11_BITER_OFFSET    0x017e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD12_SADDR_OFFSET    0x0180 /* TCD Source Address */
-#define KINETIS_DMA_TCD12_SOFF_OFFSET     0x0184 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD12_ATTR_OFFSET     0x0186 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD12_NBYTES_OFFSET   0x0188 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD12_SLAST_OFFSET    0x018c /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD12_DADDR_OFFSET    0x0190 /* TCD Destination Address */
-#define KINETIS_DMA_TCD12_DOFF_OFFSET     0x0194 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD12_CITER_OFFSET    0x0196 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD12_DLASTSGA_OFFSET 0x0198 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD12_CSR_OFFSET      0x019c /* TCD Control and Status */
-#define KINETIS_DMA_TCD12_BITER_OFFSET    0x019e /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD13_SADDR_OFFSET    0x01a0 /* TCD Source Address */
-#define KINETIS_DMA_TCD13_SOFF_OFFSET     0x01a4 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD13_ATTR_OFFSET     0x01a6 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD13_NBYTES_OFFSET   0x01a8 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD13_SLAST_OFFSET    0x01ac /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD13_DADDR_OFFSET    0x01b0 /* TCD Destination Address */
-#define KINETIS_DMA_TCD13_DOFF_OFFSET     0x01b4 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD13_CITER_OFFSET    0x01b6 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD13_DLASTSGA_OFFSET 0x01b8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD13_CSR_OFFSET      0x01bc /* TCD Control and Status */
-#define KINETIS_DMA_TCD13_BITER_OFFSET    0x01be /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD14_SADDR_OFFSET    0x01c0 /* TCD Source Address */
-#define KINETIS_DMA_TCD14_SOFF_OFFSET     0x01c4 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD14_ATTR_OFFSET     0x01c6 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD14_NBYTES_OFFSET   0x01c8 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD14_SLAST_OFFSET    0x01cc /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD14_DADDR_OFFSET    0x01d0 /* TCD Destination Address */
-#define KINETIS_DMA_TCD14_DOFF_OFFSET     0x01d4 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD14_CITER_OFFSET    0x01d6 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD14_DLASTSGA_OFFSET 0x01d8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD14_CSR_OFFSET      0x01dc /* TCD Control and Status */
-#define KINETIS_DMA_TCD14_BITER_OFFSET    0x01de /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-#define KINETIS_DMA_TCD15_SADDR_OFFSET    0x01e0 /* TCD Source Address */
-#define KINETIS_DMA_TCD15_SOFF_OFFSET     0x01e4 /* TCD Signed Source Address Offset */
-#define KINETIS_DMA_TCD15_ATTR_OFFSET     0x01e6 /* TCD Transfer Attributes */
-#define KINETIS_DMA_TCD15_NBYTES_OFFSET   0x01e8 /* TCD Minor Byte Count */
-#define KINETIS_DMA_TCD15_SLAST_OFFSET    0x01ec /* TCD Last Source Address Adjustment */
-#define KINETIS_DMA_TCD15_DADDR_OFFSET    0x01f0 /* TCD Destination Address */
-#define KINETIS_DMA_TCD15_DOFF_OFFSET     0x01f4 /* TCD Signed Destination Address Offset */
-#define KINETIS_DMA_TCD15_CITER_OFFSET    0x01f6 /* TCD Current Minor Loop Link, Major Loop Count */
-#define KINETIS_DMA_TCD15_DLASTSGA_OFFSET 0x01f8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */
-#define KINETIS_DMA_TCD15_CSR_OFFSET      0x01fc /* TCD Control and Status */
-#define KINETIS_DMA_TCD15_BITER_OFFSET    0x01fe /* TCD Beginning Minor Loop Link, Major Loop Count */
-
-/* Register Addresses *******************************************************/
-
-#define KINETIS_DMA_CR                    (KINETIS_DMAC_BASE + KINETIS_DMA_CR_OFFSET)
-#define KINETIS_DMA_ES                    (KINETIS_DMAC_BASE + KINETIS_DMA_ES_OFFSET)
-#define KINETIS_DMA_ERQ                   (KINETIS_DMAC_BASE + KINETIS_DMA_ERQ_OFFSET)
-#define KINETIS_DMA_EEI                   (KINETIS_DMAC_BASE + KINETIS_DMA_EEI_OFFSET)
-#define KINETIS_DMA_CEEI                  (KINETIS_DMAC_BASE + KINETIS_DMA_CEEI_OFFSET)
-#define KINETIS_DMA_SEEI                  (KINETIS_DMAC_BASE + KINETIS_DMA_SEEI_OFFSET)
-#define KINETIS_DMA_CERQ                  (KINETIS_DMAC_BASE + KINETIS_DMA_CERQ_OFFSET)
-#define KINETIS_DMA_SERQ                  (KINETIS_DMAC_BASE + KINETIS_DMA_SERQ_OFFSET)
-#define KINETIS_DMA_CDNE                  (KINETIS_DMAC_BASE + KINETIS_DMA_CDNE_OFFSET)
-#define KINETIS_DMA_SSRT                  (KINETIS_DMAC_BASE + KINETIS_DMA_SSRT_OFFSET)
-#define KINETIS_DMA_CERR                  (KINETIS_DMAC_BASE + KINETIS_DMA_CERR_OFFSET)
-#define KINETIS_DMA_CINT                  (KINETIS_DMAC_BASE + KINETIS_DMA_CINT_OFFSET)
-#define KINETIS_DMA_INT                   (KINETIS_DMAC_BASE + KINETIS_DMA_INT_OFFSET)
-#define KINETIS_DMA_ERR                   (KINETIS_DMAC_BASE + KINETIS_DMA_ERR_OFFSET)
-#define KINETIS_DMA_HRS                   (KINETIS_DMAC_BASE + KINETIS_DMA_HRS_OFFSET)
-
-#define KINETIS_DMA_DCHPRI(n)             (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI_OFFSET(n))
-
-#define KINETIS_DMA_DCHPRI3               (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI3_OFFSET)
-#define KINETIS_DMA_DCHPRI2               (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI2_OFFSET)
-#define KINETIS_DMA_DCHPRI1               (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI1_OFFSET)
-#define KINETIS_DMA_DCHPRI0               (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI0_OFFSET)
-#define KINETIS_DMA_DCHPRI7               (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI7_OFFSET)
-#define KINETIS_DMA_DCHPRI6               (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI6_OFFSET)
-#define KINETIS_DMA_DCHPRI5               (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI5_OFFSET)
-#define KINETIS_DMA_DCHPRI4               (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI4_OFFSET)
-#define KINETIS_DMA_DCHPRI11              (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI11_OFFSET)
-#define KINETIS_DMA_DCHPRI10              (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI10_OFFSET)
-#define KINETIS_DMA_DCHPRI9               (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI9_OFFSET)
-#define KINETIS_DMA_DCHPRI8               (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI8_OFFSET)
-#define KINETIS_DMA_DCHPRI15              (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI15_OFFSET)
-#define KINETIS_DMA_DCHPRI14              (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI14_OFFSET)
-#define KINETIS_DMA_DCHPRI13              (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI13_OFFSET)
-#define KINETIS_DMA_DCHPRI12              (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI12_OFFSET)
-
-#define KINETIS_DMA_TCD_BASE(n)           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD_OFFSET(n))
-
-#define KINETIS_DMA_TCD_SADDR(n)          (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SADDR_OFFSET)
-#define KINETIS_DMA_TCD_SOFF(n)           (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SOFF_OFFSET)
-#define KINETIS_DMA_TCD_ATTR(n)           (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_ATTR_OFFSET)
-#define KINETIS_DMA_TCD_NBYTES(n)         (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD_SLAST(n)          (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SLAST_OFFSET)
-#define KINETIS_DMA_TCD_DADDR(n)          (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DADDR_OFFSET)
-#define KINETIS_DMA_TCD_DOFF(n)           (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DOFF_OFFSET)
-#define KINETIS_DMA_TCD_CITER(n)          (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_CITER_OFFSET)
-#define KINETIS_DMA_TCD_DLASTSGA(n)       (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD_CSR(n)            (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_CSR_OFFSET)
-#define KINETIS_DMA_TCD_BITER(n)          (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD0_SADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_SADDR_OFFSET)
-#define KINETIS_DMA_TCD0_SOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_SOFF_OFFSET)
-#define KINETIS_DMA_TCD0_ATTR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_ATTR_OFFSET)
-#define KINETIS_DMA_TCD0_NBYTES           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD0_SLAST            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_SLAST_OFFSET)
-#define KINETIS_DMA_TCD0_DADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_DADDR_OFFSET)
-#define KINETIS_DMA_TCD0_DOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_DOFF_OFFSET)
-#define KINETIS_DMA_TCD0_CITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_CITER_OFFSET)
-#define KINETIS_DMA_TCD0_DLASTSGA         (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD0_CSR              (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_CSR_OFFSET)
-#define KINETIS_DMA_TCD0_BITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD1_SADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_SADDR_OFFSET)
-#define KINETIS_DMA_TCD1_SOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_SOFF_OFFSET)
-#define KINETIS_DMA_TCD1_ATTR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_ATTR_OFFSET)
-#define KINETIS_DMA_TCD1_NBYTES           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD1_SLAST            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_SLAST_OFFSET)
-#define KINETIS_DMA_TCD1_DADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_DADDR_OFFSET)
-#define KINETIS_DMA_TCD1_DOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_DOFF_OFFSET)
-#define KINETIS_DMA_TCD1_CITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_CITER_OFFSET)
-#define KINETIS_DMA_TCD1_DLASTSGA         (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD1_CSR              (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_CSR_OFFSET)
-#define KINETIS_DMA_TCD1_BITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD2_SADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_SADDR_OFFSET)
-#define KINETIS_DMA_TCD2_SOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_SOFF_OFFSET)
-#define KINETIS_DMA_TCD2_ATTR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_ATTR_OFFSET)
-#define KINETIS_DMA_TCD2_NBYTES           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD2_SLAST            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_SLAST_OFFSET)
-#define KINETIS_DMA_TCD2_DADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_DADDR_OFFSET)
-#define KINETIS_DMA_TCD2_DOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_DOFF_OFFSET)
-#define KINETIS_DMA_TCD2_CITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_CITER_OFFSET)
-#define KINETIS_DMA_TCD2_DLASTSGA         (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD2_CSR_             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_CSR_OFFSET)
-#define KINETIS_DMA_TCD2_BITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD3_SADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_SADDR_OFFSET)
-#define KINETIS_DMA_TCD3_SOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_SOFF_OFFSET)
-#define KINETIS_DMA_TCD3_ATTR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_ATTR_OFFSET)
-#define KINETIS_DMA_TCD3_NBYTES           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD3_SLAST            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_SLAST_OFFSET)
-#define KINETIS_DMA_TCD3_DADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_DADDR_OFFSET)
-#define KINETIS_DMA_TCD3_DOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_DOFF_OFFSET)
-#define KINETIS_DMA_TCD3_CITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_CITER_OFFSET)
-#define KINETIS_DMA_TCD3_DLASTSGA         (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_DLASTSGA_OFFSET
-#define KINETIS_DMA_TCD3_CSR              (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_CSR_OFFSET)
-#define KINETIS_DMA_TCD3_BITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD4_SADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_SADDR_OFFSET)
-#define KINETIS_DMA_TCD4_SOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_SOFF_OFFSET)
-#define KINETIS_DMA_TCD4_ATTR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_ATTR_OFFSET0)
-#define KINETIS_DMA_TCD4_NBYTES           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD4_SLAST            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_SLAST_OFFSET)
-#define KINETIS_DMA_TCD4_DADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_DADDR_OFFSET)
-#define KINETIS_DMA_TCD4_DOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_DOFF_OFFSET)
-#define KINETIS_DMA_TCD4_CITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_CITER_OFFSET)
-#define KINETIS_DMA_TCD4_DLASTSGA         (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD4_CSR              (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_CSR_OFFSET)
-#define KINETIS_DMA_TCD4_BITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD5_SADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_SADDR_OFFSET)
-#define KINETIS_DMA_TCD5_SOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_SOFF_OFFSET)
-#define KINETIS_DMA_TCD5_ATTR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_ATTR_OFFSET)
-#define KINETIS_DMA_TCD5_NBYTES           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD5_SLAST            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_SLAST_OFFSET)
-#define KINETIS_DMA_TCD5_DADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_DADDR_OFFSET)
-#define KINETIS_DMA_TCD5_DOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_DOFF_OFFSET)
-#define KINETIS_DMA_TCD5_CITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_CITER_OFFSET)
-#define KINETIS_DMA_TCD5_DLASTSGA         (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD5_CSR              (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_CSR_OFFSET)
-#define KINETIS_DMA_TCD5_BITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD6_SADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_SADDR_OFFSET)
-#define KINETIS_DMA_TCD6_SOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_SOFF_OFFSET)
-#define KINETIS_DMA_TCD6_ATTR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_ATTR_OFFSET)
-#define KINETIS_DMA_TCD6_NBYTES           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD6_SLAST            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_SLAST_OFFSET)
-#define KINETIS_DMA_TCD6_DADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_DADDR_OFFSET)
-#define KINETIS_DMA_TCD6_DOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_DOFF_OFFSET)
-#define KINETIS_DMA_TCD6_CITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_CITER_OFFSET)
-#define KINETIS_DMA_TCD6_DLASTSGA         (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD6_CSR              (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_CSR_OFFSET)
-#define KINETIS_DMA_TCD6_BITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD7_SADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_SADDR_OFFSET)
-#define KINETIS_DMA_TCD7_SOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_SOFF_OFFSET)
-#define KINETIS_DMA_TCD7_ATTR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_ATTR_OFFSET)
-#define KINETIS_DMA_TCD7_NBYTES           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD7_SLAST            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_SLAST_OFFSET)
-#define KINETIS_DMA_TCD7_DADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_DADDR_OFFSET)
-#define KINETIS_DMA_TCD7_DOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_DOFF_OFFSET)
-#define KINETIS_DMA_TCD7_CITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_CITER_OFFSET)
-#define KINETIS_DMA_TCD7_DLASTSGA_        (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD7_CSR              (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_CSR_OFFSET)
-#define KINETIS_DMA_TCD7_BITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD8_SADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_SADDR_OFFSET)
-#define KINETIS_DMA_TCD8_SOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_SOFF_OFFSET)
-#define KINETIS_DMA_TCD8_ATTR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_ATTR_OFFSET)
-#define KINETIS_DMA_TCD8_NBYTES           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD8_SLAST            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_SLAST_OFFSET)
-#define KINETIS_DMA_TCD8_DADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_DADDR_OFFSET)
-#define KINETIS_DMA_TCD8_DOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_DOFF_OFFSET)
-#define KINETIS_DMA_TCD8_CITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_CITER_OFFSET)
-#define KINETIS_DMA_TCD8_DLASTSGA         (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD8_CSR              (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_CSR_OFFSET)
-#define KINETIS_DMA_TCD8_BITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD9_SADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_SADDR_OFFSET)
-#define KINETIS_DMA_TCD9_SOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_SOFF_OFFSET)
-#define KINETIS_DMA_TCD9_ATTR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_ATTR_OFFSET)
-#define KINETIS_DMA_TCD9_NBYTES           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD9_SLAST            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_SLAST_OFFSET)
-#define KINETIS_DMA_TCD9_DADDR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_DADDR_OFFSET)
-#define KINETIS_DMA_TCD9_DOFF             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_DOFF_OFFSET)
-#define KINETIS_DMA_TCD9_CITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_CITER_OFFSET)
-#define KINETIS_DMA_TCD9_DLASTSGA         (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD9_CSR              (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_CSR_OFFSET)
-#define KINETIS_DMA_TCD9_BITER            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD10_SADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_SADDR_OFFSET)
-#define KINETIS_DMA_TCD10_SOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_SOFF_OFFSET)
-#define KINETIS_DMA_TCD10_ATTR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_ATTR_OFFSET)
-#define KINETIS_DMA_TCD10_NBYTES          (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD10_SLAST           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_SLAST_OFFSET)
-#define KINETIS_DMA_TCD10_DADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_DADDR_OFFSET)
-#define KINETIS_DMA_TCD10_DOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_DOFF_OFFSET)
-#define KINETIS_DMA_TCD10_CITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_CITER_OFFSET)
-#define KINETIS_DMA_TCD10_DLASTSGA        (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD10_CSR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_CSR_OFFSET)
-#define KINETIS_DMA_TCD10_BITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD11_SADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_SADDR_OFFSET)
-#define KINETIS_DMA_TCD11_SOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_SOFF_OFFSET)
-#define KINETIS_DMA_TCD11_ATTR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_ATTR_OFFSET)
-#define KINETIS_DMA_TCD11_NBYTES          (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD11_SLAST           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_SLAST_OFFSET)
-#define KINETIS_DMA_TCD11_DADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_DADDR_OFFSET)
-#define KINETIS_DMA_TCD11_DOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_DOFF_OFFSET)
-#define KINETIS_DMA_TCD11_CITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_CITER_OFFSET)
-#define KINETIS_DMA_TCD11_DLASTSGA        (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD11_CSR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_CSR_OFFSET)
-#define KINETIS_DMA_TCD11_BITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD12_SADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_SADDR_OFFSET)
-#define KINETIS_DMA_TCD12_SOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_SOFF_OFFSET)
-#define KINETIS_DMA_TCD12_ATTR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_ATTR_OFFSET)
-#define KINETIS_DMA_TCD12_NBYTES          (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD12_SLAST           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_SLAST_OFFSET)
-#define KINETIS_DMA_TCD12_DADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_DADDR_OFFSET)
-#define KINETIS_DMA_TCD12_DOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_DOFF_OFFSET)
-#define KINETIS_DMA_TCD12_CITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_CITER_OFFSET)
-#define KINETIS_DMA_TCD12_DLASTSGA        (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD12_CSR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_CSR_OFFSET)
-#define KINETIS_DMA_TCD12_BITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD13_SADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_SADDR_OFFSET)
-#define KINETIS_DMA_TCD13_SOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_SOFF_OFFSET)
-#define KINETIS_DMA_TCD13_ATTR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_ATTR_OFFSET)
-#define KINETIS_DMA_TCD13_NBYTES          (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD13_SLAST           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_SLAST_OFFSET)
-#define KINETIS_DMA_TCD13_DADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_DADDR_OFFSET)
-#define KINETIS_DMA_TCD13_DOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_DOFF_OFFSET)
-#define KINETIS_DMA_TCD13_CITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_CITER_OFFSET)
-#define KINETIS_DMA_TCD13_DLASTSGA        (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD13_CSR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_CSR_OFFSET)
-#define KINETIS_DMA_TCD13_BITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD14_SADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_SADDR_OFFSET)
-#define KINETIS_DMA_TCD14_SOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_SOFF_OFFSET)
-#define KINETIS_DMA_TCD14_ATTR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_ATTR_OFFSET)
-#define KINETIS_DMA_TCD14_NBYTES          (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD14_SLAST           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_SLAST_OFFSET)
-#define KINETIS_DMA_TCD14_DADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_DADDR_OFFSET)
-#define KINETIS_DMA_TCD14_DOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_DOFF_OFFSET)
-#define KINETIS_DMA_TCD14_CITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_CITER_OFFSET)
-#define KINETIS_DMA_TCD14_DLASTSGA        (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD14_CSR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_CSR_OFFSET)
-#define KINETIS_DMA_TCD14_BITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_BITER_OFFSET)
-
-#define KINETIS_DMA_TCD15_SADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_SADDR_OFFSET)
-#define KINETIS_DMA_TCD15_SOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_SOFF_OFFSET)
-#define KINETIS_DMA_TCD15_ATTR            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_ATTR_OFFSET)
-#define KINETIS_DMA_TCD15_NBYTES          (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_NBYTES_OFFSET)
-#define KINETIS_DMA_TCD15_SLAST           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_SLAST_OFFSET)
-#define KINETIS_DMA_TCD15_DADDR           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_DADDR_OFFSET)
-#define KINETIS_DMA_TCD15_DOFF            (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_DOFF_OFFSET)
-#define KINETIS_DMA_TCD15_CITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_CITER_OFFSET)
-#define KINETIS_DMA_TCD15_DLASTSGA        (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_DLASTSGA_OFFSET)
-#define KINETIS_DMA_TCD15_CSR             (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_CSR_OFFSET)
-#define KINETIS_DMA_TCD15_BITER           (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_BITER_OFFSET)
-
-/* Register Bit Definitions *************************************************/
-
-/* Control Register (32-bit) */
-
-                                                    /* Bit 0:  Reserved */
-#define DMA_CR_EDBG                       (1 << 1)  /* Bit 1:  Enable debug */
-#define DMA_CR_ERCA                       (1 << 2)  /* Bit 2:  Enable round robin channel arbitration */
-#if defined  KINETIS_DMA_HAS_CR_ERGA
-#  define DMA_CR_ERGA                     (1 << 3)  /* Bit 3:  Enable round robin group arbitration */
-#endif
-#define DMA_CR_HOE                        (1 << 4)  /* Bit 4:  Halt on error */
-#define DMA_CR_HALT                       (1 << 5)  /* Bit 5:  Halt DMA operations */
-#define DMA_CR_CLM                        (1 << 6)  /* Bit 6:  Continuous link mode */
-#define DMA_CR_EMLM                       (1 << 7)  /* Bit 7:  Enable minor loop mapping */
-#ifdef KINETIS_DMA_HAS_CR_GRP0PRI
-#   define DMA_CR_GRP0PRI                 (1 << 8)  /* Bit 8:  Channel Group 0 Priority */
-#endif
-                                                    /* Bit 9: Reserved */
-#ifdef KINETIS_DMA_HAS_CR_GRP1PRI
-#  define DMA_CR_GRP1PRI                  (1 << 10) /* Bit 10: Channel Group 1 Priority */
-#endif
-                                                    /* Bits 11-15: Reserved */
-#define DMA_CR_ECX                        (1 << 16) /* Bit 16: Error cancel transfer */
-#define DMA_CR_CX                         (1 << 17) /* Bit 17: Cancel transfer */
-                                                    /* Bits 18-31: Reserved */
-
-/* Error Status Register */
-
-#define DMA_ES_DBE                        (1 << 0)  /* Bit 0:  Destination bus error */
-#define DMA_ES_SBE                        (1 << 1)  /* Bit 1:  Source bus error */
-#define DMA_ES_SGE                        (1 << 2)  /* Bit 2:  Scatter/gather configuration error */
-#define DMA_ES_NCE                        (1 << 3)  /* Bit 3:  NBYTES/CITER configuration error */
-#define DMA_ES_DOE                        (1 << 4)  /* Bit 4:  Destination offset error */
-#define DMA_ES_DAE                        (1 << 5)  /* Bit 5:  Destination address error */
-#define DMA_ES_SOE                        (1 << 6)  /* Bit 6:  Source offset error */
-#define DMA_ES_SAE                        (1 << 7)  /* Bit 7:  Source address error */
-#define DMA_ES_ERRCHN_SHIFT               (8)       /* Bits 8-11/12: Error channel number or cancelled channel number */
-#define DMA_ES_ERRCHN_MASK                (((1 << KINETIS_DMA_HAS_ES_ERRCHN_BITS) - 1) << DMA_ES_ERRCHN_SHIFT)
-                                                    /* Bits 13: Reserved */
-#define DMA_ES_CPE                        (1 << 14) /* Bit 14:  Channel priority error */
-#ifdef KINETIS_DMA_HAS_ES_GPE
-#  define DMA_ES_GPE                      (1 << 15) /* Bit 15:  Group priority error */
-#endif
-#define DMA_ES_ECX                        (1 << 16) /* Bit 16:  Transfer cancelled */
-                                                    /* Bits 17-30: Reserved */
-#define DMA_ES_VLD                        (1 << 31) /* Bit 31:  Logical OR of all ERR status bits */
-
-/* Enable Request Register (ERQ), Enable Error Interrupt Register (EEI),
- * Interrupt Request Register (INT), Error Register (ERR),
- * Hardware Request Status Register (HRS) common bit definitions
- */
-
-#define DMA_REQ(n)                        (1 << (n)) /* Bit n: DMA Request n, n=0..<KINETIS_NDMACH */
-                                                     /* Bits KINETIS_NDMACH-31: Reserved */
-
-/* Clear Enable Error Interrupt Register (8-bit) */
-
-#define DMA_CEEI_SHIFT                    (0)       /* Bits 0-3/4: Clear enable error interrupt */
-#define DMA_CEEI_MASK                     (((1 << KINETIS_DMA_HAS_CEEI_CEEI_BITS) - 1) << DMA_CEEI_SHIFT)
-                                                    /* Bits 5: Reserved */
-#define DMA_CEEI_CAEE                     (1 << 6)  /* Bit 6:  Clear all enable error interrupts */
-#define DMA_CEEI_NOP                      (1 << 7)  /* Bit 7:  No operation */
-
-/* Set Enable Error Interrupt Register (8-bit) */
-
-#define DMA_SEEI_SHIFT                    (0)       /* Bits 0-3/4: Set enable error interrupt */
-#define DMA_SEEI_MASK                     (((1 << KINETIS_DMA_HAS_SEEI_SEEI_BITS) - 1) << DMA_SEEI_SHIFT)
-                                                    /* Bits 5: Reserved */
-#define DMA_SEEI_SAEE                     (1 << 6)  /* Bit 6:  Set all enable error interrupts */
-#define DMA_SEEI_NOP                      (1 << 7)  /* Bit 7:  No operation */
-
-/* Clear Enable Request Register (8-bit) */
-
-#define DMA_CERQ_SHIFT                    (0)       /* Bits 0-3: Clear enable request */
-#define DMA_CERQ_MASK                     (((1 << KINETIS_DMA_HAS_CERQ_CERQ_BITS) - 1) << DMA_CERQ_SHIFT)
-                                                    /* Bits 4-5: Reserved */
-#define DMA_CERQ_CAER                     (1 << 6)  /* Bit 6:  Clear all enable requests */
-#define DMA_CERQ_NOP                      (1 << 7)  /* Bit 7:  No operation */
-
-/* Set Enable Request Register (8-bit) */
-
-#define DMA_SERQ_SHIFT                    (0)       /* Bits 0-3: Set enable request */
-#define DMA_SERQ_MASK                     (((1 << KINETIS_DMA_HAS_SERQ_SERQ_BITS) - 1) << DMA_SERQ_SHIFT)
-                                                    /* Bits 4-5: Reserved */
-#define DMA_SERQ_SAER                     (1 << 6)  /* Bit 6:  Set all enable requests */
-#define DMA_SERQ_NOP                      (1 << 7)  /* Bit 7:  No operation */
-
-/* Clear DONE Status Bit Register (8-bit) */
-#define DMA_CDNE_SHIFT                    (0)       /* Bits 0-3: Clear DONE bit */
-#define DMA_CDNE_MASK                     (((1 << KINETIS_DMA_HAS_CDNE_CDNE_BITS) - 1) << DMA_CDNE_SHIFT)
-                                                    /* Bits 4-5: Reserved */
-#define DMA_CDNE_CADN                     (1 << 6)  /* Bit 6:  Clears all DONE bits */
-#define DMA_CDNE_NOP                      (1 << 7)  /* Bit 7:  No operation */
-
-/* Set START Bit Register (8-bit) */
-
-#define DMA_SSRT_SHIFT                    (0)       /* Bits 0-3: Set START bit */
-#define DMA_SSRT_MASK                     (((1 << KINETIS_DMA_HAS_SSRT_SSRT_BITS) - 1) << DMA_SSRT_SHIFT)
-                                                    /* Bits 4-5: Reserved */
-#define DMA_SSRT_SAST                     (1 << 6)  /* Bit 6:  Set all START bits (activates all channels) */
-#define DMA_SSRT_NOP                      (1 << 7)  /* Bit 7:  No operation */
-
-/* Clear Error Register (8-bit) */
-
-#define DMA_CERR_SHIFT                    (0)       /* Bits 0-3: Clear error indicator */
-#define DMA_CERR_MASK                     (((1 << KINETIS_DMA_HAS_CERR_CERR_BITS) - 1) << DMA_CERR_SHIFT)
-                                                    /* Bits 4-5: Reserved */
-#define DMA_CERR_CAEI                     (1 << 6)  /* Bit 6:  Clear all error indicators */
-#define DMA_CERR_NOP                      (1 << 7)  /* Bit 7:  No operation */
-
-/* Clear Interrupt Request Register (8-bit) */
-
-#define DMA_CINT_SHIFT                    (0)       /* Bits 0-3: Clear interrupt request */
-#define DMA_CINT_MASK                     (((1 << KINETIS_DMA_HAS_CINT_CINT_BITS) - 1) << DMA_CINT_SHIFT)
-                                                    /* Bits 4-5: Reserved */
-#define DMA_CINT_CAIR                     (1 << 6)  /* Bit 6:  Clear all interrupt requests */
-#define DMA_CINT_NOP                      (1 << 7)  /* Bit 7:  No operation */
-
-/* Channel n Priority Register (8-bit) */
-
-#define DMA_DCHPR_SHIFT                   (0)       /* Bits 0-3: Channel n arbitration priority */
-#define DMA_DCHPR_MASK                    (((1 << KINETIS_DMA_HAS_DCHPRI_CHPRI_BITS) - 1) << DMA_DCHPR_SHIFT)
-#ifdef KINETIS_DMA_HAS_DCHPRI_GRPPRI
-#  define DMA_DCHPR_GRPPRI                (1 << 4)  /* Bits 4-5: Channel n Current Group Priority */
-#endif
-#define DMA_DCHPR_DPA                     (1 << 6)  /* Bit 6:  Disable preempt ability */
-#define DMA_DCHPR_ECP                     (1 << 7)  /* Bit 7:  Enable channel preemption */
-
-/* Enable Asynchronous Request in Stop Register (32-bit) */
-
-#ifdef KINETIS_DMA_HAS_EARS
-#  define DMA_EARS(n)                      (1 << (n)) /* Bit n: DMA EARS n, n=0..<KINETIS_NDMACH */
-#endif
-
-/* TCD Source Address.  32-bit address value. */
-
-/* TCD Signed Source Address Offset.  32-bit offset value. */
-
-/* TCD Transfer Attributes (16-bit) */
-
-#define DMA_TCD_ATTR_DSIZE_SHIFT          (0)       /* Bits 0-2: Destination data transfer size */
-#define DMA_TCD_ATTR_DSIZE_MASK           (7 << DMA_TCD_ATTR_DSIZE_SHIFT)
-#  define DMA_TCD_ATTR_DSIZE_8BIT         (0 << DMA_TCD_ATTR_DSIZE_SHIFT) /* 8-bit */
-#  define DMA_TCD_ATTR_DSIZE_16BIT        (1 << DMA_TCD_ATTR_DSIZE_SHIFT) /* 16-bit */
-#  define DMA_TCD_ATTR_DSIZE_32BIT        (2 << DMA_TCD_ATTR_DSIZE_SHIFT) /* 32-bit */
-#  define DMA_TCD_ATTR_DSIZE_16BYTE       (4 << DMA_TCD_ATTR_DSIZE_SHIFT) /* 16-byte */
-
-#define DMA_TCD_ATTR_DMOD_SHIFT           (3)       /* Bits 3-7: Destination address modulo */
-#define DMA_TCD_ATTR_DMOD_MASK            (31 << DMA_TCD_ATTR_DMOD_SHIFT)
-#define DMA_TCD_ATTR_SSIZE_SHIFT          (8)       /* Bits 8-10: Source data transfer size */
-#define DMA_TCD_ATTR_SSIZE_MASK           (7 << DMA_TCD_ATTR_SSIZE_SHIFT)
-#  define DMA_TCD_ATTR_SSIZE_8BIT         (0 << DMA_TCD_ATTR_SSIZE_SHIFT) /* 8-bit */
-#  define DMA_TCD_ATTR_SSIZE_16BIT        (1 << DMA_TCD_ATTR_SSIZE_SHIFT) /* 16-bit */
-#  define DMA_TCD_ATTR_SSIZE_32BIT        (2 << DMA_TCD_ATTR_SSIZE_SHIFT) /* 32-bit */
-#  define DMA_TCD_ATTR_SSIZE_16BYTE       (4 << DMA_TCD_ATTR_SSIZE_SHIFT) /* 16-byte */
-
-#define DMA_TCD_ATTR_SMOD_SHIFT           (11)      /* Bits 11-15: Source address modulo */
-#define DMA_TCD_ATTR_SMOD_MASK            (31 << DMA_TCD_ATTR_SMOD_SHIFT)
-
-/* TCD Minor Byte Count.
- * Case 1: Minor Loop Disabled.
- *         In this case, the register holds a simple 32-bit count value.
- * Case 2: Minor Loop Enabled and Offset Disabled:
- */
-
-#define DMA_TCD_NBYTES2_SHIFT             (0)       /* Bits 0-29: Minor byte transfer count */
-#define DMA_TCD_NBYTES2_MASK              (0x3fffffff)
-#define DMA_TCD_NBYTES_DMLOE              (1 << 30) /* Bit 30: Destination minor loop offset enable (Case 2&3) */
-#define DMA_TCD_NBYTES_SMLOE              (1 << 31) /* Bit 31: Source minor loop offset enable (Case 2&3) */
-
-/* Case 3: (Minor Loop and Offset Enabled): */
-
-#define DMA_TCD_NBYTES3_SHIFT             (0)       /* Bits 0-9: Minor byte transfer count */
-#define DMA_TCD_NBYTES3_MASK              (0x3ff << DMA_TCD_NBYTES3_SHIFT)
-#define DMA_TCD_NBYTES_MLOFF_SHIFT        (10)      /* Bits 10-29: Sign-extended address offset */
-#define DMA_TCD_NBYTES_MLOFF_MASK         (0xfffff << DMA_TCD_NBYTES_MLOFF_SHIFT)
-                                                    /* Bit 30: Same as Case 2 */
-                                                    /* Bit 31: Same as Case 2 */
-
-/* TCD Last Source Address Adjustment. 32-bit address value. */
-
-/* TCD Destination Address. 32-bit address value. */
-
-/* TCD Signed Destination Address Offset. 32-bit offset value. */
-
-/* TCD Current Minor Loop Link, Major Loop Count. 16-bit.
- * Case 1:  Channel Linking Enabled:
- */
-
-#define DMA_TCD_CITER1_SHIFT              (0)       /* Bits 0-8: Current major iteration count */
-#define DMA_TCD_CITER1_MASK               (0x1ff << DMA_TCD_CITER1_SHIFT)
-#define DMA_TCD_CITER1_LINKCH_SHIFT       (9)       /* Bits 9-12/13: Link channel number */
-#define DMA_TCD_CITER1_LINKCH_MASK        (((1 << KINETIS_DMA_HAS_TCD_CITER1_LINKCH_BITS) - 1) << DMA_TCD_CITER1_LINKCH_SHIFT)
-                                                    /* Bits 14: Reserved */
-#define DMA_TCD_CITER_ELINK               (1 << 15) /* Bit 15: Enable channel-to-channel linking on minor-loop complete (Case 1&2) */
-
-/* Case 2:  Channel Linking Disabled: */
-
-#define DMA_TCD_CITER2_SHIFT              (0)       /* Bits 0-14: Current major iteration count */
-#define DMA_TCD_CITER2_MASK               (0x7fff << DMA_TCD_CITER2_SHIFT)
-                                                    /* Bits 15: Same as Case 1 */
-
-/* TCD Last Destination Address Adjustment/Scatter Gather Address.
- * 32-bit address value.
- */
-
-/* TCD Control and Status (16-bit) */
-
-#define DMA_TCD_CSR_START                 (1 << 0)  /* Bit 0:  Channel start */
-#define DMA_TCD_CSR_INTMAJOR              (1 << 1)  /* Bit 1:  Enable an interrupt when major iteration count completes */
-#define DMA_TCD_CSR_INTHALF               (1 << 2)  /* Bit 2:  Enable an interrupt when major counter is half complete */
-#define DMA_TCD_CSR_DREQ                  (1 << 3)  /* Bit 3:  Disable request */
-#define DMA_TCD_CSR_ESG                   (1 << 4)  /* Bit 4:  Enable scatter/gather processing */
-#define DMA_TCD_CSR_MAJORELINK            (1 << 5)  /* Bit 5:  Enable channel-to-channel linking on major loop complete */
-#define DMA_TCD_CSR_ACTIVE                (1 << 6)  /* Bit 6:  Channel active */
-#define DMA_TCD_CSR_DONE                  (1 << 7)  /* Bit 7:  Channel done */
-#define DMA_TCD_CSR_MAJORLINKCH_SHIFT     (8)       /* Bits 8-11/12: Link channel number */
-#define DMA_TCD_CSR_MAJORLINKCH_MASK      (((1 << KINETIS_DMA_HAS_TCD_CSR_MAJORLINKCH_BITS) - 1) << DMA_TCD_CSR_MAJORLINKCH_SHIFT)
-                                                    /* Bits 13: Reserved */
-#define DMA_TCD_CSR_BWC_SHIFT             (14)      /* Bits 14-15: Bandwidth control */
-#define DMA_TCD_CSR_BWC_MASK              (3 << DMA_TCD_CSR_BWC_SHIFT)
-#  define DMA_TCD_CSR_BWC_NOSTALLS        (0 << DMA_TCD_CSR_BWC_SHIFT) /* No eDMA engine stalls */
-#  define DMA_TCD_CSR_BWC_4CYCLES         (2 << DMA_TCD_CSR_BWC_SHIFT) /* eDMA engine stalls 4 cycles after each R/W */
-#  define DMA_TCD_CSR_BWC_8CYCLES         (3 << DMA_TCD_CSR_BWC_SHIFT) /* eDMA engine stalls 8 cycles after each R/W */
-
-/* TCD Beginning Minor Loop Link, Major Loop Count (16-bit).
- *
- * Case 1: Channel Linking Enabled:
- */
-
-#define DMA_TCD_BITER1_SHIFT              (0)       /* Bits 0-8: Starting major iteration count */
-#define DMA_TCD_BITER1_MASK               (0x1ff << DMA_TCD_BITER1_SHIFT)
-#define DMA_TCD_BITER1_LINKCH_SHIFT       (9)       /* Bits 9-12: Link channel number */
-#define DMA_TCD_BITER1_LINKCH_MASK        (((1 << KINETIS_DMA_HAS_TCD_BITER1_LINKCH_BITS) - 1) << DMA_TCD_BITER1_LINKCH_SHIFT)
-                                                    /* Bits 13-14: Reserved */
-#define DMA_TCD_BITER_ELINK               (1 << 15) /* Bit 15: Enable channel-to-channel linking on minor-loop complete (Case 1&2) */
-
-/* Case 2: Channel Linking Disabled: */
-
-#define DMA_TCD_BITER2_SHIFT              (0)       /* Bits 0-14: Starting major iteration count */
-#define DMA_TCD_BITER2_MASK               (0x7fff << DMA_TCD_CITER2_SHIFT)
-                                                    /* Bits 15: Same as Case 1 */
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions Prototypes
- ****************************************************************************/
-
-#endif /* __ARCH_ARM_SRC_KINETIS_HARDWARE_KINETIS_DMA_H */
diff --git a/arch/arm/src/kinetis/hardware/kinetis_dmamux.h b/arch/arm/src/kinetis/hardware/kinetis_dmamux.h
index 1d94d14..5442d69 100644
--- a/arch/arm/src/kinetis/hardware/kinetis_dmamux.h
+++ b/arch/arm/src/kinetis/hardware/kinetis_dmamux.h
@@ -56,7 +56,7 @@
 /* Channel n Configuration Register */
 
 #define DMAMUX_CHCFG_SOURCE_SHIFT       (0)       /* Bits 0-5: DMA Channel Source (slot) */
-#define DMAMUX_CHCFG_SOURCE_MASK        (63 << DMAMUX_CHCFG_SOURCE_SHIFT)
+#define DMAMUX_CHCFG_SOURCE_MASK        (0x3f << DMAMUX_CHCFG_SOURCE_SHIFT)
 #define DMAMUX_CHCFG_TRIG               (1 << 6)  /* Bit 6:  DMA Channel Trigger Enable */
 #define DMAMUX_CHCFG_ENBL               (1 << 7)  /* Bit 7:  DMA Channel Enable */
 
diff --git a/arch/arm/src/kinetis/hardware/kinetis_edma.h b/arch/arm/src/kinetis/hardware/kinetis_edma.h
new file mode 100644
index 0000000..c21c0d9
--- /dev/null
+++ b/arch/arm/src/kinetis/hardware/kinetis_edma.h
@@ -0,0 +1,855 @@
+/****************************************************************************
+ * arch/arm/src/kinetis/hardware/kinetis_edma.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_KINETIS_HARDWARE_KINETIS_EDMA_H
+#define __ARCH_ARM_SRC_KINETIS_HARDWARE_KINETIS_EDMA_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include "hardware/kinetis_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define KINETIS_EDMA_NCHANNELS              16
+
+/* eDMA Register Offsets ****************************************************/
+
+#define KINETIS_EDMA_CR_OFFSET                0x0000  /* Control */
+#define KINETIS_EDMA_ES_OFFSET                0x0004  /* Error Status */
+#define KINETIS_EDMA_ERQ_OFFSET               0x000c  /* Enable Request */
+#define KINETIS_EDMA_EEI_OFFSET               0x0014  /* Enable Error Interrupt */
+#define KINETIS_EDMA_CEEI_OFFSET              0x0018  /* Clear Enable Error Interrupt */
+#define KINETIS_EDMA_SEEI_OFFSET              0x0019  /* Set Enable Error Interrupt */
+#define KINETIS_EDMA_CERQ_OFFSET              0x001a  /* Clear Enable Request */
+#define KINETIS_EDMA_SERQ_OFFSET              0x001b  /* Set Enable Request */
+#define KINETIS_EDMA_CDNE_OFFSET              0x001c  /* Clear DONE Status Bit */
+#define KINETIS_EDMA_SSRT_OFFSET              0x001d  /* Set START Bit */
+#define KINETIS_EDMA_CERR_OFFSET              0x001e  /* Clear Error */
+#define KINETIS_EDMA_CINT_OFFSET              0x001f  /* Clear Interrupt Request */
+#define KINETIS_EDMA_INT_OFFSET               0x0024  /* Interrupt Request */
+#define KINETIS_EDMA_ERR_OFFSET               0x002c  /* Error */
+#define KINETIS_EDMA_HRS_OFFSET               0x0034  /* Hardware Request Status */
+#define KINETIS_EDMA_EARS_OFFSET              0x0044  /* Enable Asynchronous Request in Stop */
+
+#define KINETIS_EDMA_DCHPRI_OFFSET(n)         (0x0100 + ((n) & ~3) + (3 - ((n) & 3)))
+
+#define KINETIS_EDMA_DCHPRI3_OFFSET           0x0100  /* Channel 3 Priority */
+#define KINETIS_EDMA_DCHPRI2_OFFSET           0x0101  /* Channel 2 Priority */
+#define KINETIS_EDMA_DCHPRI1_OFFSET           0x0102  /* Channel 1 Priority */
+#define KINETIS_EDMA_DCHPRI0_OFFSET           0x0103  /* Channel 0 Priority */
+#define KINETIS_EDMA_DCHPRI7_OFFSET           0x0104  /* Channel 7 Priority */
+#define KINETIS_EDMA_DCHPRI6_OFFSET           0x0105  /* Channel 6 Priority */
+#define KINETIS_EDMA_DCHPRI5_OFFSET           0x0106  /* Channel 5 Priority */
+#define KINETIS_EDMA_DCHPRI4_OFFSET           0x0107  /* Channel 4 Priority */
+#define KINETIS_EDMA_DCHPRI11_OFFSET          0x0108  /* Channel 11 Priority */
+#define KINETIS_EDMA_DCHPRI10_OFFSET          0x0109  /* Channel 10 Priority */
+#define KINETIS_EDMA_DCHPRI9_OFFSET           0x010a  /* Channel 9 Priority */
+#define KINETIS_EDMA_DCHPRI8_OFFSET           0x010b  /* Channel 8 Priority */
+#define KINETIS_EDMA_DCHPRI15_OFFSET          0x010c  /* Channel 15 Priority */
+#define KINETIS_EDMA_DCHPRI14_OFFSET          0x010d  /* Channel 14 Priority */
+#define KINETIS_EDMA_DCHPRI13_OFFSET          0x010e  /* Channel 13 Priority */
+#define KINETIS_EDMA_DCHPRI12_OFFSET          0x010f  /* Channel 12 Priority */
+
+/* Transfer Control Descriptor (TCD) */
+
+#define KINETIS_EDMA_TCD_OFFSET(n)            (0x1000 + ((n) << 5))
+#define KINETIS_EDMA_TCD_SADDR_OFFSET         0x0000  /* TCD Source Address */
+#define KINETIS_EDMA_TCD_SOFF_OFFSET          0x0004  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD_ATTR_OFFSET          0x0006  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD_NBYTES_ML_OFFSET     0x0008  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD_SLAST_OFFSET         0x000c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD_DADDR_OFFSET         0x0010  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD_DOFF_OFFSET          0x0014  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD_CITER_ELINK_OFFSET   0x0016  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD_DLASTSGA_OFFSET      0x0018  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD_CSR_OFFSET           0x001c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD_BITER_ELINK_OFFSET   0x001e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD0_SADDR_OFFSET        0x1000  /* TCD Source Address */
+#define KINETIS_EDMA_TCD0_SOFF_OFFSET         0x1004  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD0_ATTR_OFFSET         0x1006  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD0_NBYTES_ML_OFFSET    0x1008  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD0_SLAST_OFFSET        0x100c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD0_DADDR_OFFSET        0x1010  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD0_DOFF_OFFSET         0x1014  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD0_CITER_ELINK_OFFSET  0x1016  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD0_DLASTSGA_OFFSET     0x1018  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD0_CSR_OFFSET          0x101c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD0_BITER_ELINK_OFFSET  0x101e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD1_SADDR_OFFSET        0x1020  /* TCD Source Address */
+#define KINETIS_EDMA_TCD1_SOFF_OFFSET         0x1024  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD1_ATTR_OFFSET         0x1026  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD1_NBYTES_ML_OFFSET    0x1028  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD1_SLAST_OFFSET        0x102c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD1_DADDR_OFFSET        0x1030  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD1_DOFF_OFFSET         0x1034  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD1_CITER_ELINK_OFFSET  0x1036  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD1_DLASTSGA_OFFSET     0x1038  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD1_CSR_OFFSET          0x103c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD1_BITER_ELINK_OFFSET  0x103e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD1_SADDR_OFFSET        0x1020  /* TCD Source Address */
+#define KINETIS_EDMA_TCD1_SOFF_OFFSET         0x1024  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD1_ATTR_OFFSET         0x1026  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD1_NBYTES_ML_OFFSET    0x1028  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD1_SLAST_OFFSET        0x102c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD1_DADDR_OFFSET        0x1030  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD1_DOFF_OFFSET         0x1034  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD1_CITER_ELINK_OFFSET  0x1036  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD1_DLASTSGA_OFFSET     0x1038  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD1_CSR_OFFSET          0x103c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD1_BITER_ELINK_OFFSET  0x103e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD2_SADDR_OFFSET        0x1040  /* TCD Source Address */
+#define KINETIS_EDMA_TCD2_SOFF_OFFSET         0x1044  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD2_ATTR_OFFSET         0x1046  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD2_NBYTES_ML_OFFSET    0x1048  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD2_SLAST_OFFSET        0x104c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD2_DADDR_OFFSET        0x1050  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD2_DOFF_OFFSET         0x1054  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD2_CITER_ELINK_OFFSET  0x1056  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD2_DLASTSGA_OFFSET     0x1058  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD2_CSR_OFFSET          0x105c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD2_BITER_ELINK_OFFSET  0x105e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD3_SADDR_OFFSET        0x1060  /* TCD Source Address */
+#define KINETIS_EDMA_TCD3_SOFF_OFFSET         0x1064  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD3_ATTR_OFFSET         0x1066  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD3_NBYTES_ML_OFFSET    0x1068  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD3_SLAST_OFFSET        0x106c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD3_DADDR_OFFSET        0x1070  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD3_DOFF_OFFSET         0x1074  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD3_CITER_ELINK_OFFSET  0x1076  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD3_DLASTSGA_OFFSET     0x1078  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD3_CSR_OFFSET          0x107c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD3_BITER_ELINK_OFFSET  0x107e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD4_SADDR_OFFSET        0x1080  /* TCD Source Address */
+#define KINETIS_EDMA_TCD4_SOFF_OFFSET         0x1084  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD4_ATTR_OFFSET         0x1086  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD4_NBYTES_ML_OFFSET    0x1088  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD4_SLAST_OFFSET        0x108c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD4_DADDR_OFFSET        0x1090  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD4_DOFF_OFFSET         0x1094  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD4_CITER_ELINK_OFFSET  0x1096  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD4_DLASTSGA_OFFSET     0x1098  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD4_CSR_OFFSET          0x109c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD4_BITER_ELINK_OFFSET  0x109e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD5_SADDR_OFFSET        0x10a0  /* TCD Source Address */
+#define KINETIS_EDMA_TCD5_SOFF_OFFSET         0x10a4  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD5_ATTR_OFFSET         0x10a6  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD5_NBYTES_ML_OFFSET    0x10a8  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD5_SLAST_OFFSET        0x10ac  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD5_DADDR_OFFSET        0x10b0  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD5_DOFF_OFFSET         0x10b4  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD5_CITER_ELINK_OFFSET  0x10b6  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD5_DLASTSGA_OFFSET     0x10b8  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD5_CSR_OFFSET          0x10bc  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD5_BITER_ELINK_OFFSET  0x10be  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD6_SADDR_OFFSET        0x10c0  /* TCD Source Address */
+#define KINETIS_EDMA_TCD6_SOFF_OFFSET         0x10c4  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD6_ATTR_OFFSET         0x10c6  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD6_NBYTES_ML_OFFSET    0x10c8  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD6_SLAST_OFFSET        0x10cc  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD6_DADDR_OFFSET        0x10d0  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD6_DOFF_OFFSET         0x10d4  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD6_CITER_ELINK_OFFSET  0x10d6  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD6_DLASTSGA_OFFSET     0x10d8  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD6_CSR_OFFSET          0x10dc  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD6_BITER_ELINK_OFFSET  0x10de  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD7_SADDR_OFFSET        0x10e0  /* TCD Source Address */
+#define KINETIS_EDMA_TCD7_SOFF_OFFSET         0x10e4  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD7_ATTR_OFFSET         0x10e6  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD7_NBYTES_ML_OFFSET    0x10e8  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD7_SLAST_OFFSET        0x10ec  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD7_DADDR_OFFSET        0x10f0  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD7_DOFF_OFFSET         0x10f4  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD7_CITER_ELINK_OFFSET  0x10f6  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD7_DLASTSGA_OFFSET     0x10f8  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD7_CSR_OFFSET          0x10fc  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD7_BITER_ELINK_OFFSET  0x10fe  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD8_SADDR_OFFSET        0x1100  /* TCD Source Address */
+#define KINETIS_EDMA_TCD8_SOFF_OFFSET         0x1104  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD8_ATTR_OFFSET         0x1106  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD8_NBYTES_ML_OFFSET    0x1108  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD8_SLAST_OFFSET        0x110c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD8_DADDR_OFFSET        0x1110  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD8_DOFF_OFFSET         0x1114  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD8_CITER_ELINK_OFFSET  0x1116  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD8_DLASTSGA_OFFSET     0x1118  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD8_CSR_OFFSET          0x111c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD8_BITER_ELINK_OFFSET  0x111e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD9_SADDR_OFFSET        0x1120  /* TCD Source Address */
+#define KINETIS_EDMA_TCD9_SOFF_OFFSET         0x1124  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD9_ATTR_OFFSET         0x1126  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD9_NBYTES_ML_OFFSET    0x1128  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD9_SLAST_OFFSET        0x112c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD9_DADDR_OFFSET        0x1130  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD9_DOFF_OFFSET         0x1134  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD9_CITER_ELINK_OFFSET  0x1136  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD9_DLASTSGA_OFFSET     0x1138  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD9_CSR_OFFSET          0x113c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD9_BITER_ELINK_OFFSET  0x113e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD10_SADDR_OFFSET       0x1140  /* TCD Source Address */
+#define KINETIS_EDMA_TCD10_SOFF_OFFSET        0x1144  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD10_ATTR_OFFSET        0x1146  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD10_NBYTES_ML_OFFSET   0x1148  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD10_SLAST_OFFSET       0x114c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD10_DADDR_OFFSET       0x1150  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD10_DOFF_OFFSET        0x1154  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD10_CITER_ELINK_OFFSET 0x1156  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD10_DLASTSGA_OFFSET    0x1158  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD10_CSR_OFFSET         0x115c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD10_BITER_ELINK_OFFSET 0x115e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD11_SADDR_OFFSET       0x1160  /* TCD Source Address */
+#define KINETIS_EDMA_TCD11_SOFF_OFFSET        0x1164  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD11_ATTR_OFFSET        0x1166  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD11_NBYTES_ML_OFFSET   0x1168  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD11_SLAST_OFFSET       0x116c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD11_DADDR_OFFSET       0x1170  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD11_DOFF_OFFSET        0x1174  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD11_CITER_ELINK_OFFSET 0x1176  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD11_DLASTSGA_OFFSET    0x1178  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD11_CSR_OFFSET         0x117c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD11_BITER_ELINK_OFFSET 0x117e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD12_SADDR_OFFSET       0x1180  /* TCD Source Address */
+#define KINETIS_EDMA_TCD12_SOFF_OFFSET        0x1184  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD12_ATTR_OFFSET        0x1186  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD12_NBYTES_ML_OFFSET   0x1188  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD12_SLAST_OFFSET       0x118c  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD12_DADDR_OFFSET       0x1190  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD12_DOFF_OFFSET        0x1194  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD12_CITER_ELINK_OFFSET 0x1196  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD12_DLASTSGA_OFFSET    0x1198  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD12_CSR_OFFSET         0x119c  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD12_BITER_ELINK_OFFSET 0x119e  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD13_SADDR_OFFSET       0x11a0  /* TCD Source Address */
+#define KINETIS_EDMA_TCD13_SOFF_OFFSET        0x11a4  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD13_ATTR_OFFSET        0x11a6  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD13_NBYTES_ML_OFFSET   0x11a8  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD13_SLAST_OFFSET       0x11ac  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD13_DADDR_OFFSET       0x11b0  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD13_DOFF_OFFSET        0x11b4  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD13_CITER_ELINK_OFFSET 0x11b6  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD13_DLASTSGA_OFFSET    0x11b8  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD13_CSR_OFFSET         0x11bc  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD13_BITER_ELINK_OFFSET 0x11be  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD14_SADDR_OFFSET       0x11c0  /* TCD Source Address */
+#define KINETIS_EDMA_TCD14_SOFF_OFFSET        0x11c4  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD14_ATTR_OFFSET        0x11c6  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD14_NBYTES_ML_OFFSET   0x11c8  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD14_SLAST_OFFSET       0x11cc  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD14_DADDR_OFFSET       0x11d0  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD14_DOFF_OFFSET        0x11d4  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD14_CITER_ELINK_OFFSET 0x11d6  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD14_DLASTSGA_OFFSET    0x11d8  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD14_CSR_OFFSET         0x11dc  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD14_BITER_ELINK_OFFSET 0x11de  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+#define KINETIS_EDMA_TCD15_SADDR_OFFSET       0x11e0  /* TCD Source Address */
+#define KINETIS_EDMA_TCD15_SOFF_OFFSET        0x11e4  /* TCD Signed Source Address Offset */
+#define KINETIS_EDMA_TCD15_ATTR_OFFSET        0x11e6  /* TCD Transfer Attributes */
+#define KINETIS_EDMA_TCD15_NBYTES_ML_OFFSET   0x11e8  /* TCD Signed Minor Loop Offset / Byte Count */
+#define KINETIS_EDMA_TCD15_SLAST_OFFSET       0x11ec  /* TCD Last Source Address Adjustment */
+#define KINETIS_EDMA_TCD15_DADDR_OFFSET       0x11f0  /* TCD Destination Address */
+#define KINETIS_EDMA_TCD15_DOFF_OFFSET        0x11f4  /* TCD Signed Destination Address Offset */
+#define KINETIS_EDMA_TCD15_CITER_ELINK_OFFSET 0x11f6  /* TCD Current Minor Loop Link, Major Loop Count */
+#define KINETIS_EDMA_TCD15_DLASTSGA_OFFSET    0x11f8  /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+#define KINETIS_EDMA_TCD15_CSR_OFFSET         0x11fc  /* TCD Control and Status */
+#define KINETIS_EDMA_TCD15_BITER_ELINK_OFFSET 0x11fe  /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+/* eDMA Register Addresses **************************************************/
+
+#define KINETIS_EDMA_CR                       (KINETIS_DMAC_BASE + KINETIS_EDMA_CR_OFFSET)
+#define KINETIS_EDMA_ES                       (KINETIS_DMAC_BASE + KINETIS_EDMA_ES_OFFSET)
+#define KINETIS_EDMA_ERQ                      (KINETIS_DMAC_BASE + KINETIS_EDMA_ERQ_OFFSET)
+#define KINETIS_EDMA_EEI                      (KINETIS_DMAC_BASE + KINETIS_EDMA_EEI_OFFSET)
+#define KINETIS_EDMA_CEEI                     (KINETIS_DMAC_BASE + KINETIS_EDMA_CEEI_OFFSET)
+#define KINETIS_EDMA_SEEI                     (KINETIS_DMAC_BASE + KINETIS_EDMA_SEEI_OFFSET)
+#define KINETIS_EDMA_CERQ                     (KINETIS_DMAC_BASE + KINETIS_EDMA_CERQ_OFFSET)
+#define KINETIS_EDMA_SERQ                     (KINETIS_DMAC_BASE + KINETIS_EDMA_SERQ_OFFSET)
+#define KINETIS_EDMA_CDNE                     (KINETIS_DMAC_BASE + KINETIS_EDMA_CDNE_OFFSET)
+#define KINETIS_EDMA_SSRT                     (KINETIS_DMAC_BASE + KINETIS_EDMA_SSRT_OFFSET)
+#define KINETIS_EDMA_CERR                     (KINETIS_DMAC_BASE + KINETIS_EDMA_CERR_OFFSET)
+#define KINETIS_EDMA_CINT                     (KINETIS_DMAC_BASE + KINETIS_EDMA_CINT_OFFSET)
+#define KINETIS_EDMA_INT                      (KINETIS_DMAC_BASE + KINETIS_EDMA_INT_OFFSET)
+#define KINETIS_EDMA_ERR                      (KINETIS_DMAC_BASE + KINETIS_EDMA_ERR_OFFSET)
+#define KINETIS_EDMA_HRS                      (KINETIS_DMAC_BASE + KINETIS_EDMA_HRS_OFFSET)
+#define KINETIS_EDMA_EARS                     (KINETIS_DMAC_BASE + KINETIS_EDMA_EARS_OFFSET)
+
+#define KINETIS_EDMA_DCHPRI(n)                (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI_OFFSET(n))
+
+#define KINETIS_EDMA_DCHPRI0                  (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI0_OFFSET)
+#define KINETIS_EDMA_DCHPRI1                  (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI1_OFFSET)
+#define KINETIS_EDMA_DCHPRI2                  (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI2_OFFSET)
+#define KINETIS_EDMA_DCHPRI3                  (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI3_OFFSET)
+#define KINETIS_EDMA_DCHPRI4                  (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI4_OFFSET)
+#define KINETIS_EDMA_DCHPRI5                  (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI5_OFFSET)
+#define KINETIS_EDMA_DCHPRI6                  (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI6_OFFSET)
+#define KINETIS_EDMA_DCHPRI7                  (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI7_OFFSET)
+#define KINETIS_EDMA_DCHPRI8                  (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI8_OFFSET)
+#define KINETIS_EDMA_DCHPRI9                  (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI9_OFFSET)
+#define KINETIS_EDMA_DCHPRI10                 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI10_OFFSET)
+#define KINETIS_EDMA_DCHPRI11                 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI11_OFFSET)
+#define KINETIS_EDMA_DCHPRI12                 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI12_OFFSET)
+#define KINETIS_EDMA_DCHPRI13                 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI13_OFFSET)
+#define KINETIS_EDMA_DCHPRI14                 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI14_OFFSET)
+#define KINETIS_EDMA_DCHPRI15                 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI15_OFFSET)
+
+/* Transfer Control Descriptor (TCD) */
+
+#define KINETIS_EDMA_TCD_BASE(n)              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD_OFFSET(n))
+#define KINETIS_EDMA_TCD_SADDR(n)             (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD_SOFF(n)              (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD_ATTR(n)              (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD_NBYTES_ML(n)         (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD_SLAST(n)             (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD_DADDR(n)             (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD_DOFF(n)              (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD_CITER_ELINK(n)       (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD_DLASTSGA(n)          (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD_CSR(n)               (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_CSR_OFFSET)
+#define KINETIS_EDMA_TCD_BITER_ELINK(n)       (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD0_SADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD0_SOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD0_ATTR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD0_NBYTES_ML           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD0_SLAST               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD0_DADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD0_DOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD0_CITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD0_DLASTSGA            (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD0_CSR                 (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_CSR_OFFSET)
+#define KINETIS_EDMA_TCD0_BITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD1_SADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD1_SOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD1_ATTR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD1_NBYTES_ML           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD1_SLAST               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD1_DADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD1_DOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD1_CITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD1_DLASTSGA            (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD1_CSR                 (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_CSR_OFFSET)
+#define KINETIS_EDMA_TCD1_BITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD2_SADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD2_SOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD2_ATTR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD2_NBYTES_ML           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD2_SLAST               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD2_DADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD2_DOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD2_CITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD2_DLASTSGA            (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD2_CSR                 (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_CSR_OFFSET)
+#define KINETIS_EDMA_TCD2_BITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD3_SADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD3_SOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD3_ATTR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD3_NBYTES_ML           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD3_SLAST               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD3_DADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD3_DOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD3_CITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD3_DLASTSGA            (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD3_CSR                 (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_CSR_OFFSET)
+#define KINETIS_EDMA_TCD3_BITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD4_SADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD4_SOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD4_ATTR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD4_NBYTES_ML           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD4_SLAST               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD4_DADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD4_DOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD4_CITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD4_DLASTSGA            (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD4_CSR                 (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_CSR_OFFSET)
+#define KINETIS_EDMA_TCD4_BITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD5_SADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD5_SOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD5_ATTR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD5_NBYTES_ML           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD5_SLAST               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD5_DADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD5_DOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD5_CITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD5_DLASTSGA            (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD5_CSR                 (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_CSR_OFFSET)
+#define KINETIS_EDMA_TCD5_BITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD6_SADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD6_SOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD6_ATTR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD6_NBYTES_ML           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD6_SLAST               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD6_DADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD6_DOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD6_CITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD6_DLASTSGA            (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD6_CSR                 (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_CSR_OFFSET)
+#define KINETIS_EDMA_TCD6_BITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD7_SADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD7_SOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD7_ATTR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD7_NBYTES_ML           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD7_SLAST               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD7_DADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD7_DOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD7_CITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD7_DLASTSGA            (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD7_CSR                 (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_CSR_OFFSET)
+#define KINETIS_EDMA_TCD7_BITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD8_SADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD8_SOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD8_ATTR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD8_NBYTES_ML           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD8_SLAST               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD8_DADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD8_DOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD8_CITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD8_DLASTSGA            (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD8_CSR                 (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_CSR_OFFSET)
+#define KINETIS_EDMA_TCD8_BITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD9_SADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD9_SOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD9_ATTR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD9_NBYTES_ML           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD9_SLAST               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD9_DADDR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD9_DOFF                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD9_CITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD9_DLASTSGA            (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD9_CSR                 (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_CSR_OFFSET)
+#define KINETIS_EDMA_TCD9_BITER_ELINK         (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD10_SADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD10_SOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD10_ATTR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD10_NBYTES_ML          (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD10_SLAST              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD10_DADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD10_DOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD10_CITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD10_DLASTSGA           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD10_CSR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_CSR_OFFSET)
+#define KINETIS_EDMA_TCD10_BITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD11_SADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD11_SOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD11_ATTR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD11_NBYTES_ML          (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD11_SLAST              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD11_DADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD11_DOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD11_CITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD11_DLASTSGA           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD11_CSR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_CSR_OFFSET)
+#define KINETIS_EDMA_TCD11_BITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD12_SADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD12_SOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD12_ATTR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD12_NBYTES_ML          (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD12_SLAST              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD12_DADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD12_DOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD12_CITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD12_DLASTSGA           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD12_CSR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_CSR_OFFSET)
+#define KINETIS_EDMA_TCD12_BITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD13_SADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD13_SOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD13_ATTR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD13_NBYTES_ML          (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD13_SLAST              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD13_DADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD13_DOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD13_CITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD13_DLASTSGA           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD13_CSR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_CSR_OFFSET)
+#define KINETIS_EDMA_TCD13_BITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD14_SADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD14_SOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD14_ATTR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD14_NBYTES_ML          (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD14_SLAST              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD14_DADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD14_DOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD14_CITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD14_DLASTSGA           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD14_CSR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_CSR_OFFSET)
+#define KINETIS_EDMA_TCD14_BITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_BITER_ELINK_OFFSET)
+
+#define KINETIS_EDMA_TCD15_SADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_SADDR_OFFSET)
+#define KINETIS_EDMA_TCD15_SOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_SOFF_OFFSET)
+#define KINETIS_EDMA_TCD15_ATTR               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_ATTR_OFFSET)
+#define KINETIS_EDMA_TCD15_NBYTES_ML          (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_NBYTES_ML_OFFSET)
+#define KINETIS_EDMA_TCD15_SLAST              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_SLAST_OFFSET)
+#define KINETIS_EDMA_TCD15_DADDR              (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_DADDR_OFFSET)
+#define KINETIS_EDMA_TCD15_DOFF               (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_DOFF_OFFSET)
+#define KINETIS_EDMA_TCD15_CITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_CITER_ELINK_OFFSET)
+#define KINETIS_EDMA_TCD15_DLASTSGA           (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_DLASTSGA_OFFSET)
+#define KINETIS_EDMA_TCD15_CSR                (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_CSR_OFFSET)
+#define KINETIS_EDMA_TCD15_BITER_ELINK        (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_BITER_ELINK_OFFSET)
+
+/* eDMA Bit-Field Definitions ***********************************************/
+
+/* Control */
+
+                                                      /* Bit 0:  Reserved */
+#define EDMA_CR_EDBG                        (1 << 1)  /* Bit 1:  Enable Debug */
+#define EDMA_CR_ERCA                        (1 << 2)  /* Bit 2:  Enable Round Robin Channel Arbitration */
+#define EDMA_CR_ERGA                        (1 << 3)  /* Bit 3:  Enable Round Robin Group Arbitration */
+#define EDMA_CR_HOE                         (1 << 4)  /* Bit 4:  Halt On Error */
+#define EDMA_CR_HALT                        (1 << 5)  /* Bit 5:  Halt DMA Operations */
+#define EDMA_CR_CLM                         (1 << 6)  /* Bit 6:  Continuous Link Mode */
+#define EDMA_CR_EMLM                        (1 << 7)  /* Bit 7:  Enable Minor Loop Mapping */
+                                                      /* Bit 8-15:  Reserved */
+#define EDMA_CR_ECX                         (1 << 16) /* Bit 16: Error Cancel Transfer */
+#define EDMA_CR_CX                          (1 << 17) /* Bit 17: Cancel Transfer */
+                                                      /* Bits 18-23: Reserved */
+                                                      /* Bits 24-30: eDMA version number (reserved) */
+#define EDMA_CR_ACTIVE                      (1 << 31) /* Bit 31: DMA Active Status */
+
+/* Error Status */
+
+#define EDMA_ES_DBE                         (1 << 0)  /* Bit 0:  Destination Bus Error */
+#define EDMA_ES_SBE                         (1 << 1)  /* Bit 1:  Source Bus Error */
+#define EDMA_ES_SGE                         (1 << 2)  /* Bit 2:  Scatter/Gather Configuration Error */
+#define EDMA_ES_NCE                         (1 << 3)  /* Bit 3:  NBYTES/CITER Configuration Error */
+#define EDMA_ES_DOE                         (1 << 4)  /* Bit 4:  Destination Offset Error */
+#define EDMA_ES_DAE                         (1 << 5)  /* Bit 5:  Destination Address Error */
+#define EDMA_ES_SOE                         (1 << 6)  /* Bit 6:  Source Offset Error */
+#define EDMA_ES_SAE                         (1 << 7)  /* Bit 7:  Source Address Error */
+#define EDMA_ES_ERRCHN_SHIFT                (8)       /* Bits 8-11: Error Channel Number or
+                                                       *         Canceled Channel Number */
+#define EDMA_ES_ERRCHN_MASK                 (15 << EDMA_ES_ERRCHN_SHIFT)
+                                                      /* Bits 23-13: Reserved */
+#define EDMA_ES_CPE                         (1 << 14) /* Bit 14: Channel Priority Error */
+                                                      /* Bit 15:  Reserved */
+#define EDMA_ES_ECX                         (1 << 16) /* Bit 16: Transfer Canceled */
+                                                      /* Bits 17-30: Reserved */
+#define EDMA_ES_VLD                         (1 << 31) /* Bit 31: Logical OR of all ERR status bits */
+
+/* Enable Request */
+
+#define EDMA_ERQ(n)                         ((uint32_t)1 << (n)) /* Bit n:  Enable DMA request n */
+
+/* Enable Error Interrupt */
+
+#define EDMA_EEI(n)                         ((uint32_t)1 << (n)) /* Bit n:  Enable error interrupt n */
+
+/* Clear Enable Error Interrupt */
+
+#define EDMA_CEEI_SHIFT                     (0)       /* Bits 0-3: Clear Enable Error Interrupt */
+#define EDMA_CEEI_MASK                      (15 << EDMA_CEEI_SHIFT)
+#  define EDMA_CEEI(n)                      ((uint32_t)(n) << EDMA_CEEI_SHIFT)
+                                                      /* Bit 54-:  Reserved */
+#define EDMA_CEEI_CAEE                      (1 << 6)  /* Bit 6:  Clear All Enable Error Interrupts */
+#define EDMA_CEEI_NOP                       (1 << 7)  /* Bit 7:  No Op enable */
+
+/* Set Enable Error Interrupt */
+
+#define EDMA_SEEI_SHIFT                     (0)       /* Bits 0-3: Set Enable Error Interrupt */
+#define EDMA_SEEI_MASK                      (15 << EDMA_SEEI_SHIFT)
+#  define EDMA_SEEI(n)                      ((uint32_t)(n) << EDMA_SEEI_SHIFT)
+                                                      /* Bit 54-:  Reserved */
+#define EDMA_SEEI_SAEE                      (1 << 6)  /* Bit 6:  Set All Enable Error Interrupts */
+#define EDMA_SEEI_NOP                       (1 << 7)  /* Bit 7:  No Op enable */
+
+/* Clear Enable Request */
+
+#define EDMA_CERQ_SHIFT                     (0)       /* Bits 0-3: Clear Enable Request */
+#define EDMA_CERQ_MASK                      (15 << EDMA_CERQ_SHIFT)
+#  define EDMA_CERQ(n)                      ((uint32_t)(n) << EDMA_CERQ_SHIFT)
+                                                      /* Bit 4-5:  Reserved */
+#define EDMA_CERQ_CAER                      (1 << 6)  /* Bit 6:  Clear All Enable Requests */
+#define EDMA_CERQ_NOP                       (1 << 7)  /* Bit 7:  No Op enable */
+
+/* Set Enable Request */
+
+#define EDMA_SERQ_SHIFT                     (0)       /* Bits 0-3: Set Enable Request */
+#define EDMA_SERQ_MASK                      (15 << EDMA_SERQ_SHIFT)
+#  define EDMA_SERQ(n)                      ((uint32_t)(n) << EDMA_SERQ_SHIFT)
+                                                      /* Bit 4-5:  Reserved */
+#define EDMA_SERQ_SAER                      (1 << 6)  /* Bit 6:  Set All Enable Requests */
+#define EDMA_SERQ_NOP                       (1 << 7)  /* Bit 7:  No Op enable */
+
+/* Clear DONE Status Bit */
+
+#define EDMA_CDNE_SHIFT                     (0)       /* Bits 0-3: Clear DONE Bit */
+#define EDMA_CDNE_MASK                      (15 << EDMA_CDNE_SHIFT)
+#  define EDMA_CDNE(n)                      ((uint32_t)(n) << EDMA_CDNE_SHIFT)
+                                                      /* Bit 4-5:  Reserved */
+#define EDMA_CDNE_CADN                      (1 << 6)  /* Bit 6:  Clears All DONE Bits */
+#define EDMA_CDNE_NOP                       (1 << 7)  /* Bit 7:  No Op enable */
+
+/* Set START Bit */
+
+#define EDMA_SSRT_SHIFT                     (0)       /* Bits 0-3: Set START Bit */
+#define EDMA_SSRT_MASK                      (15 << EDMA_SSRT_SHIFT)
+#  define EDMA_SSRT(n)                      ((uint32_t)(n) << EDMA_SSRT_SHIFT)
+                                                      /* Bit 4-5:  Reserved */
+#define EDMA_SSRT_SAST                      (1 << 6)  /* Bit 6:  Set All START Bits (activates all channels) */
+#define EDMA_SSRT_NOP                       (1 << 7)  /* Bit 7:  No Op enable */
+
+/* Clear Error */
+
+#define EDMA_CERR_SHIFT                     (0)       /* Bits 0-3: Clear Error Indicator */
+#define EDMA_CERR_MASK                      (15 << EDMA_CERR_SHIFT)
+#  define EDMA_CERR(n)                      ((uint32_t)(n) << EDMA_CERR_SHIFT)
+                                                      /* Bit 4-5:  Reserved */
+#define EDMA_CERR_CAEI                      (1 << 6)  /* Bit 6:  Clear All Error Indicators */
+#define EDMA_CERR_NOP                       (1 << 7)  /* Bit 7:  No Op enable */
+
+/* Clear Interrupt Request */
+
+#define EDMA_CINT_SHIFT                     (0)       /* Bits 0-3: Clear Interrupt Request */
+#define EDMA_CINT_MASK                      (15 << EDMA_CINT_SHIFT)
+#  define EDMA_CINT(n)                      ((uint32_t)(n) << EDMA_CINT_SHIFT)
+                                                      /* Bit 4-5:  Reserved */
+#define EDMA_CINT_CAIR                      (1 << 6)  /* Bit 6:  Clear All Interrupt Requests */
+#define EDMA_CINT_NOP                       (1 << 7)  /* Bit 7:  No Op enable */
+
+/* Interrupt Request */
+
+#define EDMA_INT(n)                         ((uint32_t)1 << (n)) /* Bit n:  Interrupt Request n */
+
+/* Error */
+
+#define EDMA_ERR(n)                         ((uint32_t)1 << (n)) /* Bit n:  Error In Channel n */
+
+/* Hardware Request Status */
+
+#define EDMA_HRS(n)                         ((uint32_t)1 << (n)) /* Bit n:  Hardware Request Status
+                                                                  * Channel n */
+
+/* Enable Asynchronous Request in Stop */
+
+#define EDMA_EARS(n)                        ((uint32_t)1 << (n)) /* Bit n:  Enable asynchronous DMA
+                                                                  * request in stop mode for channel n */
+
+/* Channel n Priority */
+
+#define EDMA_DCHPRI_CHPRI_SHIFT             (0)       /* Bits 0-3: Channel n Arbitration Priority */
+#define EDMA_DCHPRI_CHPRI_MASK              (15 << EDMA_DCHPRI_CHPRI_SHIFT)
+#  define EDMA_DCHPRI_CHPRI(n)              ((uint32_t)(n) << EDMA_DCHPRI_CHPRI_SHIFT)
+                                                      /* Bit 4-5:  Reserved */
+#define EDMA_DCHPRI_DPA                     (1 << 6)  /* Bit 6:  Disable Preempt Ability */
+#define EDMA_DCHPRI_ECP                     (1 << 7)  /* Bit 7:  Enable Channel Preemption */
+
+/* TCD Source Address (32-bit address) */
+
+/* TCD Signed Source Address Offset (16-bit offset) */
+
+/* TCD Transfer Attributes */
+
+#define TCD_ATTR_SIZE_8BIT                  (0)       /* 8-bit */
+#define TCD_ATTR_SIZE_16BIT                 (1)       /* 16-bit */
+#define TCD_ATTR_SIZE_32BIT                 (2)       /* 32-bit */
+#define TCD_ATTR_SIZE_64BIT                 (3)       /* 64-bit */
+#define TCD_ATTR_SIZE_256BIT                (5)       /* 32-byte burst (4 beats of 64 bits) */
+
+#define EDMA_TCD_ATTR_DSIZE_SHIFT           (0)       /* Bits 0-2: Destination data transfer size */
+#define EDMA_TCD_ATTR_DSIZE_MASK            (7 << EDMA_TCD_ATTR_DSIZE_SHIFT)
+#  define EDMA_TCD_ATTR_DSIZE(n)            ((uint32_t)(n)        << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 8-bit */
+#  define EDMA_TCD_ATTR_DSIZE_8BIT          (TCD_ATTR_SIZE_8BIT   << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 8-bit */
+#  define EDMA_TCD_ATTR_DSIZE_16BIT         (TCD_ATTR_SIZE_16BIT  << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 16-bit */
+#  define EDMA_TCD_ATTR_DSIZE_32BIT         (TCD_ATTR_SIZE_32BIT  << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 32-bit */
+#  define EDMA_TCD_ATTR_DSIZE_64BIT         (TCD_ATTR_SIZE_64BIT  << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 64-bit */
+#  define EDMA_TCD_ATTR_DSIZE_256BIT        (TCD_ATTR_SIZE_256BIT << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 32-byte burst */
+
+#define EDMA_TCD_ATTR_DMOD_SHIFT            (3)       /* Bits 3-7: Destination Address Modulo */
+#define EDMA_TCD_ATTR_DMOD_MASK             (31 << EDMA_TCD_ATTR_DMOD_SHIFT)
+#  define EDMA_TCD_ATTR_DMOD(n)             ((uint32_t)(n) << EDMA_TCD_ATTR_DMOD_SHIFT)
+#define EDMA_TCD_ATTR_SSIZE_SHIFT           (8)       /* Bits 8-10: Source data transfer size */
+#define EDMA_TCD_ATTR_SSIZE_MASK            (7 << EDMA_TCD_ATTR_SSIZE_SHIFT)
+#  define EDMA_TCD_ATTR_SSIZE(n)            ((uint32_t)(n)        << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 8-bit */
+#  define EDMA_TCD_ATTR_SSIZE_8BIT          (TCD_ATTR_SIZE_8BIT   << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 8-bit */
+#  define EDMA_TCD_ATTR_SSIZE_16BIT         (TCD_ATTR_SIZE_16BIT  << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 16-bit */
+#  define EDMA_TCD_ATTR_SSIZE_32BIT         (TCD_ATTR_SIZE_32BIT  << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 32-bit */
+#  define EDMA_TCD_ATTR_SSIZE_64BIT         (TCD_ATTR_SIZE_64BIT  << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 64-bit */
+#  define EDMA_TCD_ATTR_SSIZE_256BIT        (TCD_ATTR_SIZE_256BIT << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 32-byte burst */
+
+#define EDMA_TCD_ATTR_SMOD_SHIFT            (11)      /* Bits 11-15: Source Address Modulo */
+#define EDMA_TCD_ATTR_SMOD_MASK             (31 << EDMA_TCD_ATTR_SMOD_SHIFT)
+#  define EDMA_TCD_ATTR_SMOD(n)             ((uint32_t)(n) << EDMA_TCD_ATTR_SMOD_SHIFT)
+
+/* TCD Signed Minor Loop Offset / Byte Count */
+
+/* Minor Byte Count (Minor Loop Mapping Disabled -- 32-bit byte count) */
+
+/* TCD Signed Minor Loop Offset / Byte Count */
+
+/* Minor Byte Count (Minor Loop Mapping Enabled, offset disabled) */
+
+#define EDMA_TCD_NBYTES_ML_NBYTES_SHIFT     (0)       /* Bits 0-29: Minor Byte Transfer Count */
+#define EDMA_TCD_NBYTES_ML_NBYTES_MASK      (0x3fffffff << EDMA_TCD_NBYTES_ML_NBYTES_SHIFT)
+#  define EDMA_TCD_NBYTES_ML_NBYTES(n)      ((uint32_t)(n) << EDMA_TCD_NBYTES_ML_NBYTES_SHIFT)
+#define EDMA_TCD_NBYTES_ML_DMLOE            (1 << 30) /* Bit 30: Destination Minor Loop Offset enable */
+#define EDMA_TCD_NBYTES_ML_SMLOE            (1 << 31) /* Bit 31: Source Minor Loop Offset Enable */
+
+/* TCD Signed Minor Loop Offset / Byte Count */
+
+/* Minor Byte Count (Minor Loop Mapping Enabled, offset enabled) */
+
+#define EDMA_TCD_NBYTES_MLOFF_NBYTES_SHIFT  (0)      /* Bits 0-9: Minor Byte Transfer Count */
+#define EDMA_TCD_NBYTES_MLOFF_NBYTES_MASK   (0x3ff << EDMA_TCD_NBYTES_MLOFF_NBYTES_SHIFT)
+#  define EDMA_TCD_NBYTES_MLOFF_NBYTES(n)   ((uint32_t)(n) << EDMA_TCD_NBYTES_MLOFF_NBYTES_SHIFT)
+#define EDMA_TCD_NBYTES_MLOFF_MLOFF_SHIFT   (10)     /* Bits 10-29: Minor Byte Transfer Count */
+#define EDMA_TCD_NBYTES_MLOFF_MLOFF_MASK    (0xfffff << EDMA_TCD_NBYTES_MLOFF_MLOFF_SHIFT)
+#  define EDMA_TCD_NBYTES_MLOFF_MLOFF(n)    ((uint32_t)(n) << EDMA_TCD_NBYTES_MLOFF_MLOFF_SHIFT)
+#define EDMA_TCD_NBYTES_MLOFF_DMLOE         (1 << 30) /* Bit 30: Destination Minor Loop Offset enable */
+#define EDMA_TCD_NBYTES_MLOFF_SMLOE         (1 << 31) /* Bit 31: Source Minor Loop Offset Enable */
+
+/* TCD Last Source Address Adjustment (32-bit address adjustment) */
+
+/* TCD Destination Address (32-bit address) */
+
+/* TCD Signed Destination Address Offset (16-bit signed address offset) */
+
+/* TCD Current Minor Loop Link, Major Loop Count (Channel linking disabled) */
+
+#define EDMA_TCD_CITER_CITER_SHIFT          (0)       /* Bit 0-14: Starting Major Iteration Count */
+#define EDMA_TCD_CITER_CITER_MASK           (0x7fff << EDMA_TCD_CITER_CITER_SHIFT)
+#  define EDMA_TCD_CITER_CITER(n)           ((uint32_t)(n) << EDMA_TCD_CITER_CITER_SHIFT)
+#define EDMA_TCD_CITER_ELINK                (1 << 15) /* Bit 15: Enable channel-to-channel linking
+                                                       * on minor-loop complete */
+
+/* TCD Current Minor Loop Link, Major Loop Count
+ * (Channel linking enabled)
+ */
+
+#define EDMA_TCD_CITER_ELINK_CITER_SHIFT    (0)       /* Bit 0-8: Current major iteration count */
+#define EDMA_TCD_CITER_ELINK_CITER_MASK     (0x1ff << EDMA_TCD_CITER_ELINK_CITER_SHIFT)
+#  define EDMA_TCD_CITER_ELINK_CITER(n)     ((uint32_t)(n) << EDMA_TCD_CITER_ELINK_CITER_SHIFT)
+#define EDMA_TCD_CITER_ELINK_LINKCH_SHIFT   (9)       /* Bit 9-12: Minor Loop Link Channel Number */
+#define EDMA_TCD_CITER_ELINK_LINKCH_MASK    (15 << EDMA_TCD_CITER_ELINK_LINKCH_SHIFT)
+#  define EDMA_TCD_CITER_ELINK_LINKCH(n)    ((uint32_t)(n) << EDMA_TCD_CITER_ELINK_LINKCH_SHIFT)
+                                                      /* Bit 13-14: Reserved */
+#define EDMA_TCD_CITER_ELINK_ELINK          (1 << 15) /* Bit 15: Enable channel-to-channel linking
+                                                       * on minor-loop complete */
+
+/* TCD Last Destination Address Adjustment/Scatter Gather Address
+ * (32-bit address)
+ */
+
+/* TCD Control and Status */
+
+#define EDMA_TCD_CSR_START                  (1 << 0)  /* Bit 0:  Channel Start */
+#define EDMA_TCD_CSR_INTMAJOR               (1 << 1)  /* Bit 1:  Enable an interrupt when major
+                                                       *         iteration count completes */
+#define EDMA_TCD_CSR_INTHALF                (1 << 2)  /* Bit 2:  Enable an interrupt when major
+                                                       *         counter is half complete */
+#define EDMA_TCD_CSR_DREQ                   (1 << 3)  /* Bit 3:  Disable Request */
+#define EDMA_TCD_CSR_ESG                    (1 << 4)  /* Bit 4:  Enable Scatter/Gather Processing */
+#define EDMA_TCD_CSR_MAJORELINK             (1 << 5)  /* Bit 5:  Enable channel-to-channel linking
+                                                       *         on major loop complete */
+#define EDMA_TCD_CSR_ACTIVE                 (1 << 6)  /* Bit 6:  Channel Active */
+#define EDMA_TCD_CSR_DONE                   (1 << 7)  /* Bit 7:  Channel Done */
+#define EDMA_TCD_CSR_MAJORLINKCH_SHIFT      (8)       /* Bits 8-11: Major Loop Link Channel Number */
+#define EDMA_TCD_CSR_MAJORLINKCH_MASK       (15 << EDMA_TCD_CSR_MAJORLINKCH_SHIFT)
+#  define EDMA_TCD_CSR_MAJORLINKCH(n)       ((uint32_t)(n) << EDMA_TCD_CSR_MAJORLINKCH_SHIFT)
+                                                      /* Bit 112-3: Reserved */
+#define EDMA_TCD_CSR_BWC_SHIFT              (14)      /* Bits 14-15: Bandwidth Control */
+#define EDMA_TCD_CSR_BWC_MASK               (3 << EDMA_TCD_CSR_BWC_SHIFT)
+#  define EDMA_TCD_CSR_BWC_NONE             (0 << EDMA_TCD_CSR_BWC_SHIFT) /* No eDMA engine stalls */
+#  define EDMA_TCD_CSR_BWC_4CYCLES          (2 << EDMA_TCD_CSR_BWC_SHIFT) /* eDMA engine stalls for 4
+                                                                           * cycles after each R/W */
+#  define EDMA_TCD_CSR_BWC_8CYCLES          (3 << EDMA_TCD_CSR_BWC_SHIFT) /* eDMA engine stalls for 8
+                                                                           * cycles after each R/W */
+
+/* TCD Beginning Minor Loop Link, Major Loop Count
+ * (Channel linking disabled)
+ */
+
+#define EDMA_TCD_BITER_BITER_SHIFT          (0)       /* Bit 0-14: Starting Major Iteration Count */
+#define EDMA_TCD_BITER_BITER_MASK           (0x7fff << EDMA_TCD_BITER_BITER_SHIFT)
+#  define EDMA_TCD_BITER_BITER(n)           ((uint32_t)(n) << EDMA_TCD_BITER_BITER_SHIFT)
+#define EDMA_TCD_BITER_ELINK                (1 << 15) /* Bit 15: Enable channel-to-channel linking
+                                                       * on minor-loop complete */
+
+/* TCD Beginning Minor Loop Link, Major Loop Count
+ * (Channel linking enabled)
+ */
+
+#define EDMA_TCD_BITER_ELINK_BITER_SHIFT    (0)       /* Bit 0-8: Current major iteration count */
+#define EDMA_TCD_BITER_ELINK_BITER_MASK     (0x1ff << EDMA_TCD_BITER_ELINK_BITER_SHIFT)
+#  define EDMA_TCD_BITER_ELINK_BITER(n)     ((uint32_t)(n) << EDMA_TCD_BITER_ELINK_BITER_SHIFT)
+#define EDMA_TCD_BITER_ELINK_LINKCH_SHIFT   (9)       /* Bit 9-12: Link Channel Number */
+#define EDMA_TCD_BITER_ELINK_LINKCH_MASK    (15 << EDMA_TCD_BITER_ELINK_LINKCH_SHIFT)
+#  define EDMA_TCD_BITER_ELINK_LINKCH(n)    ((uint32_t)(n) << EDMA_TCD_BITER_ELINK_LINKCH_SHIFT)
+                                                      /* Bit 13-4: Reserved */
+#define EDMA_TCD_BITER_ELINK_ELINK          (1 << 15) /* Bit 15: Enable channel-to-channel linking
+                                                       * on minor-loop complete */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* In-memory representation of the 32-byte Transfer Control Descriptor
+ * (TCD)
+ */
+
+struct kinetis_edmatcd_s
+{
+  sq_entry_t node;
+  uint8_t    flags;         /* See EDMA_CONFIG_* definitions */
+  uint32_t   saddr;         /* Offset: 0x0000  TCD Source Address */
+  uint16_t   soff;          /* Offset: 0x0004  TCD Signed Source Address Offset */
+  uint16_t   attr;          /* Offset: 0x0006  TCD Transfer Attributes */
+  uint32_t   nbytes;        /* Offset: 0x0008  TCD Signed Minor Loop Offset / Byte Count */
+  uint32_t   slast;         /* Offset: 0x000c  TCD Last Source Address Adjustment */
+  uint32_t   daddr;         /* Offset: 0x0010  TCD Destination Address */
+  uint16_t   doff;          /* Offset: 0x0014  TCD Signed Destination Address Offset */
+  uint16_t   citer;         /* Offset: 0x0016  TCD Current Minor Loop Link, Major Loop Count */
+  uint32_t   dlastsga;      /* Offset: 0x0018  TCD Last Destination Address Adjustment/Scatter Gather Address */
+  uint16_t   csr;           /* Offset: 0x001c  TCD Control and Status */
+  uint16_t   biter;         /* Offset: 0x001e  TCD Beginning Minor Loop Link, Major Loop Count */
+};
+
+#endif /* __ARCH_ARM_SRC_KINETIS_HARDWARE_KINETIS_EDMA_H */
diff --git a/arch/arm/src/kinetis/kinetis_dma.c b/arch/arm/src/kinetis/kinetis_dma.c
deleted file mode 100644
index 9287560..0000000
--- a/arch/arm/src/kinetis/kinetis_dma.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/****************************************************************************
- * arch/arm/src/kinetis/kinetis_dma.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 <assert.h>
-#include <errno.h>
-#include <debug.h>
-#include <sys/types.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include <arch/board/board.h>
-
-#include "arm_arch.h"
-#include "arm_internal.h"
-
-#include "kinetis_config.h"
-#include "chip.h"
-#include "kinetis_dma.h"
-#include "hardware/kinetis_dmamux.h"
-#include "hardware/kinetis_sim.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#ifndef DMA_CHN_PER_GROUP
-#   define DMA_CHN_PER_GROUP KINETIS_NDMACH /* Number of channels per group */
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct kinetis_dma_ch
-{
-  bool used;
-  uint8_t ind;
-  uint8_t irq;
-  enum kinetis_dma_direction_e dir;
-  enum kinetis_dma_data_sz_e data_sz;
-  dma_callback_t callback;
-  void *arg;
-};
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static struct kinetis_dma_ch g_channels[KINETIS_NDMACH];
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-static int kinetis_dmainterrupt_int(int irq, void *context,
-                                    struct kinetis_dma_ch *ch)
-{
-  /* Clear bit in the interrupt */
-
-  putreg8(ch->ind, KINETIS_DMA_CINT);
-
-  /* Invoke the callback */
-
-  if (ch->callback)
-    {
-      ch->callback((DMA_HANDLE)&ch, ch->arg, 0);
-    }
-
-  return OK;
-}
-
-static int kinetis_dmainterrupt(int irq, void *context, void *arg)
-{
-  uint8_t irq_int = *(uint8_t *)arg;
-  uint32_t regval;
-  regval = getreg32(KINETIS_DMA_INT);
-
-  /* Channel irq_int and irq_int + DMA_CHN_PER_GROUP use the same arg. Check
-   * which one requested an interrupt
-   */
-
-  if ((regval & (1 << irq_int)) != 0)
-    {
-      kinetis_dmainterrupt_int(irq, context, &g_channels[irq_int]);
-    }
-
-  if ((regval & (1 << (irq_int + DMA_CHN_PER_GROUP))) != 0)
-    {
-      kinetis_dmainterrupt_int(irq, context,
-                               &g_channels[irq_int + DMA_CHN_PER_GROUP]);
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-size_t kinetis_dmaresidual(DMA_HANDLE handle)
-{
-  struct kinetis_dma_ch *ch = (struct kinetis_dma_ch *)handle;
-
-  /* Channel Linking Disabled */
-
-  return ((getreg16(KINETIS_DMA_TCD_CITER(ch->ind)) >>
-           DMA_TCD_CITER2_SHIFT) & DMA_TCD_CITER2_MASK);
-}
-
-/****************************************************************************
- * Name: kinetis_dmainitialize
- *
- * Description:
- *   Initialize the DMA subsystem.
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-void weak_function arm_dma_initialize(void)
-{
-  int i;
-  uint32_t regval;
-  int ret;
-
-  for (i = KINETIS_NDMACH - 1; i >= 0; i--)
-    {
-      g_channels[i].ind = i;
-      g_channels[i].used = false;
-      g_channels[i].irq = KINETIS_IRQ_FIRST + (i % DMA_CHN_PER_GROUP);
-
-      if (i < DMA_CHN_PER_GROUP)
-        {
-          /* Attach DMA interrupt */
-
-          ret = irq_attach(g_channels[i].irq, kinetis_dmainterrupt,
-                           (void *)&g_channels[i].ind);
-
-          if (ret == OK)
-            {
-              /* Enable the IRQ at the NVIC (still disabled at the DMA
-               * controller)
-               */
-
-              up_enable_irq(g_channels[i].irq);
-            }
-         else
-            {
-              g_channels[i].used = true;
-              g_channels[i + DMA_CHN_PER_GROUP].used = true;
-            }
-        }
-    }
-
-  /* Enable clocking for DMA */
-
-  regval  = getreg32(KINETIS_SIM_SCGC7);
-  regval |= SIM_SCGC7_DMA;
-  putreg32(regval, KINETIS_SIM_SCGC7);
-
-  /* Configure DMA for round robin arbitration */
-
-  regval  = 0;
-  regval |= DMA_CR_ERCA | DMA_CR_ERGA;
-  putreg32(regval, KINETIS_DMA_CR);
-
-  /* Enable clocking for the DMA mux */
-
-  regval  = getreg32(KINETIS_SIM_SCGC6);
-  regval |= SIM_SCGC6_DMAMUX0;
-  putreg32(regval, KINETIS_SIM_SCGC6);
-}
-
-/****************************************************************************
- * Name: kinetis_dmachannel
- *
- * Description:
- *   Allocate a DMA channel.  This function sets aside a DMA channel and
- *   gives the caller exclusive access to the DMA channel.
- *
- * Returned Value:
- *   On success, this function returns a non-NULL, void* DMA channel handle.
- *   NULL is returned on any failure.  This function can fail only if no DMA
- *   channel is available.
- *
- ****************************************************************************/
-
-DMA_HANDLE kinetis_dmachannel(uint8_t src, uint32_t per_addr,
-                              enum kinetis_dma_data_sz_e per_data_sz,
-                              enum kinetis_dma_direction_e dir)
-{
-  int i;
-  int ch_ind;
-  uint8_t regval8;
-  uint16_t regval16;
-  irqstate_t flags;
-  struct kinetis_dma_ch *ch;
-
-  /* Find available channel */
-
-  ch_ind = -1;
-  flags = enter_critical_section();
-  for (i = 0; i < KINETIS_NDMACH; i++)
-    {
-      if (!g_channels[i].used)
-        {
-          ch_ind = i;
-          g_channels[ch_ind].used = true;
-          break;
-        }
-    }
-
-  leave_critical_section(flags);
-
-  if (ch_ind == -1)
-    {
-      /* No available channel */
-
-      return NULL;
-    }
-
-  ch = &g_channels[ch_ind];
-
-  /* Copy arguments */
-
-  ch->dir = dir;
-  ch->data_sz = per_data_sz;
-
-  /* DMAMUX Set DMA channel source and enable it */
-
-  regval8 = ((((uint8_t)src) << DMAMUX_CHCFG_SOURCE_SHIFT) &
-             DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_ENBL;
-  putreg8(regval8, KINETIS_DMAMUX_CHCFG(ch_ind));
-
-  /* DMA  Set peripheral address in TCD */
-
-  if (ch->dir == KINETIS_DMA_DIRECTION_PERIPHERAL_TO_MEMORY)
-    {
-      putreg32(per_addr, KINETIS_DMA_TCD_SADDR(ch->ind));
-      putreg16(0, KINETIS_DMA_TCD_SOFF(ch->ind));
-      putreg32(0, KINETIS_DMA_TCD_SLAST(ch->ind));
-    }
-  else if (ch->dir == KINETIS_DMA_DIRECTION_MEMORY_TO_PERIPHERAL)
-    {
-      putreg32(per_addr, KINETIS_DMA_TCD_DADDR(ch->ind));
-      putreg16(0, KINETIS_DMA_TCD_DOFF(ch->ind));
-      putreg32(0, KINETIS_DMA_TCD_DLASTSGA(ch->ind));
-    }
-  else
-    {
-      ch->used = false;
-      return NULL;
-    }
-
-  /* Set data sizes */
-
-  regval16 = (DMA_TCD_ATTR_SSIZE_MASK & ((uint16_t)per_data_sz) <<
-             DMA_TCD_ATTR_SSIZE_SHIFT);
-  regval16 |= (DMA_TCD_ATTR_DSIZE_MASK & ((uint16_t)per_data_sz) <<
-               DMA_TCD_ATTR_DSIZE_SHIFT);
-  putreg16(regval16, KINETIS_DMA_TCD_ATTR(ch->ind));
-
-  /* Set minor loop count */
-
-  putreg32(1 << (uint8_t)per_data_sz, KINETIS_DMA_TCD_NBYTES(ch->ind));
-  return (DMA_HANDLE)ch;
-}
-
-/****************************************************************************
- * Name: kinetis_dmafree
- *
- * Description:
- *   Release a DMA channel.  NOTE:  The 'handle' used in this argument must
- *   NEVER be used again until kinetis_dmachannel() is called again to
- *   re-gain a valid handle.
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-void kinetis_dmafree(DMA_HANDLE handle)
-{
-  struct kinetis_dma_ch *ch = (struct kinetis_dma_ch *)handle;
-  irqstate_t flags;
-
-  DEBUGASSERT(handle != NULL);
-
-  /* Disable DMA channel in the dmamux */
-
-  putreg8(0, KINETIS_DMAMUX_CHCFG(ch->ind));
-
-  flags = enter_critical_section();
-  ch->used = false;
-  leave_critical_section(flags);
-}
-
-/****************************************************************************
- * Name: kinetis_dmasetup
- *
- * Description:
- *   Configure DMA for one transfer.
- *
- ****************************************************************************/
-
-int kinetis_dmasetup(DMA_HANDLE handle, uint32_t mem_addr, size_t ntransfers,
-                     uint16_t control)
-{
-  struct kinetis_dma_ch *ch = (struct kinetis_dma_ch *)handle;
-  uint16_t regval = 0;
-  uint32_t nbytes;
-
-  if (ntransfers > (DMA_TCD_CITER2_MASK >> DMA_TCD_CITER2_SHIFT))
-    {
-      return -EINVAL;
-    }
-
-  DEBUGASSERT(handle != NULL);
-
-  nbytes = (uint32_t)ntransfers * (uint32_t)(1 << (uint8_t)ch->data_sz);
-
-  if (ch->dir == KINETIS_DMA_DIRECTION_PERIPHERAL_TO_MEMORY)
-    {
-      putreg32(mem_addr, KINETIS_DMA_TCD_DADDR(ch->ind));
-      putreg16(1 << (uint8_t)ch->data_sz, KINETIS_DMA_TCD_DOFF(ch->ind));
-      putreg32(-nbytes, KINETIS_DMA_TCD_DLASTSGA(ch->ind));
-    }
-  else if (ch->dir == KINETIS_DMA_DIRECTION_MEMORY_TO_PERIPHERAL)
-    {
-      putreg32(mem_addr, KINETIS_DMA_TCD_SADDR(ch->ind));
-      putreg16(1 << (uint8_t)ch->data_sz, KINETIS_DMA_TCD_SOFF(ch->ind));
-      putreg32(-nbytes, KINETIS_DMA_TCD_SLAST(ch->ind));
-    }
-  else
-    {
-      return -EINVAL;
-    }
-
-  /* Set up channel with control word */
-
-  regval =  (control & DMA_TCD_CSR_MAJORELINK) ? ch->ind : 0;
-  regval <<= DMA_TCD_CSR_MAJORLINKCH_SHIFT;
-  regval &= DMA_TCD_CSR_MAJORLINKCH_MASK;
-  regval |= (DMA_TCD_CSR_INTMAJOR |
-            (control & (DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_MAJORELINK)));
-  putreg16(regval, KINETIS_DMA_TCD_CSR(ch->ind));
-
-  /* Set major loop count */
-
-  putreg16(ntransfers, KINETIS_DMA_TCD_BITER(ch->ind));
-  putreg16(ntransfers, KINETIS_DMA_TCD_CITER(ch->ind));
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: kinetis_dmastart
- *
- * Description:
- *   Start the DMA transfer
- *
- ****************************************************************************/
-
-int kinetis_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
-{
-  struct kinetis_dma_ch *ch = (struct kinetis_dma_ch *)handle;
-
-  DEBUGASSERT(handle != NULL);
-
-  ch->callback = callback;
-  ch->arg = arg;
-
-  /* Enable request register for this channel */
-
-  putreg8(ch->ind, KINETIS_DMA_SERQ);
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: kinetis_dmastop
- *
- * Description:
- *   Cancel the DMA.  After kinetis_dmastop() is called, the DMA channel is
- *   reset and kinetis_dmasetup() must be called before kinetis_dmastart()
- *   can be called again
- *
- ****************************************************************************/
-
-void kinetis_dmastop(DMA_HANDLE handle)
-{
-  struct kinetis_dma_ch *ch = (struct kinetis_dma_ch *)handle;
-
-  DEBUGASSERT(handle != NULL);
-
-  putreg8(ch->ind, KINETIS_DMA_CERQ);
-}
-
-/****************************************************************************
- * Name: kinetis_dmasample
- *
- * Description:
- *   Sample DMA register contents
- *
- ****************************************************************************/
-
-#ifdef CONFIG_DEBUG_DMA
-void kinetis_dmasample(DMA_HANDLE handle, struct kinetis_dmaregs_s *regs)
-{
-  DEBUGASSERT(handle != NULL);
-}
-#endif
-
-/****************************************************************************
- * Name: kinetis_dmadump
- *
- * Description:
- *   Dump previously sampled DMA register contents
- *
- ****************************************************************************/
-
-#ifdef CONFIG_DEBUG_DMA
-void kinetis_dmadump(DMA_HANDLE handle, const struct kinetis_dmaregs_s *regs,
-                const char *msg)
-{
-  DEBUGASSERT(handle != NULL);
-}
-#endif
diff --git a/arch/arm/src/kinetis/kinetis_dma.h b/arch/arm/src/kinetis/kinetis_dma.h
deleted file mode 100644
index fc2cdb4..0000000
--- a/arch/arm/src/kinetis/kinetis_dma.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/****************************************************************************
- * arch/arm/src/kinetis/kinetis_dma.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_KINETEIS_KINETEIS_DMA_H
-#define __ARCH_ARM_SRC_KINETEIS_KINETEIS_DMA_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <sys/types.h>
-
-#include "hardware/kinetis_dma.h"
-
-/****************************************************************************
- * Pre-processor Declarations
- ****************************************************************************/
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-typedef FAR void *DMA_HANDLE;
-typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result);
-
-/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is
- * selected.
- */
-
-#ifdef CONFIG_DEBUG_DMA
-struct kinetis_dmaglobalregs_s
-{
-#warning "Missing logic"
-  /* Global Registers */
-};
-
-struct kinetis_dmachanregs_s
-{
-#warning "Missing logic"
-  /* Channel Registers */
-};
-
-struct kinetis_dmaregs_s
-{
-  /* Global Registers */
-
-  struct kinetis_dmaglobalregs_s gbl;
-
-  /* Channel Registers */
-
-  struct kinetis_dmachanregs_s   ch;
-};
-#endif
-
-enum kinetis_dma_direction_e
-{
-  KINETIS_DMA_DIRECTION_PERIPHERAL_TO_MEMORY,
-  KINETIS_DMA_DIRECTION_MEMORY_TO_PERIPHERAL
-};
-
-/* Kinetis data transfer size */
-
-enum kinetis_dma_data_sz_e
-{
-  KINETIS_DMA_DATA_SZ_8BIT = 0,
-  KINETIS_DMA_DATA_SZ_16BIT = 1,
-  KINETIS_DMA_DATA_SZ_32BIT = 2,
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#ifndef __ASSEMBLY__
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C"
-{
-#else
-#define EXTERN extern
-#endif
-
-/****************************************************************************
- * Public Functions Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Name: kinetis_dmainitialize
- *
- * Description:
- *   Initialize the GPDMA subsystem.
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-void kinetis_dmainitialize(void);
-
-/****************************************************************************
- * Name: kinetis_dmachannel
- *
- * Description:
- *   Allocate a DMA channel.  This function sets aside a DMA channel and
- *   gives the caller exclusive access to the DMA channel.
- *
- * Input Parameters:
- *   src         - DMA request source
- *   per_addr    - Address of the peripheral data
- *   per_data_sz - Peripheral data size (register size). Note that if this
- *                 does not agree with the peripheral register size, DMA
- *                 transfers will silently fail during operation.
- *   dir         - transfer direction
- *
- * Returned Value:
- *   On success, this function returns a non-NULL, void* DMA channel handle.
- *   NULL is returned on any failure.  This function can fail only if no DMA
- *   channel is available.
- *
- ****************************************************************************/
-
-DMA_HANDLE kinetis_dmachannel(uint8_t src,
-                              uint32_t per_addr,
-                              enum kinetis_dma_data_sz_e per_data_sz,
-                              enum kinetis_dma_direction_e dir);
-
-/****************************************************************************
- * Name: kinetis_dmafree
- *
- * Description:
- *   Release a DMA channel.  NOTE:  The 'handle' used in this argument must
- *   NEVER be used again until kinetis_dmachannel() is called again to re-
- *   gain a valid handle.
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-void kinetis_dmafree(DMA_HANDLE handle);
-
-/****************************************************************************
- * Name: kinetis_dmasetup
- *
- * Description:
- *   Configure DMA for one transfer.
- *
- * Input Parameters:
- *   mem_addr   - Memory address
- *   ntransfers - Number of transfers. Must be 0<= ntransfers <= 0x7FFF
- *   control    - Channel control configuration
- *
- * Returned Value:
- *   result: 0 if ok, negative else
- *
- ****************************************************************************/
-
-int kinetis_dmasetup(DMA_HANDLE handle, uint32_t mem_addr,
-                     size_t ntransfers, uint16_t control);
-
-/****************************************************************************
- * Name: kinetis_dmastart
- *
- * Description:
- *   Start the DMA transfer
- *
- ****************************************************************************/
-
-int kinetis_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg);
-
-/****************************************************************************
- * Name: kinetis_dmastop
- *
- * Description:
- *   Cancel the DMA.  After kinetis_dmastop() is called, the DMA channel is
- *   reset and kinetis_dmasetup() must be called before kinetis_dmastart()
- *   can be called again
- *
- ****************************************************************************/
-
-void kinetis_dmastop(DMA_HANDLE handle);
-
-/****************************************************************************
- * Name: kinetis_dmaresidual
- *
- * Description:
- *   Returns the number of transfers left
- *
- * Returned Value:
- *   Residual transfers
- ****************************************************************************/
-
-size_t kinetis_dmaresidual(DMA_HANDLE handle);
-
-/****************************************************************************
- * Name: kinetis_dmasample
- *
- * Description:
- *   Sample DMA register contents
- *
- ****************************************************************************/
-
-#ifdef CONFIG_DEBUG_DMA
-void kinetis_dmasample(DMA_HANDLE handle, struct kinetis_dmaregs_s *regs);
-#else
-#  define kinetis_dmasample(handle,regs)
-#endif
-
-/****************************************************************************
- * Name: kinetis_dmadump
- *
- * Description:
- *   Dump previously sampled DMA register contents
- *
- ****************************************************************************/
-
-#ifdef CONFIG_DEBUG_DMA
-void kinetis_dmadump(DMA_HANDLE handle, const struct kinetis_dmaregs_s *regs,
-                     const char *msg);
-#else
-#  define kinetis_dmadump(handle,regs,msg)
-#endif
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* __ASSEMBLY__ */
-#endif /* __ARCH_ARM_SRC_KINETEIS_KINETEIS_DMA_H */
diff --git a/arch/arm/src/kinetis/kinetis_edma.c b/arch/arm/src/kinetis/kinetis_edma.c
new file mode 100644
index 0000000..f0b14be
--- /dev/null
+++ b/arch/arm/src/kinetis/kinetis_edma.c
@@ -0,0 +1,1464 @@
+/****************************************************************************
+ * arch/arm/src/kinetis/kinetis_edma.c
+ *
+ *   Copyright (C) 2019, 2021 Gregory Nutt. All rights reserved.
+ *   Authors: Gregory Nutt <gn...@nuttx.org>
+ *            David Sidrane <da...@nscdg.com>
+ *
+ * This file was leveraged from the NuttX S32K port.  Portions of that eDMA
+ * logic derived from NXP sample code which has a compatible BSD 3-clause
+ * license:
+ *
+ *   Copyright (c) 2015, Freescale Semiconductor, Inc.
+ *   Copyright 2016-2017 NXP
+ *   All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <queue.h>
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/semaphore.h>
+
+#include "arm_arch.h"
+#include "arm_internal.h"
+#include "sched/sched.h"
+
+#include "chip.h"
+#include "hardware/kinetis_edma.h"
+#include "hardware/kinetis_dmamux.h"
+#include "kinetis_edma.h"
+#include "hardware/kinetis_sim.h"
+
+#ifdef CONFIG_KINETIS_EDMA
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* TCD Alignment.
+ *
+ * eDMA TCDs must be aligned with the D-Cache line boundaries to facilitate
+ * cache operations on the TCDs when the D-Cache is enabled.
+ *
+ * NOTE:  The TCDs are 32-bytes in length.  We implicitly assume that the
+ * D-Cache line size is also 32-bits.  Otherwise, padding would be required
+ * at the ends of the TCDS and buffers to protect data after the end of from
+ * invalidation.
+ */
+
+#ifdef CONFIG_ARMV7M_DCACHE
+/* Align to the cache line size which we assume is >= 8 */
+
+#  define EDMA_ALIGN        ARMV7M_DCACHE_LINESIZE
+#  define EDMA_ALIGN_MASK   (EDMA_ALIGN-1)
+#  define EDMA_ALIGN_UP(n)  (((n) + EDMA_ALIGN_MASK) & ~EDMA_ALIGN_MASK)
+
+#else
+/* Special alignment is not required in this case,
+ * but we will align to 8-bytes
+ */
+
+#  define EDMA_ALIGN        8
+#  define EDMA_ALIGN_MASK   7
+#  define EDMA_ALIGN_UP(n)  (((n) + 7) & ~7)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* State of a DMA channel */
+
+enum kinetis_dmastate_e
+{
+  KINETIS_DMA_IDLE = 0,             /* No DMA in progress */
+  KINETIS_DMA_CONFIGURED,           /* DMA configured, but not yet started */
+  KINETIS_DMA_ACTIVE                /* DMA has been started and is in progress */
+};
+
+/* This structure describes one DMA channel */
+
+struct kinetis_dmach_s
+{
+  uint8_t chan;                   /* DMA channel number (0-KINETIS_EDMA_NCHANNELS) */
+  bool inuse;                     /* true: The DMA channel is in use */
+  uint8_t dmamux;                 /* The DMAMUX channel selection */
+  uint8_t ttype;                  /* Transfer type: M2M, M2P, P2M, or P2P */
+  uint8_t state;                  /* Channel state.  See enum kinetis_dmastate_e */
+  uint32_t flags;                 /* DMA channel flags */
+  edma_callback_t callback;       /* Callback invoked when the DMA completes */
+  void *arg;                      /* Argument passed to callback function */
+
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+  /* That TCD list is linked through the DLAST SGA field.  The first transfer
+   * to be performed is at the head of the list.  Subsequent TCDs are added
+   * at the tail of the list.
+   */
+
+  struct kinetis_edmatcd_s *head;   /* First TCD in the list */
+  struct kinetis_edmatcd_s *tail;   /* Last TCD in the list */
+#endif
+};
+
+/* This structure describes the state of the eDMA controller */
+
+struct kinetis_edma_s
+{
+  /* These semaphores protect the DMA channel and descriptor tables */
+
+  sem_t chsem;                    /* Protects channel table */
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+  sem_t dsem;                     /* Supports wait for free descriptors */
+#endif
+
+  /* This array describes each DMA channel */
+
+  struct kinetis_dmach_s dmach[KINETIS_EDMA_NCHANNELS];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The state of the eDMA */
+
+static struct kinetis_edma_s g_edma;
+
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+/* This is a singly-linked list of free TCDs */
+
+static sq_queue_t g_tcd_free;
+
+/* This is a pool of pre-allocated TCDs */
+
+static struct kinetis_edmatcd_s g_tcd_pool[CONFIG_KINETIS_EDMA_NTCD]
+              __attribute__((aligned(EDMA_ALIGN)));
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: kinetis_takechsem() and kinetis_givechsem()
+ *
+ * Description:
+ *   Used to get exclusive access to the DMA channel table for channel
+ *   allocation.
+ *
+ ****************************************************************************/
+
+static int kinetis_takechsem(void)
+{
+  return nxsem_wait_uninterruptible(&g_edma.chsem);
+}
+
+static inline void kinetis_givechsem(void)
+{
+  nxsem_post(&g_edma.chsem);
+}
+
+/****************************************************************************
+ * Name: kinetis_takedsem() and kinetis_givedsem()
+ *
+ * Description:
+ *   Used to wait for availability of descriptors in the descriptor table.
+ *
+ ****************************************************************************/
+
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+static void kinetis_takedsem(void)
+{
+  nxsem_wait_uninterruptible(&g_edma.dsem);
+}
+
+static inline void kinetis_givedsem(void)
+{
+  nxsem_post(&g_edma.dsem);
+}
+#endif
+
+/****************************************************************************
+ * Name: kinetis_tcd_alloc
+ *
+ * Description:
+ *   Allocate an in-memory, TCD
+ *
+ ****************************************************************************/
+
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+static struct kinetis_edmatcd_s *kinetis_tcd_alloc(void)
+{
+  struct kinetis_edmatcd_s *tcd;
+  irqstate_t flags;
+
+  /* Take the 'dsem'.  When we hold the the 'dsem', then we know that one
+   * TCD is reserved for us in the free list.
+   *
+   * NOTE: We use a critical section here because we may block waiting for
+   * the 'dsem'.  The critical section will be suspended while we are
+   * waiting.
+   */
+
+  flags = enter_critical_section();
+  kinetis_takedsem();
+
+  /* Now there should be a TCD in the free list reserved just for us */
+
+  tcd = (struct kinetis_edmatcd_s *)sq_remfirst(&g_tcd_free);
+  DEBUGASSERT(tcd != NULL);
+
+  leave_critical_section(flags);
+  return tcd;
+}
+#endif
+
+/****************************************************************************
+ * Name: kinetis_tcd_free
+ *
+ * Description:
+ *   Free an in-memory, TCD
+ *
+ ****************************************************************************/
+
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+static void kinetis_tcd_free(struct kinetis_edmatcd_s *tcd)
+{
+  irqstate_t flags;
+
+  /* Add the the TCD to the end of the free list and post the 'dsem',
+   * possibly waking up another thread that might be waiting for
+   * a TCD.
+   */
+
+  flags = spin_lock_irqsave(NULL);
+  sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
+  kinetis_givedsem();
+  spin_unlock_irqrestore(NULL, flags);
+}
+#endif
+
+/****************************************************************************
+ * Name: kinetis_tcd_initialize()
+ *
+ * Description:
+ *   Initialize the TCD free list from the pool of pre-allocated TCDs.
+ *
+ * Assumptions:
+ *   Called early in the initialization sequence so no special protection is
+ *   necessary.
+ *
+ ****************************************************************************/
+
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+static inline void kinetis_tcd_initialize(void)
+{
+  sq_entry_t *tcd;
+  int i;
+
+  /* Add each pre-allocated TCD to the tail of the TCD free list */
+
+  sq_init(&g_tcd_free);
+  for (i = 0; i < CONFIG_KINETIS_EDMA_NTCD; i++)
+    {
+      tcd = (sq_entry_t *)&g_tcd_pool[i];
+      sq_addlast(tcd, &g_tcd_free);
+    }
+}
+#endif
+
+/****************************************************************************
+ * Name: kinetis_tcd_chanlink
+ *
+ * Description:
+ *   This function configures either a minor link or a major link. The minor
+ *   link means the channel link is triggered every time CITER decreases by 1
+ *   The major link means that the channel link  is triggered when the CITER
+ *   is exhausted.
+ *
+ *   NOTE: Users should ensure that DONE flag is cleared before calling this
+ *   interface, or the configuration is invalid.
+ *
+ * Input Parameters:
+ *   tcd  - Point to the TCD structure.
+ *   type - Channel link type.
+ *   chan - The linked channel number.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_KINETIS_EDMA_ELINK
+static inline void kinetis_tcd_chanlink(uint8_t flags,
+                                        struct kinetis_dmach_s *linkch,
+                                        struct kinetis_edmatcd_s *tcd)
+{
+  uint16_t regval16;
+
+  flags &= EDMA_CONFIG_LINKTYPE_MASK;
+
+  if (linkch == NULL || flags == EDMA_CONFIG_LINKTYPE_LINKNONE)
+    {
+#if 0 /* Already done */
+      /* No link or no link channel provided */
+
+      /* Disable minor links */
+
+      tcd->citer &= ~EDMA_TCD_CITER_ELINK;
+      tcd->biter &= ~EDMA_TCD_BITER_ELINK;
+
+      /* Disable major link */
+
+      tcd->csr   &= ~EDMA_TCD_CSR_MAJORELINK;
+#endif
+    }
+  else if (flags == EDMA_CONFIG_LINKTYPE_MINORLINK) /* Minor link config */
+    {
+      /* Enable minor link */
+
+      tcd->citer |= EDMA_TCD_CITER_ELINK_ELINK;
+      tcd->biter |= EDMA_TCD_BITER_ELINK_ELINK;
+
+      /* Set linked channel */
+
+      regval16    = tcd->citer;
+      regval16   &= ~EDMA_TCD_CITER_ELINK_LINKCH_MASK;
+      regval16   |= EDMA_TCD_CITER_ELINK_LINKCH(linkch->chan);
+      tcd->citer  = regval16;
+
+      regval16    = tcd->biter;
+      regval16   &= ~EDMA_TCD_BITER_ELINK_LINKCH_MASK;
+      regval16   |= EDMA_TCD_BITER_ELINK_LINKCH(linkch->chan);
+      tcd->biter  = regval16;
+    }
+  else /* if (flags == EDMA_CONFIG_LINKTYPE_MAJORLINK)  Major link config */
+    {
+      /* Enable major link */
+
+      regval16    = tcd->csr;
+      regval16   |= EDMA_TCD_CSR_MAJORELINK;
+      tcd->csr    = regval16;
+
+      /* Set major linked channel */
+
+      regval16   &= ~EDMA_TCD_CSR_MAJORLINKCH_MASK;
+      regval16   |=  EDMA_TCD_CSR_MAJORLINKCH(linkch->chan);
+      tcd->csr    = regval16;
+    }
+}
+#endif
+
+/****************************************************************************
+ * Name: kinetis_tcd_configure
+ *
+ * Description:
+ *  Configure all TCD registers to the specified values.  'tcd' is an
+ *  'overlay' that may refer either to either the TCD register set or to an
+ *  in-memory TCD structure.
+ *
+ ****************************************************************************/
+
+static inline void kinetis_tcd_configure(struct kinetis_edmatcd_s *tcd,
+                            const struct kinetis_edma_xfrconfig_s *config)
+{
+  tcd->flags    = config->flags;
+  tcd->saddr    = config->saddr;
+  tcd->soff     = config->soff;
+  tcd->attr     = EDMA_TCD_ATTR_SSIZE(config->ssize) |  /* Transfer Attributes */
+                  EDMA_TCD_ATTR_DSIZE(config->dsize);
+  tcd->nbytes   = config->nbytes;
+  tcd->slast    = config->flags & EDMA_CONFIG_LOOPSRC ?  -config->iter : 0;
+  tcd->daddr    = config->daddr;
+  tcd->doff     = config->doff;
+  tcd->citer    = config->iter & EDMA_TCD_CITER_CITER_MASK;
+  tcd->biter    = config->iter & EDMA_TCD_BITER_BITER_MASK;
+  tcd->csr      = config->flags & EDMA_CONFIG_LOOPDEST ?
+                                  0 : EDMA_TCD_CSR_DREQ;
+  tcd->csr      |= config->flags & EDMA_CONFIG_INTHALF ?
+                                  EDMA_TCD_CSR_INTHALF : 0;
+  tcd->dlastsga = config->flags & EDMA_CONFIG_LOOPDEST ?  -config->iter : 0;
+
+  /* And special case flags */
+
+#ifdef CONFIG_KINETIS_EDMA_ELINK
+  /* Configure major/minor link mapping */
+
+  kinetis_tcd_chanlink(config->flags,
+                       (struct kinetis_dmach_s *)config->linkch,
+                       tcd);
+#endif
+}
+
+/****************************************************************************
+ * Name: kinetis_tcd_instantiate
+ *
+ * Description:
+ *   Copy an in-memory TCD into eDMA channel TCD registers
+ *
+ ****************************************************************************/
+
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+static void kinetis_tcd_instantiate(struct kinetis_dmach_s *dmach,
+                                    const struct kinetis_edmatcd_s *tcd)
+{
+  uintptr_t base = KINETIS_EDMA_TCD_BASE(dmach->chan);
+
+  /* Push tcd into hardware TCD register */
+
+  putreg32(tcd->saddr,    base + KINETIS_EDMA_TCD_SADDR_OFFSET);
+  putreg16(tcd->soff,     base + KINETIS_EDMA_TCD_SOFF_OFFSET);
+  putreg16(tcd->attr,     base + KINETIS_EDMA_TCD_ATTR_OFFSET);
+  putreg32(tcd->nbytes,   base + KINETIS_EDMA_TCD_NBYTES_ML_OFFSET);
+  putreg32(tcd->slast,    base + KINETIS_EDMA_TCD_SLAST_OFFSET);
+  putreg32(tcd->daddr,    base + KINETIS_EDMA_TCD_DADDR_OFFSET);
+  putreg16(tcd->doff,     base + KINETIS_EDMA_TCD_DOFF_OFFSET);
+  putreg16(tcd->citer,    base + KINETIS_EDMA_TCD_CITER_ELINK_OFFSET);
+  putreg32(tcd->dlastsga, base + KINETIS_EDMA_TCD_DLASTSGA_OFFSET);
+
+  /* Clear DONE bit first, otherwise ESG cannot be set */
+
+  putreg16(0,             base + KINETIS_EDMA_TCD_CSR_OFFSET);
+  putreg16(tcd->csr,      base + KINETIS_EDMA_TCD_CSR_OFFSET);
+
+  putreg16(tcd->biter,    base + KINETIS_EDMA_TCD_BITER_ELINK_OFFSET);
+}
+#endif
+
+/****************************************************************************
+ * Name: kinetis_dmaterminate
+ *
+ * Description:
+ *   Terminate the DMA transfer and disable the DMA channel
+ *
+ ****************************************************************************/
+
+static void kinetis_dmaterminate(struct kinetis_dmach_s *dmach, int result)
+{
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+  struct kinetis_edmatcd_s *tcd;
+  struct kinetis_edmatcd_s *next;
+#endif
+  uintptr_t regaddr;
+  uint8_t regval8;
+  uint8_t chan;
+
+  /* Disable channel ERROR interrupts */
+
+  chan            = dmach->chan;
+  regval8         = EDMA_CEEI(chan);
+  putreg8(regval8, KINETIS_EDMA_CEEI);
+
+  /* Disable channel IRQ requests */
+
+  regval8         = EDMA_CERQ(chan);
+  putreg8(regval8, KINETIS_EDMA_CERQ);
+
+  /* Check for an Rx (memory-to-peripheral/memory-to-memory) DMA transfer */
+
+  if (dmach->ttype == EDMA_MEM2MEM || dmach->ttype == EDMA_PERIPH2MEM)
+    {
+      /* Invalidate the cache to force reloads from memory. */
+
+#warning Missing logic
+    }
+
+  /* Perform the DMA complete callback */
+
+  if (dmach->callback)
+    {
+      dmach->callback((DMACH_HANDLE)dmach, dmach->arg, true, result);
+    }
+
+  /* Clear CSR to disable channel. Because if the given channel started,
+   * transfer CSR will be not zero. Because if it is the last transfer, DREQ
+   * will be set.  If not, ESG will be set.
+   */
+
+  regaddr         = KINETIS_EDMA_TCD_CSR(chan);
+  putreg16(0, regaddr);
+
+  /* Cancel next TCD transfer. */
+
+  regaddr         = KINETIS_EDMA_TCD_DLASTSGA(chan);
+  putreg16(0, regaddr);
+
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+  /* Return all allocated TCDs to the free list */
+
+  for (tcd = dmach->head; tcd != NULL; tcd = next)
+    {
+      /* If channel looped to itself we are done
+       * if not continue to free tcds in chain
+       */
+
+       next = tcd->flags & EDMA_CONFIG_LOOPDEST ?
+              NULL : (struct kinetis_edmatcd_s *)tcd->dlastsga;
+
+       kinetis_tcd_free(tcd);
+    }
+
+  dmach->head = NULL;
+  dmach->tail = NULL;
+#endif
+
+  dmach->callback = NULL;
+  dmach->arg      = NULL;
+  dmach->state    = KINETIS_DMA_IDLE;
+}
+
+/****************************************************************************
+ * Name: kinetis_edma_interrupt
+ *
+ * Description:
+ *   DMA interrupt handler.  This function clears the channel major
+ *   interrupt flag and calls the callback function if it is not NULL.
+ *
+ *   NOTE:  For the case using TCD queue, when the major iteration count is
+ *   exhausted, additional operations are performed.  These include the
+ *   final address adjustments and reloading of the BITER field into the
+ *   CITER.  Assertion of an optional interrupt request also occurs at this
+ *   time, as does a possible fetch of a new TCD from memory using the
+ *   scatter/gather address pointer included in the descriptor (if scatter/
+ *   gather is enabled).
+ *
+ ****************************************************************************/
+
+static int kinetis_edma_interrupt(int irq, void *context, FAR void *arg)
+{
+  struct kinetis_dmach_s *dmach;
+  uintptr_t regaddr;
+  uint8_t   regval8;
+  uint16_t  regval16;
+  uint32_t  regval32;
+  uint8_t   chan;
+  int       result;
+
+  /* 'arg' should the DMA channel instance. */
+
+  dmach = (struct kinetis_dmach_s *)arg;
+  DEBUGASSERT(dmach != NULL);
+
+  chan  = dmach->chan;
+  DEBUGASSERT(chan < KINETIS_EDMA_NCHANNELS && dmach == &g_edma.dmach[chan]);
+
+  /* Check for an eDMA pending interrupt on this channel */
+
+  regval32 = getreg32(KINETIS_EDMA_INT);
+  if ((regval32 & EDMA_INT(chan)) != 0)
+    {
+      /* An interrupt is pending.  This should only happen if the channel is
+       * active.
+       */
+
+      DEBUGASSERT(dmach->state == KINETIS_DMA_ACTIVE);
+
+      /* Clear the pending eDMA channel interrupt */
+
+      regval8 = EDMA_CINT(chan);
+      putreg8(regval8, KINETIS_EDMA_CINT);
+
+      /* Get the eDMA TCD Control and Status register value. */
+
+      regaddr  = KINETIS_EDMA_TCD_CSR(chan);
+      regval16 = getreg16(regaddr);
+
+      /* Check if transfer has finished. */
+
+      if ((regval16 & EDMA_TCD_CSR_DONE) != 0)
+        {
+          /* Clear the pending DONE interrupt status. */
+
+          regval8 = EDMA_CDNE(chan);
+          putreg8(regval8, KINETIS_EDMA_CDNE);
+          result = OK;
+        }
+      else
+        {
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+          /* Perform the end-of-major-cycle DMA callback */
+
+          if (dmach->callback != NULL)
+            {
+              dmach->callback((DMACH_HANDLE)dmach, dmach->arg,
+                              false, 0);
+            }
+
+          return OK;
+#else
+          /* Otherwise the interrupt was not expected! */
+
+          DEBUGPANIC();
+          result = -EPIPE;
+#endif
+        }
+
+      /* Terminate the transfer when it is done. */
+
+      kinetis_dmaterminate(dmach, result);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: kinetis_error_interrupt
+ *
+ * Description:
+ *  DMA error interrupt handler
+ *
+ ****************************************************************************/
+
+static int kinetis_error_interrupt(int irq, void *context, FAR void *arg)
+{
+  uint32_t errstatus;
+  uint32_t errmask;
+  uint8_t regval8;
+  unsigned int chan;
+
+  /* Get the set of pending error interrupts */
+
+  errstatus = getreg32(KINETIS_EDMA_ERR);
+
+  /* Check for an error on each channel */
+
+  for (chan = 0; chan < KINETIS_EDMA_NCHANNELS && errstatus != 0; chan++)
+    {
+      /* Check for a pending error interrupt on each channel */
+
+      errmask = EDMA_ERR(chan);
+      if ((errstatus & errmask) != 0)
+        {
+          dmaerr("ERROR: DMACH%u ES=%08lx\n",
+                 chan, (unsigned long)getreg32(KINETIS_EDMA_ES));
+
+          /* Clear the pending error interrupt status. */
+
+          regval8 = EDMA_CERR(chan);
+          putreg8(regval8, KINETIS_EDMA_CERR);
+
+          /* Remove the bit from the sample ERR register so that perhaps we
+           * can exit this loop early.
+           */
+
+          errstatus &= ~errmask;
+
+          /* Terminate the transfer on any error */
+
+          kinetis_dmaterminate(&g_edma.dmach[chan], -EIO);
+        }
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arm_dma_initialize
+ *
+ * Description:
+ *   Initialize the DMA subsystem
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void weak_function arm_dma_initialize(void)
+{
+  uintptr_t regaddr;
+  uint32_t regval;
+  int i;
+
+  dmainfo("Initialize eDMA\n");
+
+  /* Enable clocking for DMA */
+
+  regval  = getreg32(KINETIS_SIM_SCGC7);
+  regval |= SIM_SCGC7_DMA;
+  putreg32(regval, KINETIS_SIM_SCGC7);
+
+  /* Enable clocking for the DMA mux */
+
+  regval  = getreg32(KINETIS_SIM_SCGC6);
+  regval |= SIM_SCGC6_DMAMUX0;
+  putreg32(regval, KINETIS_SIM_SCGC6);
+
+  /* Configure the eDMA controller */
+
+  regval = getreg32(KINETIS_EDMA_CR);
+  regval &= ~(EDMA_CR_EDBG | EDMA_CR_ERCA | EDMA_CR_HOE | EDMA_CR_CLM |
+              EDMA_CR_EMLM);
+
+#ifdef CONFIG_KINETIS_EDMA_EDBG
+  regval |= EDMA_CR_EDBG;   /* Enable Debug */
+#endif
+#ifdef CONFIG_KINETIS_EDMA_ERCA
+  regval |= EDMA_CR_ERCA;   /* Enable Round Robin Channel Arbitration */
+#endif
+#ifdef CONFIG_KINETIS_EDMA_ERGA
+  regval |= EDMA_CR_ERGA;   /* Enable Round Robin Group Arbitration */
+#endif
+#ifdef CONFIG_KINETIS_EDMA_HOE
+  regval |= EDMA_CR_HOE;    /* Halt On Error */
+#endif
+#ifdef CONFIG_KINETIS_EDMA_CLM
+  regval |= EDMA_CR_CLM;    /* Continuous Link Mode */
+#endif
+#ifdef CONFIG_KINETIS_EDMA_EMLIM
+  regval |= EDMA_CR_EMLM;   /* Enable Minor Loop Mapping */
+#endif
+
+  putreg32(regval, KINETIS_EDMA_CR);
+
+  /* Initialize data structures */
+
+  memset(&g_edma, 0, sizeof(struct kinetis_edma_s));
+  for (i = 0; i < KINETIS_EDMA_NCHANNELS; i++)
+    {
+      g_edma.dmach[i].chan = i;
+    }
+
+  /* Initialize semaphores */
+
+  nxsem_init(&g_edma.chsem, 0, 1);
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+  nxsem_init(&g_edma.dsem, 0, CONFIG_KINETIS_EDMA_NTCD);
+
+  /* The 'dsem' is used for signaling rather than mutual exclusion and,
+   * hence, should not have priority inheritance enabled.
+   */
+
+  nxsem_set_protocol(&g_edma.dsem, SEM_PRIO_NONE);
+
+  /* Initialize the list of free TCDs from the pool of pre-allocated TCDs. */
+
+  kinetis_tcd_initialize();
+#endif
+
+  /* Attach DMA interrupt vectors. */
+
+  for (i = 0; i < KINETIS_EDMA_NCHANNELS; i++)
+    {
+      irq_attach(KINETIS_IRQ_DMACH0 + i,
+                 kinetis_edma_interrupt, &g_edma.dmach[i]);
+    }
+
+  /* Attach the DMA error interrupt vector */
+
+  irq_attach(KINETIS_IRQ_DMAERR, kinetis_error_interrupt, NULL);
+
+  /* Disable and clear all error interrupts */
+
+  putreg32(0, KINETIS_EDMA_EEI);
+  putreg32(0xffffffff, KINETIS_EDMA_ERR);
+
+  /* Disable all DMA channel interrupts at the eDMA controller */
+
+  for (i = 0; i < KINETIS_EDMA_NCHANNELS; i++)
+    {
+      /* Disable all DMA channels and DMA channel interrupts */
+
+      regaddr = KINETIS_EDMA_TCD_CSR(i);
+      putreg16(0, regaddr);
+    }
+
+  /* Clear all pending DMA channel interrupts */
+
+  putreg32(0xffffffff, KINETIS_EDMA_INT);
+
+  /* Enable the channel interrupts at the NVIC (still disabled at the eDMA
+   * controller).
+   */
+
+  for (i = 0; i < KINETIS_EDMA_NCHANNELS; i++)
+    {
+      up_enable_irq(KINETIS_IRQ_DMACH0 + i);
+    }
+
+  /* Enable the DMA error interrupt */
+
+  up_enable_irq(KINETIS_IRQ_DMAERR);
+}
+
+/****************************************************************************
+ * Name: kinetis_dmach_alloc
+ *
+ *   Allocate a DMA channel.  This function sets aside a DMA channel,
+ *   initializes the DMAMUX for the channel, then gives the caller exclusive
+ *   access to the DMA channel.
+ *
+ * Input Parameters:
+ *   dmamux - DMAMUX configuration see DMAMUX channel configuration register
+ *            bit-field definitions in hardware/kinetis_dmamux.h.
+ *            Settings include:
+ *
+ *            DMAMUX_CHCFG_SOURCE     Chip-specific DMA source (required)
+ *            DMAMUX_CHCFG_TRIG       DMA Channel Trigger Enable (optional)
+ *            DMAMUX_CHCFG_ENBL       DMA Mux Channel Enable (required)
+ *
+ *            A value of zero will disable the DMAMUX channel.
+ *   dchpri - DCHPRI channel priority configuration.  See DCHPRI channel
+ *            configuration register bit-field definitions in
+ *            hardware/kinetis_edma.h.  Meaningful settings include:
+ *
+ *            EDMA_DCHPRI_CHPRI       Channel Arbitration Priority
+ *            DCHPRI_DPA              Disable Preempt Ability
+ *            DCHPRI_ECP              Enable Channel Preemption
+ *
+ *            The power-on default, 0x05, is a reasonable choice.
+ *
+ * Returned Value:
+ *   If a DMA channel is available, this function returns a non-NULL, void*
+ *   DMA channel handle.  NULL is returned on any failure.
+ *
+ ****************************************************************************/
+
+DMACH_HANDLE kinetis_dmach_alloc(uint8_t dmamux, uint8_t dchpri)
+{
+  struct kinetis_dmach_s *dmach;
+  unsigned int chndx;
+  int ret;
+
+  /* Search for an available DMA channel */
+
+  dmach = NULL;
+  ret = kinetis_takechsem();
+  if (ret < 0)
+    {
+      return NULL;
+    }
+
+  for (chndx = 0; chndx < KINETIS_EDMA_NCHANNELS; chndx++)
+    {
+      struct kinetis_dmach_s *candidate = &g_edma.dmach[chndx];
+      uintptr_t regaddr;
+      uint8_t regval8;
+
+      if (!candidate->inuse)
+        {
+          dmach         = candidate;
+          dmach->inuse  = true;
+          dmach->state  = KINETIS_DMA_IDLE;
+          dmach->dmamux = dmamux;
+
+          /* Clear any pending interrupts on the channel */
+
+          DEBUGASSERT(chndx == dmach->chan);
+          regaddr = KINETIS_EDMA_TCD_CSR(chndx);
+          putreg16(0, regaddr);
+
+          /* Make sure that the channel is disabled. */
+
+          regval8 = EDMA_CERQ(chndx);
+          putreg8(regval8, KINETIS_EDMA_CERQ);
+
+          /* Disable the associated DMAMUX for now */
+
+          putreg8(0, KINETIS_DMAMUX_CHCFG(chndx));
+          break;
+        }
+    }
+
+  kinetis_givechsem();
+
+  /* Show the result of the allocation */
+
+  if (dmach != NULL)
+    {
+      dmainfo("CH%d: returning dmach: %p\n", dmach->chan, dmach);
+    }
+  else
+    {
+      dmaerr("ERROR: Failed allocate eDMA channel\n");
+    }
+
+  return (DMACH_HANDLE)dmach;
+}
+
+/****************************************************************************
+ * Name: kinetis_dmach_free
+ *
+ * Description:
+ *   Release a DMA channel.  NOTE:  The 'handle' used in this argument must
+ *   NEVER be used again until kinetis_dmach_alloc() is called again to
+ *   re-gain a valid handle.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void kinetis_dmach_free(DMACH_HANDLE handle)
+{
+  struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle;
+  uint8_t regval8;
+
+  dmainfo("dmach: %p\n", dmach);
+  DEBUGASSERT(dmach != NULL && dmach->inuse &&
+              dmach->state != KINETIS_DMA_ACTIVE);
+
+  /* Mark the channel no longer in use.  Clearing the inuse flag is an atomic
+   * operation and so should be safe.
+   */
+
+  dmach->flags = 0;
+  dmach->inuse = false;                   /* No longer in use */
+  dmach->state = KINETIS_DMA_IDLE;        /* Better not be active! */
+
+  /* Make sure that the channel is disabled. */
+
+  regval8 = EDMA_CERQ(dmach->chan);
+  putreg8(regval8, KINETIS_EDMA_CERQ);
+
+  /* Disable the associated DMAMUX */
+
+  putreg8(0, KINETIS_DMAMUX_CHCFG(dmach->chan));
+}
+
+/****************************************************************************
+ * Name: kinetis_dmach_xfrsetup
+ *
+ * Description:
+ *   This function adds the eDMA transfer to the DMA sequence.  The request
+ *   is setup according to the content of the transfer configuration
+ *   structure. For "normal" DMA, kinetis_dmach_xfrsetup is called only once.
+ *   Scatter/gather DMA is accomplished by calling this function repeatedly,
+ *   once for each transfer in the sequence.  Scatter/gather DMA processing
+ *   is enabled automatically when the second transfer configuration is
+ *   received.
+ *
+ *   This function may be called multiple times to handle multiple,
+ *   discontinuous transfers (scatter-gather)
+ *
+ * Input Parameters:
+ *   handle - DMA channel handle created by kinetis_dmach_alloc()
+ *   config - A DMA transfer configuration instance, populated by the
+ *            The content of 'config' describes the transfer
+ *
+ * Returned Value
+ *   Zero (OK) is returned on success; a negated errno value is returned on
+ *   any failure.
+ *
+ ****************************************************************************/
+
+int kinetis_dmach_xfrsetup(DMACH_HANDLE *handle,
+                           const struct kinetis_edma_xfrconfig_s *config)
+{
+  struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle;
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+  struct kinetis_edmatcd_s *tcd;
+  struct kinetis_edmatcd_s *prev;
+#endif
+  uintptr_t regaddr;
+  uint16_t regval16;
+
+  DEBUGASSERT(dmach != NULL);
+  dmainfo("dmach%u: %p config: %p\n", dmach->chan, dmach, config);
+
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+  /* Scatter/gather DMA is supported */
+
+  /* Allocate a TCD, waiting if necessary */
+
+  tcd = kinetis_tcd_alloc();
+
+  /* Configure current TCD block transfer. */
+
+  kinetis_tcd_configure(tcd, config);
+
+  /* Enable the interrupt when the major iteration count completes for this
+   * TCD.  For "normal" DMAs, this will correspond to the DMA DONE
+   * interrupt; for scatter gather DMAs, multiple interrupts will be
+   * generated with the final being the DONE interrupt.
+   */
+
+  tcd->csr |= EDMA_TCD_CSR_INTMAJOR;
+
+  /* Is looped to it's self? */
+
+  if (config->flags & EDMA_CONFIG_LOOP_MASK)
+    {
+      /* Enable major link */
+
+      tcd->csr |= EDMA_TCD_CSR_MAJORELINK;
+
+      /* Set major linked channel back to this one */
+
+      tcd->csr   &= ~EDMA_TCD_CSR_MAJORLINKCH_MASK;
+      tcd->csr   |=  EDMA_TCD_CSR_MAJORLINKCH(dmach->chan);
+    }
+
+  /* Is this the first descriptor in the list? */
+
+  if (dmach->head == NULL)
+    {
+      /* Yes.. add it to the list */
+
+      dmach->head  = tcd;
+      dmach->tail  = tcd;
+      dmach->ttype = config->ttype;
+
+      /* And instantiate the first TCD in the DMA channel TCD registers. */
+
+      kinetis_tcd_instantiate(dmach, tcd);
+    }
+  else
+    {
+      /* Cannot mix transfer types (only because of cache-related operations.
+       * this restriction could be removed with some effort).
+       */
+
+      if (dmach->ttype != config->ttype ||
+          dmach->flags & EDMA_CONFIG_LOOPDEST)
+        {
+          kinetis_tcd_free(tcd);
+          return -EINVAL;
+        }
+
+      /* Chain from previous descriptor in the list. */
+
+      /* Enable scatter/gather feature in the previous TCD. */
+
+      prev           = dmach->tail;
+      regval16       = prev->csr;
+      regval16      &= ~EDMA_TCD_CSR_DREQ;
+      regval16      |= EDMA_TCD_CSR_ESG;
+      prev->csr      = regval16;
+
+      prev->dlastsga = (uint32_t)tcd;
+      dmach->tail    = tcd;
+
+      /* Clean cache associated with the previous TCD memory */
+
+      up_clean_dcache((uintptr_t)prev,
+                      (uintptr_t)prev + sizeof(struct kinetis_edmatcd_s));
+
+      /* Check if the TCD block in the DMA channel registers is the same as
+       * the previous previous TCD.  This can happen if the previous TCD was
+       * the first TCD and has already be loaded into the TCD registers.
+       */
+
+      if (dmach->head == prev)
+        {
+          /* Enable scatter/gather also in the TCD registers. */
+
+          regaddr   = KINETIS_EDMA_TCD_CSR(dmach->chan);
+          regval16  = getreg16(regaddr);
+          regval16 &= ~EDMA_TCD_CSR_DREQ;
+          regval16 |= EDMA_TCD_CSR_ESG;
+          putreg16(regval16, regaddr);
+
+          regaddr   = KINETIS_EDMA_TCD_DLASTSGA(dmach->chan);
+          putreg32((uint32_t)tcd, regaddr);
+        }
+    }
+
+  /* Clean cache associated with the TCD memory */
+
+  up_clean_dcache((uintptr_t)tcd,
+                  (uintptr_t)tcd + sizeof(struct kinetis_edmatcd_s));
+#else
+  /* Scatter/gather DMA is NOT supported */
+
+  /* Check if eDMA is busy: if the channel has started transfer, CSR will be
+   * non-zero.
+   */
+
+  regaddr  = KINETIS_EDMA_TCD_CSR(dmach->chan);
+  regval16 = getreg16(regaddr);
+
+  if (regval16 != 0 && (regval16 & EDMA_TCD_CSR_DONE) == 0)
+    {
+      return -EBUSY;
+    }
+
+  /* Configure channel TCD registers to the values specified in config. */
+
+  kinetis_tcd_configure((struct kinetis_edmatcd_s *)
+                        KINETIS_EDMA_TCD_BASE(dmach->chan), config);
+
+  /* Enable the DONE interrupt when the major iteration count completes. */
+
+  regaddr         = KINETIS_EDMA_TCD_CSR(dmach->chan);
+  modifyreg16(regaddr, 0, EDMA_TCD_CSR_INTMAJOR);
+#endif
+
+  /* Check for an Rx (memory-to-peripheral/memory-to-memory) DMA transfer */
+
+  if (dmach->ttype == EDMA_MEM2MEM || dmach->ttype == EDMA_PERIPH2MEM)
+    {
+      /* Invalidate caches associated with the destination DMA memory.
+       * REVISIT:  nbytes is the number of bytes transferred on each
+       * minor loop.  The following is only valid when the major loop
+       * is one.
+       */
+
+      up_invalidate_dcache((uintptr_t)config->daddr,
+                           (uintptr_t)config->daddr + config->nbytes);
+    }
+
+  /* Check for an Tx (peripheral-to-memory/memory-to-memory) DMA transfer */
+
+  if (dmach->ttype == EDMA_MEM2MEM || dmach->ttype == EDMA_MEM2PERIPH)
+    {
+      /* Clean caches associated with the source DMA memory.
+       * REVISIT:  nbytes is the number of bytes transferred on each
+       * minor loop.  The following is only valid when the major loop
+       * is one.
+       */
+#warning Missing logic
+
+      up_clean_dcache((uintptr_t)config->saddr,
+                      (uintptr_t)config->saddr + config->nbytes);
+    }
+
+  /* Set the DMAMUX source and enable and optional trigger */
+
+  putreg8(dmach->dmamux, KINETIS_DMAMUX_CHCFG(dmach->chan));
+
+  dmach->state = KINETIS_DMA_CONFIGURED;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: kinetis_dmach_start
+ *
+ * Description:
+ *   Start the DMA transfer.  This function should be called after the final
+ *   call to kinetis_dmach_xfrsetup() in order to avoid race conditions.
+ *
+ *   At the conclusion of each major DMA loop, a callback to the user
+ *   provided function is made:  |For "normal" DMAs, this will correspond to
+ *   the DMA DONE interrupt; for scatter gather DMAs, multiple interrupts
+ *   will be generated with the final being the DONE interrupt.
+ *
+ *   At the conclusion of the DMA, the DMA channel is reset, all TCDs are
+ *   freed, and the callback function is called with the the success/fail
+ *   result of the DMA.
+ *
+ *   NOTE: On Rx DMAs (peripheral-to-memory or memory-to-memory), it is
+ *   necessary to invalidate the destination memory.  That is not done
+ *   automatically by the DMA module.  Invalidation of the destination memory
+ *   regions is the responsibility of the caller.
+ *
+ * Input Parameters:
+ *   handle   - DMA channel handle created by kinetis_dmach_alloc()
+ *   callback - The callback to be invoked when the DMA is completes or is
+ *              aborted.
+ *   arg      - An argument that accompanies the callback
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned on
+ *   any failure.
+ *
+ ****************************************************************************/
+
+int kinetis_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
+                        void *arg)
+{
+  struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle;
+  irqstate_t flags;
+  uint8_t regval8;
+  uint8_t chan;
+
+  DEBUGASSERT(dmach != NULL && dmach->state == KINETIS_DMA_CONFIGURED);
+  chan            = dmach->chan;
+  dmainfo("dmach%u: %p callback: %p arg: %p\n", chan, dmach, callback, arg);
+
+  /* Save the callback info.  This will be invoked when the DMA completes */
+
+  flags           = spin_lock_irqsave(NULL);
+  dmach->callback = callback;
+  dmach->arg      = arg;
+
+#if CONFIG_KINETIS_EDMA_NTCD > 0
+  /* Although it is not recommended, it might be possible to call this
+   * function multiple times while adding TCDs on the fly.
+   */
+
+  if (dmach->state != KINETIS_DMA_ACTIVE)
+#endif
+    {
+      dmach->state    = KINETIS_DMA_ACTIVE;
+
+      /* Enable channel ERROR interrupts */
+
+      regval8         = EDMA_SEEI(chan);
+      putreg8(regval8, KINETIS_EDMA_SEEI);
+
+      /* Enable the DMA request for this channel */
+
+      regval8         = EDMA_SERQ(chan);
+      putreg8(regval8, KINETIS_EDMA_SERQ);
+    }
+
+  spin_unlock_irqrestore(NULL, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: kinetis_dmach_stop
+ *
+ * Description:
+ *   Cancel the DMA.  After kinetis_dmach_stop() is called, the DMA channel
+ *   is reset, all TCDs are freed, and kinetis_dmarx/txsetup() must be called
+ *   before kinetis_dmach_start() can be called again.
+ *
+ * Input Parameters:
+ *   handle   - DMA channel handle created by kinetis_dmach_alloc()
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void kinetis_dmach_stop(DMACH_HANDLE handle)
+{
+  struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle;
+  irqstate_t flags;
+
+  dmainfo("dmach: %p\n", dmach);
+  DEBUGASSERT(dmach != NULL);
+
+  flags = spin_lock_irqsave(NULL);
+  kinetis_dmaterminate(dmach, -EINTR);
+  spin_unlock_irqrestore(NULL, flags);
+}
+
+/****************************************************************************
+ * Name: kinetis_dmach_getcount
+ *
+ * Description:
+ *   This function checks the TCD (Task Control Descriptor) status for a
+ *   specified eDMA channel and returns the the number of major loop counts
+ *   that have not finished.
+ *
+ *   NOTES:
+ *   1. This function can only be used to get unfinished major loop count of
+ *      transfer without the next TCD, or it might be inaccuracy.
+ *   2. The unfinished/remaining transfer bytes cannot be obtained directly
+ *      from registers while the channel is running.
+ *
+ *   Because to calculate the remaining bytes, the initial NBYTES configured
+ *   in DMA_TCDn_NBYTES_MLNO register is needed while the eDMA IP does not
+ *   support getting it while a channel is active.  In another words, the
+ *   NBYTES value reading is always the actual (decrementing) NBYTES value
+ *   the dma_engine is working with while a channel is running.
+ *   Consequently, to get the remaining transfer bytes, a software-saved
+ *   initial value of NBYTES (for example copied before enabling the channel)
+ *   is needed. The formula to calculate it is shown below:
+ *
+ *     RemainingBytes = RemainingMajorLoopCount *
+ *                      NBYTES(initially configured)
+ *
+ * Input Parameters:
+ *   handle  - DMA channel handle created by kinetis_dmach_alloc()
+ *
+ * Returned Value:
+ *   Major loop count which has not been transferred yet for the current TCD.
+ *
+ ****************************************************************************/
+
+unsigned int kinetis_dmach_getcount(DMACH_HANDLE *handle)
+{
+  struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle;
+  unsigned int remaining = 0;
+  uintptr_t regaddr;
+  uint16_t regval16;
+
+  DEBUGASSERT(dmach != NULL);
+
+  /* If the DMA is done, then the remaining count is zero */
+
+  regaddr  = KINETIS_EDMA_TCD_CSR(dmach->chan);
+  regval16 = getreg16(regaddr);
+
+  if ((regval16 & EDMA_TCD_CSR_DONE) == 0)
+    {
+      /* Calculate the unfinished bytes */
+
+      regaddr  = KINETIS_EDMA_TCD_CITER_ELINK(dmach->chan);
+      regval16 = getreg16(regaddr);
+
+      if ((regval16 & EDMA_TCD_CITER_ELINK) != 0)
+        {
+          remaining = (regval16 & EDMA_TCD_CITER_ELINK_CITER_MASK) >>
+                      EDMA_TCD_CITER_ELINK_CITER_SHIFT;
+        }
+      else
+        {
+          remaining = (regval16 & EDMA_TCD_CITER_CITER_MASK) >>
+                      EDMA_TCD_CITER_CITER_SHIFT;
+        }
+    }
+
+  return remaining;
+}
+
+/****************************************************************************
+ * Name: kinetis_dmasample
+ *
+ * Description:
+ *   Sample DMA register contents
+ *
+ * Assumptions:
+ *   - DMA handle allocated by kinetis_dmach_alloc()
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+void kinetis_dmasample(DMACH_HANDLE handle, struct kinetis_dmaregs_s *regs)
+{
+  struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle;
+  uintptr_t regaddr;
+  unsigned int chan;
+  irqstate_t flags;
+
+  DEBUGASSERT(dmach != NULL && regs != NULL);
+  chan           = dmach->chan;
+  regs->chan     = chan;
+
+  /* eDMA Global Registers */
+
+  flags          = spin_lock_irqsave(NULL);
+
+  regs->cr       = getreg32(KINETIS_EDMA_CR);   /* Control */
+  regs->es       = getreg32(KINETIS_EDMA_ES);   /* Error Status */
+  regs->erq      = getreg32(KINETIS_EDMA_ERQ);  /* Enable Request */
+  regs->req      = getreg32(KINETIS_EDMA_INT);  /* Interrupt Request */
+  regs->err      = getreg32(KINETIS_EDMA_ERR);  /* Error */
+  regs->hrs      = getreg32(KINETIS_EDMA_HRS);  /* Hardware Request Status */
+  regs->ears     = getreg32(KINETIS_EDMA_EARS); /* Enable Asynchronous Request in Stop */
+
+  /* eDMA Channel registers */
+
+  regaddr        = KINETIS_EDMA_DCHPRI(chan);
+  regs->dchpri   = getreg8(regaddr);          /* Channel priority */
+
+  /* eDMA TCD */
+
+  base           = KINETIS_EDMA_TCD_BASE(chan);
+  regs->saddr    = getreg32(base + KINETIS_EDMA_TCD_SADDR_OFFSET);
+  regs->soff     = getreg16(base + KINETIS_EDMA_TCD_SOFF_OFFSET);
+  regs->attr     = getreg16(base + KINETIS_EDMA_TCD_ATTR_OFFSET);
+  regs->nbml     = getreg32(base + KINETIS_EDMA_TCD_NBYTES_ML_OFFSET);
+  regs->slast    = getreg32(base + KINETIS_EDMA_TCD_SLAST_OFFSET);
+  regs->daddr    = getreg32(base + KINETIS_EDMA_TCD_DADDR_OFFSET);
+  regs->doff     = getreg16(base + KINETIS_EDMA_TCD_DOFF_OFFSET);
+  regs->citer    = getreg16(base + KINETIS_EDMA_TCD_CITER_ELINK_OFFSET);
+  regs->dlastsga = getreg32(base + KINETIS_EDMA_TCD_DLASTSGA_OFFSET);
+  regs->csr      = getreg16(base + KINETIS_EDMA_TCD_CSR_OFFSET);
+  regs->biter    = getreg16(base + KINETIS_EDMA_TCD_BITER_ELINK_OFFSET);
+
+  /* DMAMUX registers */
+
+  regaddr        = KINETIS_DMAMUX_CHCFG(chan);
+  regs->dmamux   = getreg32(regaddr);         /* Channel configuration */
+
+  spin_unlock_irqrestore(NULL, flags);
+}
+#endif /* CONFIG_DEBUG_DMA */
+
+/****************************************************************************
+ * Name: kinetis_dmadump
+ *
+ * Description:
+ *   Dump previously sampled DMA register contents
+ *
+ * Assumptions:
+ *   - DMA handle allocated by kinetis_dmach_alloc()
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+void kinetis_dmadump(const struct kinetis_dmaregs_s *regs, const char *msg)
+{
+  unsigned int chan;
+
+  DEBUGASSERT(regs != NULL && msg != NULL);
+
+  chan = regs->chan;
+  DEBUGASSERT(chan < KINETIS_EDMA_NCHANNELS);
+
+  dmainfo("%s\n", msg);
+  dmainfo("  eDMA Global Registers:\n");
+  dmainfo("          CR: %08x\n", regs->cr);
+  dmainfo("          ES: %08x\n", regs->es);
+  dmainfo("         ERQ: %08x\n", regs->erq);
+  dmainfo("         INT: %08x\n", regs->req);
+  dmainfo("         ERR: %08x\n", regs->err);
+  dmainfo("        EARS: %08x\n", regs->hrs);
+
+  /* eDMA Channel registers */
+
+  dmainfo("  eDMA Channel %u Registers:\n", chan);
+  dmainfo("    DCHPRI: %02x\n", regs->dchpri);
+
+  /* eDMA TCD */
+
+  dmainfo("  eDMA Channel %u TCD Registers:\n", chan);
+  dmainfo("       SADDR: %08x\n", regs->saddr);
+  dmainfo("        SOFF: %04x\n", regs->soff);
+  dmainfo("        ATTR: %04x\n", regs->attr);
+  dmainfo("        NBML: %05x\n", regs->nbml);
+  dmainfo("       SLAST: %05x\n", regs->slast);
+  dmainfo("       DADDR: %05x\n", regs->daddr);
+  dmainfo("        DOFF: %04x\n", regs->doff);
+  dmainfo("       CITER: %04x\n", regs->citer);
+  dmainfo("    DLASTSGA: %08x\n", regs->dlastsga);
+  dmainfo("         CSR: %04x\n", regs->csr);
+  dmainfo("       BITER: %04x\n", regs->biter);
+
+  /* DMAMUX registers */
+
+  dmainfo("  DMAMUX Channel %u Registers:\n", chan);
+  dmainfo("      DMAMUX: %08x\n", regs->dmamux);
+}
+#endif /* CONFIG_DEBUG_DMA */
+#endif /* CONFIG_KINETIS_EDMA */
diff --git a/arch/arm/src/kinetis/kinetis_edma.h b/arch/arm/src/kinetis/kinetis_edma.h
new file mode 100644
index 0000000..72ba838
--- /dev/null
+++ b/arch/arm/src/kinetis/kinetis_edma.h
@@ -0,0 +1,455 @@
+/****************************************************************************
+ * arch/arm/src/kinetis/kinetis_edma.h
+ *
+ *   Copyright (C) 2019 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * This file was leveraged from the NuttX i.MXRT port.
+ * Portions of that eDMA logic derived from NXP sample code which has
+ * a compatible BSD 3-clause license:
+ *
+ *   Copyright (c) 2015, Freescale Semiconductor, Inc.
+ *   Copyright 2016-2017 NXP
+ *   All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_EDMAC_H
+#define __ARCH_ARM_SRC_KINETIS_KINETIS_EDMAC_H
+
+/* General Usage:
+ *
+ * 1. Allocate a DMA channel
+ *
+ *      DMACH_HANDLE handle;
+ *      handle = edma_dmach_alloc(dmamux, dchpri);
+ *
+ *    Where 'dmamux' is the channel DMAMUX configuration register setting and
+ *    'dchpri' is the channel DCHPRIO priority register setting.
+ *
+ * 2. Create the transfer configuration:
+ *
+ *      struct kinetis_edma_xfrconfig_s config;
+ *      config.saddr = ..;
+ *      config.daddr = ..;
+ *      etc.
+ *
+ * 3. Setup the transfer in hardware:
+ *
+ *      int ret;
+ *      ret = kinetis_dmach_xfrsetup(handle, &config);
+ *
+ * 4. If you are setting up a scatter gather DMA
+ *    (with CONFIG_KINETIS_EDMA_NTCD > 0), then repeat steps 2 and 3 for
+ *     each segment of the transfer.
+ *
+ * 5. Start the DMA:
+ *
+ *      ret = kinetis_dmach_start(handle, my_callback_func, priv);
+ *
+ *    Where my_callback_func() is called when the DMA completes or an error
+ *    occurs. 'priv' represents some internal driver state that will be
+ *    provided with the callback.
+ *
+ * 6. If you need to stop the DMA and free resources (such as if a timeout
+ *    occurs), then:
+ *
+ *     i mxrt_dmach_stop(handle);
+ *
+ * 7. The callback will be received when the DMA completes (or an error
+ *    occurs). After that, you may free  the DMA channel, or re-use it on
+ *    subsequent DMAs.
+ *
+ *      kinetis_dmach_free(handle);
+ *
+ * Almost non-invasive debug instrumentation is available.  You may call
+ * kinetis_dmasample() to save the current state of the eDMA registers at
+ * any given point in time.  At some later, postmortem analysis, you can
+ * dump the content of the buffered registers with kinetis_dmadump().
+ * kinetis_dmasample() is also available for monitoring DMA progress.
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include "hardware/kinetis_edma.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration flags.
+ *
+ * REVISIT:  Many missing options that should be represented as flags:
+ * 1. Bandwidth
+ * 2. Source/Destination modulo
+ */
+
+#define EDMA_CONFIG_LINKTYPE_SHIFT       (0) /* Bits 0-1: Link type */
+#define EDMA_CONFIG_LINKTYPE_MASK        (3 << EDMA_CONFIG_LINKTYPE_SHIFT)
+#  define EDMA_CONFIG_LINKTYPE_LINKNONE  (0 << EDMA_CONFIG_LINKTYPE_SHIFT) /* No channel link */
+#  define EDMA_CONFIG_LINKTYPE_MINORLINK (1 << EDMA_CONFIG_LINKTYPE_SHIFT) /* Channel link after each minor loop */
+#  define EDMA_CONFIG_LINKTYPE_MAJORLINK (2 << EDMA_CONFIG_LINKTYPE_SHIFT) /* Channel link when major loop count exhausted */
+
+#define EDMA_CONFIG_LOOP_SHIFT           (2) /* Bits 2: Loop type */
+#define EDMA_CONFIG_LOOP_MASK            (3 << EDMA_CONFIG_LOOP_SHIFT)
+#  define EDMA_CONFIG_LOOPNONE           (0 << EDMA_CONFIG_LOOP_SHIFT) /* No looping */
+#  define EDMA_CONFIG_LOOPSRC            (1 << EDMA_CONFIG_LOOP_SHIFT) /* Source looping */
+#  define EDMA_CONFIG_LOOPDEST           (2 << EDMA_CONFIG_LOOP_SHIFT) /* Dest looping */
+
+#define EDMA_CONFIG_INTHALF              (1 << 3) /* Bits 3: Int on HALF */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+typedef FAR void *DMACH_HANDLE;
+typedef void (*edma_callback_t)(DMACH_HANDLE handle,
+                                void *arg, bool done, int result);
+
+/* eDMA transfer type */
+
+enum kinetis_edma_xfrtype_e
+{
+  EDMA_MEM2MEM = 0,      /* Transfer from memory to memory */
+  EDMA_PERIPH2MEM,       /* Transfer from peripheral to memory */
+  EDMA_MEM2PERIPH,       /* Transfer from memory to peripheral */
+};
+
+/* eDMA transfer sises */
+
+enum kinetis_edma_sizes_e
+{
+  EDMA_8BIT    = 0,      /* Transfer data size 8 */
+  EDMA_16BIT   = 1,      /* Transfer data size 16 */
+  EDMA_32BIT   = 2,      /* Transfer data size 32 */
+};
+
+/* This structure holds the source/destination transfer attribute
+ * configuration.
+ */
+
+struct kinetis_edma_xfrconfig_s
+{
+    uint32_t saddr;      /* Source data address. */
+    uint32_t daddr;      /* Destination data address. */
+    int16_t  soff;       /* Sign-extended offset for current source address. */
+    int16_t  doff;       /* Sign-extended offset for current destination address. */
+    uint16_t iter;       /* Major loop iteration count. */
+    uint8_t  flags;      /* See EDMA_CONFIG_* definitions */
+    uint8_t  ssize;      /* Source data transfer size (see TCD_ATTR_SIZE_* definitions in rdware/. */
+    uint8_t  dsize;      /* Destination data transfer size. */
+    uint8_t  ttype;      /* Transfer type (see enum kinetis_edma_xfrtype_e). */
+#ifdef CONFIG_KINETIS_EDMA_EMLIM
+    uint16_t nbytes;     /* Bytes to transfer in a minor loop */
+#else
+    uint32_t nbytes;     /* Bytes to transfer in a minor loop */
+#endif
+#ifdef CONFIG_KINETIS_EDMA_ELINK
+    DMACH_HANDLE linkch; /* Link channel (With EDMA_CONFIG_LINKTYPE_* flags) */
+#endif
+};
+
+/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA
+ * is selected
+ */
+
+#ifdef CONFIG_DEBUG_DMA
+struct kinetis_dmaregs_s
+{
+  uint8_t chan;          /* Sampled channel */
+
+  /* eDMA Global Registers */
+
+  uint32_t cr;           /* Control */
+  uint32_t es;           /* Error Status */
+  uint32_t erq;          /* Enable Request */
+  uint32_t req;          /* Interrupt Request */
+  uint32_t err;          /* Error */
+  uint32_t hrs;          /* Hardware Request Status */
+  uint32_t ears;         /* Enable Asynchronous Request in Stop */
+
+  /* eDMA Channel registers */
+
+  uint8_t dchpri;        /* Channel priority */
+
+  /* eDMA TCD */
+
+  uint32_t saddr;        /* TCD Source Address */
+  uint16_t soff;         /* TCD Signed Source Address Offset */
+  uint16_t attr;         /* TCD Transfer Attributes */
+  uint32_t nbml;         /* TCD Signed Minor Loop Offset / Byte Count */
+  uint32_t slast;        /* TCD Last Source Address Adjustment */
+  uint32_t daddr;        /* TCD Destination Address */
+  uint16_t doff;         /* TCD Signed Destination Address Offset */
+  uint16_t citer;        /* TCD Current Minor Loop Link, Major Loop Count */
+  uint32_t dlastsga;     /* TCD Last Destination Address Adjustment/Scatter Gather Address */
+  uint16_t csr;          /* TCD Control and Status */
+  uint16_t biter;        /* TCD Beginning Minor Loop Link, Major Loop Count */
+
+  /* DMAMUX registers */
+
+  uint32_t dmamux;       /* Channel configuration */
+};
+#endif /* CONFIG_DEBUG_DMA */
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: kinetis_dmach_alloc
+ *
+ *   Allocate a DMA channel.  This function sets aside a DMA channel,
+ *   initializes the DMAMUX for the channel, then gives the caller exclusive
+ *   access to the DMA channel.
+ *
+ * Input Parameters:
+ *   dmamux - DMAMUX configuration see DMAMUX channel configuration register
+ *            bit-field definitions in hardware/kinetis_dmamux.h.
+ *            Settings include:
+ *
+ *            DMAMUX_CHCFG_SOURCE     Chip-specific DMA source (required)
+ *            DMAMUX_CHCFG_TRIG       DMA Channel Trigger Enable (optional)
+ *            DMAMUX_CHCFG_ENBL       DMA Mux Channel Enable (required)
+ *
+ *            A value of zero will disable the DMAMUX channel.
+ *   dchpri - DCHPRI channel priority configuration.  See DCHPRI channel
+ *            configuration register bit-field definitions in
+ *            hardware/kinetis_edma.h.  Meaningful settings include:
+ *
+ *            EDMA_DCHPRI_CHPRI       Channel Arbitration Priority
+ *            DCHPRI_DPA              Disable Preempt Ability
+ *            DCHPRI_ECP              Enable Channel Preemption
+ *
+ *            The power-on default, 0x05, is a reasonable choice.
+ *
+ * Returned Value:
+ *   If a DMA channel is available, this function returns a non-NULL, void*
+ *   DMA channel handle.  NULL is returned on any failure.
+ *
+ ****************************************************************************/
+
+DMACH_HANDLE kinetis_dmach_alloc(uint8_t dmamux, uint8_t dchpri);
+
+/****************************************************************************
+ * Name: kinetis_dmach_free
+ *
+ * Description:
+ *   Release a DMA channel.
+ *   NOTE:  The 'handle' used in this argument must NEVER be used again
+ *   until kinetis_dmach_alloc() is called again to re-gain a valid handle.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void kinetis_dmach_free(DMACH_HANDLE handle);
+
+/****************************************************************************
+ * Name: kinetis_dmach_xfrsetup
+ *
+ * Description:
+ *   This function adds the eDMA transfer to the DMA sequence.  The request
+ *   is setup according to the content of the transfer configuration
+ *   structure.  For "normal" DMA, kinetis_dmach_xfrsetup is called only
+ *   once.
+ *   Scatter/gather DMA is accomplished by calling this function repeatedly,
+ *   once for each transfer in the sequence.  Scatter/gather DMA processing
+ *   is enabled automatically when the second transfer configuration is
+ *   received.
+ *
+ *   This function may be called multiple times to handle multiple,
+ *   discontinuous transfers (scatter-gather)
+ *
+ * Input Parameters:
+ *   handle - DMA channel handle created by kinetis_dmach_alloc()
+ *   config - A DMA transfer configuration instance, populated by the
+ *            The content of 'config' describes the transfer
+ *
+ * Returned Value
+ *   Zero (OK) is returned on success; a negated errno value is returned on
+ *   any failure.
+ *
+ ****************************************************************************/
+
+int kinetis_dmach_xfrsetup(DMACH_HANDLE *handle,
+                           const struct kinetis_edma_xfrconfig_s *config);
+
+/****************************************************************************
+ * Name: kinetis_dmach_start
+ *
+ * Description:
+ *   Start the DMA transfer by enabling the channel DMA request.
+ *   This function should be called after the final call to
+ *   kinetis_dmasetup() in order to avoid race conditions.
+ *
+ *   At the conclusion of each major DMA loop, a callback to the
+ *   user-provided function is made:  |For "normal" DMAs, this will
+ *   correspond to the DMA DONE interrupt; for scatter gather DMAs, multiple
+ *   interrupts will be generated with the final being the DONE interrupt.
+ *
+ *   At the conclusion of the DMA, the DMA channel is reset, all TCDs are
+ *   freed, and the callback function is called with the the success/fail
+ *   result of the DMA.
+ *
+ *   NOTE:
+ *   On Rx DMAs (peripheral-to-memory or memory-to-memory), it is necessary
+ *   to invalidate the destination memory.  That is not done automatically
+ *   by the DMA module.  Invalidation of the destination memory regions is
+ *   the responsibility of the caller.
+ *
+ * Input Parameters:
+ *   handle   - DMA channel handle created by kinetis_dmach_alloc()
+ *   callback - The callback to be invoked when the DMA is completes or is
+ *              aborted.
+ *   arg      - An argument that accompanies the callback
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned on
+ *   any failure.
+ *
+ ****************************************************************************/
+
+int kinetis_dmach_start(DMACH_HANDLE handle,
+                        edma_callback_t callback, void *arg);
+
+/****************************************************************************
+ * Name: kinetis_dmach_stop
+ *
+ * Description:
+ *   Cancel the DMA.  After kinetis_dmach_stop() is called, the DMA channel
+ *   is reset, all TCDs are freed, and kinetis_dmarx/txsetup() must be called
+ *   before kinetis_dmach_start() can be called again
+ *
+ * Input Parameters:
+ *   handle   - DMA channel handle created by kinetis_dmach_alloc()
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void kinetis_dmach_stop(DMACH_HANDLE handle);
+
+/****************************************************************************
+ * Name: kinetis_dmach_getcount
+ *
+ * Description:
+ *   This function checks the TCD (Task Control Descriptor) status for a
+ *   specified eDMA channel and returns the the number of major loop counts
+ *   that have not finished.
+ *
+ *   NOTES:
+ *   1. This function can only be used to get unfinished major loop count of
+ *      transfer without the next TCD, or it might be inaccuracy.
+ *   2. The unfinished/remaining transfer bytes cannot be obtained directly
+ *      from registers while the channel is running.
+ *
+ *   Because to calculate the remaining bytes, the initial NBYTES configured
+ *   in DMA_TCDn_NBYTES_MLNO register is needed while the eDMA IP does not
+ *   support getting it while a channel is active.  In another words, the
+ *   NBYTES value reading is always the actual (decrementing) NBYTES value
+ *   the dma_engine is working with while a channel is running.
+ *   Consequently, to get the remaining transfer bytes, a software-saved
+ *   initial value of NBYTES (for example copied before enabling the channel)
+ *   is needed. The formula to calculate it is shown below:
+ *
+ *    RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured)
+ *
+ * Input Parameters:
+ *   handle  - DMA channel handle created by kinetis_dmach_alloc()
+ *
+ * Returned Value:
+ *   Major loop count which has not been transferred yet for the current TCD.
+ *
+ ****************************************************************************/
+
+unsigned int kinetis_dmach_getcount(DMACH_HANDLE *handle);
+
+/****************************************************************************
+ * Name: kinetis_dmasample
+ *
+ * Description:
+ *   Sample DMA register contents
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+void kinetis_dmasample(DMACH_HANDLE handle, struct kinetis_dmaregs_s *regs);
+#else
+#  define kinetis_dmasample(handle,regs)
+#endif
+
+/****************************************************************************
+ * Name: kinetis_dmadump
+ *
+ * Description:
+ *   Dump previously sampled DMA register contents
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_DMA
+void kinetis_dmadump(const struct kinetis_dmaregs_s *regs, const char *msg);
+#else
+#  define kinetis_dmadump(handle,regs,msg)
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_EDMAC_H */