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 2022/08/10 03:22:43 UTC

[incubator-nuttx] branch master updated: s32k1xx:LPI2C Add DMA support

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


The following commit(s) were added to refs/heads/master by this push:
     new 32c4bdb7a6 s32k1xx:LPI2C Add DMA support
32c4bdb7a6 is described below

commit 32c4bdb7a67d621083cd0a70c0de1653dce0e79a
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Mon Aug 1 10:11:15 2022 -0700

    s32k1xx:LPI2C Add DMA support
---
 arch/arm/src/s32k1xx/Kconfig                  |  63 ++++
 arch/arm/src/s32k1xx/hardware/s32k1xx_lpi2c.h |  60 +--
 arch/arm/src/s32k1xx/s32k1xx_lpi2c.c          | 509 +++++++++++++++++++++++++-
 3 files changed, 598 insertions(+), 34 deletions(-)

diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig
index a011e6002c..5da747b11b 100644
--- a/arch/arm/src/s32k1xx/Kconfig
+++ b/arch/arm/src/s32k1xx/Kconfig
@@ -641,6 +641,58 @@ config S32K1XX_LPSPI_HWPCS
 	
 endmenu # LPSPI Configuration
 
+menu "LPI2C Configuration"
+	depends on S32K1XX_LPI2C
+
+config S32K1XX_LPI2C_DMA
+	bool "I2C DMA Support"
+	default n
+	depends on S32K1XX_LPI2C && S32K1XX_EDMA && !I2C_POLLED
+	---help---
+		This option enables the DMA for I2C transfers.
+		Note: The user can define CONFIG_I2C_DMAPRIO: a custom priority value
+		for the I2C dma streams, else the default priority level is set to
+		medium.
+
+config S32K1XX_LPI2C_DMA_MAXMSG
+	int "Maximum number messages that will be DMAed"
+	default 8
+	depends on S32K1XX_LPI2C_DMA
+	---help---
+		This option set the mumber of mesg that can be in a transfer.
+		It is used to allocate space for the 16 bit LPI2C commands
+		that will be DMA-ed to the LPI2C device.
+
+config S32K1XX_LPI2C_DYNTIMEO
+	bool "Use dynamic timeouts"
+	default n
+	depends on S32K1XX_LPI2C
+
+config S32K1XX_LPI2C_DYNTIMEO_USECPERBYTE
+	int "Timeout Microseconds per Byte"
+	default 500
+	depends on S32K1XX_LPI2C_DYNTIMEO
+
+config S32K1XX_LPI2C_DYNTIMEO_STARTSTOP
+	int "Timeout for Start/Stop (Milliseconds)"
+	default 1000
+	depends on S32K1XX_LPI2C_DYNTIMEO
+
+config S32K1XX_LPI2C_TIMEOSEC
+	int "Timeout seconds"
+	default 0
+	depends on S32K1XX_LPI2C
+
+config S32K1XX_LPI2C_TIMEOMS
+	int "Timeout Milliseconds"
+	default 500
+	depends on S32K1XX_LPI2C && !S32K1XX_LPI2C_DYNTIMEO
+
+config S32K1XX_LPI2C_TIMEOTICKS
+	int "Timeout for Done and Stop (ticks)"
+	default 500
+	depends on S32K1XX_LPI2C && !S32K1XX_LPI2C_DYNTIMEO
+
 menu "LPI2C0 Master Configuration"
 	depends on S32K1XX_LPI2C0
 
@@ -648,6 +700,11 @@ config LPI2C0_BUSYIDLE
 	int "Bus idle timeout period in clock cycles"
 	default 0
 
+config LPI2C0_DMA
+	bool "Enable DMA for I2C0"
+	default n
+	depends on S32K1XX_LPI2C_DMA
+
 config LPI2C0_FILTSCL
 	int "I2C master digital glitch filters for SCL input in clock cycles"
 	default 0
@@ -678,6 +735,11 @@ endmenu # LPI2C0 Slave Configuration
 menu "LPI2C1 Master Configuration"
 	depends on S32K1XX_LPI2C1
 
+config LPI2C1_DMA
+	bool "Enable DMA for I2C1"
+	default n
+	depends on S32K1XX_LPI2C_DMA
+
 config LPI2C1_BUSYIDLE
 	int "Bus idle timeout period in clock cycles"
 	default 0
@@ -708,6 +770,7 @@ config LPI2C1_SLAVE_BUS
 		the LPI2C master.  These pins need to be defined in the board.h.
 
 endmenu # LPI2C1 Slave Configuration
+endmenu # LPI2C Configuration
 
 menu "Ethernet Configuration"
 	depends on S32K1XX_ENET
diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_lpi2c.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_lpi2c.h
index b9740b7ccc..dbdc70255a 100644
--- a/arch/arm/src/s32k1xx/hardware/s32k1xx_lpi2c.h
+++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_lpi2c.h
@@ -239,7 +239,7 @@
 /* LPI2C Master Config Register 1  */
 
 #define LPI2C_MCFGR1_PRESCALE_MASK          (7 << 0)  /* Clock Prescaler Bit Mask */
-#  define LPI2C_MCFGR1_PRESCALE(n)          (n & LPI2C_MCFGR1_PRESCALE_MASK)
+#  define LPI2C_MCFGR1_PRESCALE(n)          ((n) & LPI2C_MCFGR1_PRESCALE_MASK)
 #  define LPI2C_MCFGR1_PRESCALE_1           (0)
 #  define LPI2C_MCFGR1_PRESCALE_2           (1)
 #  define LPI2C_MCFGR1_PRESCALE_4           (2)
@@ -254,7 +254,7 @@
                                                       /* Bits 15-11 Reserved */
 #define LPI2C_MCFGR1_MATCFG_SHIFT           (16)
 #define LPI2C_MCFGR1_MATCFG_MASK            (7 << LPI2C_MCFGR1_MATCFG_SHIFT)  /* Match Configuration Bit Mask */
-#  define LPI2C_MCFGR1_MATCFG(n)            ((n << LPI2C_MCFGR1_MATCFG_SHIFT) & LPI2C_MCFGR1_MATCFG_MASK)
+#  define LPI2C_MCFGR1_MATCFG(n)            (((n) << LPI2C_MCFGR1_MATCFG_SHIFT) & LPI2C_MCFGR1_MATCFG_MASK)
 #  define LPI2C_MCFGR1_MATCFG_DISABLE       (0 << LPI2C_MCFGR1_MATCFG_SHIFT)
                                                      /* LPI2C_MCFG1_MATCFG = 001b Reserved */
 #  define LPI2C_MCFGR1_MATCFG2              (2 << LPI2C_MCFGR1_MATCFG_SHIFT)
@@ -266,7 +266,7 @@
                                                     /* Bits 23-19 Reserved */
 #define LPI2C_MCFGR1_PINCFG_SHIFT           (24)
 #define LPI2C_MCFGR1_PINCFG_MASK            (7 << LPI2C_MCFGR1_PINCFG_SHIFT)  /* Pin Configuration Bit Mask */
-#  define LPI2C_MCFGR1_PINCFG(n)            ((n << LPI2C_MCFGR1_PINCFG_SHIFT) & LPI2C_MCFGR1_PINCFG_MASK)
+#  define LPI2C_MCFGR1_PINCFG(n)            (((n) << LPI2C_MCFGR1_PINCFG_SHIFT) & LPI2C_MCFGR1_PINCFG_MASK)
 #  define LPI2C_MCFGR1_PINCFG0              (0 << LPI2C_MCFGR1_PINCFG_SHIFT)
 #  define LPI2C_MCFGR1_PINCFG1              (1 << LPI2C_MCFGR1_PINCFG_SHIFT)
 #  define LPI2C_MCFGR1_PINCFG2              (2 << LPI2C_MCFGR1_PINCFG_SHIFT)
@@ -281,17 +281,17 @@
 
 #define LPI2C_MCFG2_BUSIDLE_MASK            (0xfff << 0)  /* Bus Idle Timeout Period in Clock Cycles */
 #define LPI2C_MCFG2_BUSIDLE_DISABLE         (0)
-#  define LPI2C_MCFG2_BUSIDLE(n)            (n & LPI2C_MCFG2_BUSIDLE_MASK)
+#  define LPI2C_MCFG2_BUSIDLE(n)            ((n) & LPI2C_MCFG2_BUSIDLE_MASK)
                                                      /* Bits 15-12 Reserved */
 #define LPI2C_MCFG2_FILTSCL_SHIFT           (16)
 #define LPI2C_MCFG2_FILTSCL_MASK            (15 << LPI2C_MCFG2_FILTSCL_SHIFT)  /* Glitch Filter SCL */
 #define LPI2C_MCFG2_FILTSCL_DISABLE         (0 << LPI2C_MCFG2_FILTSCL_SHIFT)
-#  define LPI2C_MCFG2_FILTSCL_CYCLES(n)     ((n << LPI2C_MCFG2_FILTSCL_SHIFT) & LPI2C_MCFG2_FILTSCL_MASK)
+#  define LPI2C_MCFG2_FILTSCL_CYCLES(n)     (((n) << LPI2C_MCFG2_FILTSCL_SHIFT) & LPI2C_MCFG2_FILTSCL_MASK)
                                                      /* Bits 23-20 Reserved */
 #define LPI2C_MCFG2_FILTSDA_SHIFT           (24)
 #define LPI2C_MCFG2_FILTSDA_MASK            (15 << LPI2C_MCFG2_FILTSDA_SHIFT)  /* Glitch Filter SDA */
 #define LPI2C_MCFG2_FILTSDA_DISABLE         (0 << LPI2C_MCFG2_FILTSDA_SHIFT)
-#  define LPI2C_MCFG2_FILTSDA_CYCLES(n)     ((n << LPI2C_MCFG2_FILTSDA_SHIFT) & LPI2C_MCFG2_FILTSDA_MASK)
+#  define LPI2C_MCFG2_FILTSDA_CYCLES(n)     (((n) << LPI2C_MCFG2_FILTSDA_SHIFT) & LPI2C_MCFG2_FILTSDA_MASK)
                                                      /* Bits 31-28 Reserved */
 
 /* LPI2C Master Config Register 3  */
@@ -299,56 +299,56 @@
                                                      /* Bits 7-0 Reserved */
 #define LPI2C_MCFG3_PINLOW_SHIFT            (8)
 #define LPI2C_MCFG3_PINLOW_MASK             (0xfff << LPI2C_MCFG3_PINLOW_SHIFT)  /* Configure The Pin Low Timeout in Clock Cycles */
-#  define LPI2C_MCFG3_PINLOW_CYCLES(n)      ((n << LPI2C_MCFG3_PINLOW_SHIFT) & LPI2C_MCFG3_PINLOW_MASK)
+#  define LPI2C_MCFG3_PINLOW_CYCLES(n)      (((n) << LPI2C_MCFG3_PINLOW_SHIFT) & LPI2C_MCFG3_PINLOW_MASK)
                                                      /* Bits 31-20 Reserved */
 
 /* LPI2C Master Data Match Register  */
 
 #define LPI2C_MDMR_MATCH0_SHIFT             (0)
 #define LPI2C_MDMR_MATCH0_MASK              (0xff << LPI2C_MDMR_MATCH0_SHIFT)  /* Match 0 Value */
-#  define LPI2C_MDMR_MATCH0(n)              ((n << LPI2C_MDMR_MATCH0_SHIFT) & LPI2C_MDMR_MATCH0_MASK)
+#  define LPI2C_MDMR_MATCH0(n)              (((n) << LPI2C_MDMR_MATCH0_SHIFT) & LPI2C_MDMR_MATCH0_MASK)
                                                      /* Bits 15-8 Reserved */
 #define LPI2C_MDMR_MATCH1_SHIFT             (16)
 #define LPI2C_MDMR_MATCH1_MASK              (0xff << LPI2C_MDMR_MATCH1_SHIFT)  /* Match 1 Value */
-#  define LPI2C_MDMR_MATCH1(n)              ((n << LPI2C_MDMR_MATCH1_SHIFT) & LPI2C_MDMR_MATCH1_MASK)
+#  define LPI2C_MDMR_MATCH1(n)              (((n) << LPI2C_MDMR_MATCH1_SHIFT) & LPI2C_MDMR_MATCH1_MASK)
                                                      /* Bits 31-24 Reserved */
 
 /* LPI2C Master Clock Configuration Register 0 */
 
 #define LPI2C_MCCR0_CLKLO_SHIFT             (0)
 #define LPI2C_MCCR0_CLKLO_MASK              (0x3f << LPI2C_MCCR0_CLKLO_SHIFT)  /* Clock Low Period */
-#  define LPI2C_MCCR0_CLKLO(n)              ((n << LPI2C_MCCR0_CLKLO_SHIFT) & LPI2C_MCCR0_CLKLO_MASK)
+#  define LPI2C_MCCR0_CLKLO(n)              (((n) << LPI2C_MCCR0_CLKLO_SHIFT) & LPI2C_MCCR0_CLKLO_MASK)
                                                      /* Bits 7-6 Reserved */
 #define LPI2C_MCCR0_CLKHI_SHIFT             (8)
 #define LPI2C_MCCR0_CLKHI_MASK              (0x3f << LPI2C_MCCR0_CLKHI_SHIFT)  /* Clock High Period */
-#  define LPI2C_MCCR0_CLKHI(n)              ((n << LPI2C_MCCR0_CLKHI_SHIFT) & LPI2C_MCCR0_CLKHI_MASK)
+#  define LPI2C_MCCR0_CLKHI(n)              (((n) << LPI2C_MCCR0_CLKHI_SHIFT) & LPI2C_MCCR0_CLKHI_MASK)
                                                      /* Bits 15-14 Reserved */
 #define LPI2C_MCCR0_SETHOLD_SHIFT           (16)
 #define LPI2C_MCCR0_SETHOLD_MASK            (0x3f << LPI2C_MCCR0_SETHOLD_SHIFT)  /* Setup Hold Delay */
-#  define LPI2C_MCCR0_SETHOLD(n)            ((n << LPI2C_MCCR0_SETHOLD_SHIFT) & LPI2C_MCCR0_SETHOLD_MASK)
+#  define LPI2C_MCCR0_SETHOLD(n)            (((n) << LPI2C_MCCR0_SETHOLD_SHIFT) & LPI2C_MCCR0_SETHOLD_MASK)
                                                      /* Bits 23-22 Reserved */
 #define LPI2C_MCCR0_DATAVD_SHIFT            (24)
 #define LPI2C_MCCR0_DATAVD_MASK             (0x3f << LPI2C_MCCR0_DATAVD_SHIFT)  /* Setup Hold Delay */
-#  define LPI2C_MCCR0_DATAVD(n)             ((n << LPI2C_MCCR0_DATAVD_SHIFT) & LPI2C_MCCR0_DATAVD_MASK)
+#  define LPI2C_MCCR0_DATAVD(n)             (((n) << LPI2C_MCCR0_DATAVD_SHIFT) & LPI2C_MCCR0_DATAVD_MASK)
                                                      /* Bits 31-30 Reserved */
 
 /* LPI2C Master Clock Configuration Register 1 */
 
 #define LPI2C_MCCR1_CLKLO_SHIFT             (0)
 #define LPI2C_MCCR1_CLKLO_MASK              (0x3f << LPI2C_MCCR1_CLKLO_SHIFT)  /* Clock Low Period */
-#  define LPI2C_MCCR1_CLKLO(n)              ((n << LPI2C_MCCR1_CLKLO_SHIFT) & LPI2C_MCCR1_CLKLO_MASK)
+#  define LPI2C_MCCR1_CLKLO(n)              (((n) << LPI2C_MCCR1_CLKLO_SHIFT) & LPI2C_MCCR1_CLKLO_MASK)
                                                      /* Bits 7-6 Reserved */
 #define LPI2C_MCCR1_CLKHI_SHIFT             (8)
 #define LPI2C_MCCR1_CLKHI_MASK              (0x3f << LPI2C_MCCR1_CLKHI_SHIFT)  /* Clock High Period */
-#  define LPI2C_MCCR1_CLKHI(n)              ((n << LPI2C_MCCR1_CLKHI_SHIFT) & LPI2C_MCCR1_CLKHI_MASK)
+#  define LPI2C_MCCR1_CLKHI(n)              (((n) << LPI2C_MCCR1_CLKHI_SHIFT) & LPI2C_MCCR1_CLKHI_MASK)
                                                      /* Bits 15-14 Reserved */
 #define LPI2C_MCCR1_SETHOLD_SHIFT           (16)
 #define LPI2C_MCCR1_SETHOLD_MASK            (0x3f << LPI2C_MCCR1_SETHOLD_SHIFT)  /* Setup Hold Delay */
-#  define LPI2C_MCCR1_SETHOLD(n)            ((n << LPI2C_MCCR1_SETHOLD_SHIFT) & LPI2C_MCCR1_SETHOLD_MASK)
+#  define LPI2C_MCCR1_SETHOLD(n)            (((n) << LPI2C_MCCR1_SETHOLD_SHIFT) & LPI2C_MCCR1_SETHOLD_MASK)
                                                      /* Bits 23-22 Reserved */
 #define LPI2C_MCCR1_DATAVD_SHIFT            (24)
 #define LPI2C_MCCR1_DATAVD_MASK             (0x3f << LPI2C_MCCR1_DATAVD_SHIFT)  /* Setup Hold Delay */
-#  define LPI2C_MCCR1_DATAVD(n)             ((n << LPI2C_MCCR1_DATAVD_SHIFT) & LPI2C_MCCR1_DATAVD_MASK)
+#  define LPI2C_MCCR1_DATAVD(n)             (((n) << LPI2C_MCCR1_DATAVD_SHIFT) & LPI2C_MCCR1_DATAVD_MASK)
                                                      /* Bits 31-30 Reserved */
 
 /* LPI2C Master FIFO Control Register */
@@ -356,13 +356,13 @@
 #define LPI2C_MFCR_TXWATER_SHIFT            (0)
 #define LPI2C_MFCR_TXWATER_MASK             (3 << LPI2C_MFCR_TXWATER_SHIFT)  /* Transmit FIFO Watermark*/
 
-#  define LPI2C_MFCR_TXWATER(n)             ((n << LPI2C_MFCR_TXWATER_SHIFT) &  LPI2C_MFCR_TXWATER_MASK)  /* Transmit FIFO Watermark*/
+#  define LPI2C_MFCR_TXWATER(n)             (((n) << LPI2C_MFCR_TXWATER_SHIFT) &  LPI2C_MFCR_TXWATER_MASK)  /* Transmit FIFO Watermark*/
 
                                                      /* Bits 15-2 Reserved */
 #define LPI2C_MFCR_RXWATER_SHIFT            (16)
 #define LPI2C_MFCR_RXWATER_MASK             (3 << LPI2C_MFCR_RXWATER_SHIFT)  /* Receive FIFO Watermark */
 
-#  define LPI2C_MFCR_RXWATER(n)             ((n << LPI2C_MFCR_RXWATER_SHIFT) &  LPI2C_MFCR_RXWATER_MASK)  /* Transmit FIFO Watermark*/
+#  define LPI2C_MFCR_RXWATER(n)             (((n) << LPI2C_MFCR_RXWATER_SHIFT) &  LPI2C_MFCR_RXWATER_MASK)  /* Transmit FIFO Watermark*/
 
                                                      /* Bits 31-18 Reserved */
 
@@ -381,10 +381,10 @@
 
 #define LPI2C_MTDR_DATA_SHIFT               (0)
 #define LPI2C_MTDR_DATA_MASK                (0xff << LPI2C_MTDR_DATA_SHIFT)  /* Transmit Data */
-#  define LPI2C_MTDR_DATA(n)                (n & LPI2C_MTDR_DATA_MASK)
+#  define LPI2C_MTDR_DATA(n)                ((n) & LPI2C_MTDR_DATA_MASK)
 #define LPI2C_MTDR_CMD_SHIFT                (8)
 #define LPI2C_MTDR_CMD_MASK                 (7 << LPI2C_MTDR_CMD_SHIFT)  /* Command Data */
-#  define LPI2C_MTDR_CMD(n)                 ((n << LPI2C_MTDR_CMD_SHIFT) & LPI2C_MTDR_CMD_MASK)
+#  define LPI2C_MTDR_CMD(n)                 (((n) << LPI2C_MTDR_CMD_SHIFT) & LPI2C_MTDR_CMD_MASK)
 #  define LPI2C_MTDR_CMD_TXD                (0 << LPI2C_MTDR_CMD_SHIFT)
 #  define LPI2C_MTDR_CMD_RXD                (1 << LPI2C_MTDR_CMD_SHIFT)
 #  define LPI2C_MTDR_CMD_STOP               (2 << LPI2C_MTDR_CMD_SHIFT)
@@ -478,7 +478,7 @@
                                                       /* Bits 15-14 Reserved */
 #define LPI2C_SCFG1_ADDRCFG_SHIFT           (16)
 #define LPI2C_SCFG1_ADDRCFG_MASK            (7 << LPI2C_SCFG1_ADDRCFG_SHIFT)  /* Address Configuration Bit Mask */
-#  define LPI2C_SCFG1_ADDRCFG(n)            ((n << LPI2C_SCFG1_ADDRCFG_SHIFT) & LPI2C_SCFG1_ADDRCFG_MASK)
+#  define LPI2C_SCFG1_ADDRCFG(n)            (((n) << LPI2C_SCFG1_ADDRCFG_SHIFT) & LPI2C_SCFG1_ADDRCFG_MASK)
 #  define LPI2C_SCFG1_ADDRCFG0              (0 << LPI2C_SCFG1_ADDRCFG_SHIFT)
 #  define LPI2C_SCFG1_ADDRCFG1              (2 << LPI2C_SCFG1_ADDRCFG_SHIFT)
 #  define LPI2C_SCFG1_ADDRCFG2              (2 << LPI2C_SCFG1_ADDRCFG_SHIFT)
@@ -492,21 +492,21 @@
 /* LPI2C Slave Configuration Register 2  */
 
 #define LPI2C_SCFG2_CLKHOLD_MASK            (15 << 0) /* Clock Hold Time */
-#  define LPI2C_SCFG2_CLKHOLD(n)            (n & LPI2C_SCFG2_CLKHOLD_MASK)
+#  define LPI2C_SCFG2_CLKHOLD(n)            ((n) & LPI2C_SCFG2_CLKHOLD_MASK)
                                                       /* Bits 7-4 Reserved */
 #define LPI2C_SCFG2_DATAVD_SHIFT            (8)
 #define LPI2C_SCFG2_DATAVD_MASK             (0x3f << LPI2C_SCFG2_DATAVD_SHIFT)  /* Data Valid Delay */
-#  define LPI2C_SCFG2_DATAVD(n)             ((n << LPI2C_SCFG2_DATAVD_SHIFT) & LPI2C_SCFG2_DATAVD_MASK)
+#  define LPI2C_SCFG2_DATAVD(n)             (((n) << LPI2C_SCFG2_DATAVD_SHIFT) & LPI2C_SCFG2_DATAVD_MASK)
                                                       /* Bits 15-14 Reserved */
 #define LPI2C_SCFG2_FILTSCL_SHIFT           (16)
 #define LPI2C_SCFG2_FILTSCL_MASK            (15 << LPI2C_SCFG2_FILTSCL_SHIFT)  /* Glitch Filter SCL */
 #define LPI2C_SCFG2_FILTSCL_DISABLE         (0 << LPI2C_SCFG2_FILTSCL_SHIFT)
-#  define LPI2C_SCFG2_FILTSCL_CYCLES(n)     ((n << LPI2C_SCFG2_FILTSCL_SHIFT) & LPI2C_SCFG2_FILTSCL_MASK)
+#  define LPI2C_SCFG2_FILTSCL_CYCLES(n)     (((n) << LPI2C_SCFG2_FILTSCL_SHIFT) & LPI2C_SCFG2_FILTSCL_MASK)
                                                       /* Bits 23-20 Reserved */
 #define LPI2C_SCFG2_FILTSDA_SHIFT           (24)
 #define LPI2C_SCFG2_FILTSDA_MASK            (15 << LPI2C_SCFG2_FILTSDA_SHIFT)  /* Glitch Filter SDA */
 #define LPI2C_SCFG2_FILTSDA_DISABLE         (0 << LPI2C_SCFG2_FILTSDA_SHIFT)
-#  define LPI2C_SCFG2_FILTSDA_CYCLES(n)     ((n << LPI2C_SCFG2_FILTSDA_SHIFT) & LPI2C_SCFG2_FILTSDA_MASK)
+#  define LPI2C_SCFG2_FILTSDA_CYCLES(n)     (((n) << LPI2C_SCFG2_FILTSDA_SHIFT) & LPI2C_SCFG2_FILTSDA_MASK)
                                                       /* Bits 31-28 Reserved */
 
 /* LPI2C Slave Address Match Register  */
@@ -514,11 +514,11 @@
                                                       /* Bit 0 Reserved */
 #define LPI2C_SAMR_ADDR0_SHIFT              (1)
 #define LPI2C_SAMR_ADDR0_MASK               (0x3ff << LPI2C_SAMR_ADDR0_SHIFT)  /* Address 0 Value */
-#  define LPI2C_SAMR_ADDR0(n)               ((n << LPI2C_SAMR_ADDR0_SHIFT) & LPI2C_SAMR_ADDR0_MASK)
+#  define LPI2C_SAMR_ADDR0(n)               (((n) << LPI2C_SAMR_ADDR0_SHIFT) & LPI2C_SAMR_ADDR0_MASK)
                                                       /* Bits 16-11 Reserved */
 #define LPI2C_SAMR_ADDR1_SHIFT              (17)
 #define LPI2C_SAMR_ADDR1_MASK               (0x3ff << LPI2C_SAMR_ADDR1_SHIFT)  /* Address 1 Value */
-#  define LPI2C_SAMR_ADDR1(n)               ((n << LPI2C_SAMR_ADDR1_SHIFT) & LPI2C_SAMR_ADDR1_MASK)
+#  define LPI2C_SAMR_ADDR1(n)               (((n) << LPI2C_SAMR_ADDR1_SHIFT) & LPI2C_SAMR_ADDR1_MASK)
                                                       /* Bits 31-27 Reserved */
 
 /* LPI2C Slave Address Status Register  */
@@ -538,14 +538,14 @@
 
 #define LPI2C_STDR_DATA_SHIFT               (0)
 #define LPI2C_STDR_DATA_MASK                (0xff << LPI2C_STDR_DATA_SHIFT)  /* Transmit Data */
-#  define LPI2C_STDR_DATA(n)                ((n << LPI2C_STDR_DATA_SHIFT) & LPI2C_STDR_DATA_MASK)
+#  define LPI2C_STDR_DATA(n)                (((n) << LPI2C_STDR_DATA_SHIFT) & LPI2C_STDR_DATA_MASK)
                                                       /* Bits 31-8 Reserved */
 
 /* LPI2C Slave Receive Data Register  */
 
 #define LPI2C_SRDR_DATA_SHIFT               (0)
 #define LPI2C_SRDR_DATA_MASK                (0xff << LPI2C_SRDR_DATA_SHIFT)  /* Receive Data */
-#  define LPI2C_SRDR_DATA(n)                ((n << LPI2C_SRDR_DATA_SHIFT) & LPI2C_SRDR_DATA_MASK)
+#  define LPI2C_SRDR_DATA(n)                (((n) << LPI2C_SRDR_DATA_SHIFT) & LPI2C_SRDR_DATA_MASK)
                                                       /* Bits 8-31 Reserved */
 
 #endif /* __ARCH_ARM_SRC_S32K1XX_HARDWARE_S32K1XX_LPI2C_H */
diff --git a/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c b/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c
index 1a900fc724..cccfa6f150 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c
@@ -43,7 +43,9 @@
 #include <arch/irq.h>
 
 #include "arm_internal.h"
+#include "s32k1xx_edma.h"
 #include "s32k1xx_pin.h"
+#include "hardware/s32k1xx_dmamux.h"
 #include "hardware/s32k1xx_pinmux.h"
 #include "s32k1xx_lpi2c.h"
 #include "s32k1xx_periphclocks.h"
@@ -163,6 +165,10 @@ struct s32k1xx_lpi2c_config_s
 #ifndef CONFIG_I2C_POLLED
   uint32_t irq;               /* Event IRQ */
 #endif
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+  uint32_t        dma_rxreqsrc;  /* DMA mux rx source */
+  uint32_t        dma_txreqsrc;  /* DMA mux tx source */
+#endif
 };
 
 /* I2C Device Private Data */
@@ -202,6 +208,11 @@ struct s32k1xx_lpi2c_priv_s
   struct s32k1xx_trace_s trace[CONFIG_I2C_NTRACE];
 #endif
 
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+  DMACH_HANDLE rxdma;                                  /* rx DMA handle */
+  DMACH_HANDLE txdma;                                  /* tx DMA handle */
+  uint16_t     cmnds[CONFIG_S32K1XX_LPI2C_DMA_MAXMSG]; /* Commands */
+#endif
   uint32_t status;             /* End of transfer SR2|SR1 status */
 };
 
@@ -273,6 +284,13 @@ static int s32k1xx_lpi2c_transfer(struct i2c_master_s *dev,
 static int s32k1xx_lpi2c_reset(struct i2c_master_s *dev);
 #endif
 
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static void s32k1xx_rxdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+                                  int result);
+static void s32k1xx_txdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+                                  int result);
+#endif
+
 /****************************************************************************
  * Private Data
  ****************************************************************************/
@@ -318,6 +336,10 @@ static const struct s32k1xx_lpi2c_config_s s32k1xx_lpi2c0_config =
 #ifndef CONFIG_I2C_POLLED
   .irq        = S32K1XX_IRQ_LPI2C0M,
 #endif
+#ifdef CONFIG_LPI2C0_DMA
+  .dma_rxreqsrc    = S32K1XX_DMACHAN_LPI2C0_RX,
+  .dma_txreqsrc    = S32K1XX_DMACHAN_LPI2C0_TX,
+#endif
 };
 
 static struct s32k1xx_lpi2c_priv_s s32k1xx_lpi2c0_priv =
@@ -348,6 +370,10 @@ static const struct s32k1xx_lpi2c_config_s s32k1xx_lpi2c1_config =
 #ifndef CONFIG_I2C_POLLED
   .irq        = S32K1XX_IRQ_LPI2C1M,
 #endif
+#ifdef CONFIG_LPI2C1_DMA
+  .dma_rxreqsrc    = S32K1XX_DMACHAN_LPI2C1_RX,
+  .dma_txreqsrc    = S32K1XX_DMACHAN_LPI2C1_TX,
+#endif
 };
 
 static struct s32k1xx_lpi2c_priv_s s32k1xx_lpi2c1_priv =
@@ -478,13 +504,17 @@ s32k1xx_lpi2c_sem_waitdone(struct s32k1xx_lpi2c_priv_s *priv)
 
   flags = enter_critical_section();
 
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+  if (priv->rxdma == NULL && priv->txdma == NULL)
+    {
+#endif
   /* Enable Interrupts when master mode */
 
   if (priv->config->mode == LPI2C_MASTER)
     {
       if ((priv->flags & I2C_M_READ) != 0)
         {
-          regval = LPI2C_MIER_TDIE | LPI2C_MIER_RDIE | LPI2C_MIER_NDIE | \
+          regval = LPI2C_MIER_TDIE | LPI2C_MIER_RDIE | LPI2C_MIER_NDIE |
                    LPI2C_MIER_ALIE | LPI2C_MIER_SDIE;
           s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MIER_OFFSET, regval);
         }
@@ -507,7 +537,10 @@ s32k1xx_lpi2c_sem_waitdone(struct s32k1xx_lpi2c_priv_s *priv)
    * are currently disabled but will be temporarily re-enabled below when
    * nxsem_tickwait_uninterruptible() sleeps.
    */
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+    }
 
+#endif
   priv->intstate = INTSTATE_WAITING;
   do
     {
@@ -755,6 +788,112 @@ s32k1xx_lpi2c_sem_destroy(struct s32k1xx_lpi2c_priv_s *priv)
 #endif
 }
 
+/****************************************************************************
+ * Name: s32k1xx_rxdma_callback
+ *
+ * Description:
+ *   This function performs the next I2C operation
+ *
+ ****************************************************************************/
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static void s32k1xx_rxdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+                              int result)
+{
+  struct s32k1xx_lpi2c_priv_s *priv = (struct s32k1xx_lpi2c_priv_s *)arg;
+
+  s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MIER_OFFSET, 0,
+                              LPI2C_MIER_SDIE);
+
+  if (result != OK)
+    {
+      priv->status = s32k1xx_lpi2c_getstatus(priv);
+
+      if ((priv->status & LPI2C_MSR_ERROR_MASK) != 0)
+        {
+          i2cerr("ERROR: MSR: status: 0x0%" PRIx32 "\n", priv->status);
+
+          s32k1xx_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0);
+
+          /* Clear the TX and RX FIFOs */
+
+          s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MCR_OFFSET, 0,
+                                LPI2C_MCR_RTF | LPI2C_MCR_RRF);
+
+          /* Clear the error */
+
+          s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MSR_OFFSET,
+                             (priv->status & (LPI2C_MSR_NDF |
+                                              LPI2C_MSR_ALF |
+                                              LPI2C_MSR_FEF |
+                                              LPI2C_MSR_PLTF)));
+
+          if (priv->intstate == INTSTATE_WAITING)
+            {
+              /* inform the thread that transfer is complete
+               * and wake it up
+               */
+
+              priv->intstate = INTSTATE_DONE;
+              nxsem_post(&priv->sem_isr);
+            }
+        }
+    }
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_txdma_callback
+ *
+ * Description:
+ *   This function performs the next I2C operation
+ *
+ ****************************************************************************/
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static void s32k1xx_txdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+                              int result)
+{
+  struct s32k1xx_lpi2c_priv_s *priv = (struct s32k1xx_lpi2c_priv_s *)arg;
+
+  s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MIER_OFFSET, 0,
+                              LPI2C_MIER_SDIE);
+
+  if (result != OK)
+    {
+      priv->status = s32k1xx_lpi2c_getstatus(priv);
+
+      if ((priv->status & LPI2C_MSR_ERROR_MASK) != 0)
+        {
+          i2cerr("ERROR: MSR: status: 0x0%" PRIx32 "\n", priv->status);
+
+          s32k1xx_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0);
+
+          /* Clear the TX and RX FIFOs */
+
+          s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MCR_OFFSET, 0,
+                                LPI2C_MCR_RTF | LPI2C_MCR_RRF);
+
+          /* Clear the error */
+
+          s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MSR_OFFSET,
+                             (priv->status & (LPI2C_MSR_NDF |
+                                              LPI2C_MSR_ALF |
+                                              LPI2C_MSR_FEF |
+                                              LPI2C_MSR_PLTF)));
+
+          if (priv->intstate == INTSTATE_WAITING)
+            {
+              /* inform the thread that transfer is complete
+               * and wake it up
+               */
+
+              priv->intstate = INTSTATE_DONE;
+              nxsem_post(&priv->sem_isr);
+            }
+        }
+    }
+}
+#endif
+
 /****************************************************************************
  * Name: s32k1xx_lpi2c_trace*
  *
@@ -1142,6 +1281,20 @@ s32k1xx_lpi2c_getstatus(struct s32k1xx_lpi2c_priv_s *priv)
   return s32k1xx_lpi2c_getreg(priv, S32K1XX_LPI2C_MSR_OFFSET);
 }
 
+/****************************************************************************
+ * Name: imxrt_lpi2c_getenabledints
+ *
+ * Description:
+ *   Get 32-bit status
+ *
+ ****************************************************************************/
+
+static inline uint32_t
+s32k1xx_lpi2c_getenabledints(struct s32k1xx_lpi2c_priv_s *priv)
+{
+  return s32k1xx_lpi2c_getreg(priv, S32K1XX_LPI2C_MIER_OFFSET);
+}
+
 /****************************************************************************
  * Name: s32k1xx_lpi2c_isr_process
  *
@@ -1154,7 +1307,87 @@ static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s *priv)
 {
   uint32_t status = s32k1xx_lpi2c_getstatus(priv);
 
-  /* Check for new trace setup */
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+  uint32_t current_status = status;
+
+  /* Condition the status with only the enabled interrupts */
+
+  status &= s32k1xx_lpi2c_getenabledints(priv);
+
+  if (priv->rxdma != NULL || priv->txdma != NULL)
+    {
+      /* End of packet or Stop */
+
+      if ((status & (LPI2C_MSR_SDF | LPI2C_MSR_EPF)) != 0)
+        {
+          s32k1xx_lpi2c_traceevent(priv, I2CEVENT_STOP, 0);
+
+          /* Acknowledge End of packet or Stop */
+
+          s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MSR_OFFSET, status &
+                                                           (LPI2C_MSR_SDF |
+                                                           LPI2C_MSR_EPF));
+        }
+
+      /* Is there an Error condition */
+
+      if (current_status & LPI2C_MSR_ERROR_MASK)
+        {
+          s32k1xx_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0);
+
+          /* Shutdown DMA */
+
+          if (priv->rxdma != NULL)
+            {
+              s32k1xx_dmach_stop(priv->rxdma);
+            }
+
+          if (priv->txdma != NULL)
+            {
+               s32k1xx_dmach_stop(priv->txdma);
+            }
+
+          /* Clear the TX and RX FIFOs */
+
+          s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MCR_OFFSET, 0,
+                                LPI2C_MCR_RTF | LPI2C_MCR_RRF);
+
+          /* Clear the error */
+
+          s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MSR_OFFSET,
+                            (current_status & (LPI2C_MSR_NDF |
+                                               LPI2C_MSR_ALF |
+                                               LPI2C_MSR_FEF)));
+
+          /* Return the full error status */
+
+          status = current_status;
+        }
+
+      /* Mark that this transaction stopped */
+
+      priv->msgv = NULL;
+      priv->msgc = 0;
+      priv->dcnt = -1;
+
+      if (priv->intstate == INTSTATE_WAITING)
+        {
+          /* Update Status once at the end */
+
+          priv->status = status;
+
+          /* inform the thread that transfer is complete
+           * and wake it up
+           */
+
+          priv->intstate = INTSTATE_DONE;
+          nxsem_post(&priv->sem_isr);
+        }
+
+      return OK;
+    }
+
+#endif  /* Check for new trace setup */
 
   s32k1xx_lpi2c_tracenew(priv, status);
 
@@ -1297,8 +1530,8 @@ static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s *priv)
                * and wake it up
                */
 
-              nxsem_post(&priv->sem_isr);
               priv->intstate = INTSTATE_DONE;
+              nxsem_post(&priv->sem_isr);
             }
 #else
           priv->status = status;
@@ -1350,8 +1583,8 @@ static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s *priv)
                * and wake it up
                */
 
-              nxsem_post(&priv->sem_isr);
               priv->intstate = INTSTATE_DONE;
+              nxsem_post(&priv->sem_isr);
             }
 #else
           priv->status = status;
@@ -1491,6 +1724,223 @@ static int s32k1xx_lpi2c_deinit(struct s32k1xx_lpi2c_priv_s *priv)
  * Device Driver Operations
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_command_configure
+ *
+ * Description:
+ *   Create a command TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int
+s32k1xx_lpi2c_dma_command_configure(struct s32k1xx_lpi2c_priv_s
+                                    *priv, uint16_t *ccmd,
+                                     uint32_t ncmd)
+{
+  struct s32k1xx_edma_xfrconfig_s config;
+  memset(&config, 0, sizeof(config));
+
+  config.saddr  = (uint32_t) ccmd;
+  config.daddr  = priv->config->base + S32K1XX_LPI2C_MTDR_OFFSET;
+  config.soff   = sizeof(uint16_t);
+  config.doff   = 0;
+  config.iter   = 1;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = EDMA_16BIT;
+  config.dsize  = EDMA_16BIT;
+  config.nbytes = sizeof(uint16_t) * ncmd;
+
+  up_clean_dcache((uintptr_t)config.saddr,
+                  (uintptr_t)config.saddr + config.nbytes);
+
+  return s32k1xx_dmach_xfrsetup(priv->txdma, &config);
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_data_configure
+ *
+ * Description:
+ *   Create a data TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_dma_data_configure(struct s32k1xx_lpi2c_priv_s
+                                              *priv,
+                                              struct i2c_msg_s *msg)
+{
+  DMACH_HANDLE dma;
+  struct s32k1xx_edma_xfrconfig_s config;
+  memset(&config, 0, sizeof(config));
+
+  config.iter   = msg->length;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = EDMA_8BIT;
+  config.dsize  = EDMA_8BIT;
+  config.nbytes = sizeof(msg->buffer[0]);
+
+  if (msg->flags & I2C_M_READ)
+    {
+      dma           = priv->rxdma;
+      config.saddr  = priv->config->base + S32K1XX_LPI2C_MRDR_OFFSET;
+      config.daddr  = (uint32_t) msg->buffer;
+      config.soff   = 0;
+      config.doff   = sizeof(msg->buffer[0]);
+      up_invalidate_dcache((uintptr_t)msg->buffer,
+                           (uintptr_t)msg->buffer + msg->length);
+    }
+  else
+    {
+      dma           = priv->txdma;
+      config.saddr  = (uint32_t) msg->buffer;
+      config.daddr  = priv->config->base + S32K1XX_LPI2C_MTDR_OFFSET;
+      config.soff   = sizeof(msg->buffer[0]);
+      config.doff   = 0;
+      up_clean_dcache((uintptr_t)msg->buffer,
+                      (uintptr_t)msg->buffer + msg->length);
+    }
+
+  return s32k1xx_dmach_xfrsetup(dma, &config) ? 0 : msg->length;
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_configure_dma_transfer
+ *
+ * Description:
+ *   DMA based I2C transfer function
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_form_command_list(struct s32k1xx_lpi2c_priv_s
+                                              *priv, struct i2c_msg_s *msg,
+                                              int ncmds)
+{
+  ssize_t length = 0;
+
+  if (priv->flags & I2C_M_NOSTART)
+    {
+      if (priv->flags & I2C_M_READ)
+        {
+          /* No start read operation */
+
+          priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_RXD |
+                                 LPI2C_MTDR_DATA(msg->length - 1);
+        }
+    }
+  else
+    {
+      /* A start based read or write operation */
+
+      /* Create bus address with R/W */
+
+      uint16_t badd = (priv->flags & I2C_M_READ) ? I2C_READADDR8(msg->addr) :
+                                                   I2C_WRITEADDR8(msg->addr);
+
+      priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_START | LPI2C_MTDR_DATA(badd);
+
+      if (badd & I2C_READBIT)
+        {
+          length =  msg->length;
+          while (length)
+            {
+              if (length > 256u)
+                {
+                  priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_RXD |
+                                         LPI2C_MTDR_DATA(256u - 1);
+                  length -= 256u;
+                }
+              else
+                {
+                  priv->cmnds[ncmds++] = LPI2C_MTDR_CMD_RXD |
+                                         LPI2C_MTDR_DATA(length - 1);
+                  length = 0;
+                }
+            }
+        }
+    }
+
+  return ncmds;
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_dma_transfer
+ *
+ * Description:
+ *   DMA based I2C transfer function
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+static int s32k1xx_lpi2c_dma_transfer(struct s32k1xx_lpi2c_priv_s *priv)
+{
+  int m;
+  int ntotcmds = 0;
+  int ncmds = 0;
+  uint16_t *ccmnd = NULL;
+
+  /* Disable Interrupts */
+
+  s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MIER_OFFSET,
+                            LPI2C_MIER_RDIE | LPI2C_MIER_TDIE, 0);
+
+  /* Disable DMA */
+
+  s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MDER_OFFSET, LPI2C_MDER_TDDE |
+                                                       LPI2C_MDER_RDDE, 0);
+
+  /* Turn off auto_stop option */
+
+  s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MCFGR1_OFFSET, 0,
+                          LPI2C_MCFGR1_IGNACK | LPI2C_MCFGR1_AUTOSTOP);
+
+  /* Form chains of tcd to process the messages */
+
+  for (m = 0; m < priv->msgc; m++)
+    {
+      ncmds = 0;
+      priv->flags = priv->msgv[m].flags;
+
+      /* Form a command list */
+
+      ccmnd = &priv->cmnds[ntotcmds];
+
+      ncmds = s32k1xx_lpi2c_form_command_list(priv, &priv->msgv[m],
+                                              ntotcmds);
+
+      /* Have commands for this message ? */
+
+      if (ncmds != 0)
+        {
+          /* Build up a TCD with the command from this message */
+
+          s32k1xx_lpi2c_dma_command_configure(priv, ccmnd, ncmds - ntotcmds);
+
+          ntotcmds += ncmds;
+
+          DEBUGASSERT(ntotcmds < CONFIG_S32K1XX_LPI2C_DMA_MAXMSG);
+
+          s32k1xx_lpi2c_dma_data_configure(priv, &priv->msgv[m]);
+        }
+    }
+
+  s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MIER_OFFSET,
+                     LPI2C_MIER_NDIE | LPI2C_MIER_ALIE |
+                     LPI2C_MIER_PLTIE | LPI2C_MIER_FEIE);
+
+  s32k1xx_dmach_start(priv->rxdma, s32k1xx_rxdma_callback, (void *)priv);
+  s32k1xx_dmach_start(priv->txdma, s32k1xx_txdma_callback, (void *)priv);
+
+  s32k1xx_lpi2c_modifyreg(priv, S32K1XX_LPI2C_MDER_OFFSET, 0,
+                          LPI2C_MDER_TDDE | LPI2C_MDER_RDDE);
+  return OK;
+}
+#endif
+
 /****************************************************************************
  * Name: s32k1xx_lpi2c_transfer
  *
@@ -1548,8 +1998,27 @@ static int s32k1xx_lpi2c_transfer(struct i2c_master_s *dev,
    * the BUSY flag.
    */
 
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+  if (priv->rxdma || priv->txdma)
+    {
+      s32k1xx_lpi2c_dma_transfer(priv);
+    }
+#endif
+
   if (s32k1xx_lpi2c_sem_waitdone(priv) < 0)
     {
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+      if (priv->rxdma != NULL)
+        {
+          s32k1xx_dmach_stop(priv->rxdma);
+        }
+
+      if (priv->txdma != NULL)
+        {
+          s32k1xx_dmach_stop(priv->txdma);
+        }
+
+#endif
       ret = -ETIMEDOUT;
 
       i2cerr("ERROR: Timed out: MCR: status: 0x%" PRIx32 "\n", priv->status);
@@ -1787,6 +2256,22 @@ struct i2c_master_s *s32k1xx_i2cbus_initialize(int port)
     {
       s32k1xx_lpi2c_sem_init(priv);
       s32k1xx_lpi2c_init(priv);
+
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+      if (priv->config->dma_txreqsrc != 0)
+        {
+          priv->txdma = s32k1xx_dmach_alloc(priv->config->dma_txreqsrc |
+                                        DMAMUX_CHCFG_ENBL, 0);
+          DEBUGASSERT(priv->txdma != NULL);
+        }
+
+      if (priv->config->dma_rxreqsrc != 0)
+        {
+          priv->rxdma = s32k1xx_dmach_alloc(priv->config->dma_rxreqsrc |
+                                        DMAMUX_CHCFG_ENBL, 0);
+          DEBUGASSERT(priv->rxdma != NULL);
+        }
+#endif
     }
 
   leave_critical_section(flags);
@@ -1828,6 +2313,22 @@ int s32k1xx_i2cbus_uninitialize(struct i2c_master_s *dev)
 
   /* Disable power and other HW resource (GPIO's) */
 
+#ifdef CONFIG_S32K1XX_LPI2C_DMA
+  if (priv->rxdma != NULL)
+    {
+      s32k1xx_dmach_stop(priv->rxdma);
+      s32k1xx_dmach_free(priv->rxdma);
+      priv->rxdma = NULL;
+    }
+
+  if (priv->txdma != NULL)
+    {
+      s32k1xx_dmach_stop(priv->txdma);
+      s32k1xx_dmach_free(priv->txdma);
+      priv->txdma = NULL;
+    }
+#endif
+
   s32k1xx_lpi2c_deinit(priv);
 
   /* Release unused resources */