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/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 436c814c2e mcx-nxxx: Add LPI2C driver for mcx-nxxx architecture
436c814c2e is described below

commit 436c814c2e0cfcba3e51fee7259fafcee8da656e
Author: Ville Juven <ville.ju...@unikie.com>
AuthorDate: Mon Jun 2 15:59:25 2025 +0300

    mcx-nxxx: Add LPI2C driver for mcx-nxxx architecture
    
    This adds a LPI2C driver for the mcx-nxxx chip, and the necessary board
    definitions for the frdm-mcxn236 evaluation kit.
    
    Signed-off-by: Ville Juven <ville.ju...@unikie.com>
---
 arch/arm/src/mcx-nxxx/Kconfig                      |  250 ++
 arch/arm/src/mcx-nxxx/Make.defs                    |    4 +
 arch/arm/src/mcx-nxxx/hardware/nxxx_lpi2c.h        |  627 +++++
 arch/arm/src/mcx-nxxx/nxxx_lpi2c.c                 | 2478 ++++++++++++++++++++
 .../board.h => arch/arm/src/mcx-nxxx/nxxx_lpi2c.h  |   64 +-
 .../mcx-nxxx/frdm-mcxn236/configs/nsh/defconfig    |    1 +
 boards/arm/mcx-nxxx/frdm-mcxn236/include/board.h   |    3 +
 7 files changed, 3390 insertions(+), 37 deletions(-)

diff --git a/arch/arm/src/mcx-nxxx/Kconfig b/arch/arm/src/mcx-nxxx/Kconfig
index 975486003c..25f029e358 100644
--- a/arch/arm/src/mcx-nxxx/Kconfig
+++ b/arch/arm/src/mcx-nxxx/Kconfig
@@ -26,6 +26,10 @@ config NXXX_GPIO_IRQ
        bool "GPIO Interrupt Support"
        default y
 
+config NXXX_LPI2C
+       bool "LPI2C support"
+       default n
+
 menu "LPUART"
 
 config NXXX_LPUART
@@ -117,6 +121,252 @@ endmenu # LPUART Configuration
 
 endmenu # LPUART
 
+menu "LPI2C Peripherals"
+
+menuconfig NXXX_LPI2C0
+       bool "LPI2C0"
+       default n
+       select NXXX_LPI2C
+
+if NXXX_LPI2C0
+
+config NXXX_LPI2C0_BUSYIDLE
+       int "Bus idle timeout period in clock cycles"
+       default 0
+
+config NXXX_LPI2C0_FILTSCL
+       int "I2C master digital glitch filters for SCL input in clock cycles"
+       default 0
+
+config NXXX_LPI2C0_FILTSDA
+       int "I2C master digital glitch filters for SDA input in clock cycles"
+       default 0
+
+endif # NXXX_LPI2C0
+
+menuconfig NXXX_LPI2C1
+       bool "LPI2C1"
+       default n
+       select NXXX_LPI2C
+
+if NXXX_LPI2C1
+
+config NXXX_LPI2C1_BUSYIDLE
+       int "Bus idle timeout period in clock cycles"
+       default 0
+
+config NXXX_LPI2C1_DMA
+       bool "Enable DMA for I2C1"
+       default n
+       depends on NXXX_LPI2C_DMA
+
+config NXXX_LPI2C1_FILTSCL
+       int "I2C master digital glitch filters for SCL input in clock cycles"
+       default 0
+
+config NXXX_LPI2C1_FILTSDA
+       int "I2C master digital glitch filters for SDA input in clock cycles"
+       default 0
+
+endif # NXXX_LPI2C1
+
+menuconfig NXXX_LPI2C2
+       bool "LPI2C2"
+       default n
+       select NXXX_LPI2C
+
+if NXXX_LPI2C2
+
+config NXXX_LPI2C2_BUSYIDLE
+       int "Bus idle timeout period in clock cycles"
+       default 0
+
+config NXXX_LPI2C2_DMA
+       bool "Enable DMA for I2C2"
+       default n
+       depends on NXXX_LPI2C_DMA
+
+config NXXX_LPI2C2_FILTSCL
+       int "I2C master digital glitch filters for SCL input in clock cycles"
+       default 0
+
+config NXXX_LPI2C2_FILTSDA
+       int "I2C master digital glitch filters for SDA input in clock cycles"
+       default 0
+
+endif # NXXX_LPI2C2
+
+menuconfig NXXX_LPI2C3
+       bool "LPI2C3"
+       default n
+       select NXXX_LPI2C
+
+if NXXX_LPI2C3
+
+config NXXX_LPI2C3_BUSYIDLE
+       int "Bus idle timeout period in clock cycles"
+       default 0
+
+config NXXX_LPI2C3_DMA
+       bool "Enable DMA for I2C3"
+       default n
+       depends on NXXX_LPI2C_DMA
+
+config NXXX_LPI2C3_FILTSCL
+       int "I2C master digital glitch filters for SCL input in clock cycles"
+       default 0
+
+config NXXX_LPI2C3_FILTSDA
+       int "I2C master digital glitch filters for SDA input in clock cycles"
+       default 0
+
+endif # NXXX_LPI2C3
+
+menuconfig NXXX_LPI2C4
+       bool "LPI2C4"
+       default n
+       select NXXX_LPI2C
+
+if NXXX_LPI2C4
+
+config NXXX_LPI2C4_BUSYIDLE
+       int "Bus idle timeout period in clock cycles"
+       default 0
+
+config NXXX_LPI2C4_DMA
+       bool "Enable DMA for I2C4"
+       default n
+       depends on NXXX_LPI2C_DMA
+
+config NXXX_LPI2C4_FILTSCL
+       int "I2C master digital glitch filters for SCL input in clock cycles"
+       default 0
+
+config NXXX_LPI2C4_FILTSDA
+       int "I2C master digital glitch filters for SDA input in clock cycles"
+       default 0
+
+endif # NXXX_LPI2C4
+
+menuconfig NXXX_LPI2C5
+       bool "LPI2C5"
+       default n
+       select NXXX_LPI2C
+
+if NXXX_LPI2C5
+
+config NXXX_LPI2C5_BUSYIDLE
+       int "Bus idle timeout period in clock cycles"
+       default 0
+
+config NXXX_LPI2C5_FILTSCL
+       int "I2C master digital glitch filters for SCL input in clock cycles"
+       default 0
+
+config NXXX_LPI2C5_FILTSDA
+       int "I2C master digital glitch filters for SDA input in clock cycles"
+       default 0
+
+endif # NXXX_LPI2C5
+
+menuconfig NXXX_LPI2C6
+       bool "LPI2C6"
+       default n
+       select NXXX_LPI2C
+
+if NXXX_LPI2C6
+
+config NXXX_LPI2C6_BUSYIDLE
+       int "Bus idle timeout period in clock cycles"
+       default 0
+
+config NXXX_LPI2C6_FILTSCL
+       int "I2C master digital glitch filters for SCL input in clock cycles"
+       default 0
+
+config NXXX_LPI2C6_FILTSDA
+       int "I2C master digital glitch filters for SDA input in clock cycles"
+       default 0
+
+endif # NXXX_LPI2C6
+
+menuconfig NXXX_LPI2C7
+       bool "LPI2C7"
+       default n
+       select NXXX_LPI2C
+
+if NXXX_LPI2C7
+
+config NXXX_LPI2C7_BUSYIDLE
+       int "Bus idle timeout period in clock cycles"
+       default 0
+
+config NXXX_LPI2C7_FILTSCL
+       int "I2C master digital glitch filters for SCL input in clock cycles"
+       default 0
+
+config NXXX_LPI2C7_FILTSDA
+       int "I2C master digital glitch filters for SDA input in clock cycles"
+       default 0
+
+endif # NXXX_LPI2C7
+
+endmenu # LPI2C Peripherals
+
+menu "LPI2C Configuration"
+       depends on NXXX_LPI2C
+
+config NXXX_LPI2C_DMA
+       bool "I2C DMA Support"
+       default n
+       depends on NXXX_LPI2C && NXXX_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 NXXX_LPI2C_DMA_MAXMSG
+       int "Maximum number messages that will be DMAed"
+       default 8
+       depends on NXXX_LPI2C_DMA
+       ---help---
+               This option sets the number 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 NXXX_LPI2C_DYNTIMEO
+       bool "Use dynamic timeouts"
+       default n
+       depends on NXXX_LPI2C
+
+config NXXX_LPI2C_DYNTIMEO_USECPERBYTE
+       int "Timeout Microseconds per Byte"
+       default 500
+       depends on NXXX_LPI2C_DYNTIMEO
+
+config NXXX_LPI2C_DYNTIMEO_STARTSTOP
+       int "Timeout for Start/Stop (Milliseconds)"
+       default 1000
+       depends on NXXX_LPI2C_DYNTIMEO
+
+config NXXX_LPI2C_TIMEOSEC
+       int "Timeout seconds"
+       default 0
+       depends on NXXX_LPI2C
+
+config NXXX_LPI2C_TIMEOMS
+       int "Timeout Milliseconds"
+       default 500
+       depends on NXXX_LPI2C && !NXXX_LPI2C_DYNTIMEO
+
+config NXXX_LPI2C_TIMEOTICKS
+       int "Timeout for Done and Stop (ticks)"
+       default 500
+       depends on NXXX_LPI2C && !NXXX_LPI2C_DYNTIMEO
+
+endmenu # LPI2C Configuration
+
 endmenu # NXXX Peripheral Selection
 
 endif # ARCH_CHIP_NXXX
diff --git a/arch/arm/src/mcx-nxxx/Make.defs b/arch/arm/src/mcx-nxxx/Make.defs
index 76270e3c10..05ae7d6107 100644
--- a/arch/arm/src/mcx-nxxx/Make.defs
+++ b/arch/arm/src/mcx-nxxx/Make.defs
@@ -34,3 +34,7 @@ endif
 ifeq ($(CONFIG_NXXX_GPIO_IRQ),y)
   CHIP_CSRCS += nxxx_gpioirq.c
 endif
+
+ifeq ($(CONFIG_NXXX_LPI2C),y)
+  CHIP_CSRCS += nxxx_lpi2c.c
+endif
diff --git a/arch/arm/src/mcx-nxxx/hardware/nxxx_lpi2c.h 
b/arch/arm/src/mcx-nxxx/hardware/nxxx_lpi2c.h
new file mode 100644
index 0000000000..12f9476888
--- /dev/null
+++ b/arch/arm/src/mcx-nxxx/hardware/nxxx_lpi2c.h
@@ -0,0 +1,627 @@
+/****************************************************************************
+ * arch/arm/src/mcx-nxxx/hardware/nxxx_lpi2c.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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_MCX_NXXX_HARDWARE_NXXX_LPI2C_H
+#define __ARCH_ARM_SRC_MCX_NXXX_HARDWARE_NXXX_LPI2C_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register offsets *********************************************************/
+
+#define NXXX_LPI2C_VERID_OFFSET             0x0000  /* Version ID Register 
offset */
+#define NXXX_LPI2C_PARAM_OFFSET             0x0004  /* Parameter Register 
offset */
+#define NXXX_LPI2C_MCR_OFFSET               0x0010  /* Master Control Register 
offset */
+#define NXXX_LPI2C_MSR_OFFSET               0x0014  /* Master Status Register 
offset */
+#define NXXX_LPI2C_MIER_OFFSET              0x0018  /* Master Interrupt Enable 
Register offset */
+#define NXXX_LPI2C_MDER_OFFSET              0x001c  /* Master DMA Enable 
Register offset */
+#define NXXX_LPI2C_MCFGR0_OFFSET            0x0020  /* Master Config Register 
0 offset */
+#define NXXX_LPI2C_MCFGR1_OFFSET            0x0024  /* Master Config Register 
1 offset */
+#define NXXX_LPI2C_MCFGR2_OFFSET            0x0028  /* Master Config Register 
2 offset */
+#define NXXX_LPI2C_MCFGR3_OFFSET            0x002c  /* Master Config Register 
3 offset */
+#define NXXX_LPI2C_MDMR_OFFSET              0x0040  /* Master Data Match 
Register offset */
+#define NXXX_LPI2C_MCCR0_OFFSET             0x0048  /* Master Clock 
Configuration Register 0 offset */
+#define NXXX_LPI2C_MCCR1_OFFSET             0x0050  /* Master Clock 
Configuration Register 1 offset */
+#define NXXX_LPI2C_MFCR_OFFSET              0x0058  /* Master FIFO Control 
Register offset */
+#define NXXX_LPI2C_MFSR_OFFSET              0x005C  /* Master FIFO Status 
Register offset */
+#define NXXX_LPI2C_MTDR_OFFSET              0x0060  /* Master Transmit Data 
Register offset */
+#define NXXX_LPI2C_MRDR_OFFSET              0x0070  /* Master Receive Data 
Register offset */
+#define NXXX_LPI2C_SCR_OFFSET               0x0110  /* Slave Control Register 
offset */
+#define NXXX_LPI2C_SSR_OFFSET               0x0114  /* Slave Status Register 
offset */
+#define NXXX_LPI2C_SIER_OFFSET              0x0118  /* Slave Interrupt Enable 
Register offset */
+#define NXXX_LPI2C_SDER_OFFSET              0x011c  /* Slave DMA Enable 
Register offset */
+#define NXXX_LPI2C_SCFGR1_OFFSET            0x0124  /* Slave Config Register 1 
offset */
+#define NXXX_LPI2C_SCFGR2_OFFSET            0x0128  /* Slave Config Register 2 
offset */
+#define NXXX_LPI2C_SAMR_OFFSET              0x0140  /* Slave Address Match 
Register offset */
+#define NXXX_LPI2C_SASR_OFFSET              0x0150  /* Slave Address Status 
Register offset */
+#define NXXX_LPI2C_STAR_OFFSET              0x0154  /* Slave Transmit ACK 
Register offset */
+#define NXXX_LPI2C_STDR_OFFSET              0x0160  /* Slave Transmit Data 
Register offset */
+#define NXXX_LPI2C_SRDR_OFFSET              0x0170  /* Slave Receive Data 
Register offset */
+
+/* Register addresses *******************************************************/
+
+/* LPI2C1 Registers */
+
+#define NXXX_LPI2C1_VERID                  (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_VERID_OFFSET)   /* Version ID Register */
+#define NXXX_LPI2C1_PARAM                  (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_PARAM_OFFSET)   /* Parameter Register  */
+#define NXXX_LPI2C1_MCR                    (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MCR_OFFSET)     /* Master Control Register  */
+#define NXXX_LPI2C1_MSR                    (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MSR_OFFSET)     /* Master Status Register  */
+#define NXXX_LPI2C1_MIER                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MIER_OFFSET)    /* Master Interrupt Enable Register  */
+#define NXXX_LPI2C1_MDER                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MDER_OFFSET)    /* Master DMA Enable Register  */
+#define NXXX_LPI2C1_MCFGR0                 (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MCFGR0_OFFSET)  /* Master Config Register 0  */
+#define NXXX_LPI2C1_MCFGR1                 (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MCFGR1_OFFSET)  /* Master Config Register 1  */
+#define NXXX_LPI2C1_MCFGR2                 (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MCFGR2_OFFSET)  /* Master Config Register 2  */
+#define NXXX_LPI2C1_MCFGR3                 (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MCFGR3_OFFSET)  /* Master Config Register 3  */
+#define NXXX_LPI2C1_MDMR                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MDMR_OFFSET)    /* Master Data Match Register  */
+#define NXXX_LPI2C1_MCCR0                  (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MCCR0_OFFSET)   /* Master Clock Configuration Register 0  */
+#define NXXX_LPI2C1_MCCR1                  (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MCCR1_OFFSET)   /* Master Clock Configuration Register 1  */
+#define NXXX_LPI2C1_MFCR                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MFCR_OFFSET)    /* Master FIFO Control Register  */
+#define NXXX_LPI2C1_MFSR                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MFSR_OFFSET)    /* Master FIFO Status Register  */
+#define NXXX_LPI2C1_MTDR                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MTDR_OFFSET)    /* Master Transmit Data Register  */
+#define NXXX_LPI2C1_MRDR                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_MRDR_OFFSET)    /* Master Receive Data Register  */
+#define NXXX_LPI2C1_SCR                    (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_SCR_OFFSET)     /* Slave Control Register  */
+#define NXXX_LPI2C1_SSR                    (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_SSR_OFFSET)     /* Slave Status Register  */
+#define NXXX_LPI2C1_SIER                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_SIER_OFFSET)    /* Slave Interrupt Enable Register  */
+#define NXXX_LPI2C1_SDER                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_SDER_OFFSET)    /* Slave DMA Enable Register  */
+#define NXXX_LPI2C1_SCFGR1                 (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_SCFGR1_OFFSET)  /* Slave Config Register 1  */
+#define NXXX_LPI2C1_SCFGR2                 (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_SCFGR2_OFFSET)  /* Slave Config Register 2  */
+#define NXXX_LPI2C1_SAMR                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_SAMR_OFFSET)    /* Slave Address Match Register  */
+#define NXXX_LPI2C1_SASR                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_SASR_OFFSET)    /* Slave Address Status Register  */
+#define NXXX_LPI2C1_STAR                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_STAR_OFFSET)    /* Slave Transmit ACK Register  */
+#define NXXX_LPI2C1_STDR                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_STDR_OFFSET)    /* Slave Transmit Data Register  */
+#define NXXX_LPI2C1_SRDR                   (NXXX_LPI2C1_BASE + 
NXXX_LPI2C_SRDR_OFFSET)    /* Slave Receive Data Register  */
+
+/* LPI2C2 Registers */
+
+#define NXXX_LPI2C2_VERID                  (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_VERID_OFFSET)   /* Version ID Register */
+#define NXXX_LPI2C2_PARAM                  (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_PARAM_OFFSET)   /* Parameter Register  */
+#define NXXX_LPI2C2_MCR                    (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MCR_OFFSET)     /* Master Control Register  */
+#define NXXX_LPI2C2_MSR                    (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MSR_OFFSET)     /* Master Status Register  */
+#define NXXX_LPI2C2_MIER                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MIER_OFFSET)    /* Master Interrupt Enable Register  */
+#define NXXX_LPI2C2_MDER                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MDER_OFFSET)    /* Master DMA Enable Register  */
+#define NXXX_LPI2C2_MCFGR0                 (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MCFGR0_OFFSET)  /* Master Config Register 0  */
+#define NXXX_LPI2C2_MCFGR1                 (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MCFGR1_OFFSET)  /* Master Config Register 1  */
+#define NXXX_LPI2C2_MCFGR2                 (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MCFGR2_OFFSET)  /* Master Config Register 2  */
+#define NXXX_LPI2C2_MCFGR3                 (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MCFGR3_OFFSET)  /* Master Config Register 3  */
+#define NXXX_LPI2C2_MDMR                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MDMR_OFFSET)    /* Master Data Match Register  */
+#define NXXX_LPI2C2_MCCR0                  (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MCCR0_OFFSET)   /* Master Clock Configuration Register 0  */
+#define NXXX_LPI2C2_MCCR1                  (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MCCR1_OFFSET)   /* Master Clock Configuration Register 1  */
+#define NXXX_LPI2C2_MFCR                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MFCR_OFFSET)    /* Master FIFO Control Register  */
+#define NXXX_LPI2C2_MFSR                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MFSR_OFFSET)    /* Master FIFO Status Register  */
+#define NXXX_LPI2C2_MTDR                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MTDR_OFFSET)    /* Master Transmit Data Register  */
+#define NXXX_LPI2C2_MRDR                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_MRDR_OFFSET)    /* Master Receive Data Register  */
+#define NXXX_LPI2C2_SCR                    (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_SCR_OFFSET)     /* Slave Control Register  */
+#define NXXX_LPI2C2_SSR                    (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_SSR_OFFSET)     /* Slave Status Register  */
+#define NXXX_LPI2C2_SIER                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_SIER_OFFSET)    /* Slave Interrupt Enable Register  */
+#define NXXX_LPI2C2_SDER                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_SDER_OFFSET)    /* Slave DMA Enable Register  */
+#define NXXX_LPI2C2_SCFGR1                 (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_SCFGR1_OFFSET)  /* Slave Config Register 1  */
+#define NXXX_LPI2C2_SCFGR2                 (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_SCFGR2_OFFSET)  /* Slave Config Register 2  */
+#define NXXX_LPI2C2_SAMR                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_SAMR_OFFSET)    /* Slave Address Match Register  */
+#define NXXX_LPI2C2_SASR                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_SASR_OFFSET)    /* Slave Address Status Register  */
+#define NXXX_LPI2C2_STAR                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_STAR_OFFSET)    /* Slave Transmit ACK Register  */
+#define NXXX_LPI2C2_STDR                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_STDR_OFFSET)    /* Slave Transmit Data Register  */
+#define NXXX_LPI2C2_SRDR                   (NXXX_LPI2C2_BASE + 
NXXX_LPI2C_SRDR_OFFSET)    /* Slave Receive Data Register  */
+
+/* LPI2C3 Registers */
+
+#define NXXX_LPI2C3_VERID                  (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_VERID_OFFSET)   /* Version ID Register */
+#define NXXX_LPI2C3_PARAM                  (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_PARAM_OFFSET)   /* Parameter Register  */
+#define NXXX_LPI2C3_MCR                    (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MCR_OFFSET)     /* Master Control Register  */
+#define NXXX_LPI2C3_MSR                    (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MSR_OFFSET)     /* Master Status Register  */
+#define NXXX_LPI2C3_MIER                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MIER_OFFSET)    /* Master Interrupt Enable Register  */
+#define NXXX_LPI2C3_MDER                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MDER_OFFSET)    /* Master DMA Enable Register  */
+#define NXXX_LPI2C3_MCFGR0                 (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MCFGR0_OFFSET)  /* Master Config Register 0  */
+#define NXXX_LPI2C3_MCFGR1                 (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MCFGR1_OFFSET)  /* Master Config Register 1  */
+#define NXXX_LPI2C3_MCFGR2                 (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MCFGR2_OFFSET)  /* Master Config Register 2  */
+#define NXXX_LPI2C3_MCFGR3                 (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MCFGR3_OFFSET)  /* Master Config Register 3  */
+#define NXXX_LPI2C3_MDMR                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MDMR_OFFSET)    /* Master Data Match Register  */
+#define NXXX_LPI2C3_MCCR0                  (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MCCR0_OFFSET)   /* Master Clock Configuration Register 0  */
+#define NXXX_LPI2C3_MCCR1                  (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MCCR1_OFFSET)   /* Master Clock Configuration Register 1  */
+#define NXXX_LPI2C3_MFCR                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MFCR_OFFSET)    /* Master FIFO Control Register  */
+#define NXXX_LPI2C3_MFSR                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MFSR_OFFSET)    /* Master FIFO Status Register  */
+#define NXXX_LPI2C3_MTDR                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MTDR_OFFSET)    /* Master Transmit Data Register  */
+#define NXXX_LPI2C3_MRDR                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_MRDR_OFFSET)    /* Master Receive Data Register  */
+#define NXXX_LPI2C3_SCR                    (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_SCR_OFFSET)     /* Slave Control Register  */
+#define NXXX_LPI2C3_SSR                    (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_SSR_OFFSET)     /* Slave Status Register  */
+#define NXXX_LPI2C3_SIER                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_SIER_OFFSET)    /* Slave Interrupt Enable Register  */
+#define NXXX_LPI2C3_SDER                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_SDER_OFFSET)    /* Slave DMA Enable Register  */
+#define NXXX_LPI2C3_SCFGR1                 (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_SCFGR1_OFFSET)  /* Slave Config Register 1  */
+#define NXXX_LPI2C3_SCFGR2                 (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_SCFGR2_OFFSET)  /* Slave Config Register 2  */
+#define NXXX_LPI2C3_SAMR                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_SAMR_OFFSET)    /* Slave Address Match Register  */
+#define NXXX_LPI2C3_SASR                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_SASR_OFFSET)    /* Slave Address Status Register  */
+#define NXXX_LPI2C3_STAR                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_STAR_OFFSET)    /* Slave Transmit ACK Register  */
+#define NXXX_LPI2C3_STDR                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_STDR_OFFSET)    /* Slave Transmit Data Register  */
+#define NXXX_LPI2C3_SRDR                   (NXXX_LPI2C3_BASE + 
NXXX_LPI2C_SRDR_OFFSET)    /* Slave Receive Data Register  */
+
+/* LPI2C4 Registers */
+
+#define NXXX_LPI2C4_VERID                  (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_VERID_OFFSET)   /* Version ID Register */
+#define NXXX_LPI2C4_PARAM                  (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_PARAM_OFFSET)   /* Parameter Register  */
+#define NXXX_LPI2C4_MCR                    (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MCR_OFFSET)     /* Master Control Register  */
+#define NXXX_LPI2C4_MSR                    (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MSR_OFFSET)     /* Master Status Register  */
+#define NXXX_LPI2C4_MIER                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MIER_OFFSET)    /* Master Interrupt Enable Register  */
+#define NXXX_LPI2C4_MDER                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MDER_OFFSET)    /* Master DMA Enable Register  */
+#define NXXX_LPI2C4_MCFGR0                 (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MCFGR0_OFFSET)  /* Master Config Register 0  */
+#define NXXX_LPI2C4_MCFGR1                 (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MCFGR1_OFFSET)  /* Master Config Register 1  */
+#define NXXX_LPI2C4_MCFGR2                 (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MCFGR2_OFFSET)  /* Master Config Register 2  */
+#define NXXX_LPI2C4_MCFGR3                 (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MCFGR3_OFFSET)  /* Master Config Register 3  */
+#define NXXX_LPI2C4_MDMR                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MDMR_OFFSET)    /* Master Data Match Register  */
+#define NXXX_LPI2C4_MCCR0                  (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MCCR0_OFFSET)   /* Master Clock Configuration Register 0  */
+#define NXXX_LPI2C4_MCCR1                  (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MCCR1_OFFSET)   /* Master Clock Configuration Register 1  */
+#define NXXX_LPI2C4_MFCR                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MFCR_OFFSET)    /* Master FIFO Control Register  */
+#define NXXX_LPI2C4_MFSR                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MFSR_OFFSET)    /* Master FIFO Status Register  */
+#define NXXX_LPI2C4_MTDR                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MTDR_OFFSET)    /* Master Transmit Data Register  */
+#define NXXX_LPI2C4_MRDR                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_MRDR_OFFSET)    /* Master Receive Data Register  */
+#define NXXX_LPI2C4_SCR                    (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_SCR_OFFSET)     /* Slave Control Register  */
+#define NXXX_LPI2C4_SSR                    (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_SSR_OFFSET)     /* Slave Status Register  */
+#define NXXX_LPI2C4_SIER                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_SIER_OFFSET)    /* Slave Interrupt Enable Register  */
+#define NXXX_LPI2C4_SDER                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_SDER_OFFSET)    /* Slave DMA Enable Register  */
+#define NXXX_LPI2C4_SCFGR1                 (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_SCFGR1_OFFSET)  /* Slave Config Register 1  */
+#define NXXX_LPI2C4_SCFGR2                 (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_SCFGR2_OFFSET)  /* Slave Config Register 2  */
+#define NXXX_LPI2C4_SAMR                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_SAMR_OFFSET)    /* Slave Address Match Register  */
+#define NXXX_LPI2C4_SASR                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_SASR_OFFSET)    /* Slave Address Status Register  */
+#define NXXX_LPI2C4_STAR                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_STAR_OFFSET)    /* Slave Transmit ACK Register  */
+#define NXXX_LPI2C4_STDR                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_STDR_OFFSET)    /* Slave Transmit Data Register  */
+#define NXXX_LPI2C4_SRDR                   (NXXX_LPI2C4_BASE + 
NXXX_LPI2C_SRDR_OFFSET)    /* Slave Receive Data Register  */
+
+/* Register bit definitions *************************************************/
+
+/* LPI2C Version ID Register */
+
+#define LPI2C_VERID_FEATURE_SHIFT           (0)
+#define LPI2C_VERID_FEATURE_MASK            (0xffff << 
LPI2C_VERID_FEATURE_SHIFT)
+#define LPI2C_VERID_MINOR_SHIFT             (16)
+#define LPI2C_VERID_MINOR_MASK              (0xff << LPI2C_VERID_MINOR_SHIFT)
+#define LPI2C_VERID_MAJOR_SHIFT             (24)
+#define LPI2C_VERID_MAJOR_MASK              (0xff << LPI2C_VERID_MAJOR_SHIFT)
+
+/* LPI2C Parameter Register  */
+
+#define LPI2C_PARAM_MTXFIFO_MASK            (0x0f) /* Config number of words 
in master transmit fifo to 2^MTXFIFO (pow(2,MTXFIFO )) */
+#  define LPI2C_PARAM_MTXFIFO_1_WORDS       (0)
+#  define LPI2C_PARAM_MTXFIFO_2_WORDS       (1)
+#  define LPI2C_PARAM_MTXFIFO_4_WORDS       (2)
+#  define LPI2C_PARAM_MTXFIFO_8_WORDS       (3)
+#  define LPI2C_PARAM_MTXFIFO_16_WORDS      (4)
+#  define LPI2C_PARAM_MTXFIFO_32_WORDS      (5)
+#  define LPI2C_PARAM_MTXFIFO_64_WORDS      (6)
+#  define LPI2C_PARAM_MTXFIFO_128_WORDS     (7)
+#  define LPI2C_PARAM_MTXFIFO_256_WORDS     (8)
+#  define LPI2C_PARAM_MTXFIFO_512_WORDS     (9)
+#  define LPI2C_PARAM_MTXFIFO_1024_WORDS    (10)
+#  define LPI2C_PARAM_MTXFIFO_2048_WORDS    (11)
+#  define LPI2C_PARAM_MTXFIFO_4096_WORDS    (12)
+#  define LPI2C_PARAM_MTXFIFO_8192_WORDS    (13)
+#  define LPI2C_PARAM_MTXFIFO_16384_WORDS   (14)
+#  define LPI2C_PARAM_MTXFIFO_32768_WORDS   (15)
+
+#define LPI2C_PARAM_MRXFIFO_SHIFT           (8)
+#define LPI2C_PARAM_MRXFIFO_MASK            (0x0f << 
LPI2C_PARAM_MRXFIFO_SHIFT) /* Config number of words in master receive fifo 
2^MRXFIFO (pow(2,MTRFIFO )) */
+#  define LPI2C_PARAM_MRXFIFO_1_WORDS       (0 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_2_WORDS       (1 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_4_WORDS       (2 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_8_WORDS       (3 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_16_WORDS      (4 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_32_WORDS      (5 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_64_WORDS      (6 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_128_WORDS     (7 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_256_WORDS     (8 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_512_WORDS     (9 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_1024_WORDS    (10 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_2048_WORDS    (11 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_4096_WORDS    (12 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_8192_WORDS    (13 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_16384_WORDS   (14 << LPI2C_PARAM_MRXFIFO_SHIFT)
+#  define LPI2C_PARAM_MRXFIFO_32768_WORDS   (15 << LPI2C_PARAM_MRXFIFO_SHIFT)
+
+/* LPI2C Master Control Register  */
+
+#define LPI2C_MCR_MEN                       (1 << 0)  /* Master Enable Bit */
+#define LPI2C_MCR_RST                       (1 << 1)  /* Software Reset Bit */
+#define LPI2C_MCR_DOZEN                     (1 << 2)  /* Doze Mode Enable Bit 
*/
+#define LPI2C_MCR_DBGEN                     (1 << 3)  /* Debug Enable Bit */
+                                                      /* Bits 7-4 Reserved */
+#define LPI2C_MCR_RTF                       (1 << 8)  /* Reset Transmit FIFO 
Bit */
+#define LPI2C_MCR_RRF                       (1 << 9)  /* Reset Receive FIFO 
Bit */
+                                                      /* Bits 31-10 Reserved */
+
+/* LPI2C Master Status Register  */
+
+#define LPI2C_MSR_TDF                       (1 << 0)  /* Transmit Data Flag 
Bit */
+#define LPI2C_MSR_RDF                       (1 << 1)  /* Receive Data Flag Bit 
*/
+                                                      /* Bits 7-2 Reserved */
+#define LPI2C_MSR_EPF                       (1 << 8)  /* End Packet Flag Bit */
+#define LPI2C_MSR_SDF                       (1 << 9)  /* STOP Detect Flag Bit 
*/
+#define LPI2C_MSR_NDF                       (1 << 10) /* NACK Detect Flag Bit 
*/
+#define LPI2C_MSR_ALF                       (1 << 11) /* Arbitration Lost Flag 
Bit */
+#define LPI2C_MSR_FEF                       (1 << 12) /* FIFO Error Flag Bit */
+#define LPI2C_MSR_PLTF                      (1 << 13) /* Pin Low Timeout Flag 
Bit */
+#define LPI2C_MSR_DMF                       (1 << 14) /* Data Match Flag Bit */
+                                                      /* Bits 23-15 Reserved */
+#define LPI2C_MSR_MBF                       (1 << 24) /* Master Busy Flag Bit 
*/
+#define LPI2C_MSR_BBF                       (1 << 25) /* Bus Busy Flag Bit */
+                                                      /* Bits 31-26 Reserved */
+#define LPI2C_MSR_ERROR_MASK                (LPI2C_MSR_NDF | LPI2C_MSR_ALF | \
+                                             LPI2C_MSR_FEF)
+
+/* LPI2C Master Interrupt Enable Register  */
+
+#define LPI2C_MIER_TDIE                     (1 << 0)  /* Transmit Data 
Interrupt Enable Bit */
+#define LPI2C_MIER_RDIE                     (1 << 1)  /* Receive Data 
Interrupt Enable Bit */
+                                                      /* Bits 7-2 Reserved */
+#define LPI2C_MIER_EPIE                     (1 << 8)  /* End Packet Interrupt 
Enable Bit */
+#define LPI2C_MIER_SDIE                     (1 << 9)  /* STOP Detect Interrupt 
Enable Bit */
+#define LPI2C_MIER_NDIE                     (1 << 10) /* NACK Detect Interrupt 
Enable Bit */
+#define LPI2C_MIER_ALIE                     (1 << 11) /* Arbitration Lost 
Interrupt Enable Bit */
+#define LPI2C_MIER_FEIE                     (1 << 12) /* FIFO Error Interrupt 
Enable Bit */
+#define LPI2C_MIER_PLTIE                    (1 << 13) /* Pin Low Timeout 
Interrupt Enable Bit */
+#define LPI2C_MIER_DMIE                     (1 << 14) /* Data Match Interrupt 
Enable Bit */
+                                                      /* Bits 31-15 Reserved */
+
+/* LPI2C Master DMA Enable Register  */
+
+#define LPI2C_MDER_TDDE                     (1 << 0)  /* Transmit Data DMA 
Enable Bit */
+#define LPI2C_MDER_RDDE                     (1 << 1)  /* Transmit Data DMA 
Enable Bit */
+                                                      /* Bits 31-2 Reserved */
+
+/* LPI2C Master Config Register 0  */
+
+#define LPI2C_MCFG0_HREN                    (1 << 0)  /* Host Request Enable 
Bit */
+#define LPI2C_MCFG0_HRPOL                   (1 << 1)  /* Host Request Polarity 
Bit */
+#define LPI2C_MCFG0_HRSEL                   (1 << 2)  /* Host Request Select 
Bit */
+                                                      /* Bits 7-3 Reserved */
+#define LPI2C_MCFG0_CIRFIFO                 (1 << 8)  /* Circular FIFO Enable 
Bit */
+#define LPI2C_MCFG0_RDMO                    (1 << 9)  /* Receive Data Match 
Only Bit */
+                                                      /* Bits 15-10 Reserved */
+#define LPI2C_MCFG0_RELAX                   (1 << 16) /* Relaxed Mode */
+#define LPI2C_MCFG0_ABORT                   (1 << 17) /* Abort Transfer */
+                                                      /* Bits 31-18 Reserved */
+
+/* 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_1            (0)
+#  define LPI2C_MCFGR1_PRESCALE_2            (1)
+#  define LPI2C_MCFGR1_PRESCALE_4            (2)
+#  define LPI2C_MCFGR1_PRESCALE_8            (3)
+#  define LPI2C_MCFGR1_PRESCALE_16           (4)
+#  define LPI2C_MCFGR1_PRESCALE_32           (5)
+#  define LPI2C_MCFGR1_PRESCALE_64           (6)
+#  define LPI2C_MCFGR1_PRESCALE_128          (7)
+#define LPI2C_MCFGR1_AUTOSTOP                (1 << 8)  /* Automatic STOP 
Generation Bit */
+#define LPI2C_MCFGR1_IGNACK                  (1 << 9)  /* Ignore NACK Bit */
+#define LPI2C_MCFGR1_TIMECFG                 (1 << 10) /* Timeout 
Configuration Bit */
+                                                       /* 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_DISABLE        (0 << LPI2C_MCFGR1_MATCFG_SHIFT)
+                                                      /* LPI2C_MCFG1_MATCFG = 
001b Reserved */
+#  define LPI2C_MCFGR1_MATCFG2               (2 << LPI2C_MCFGR1_MATCFG_SHIFT)
+#  define LPI2C_MCFGR1_MATCFG3               (3 << LPI2C_MCFGR1_MATCFG_SHIFT)
+#  define LPI2C_MCFGR1_MATCFG4               (4 << LPI2C_MCFGR1_MATCFG_SHIFT)
+#  define LPI2C_MCFGR1_MATCFG5               (5 << LPI2C_MCFGR1_MATCFG_SHIFT)
+#  define LPI2C_MCFGR1_MATCFG6               (6 << LPI2C_MCFGR1_MATCFG_SHIFT)
+#  define LPI2C_MCFGR1_MATCFG7               (7 << LPI2C_MCFGR1_MATCFG_SHIFT)
+                                                     /* 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_PINCFG0               (0 << LPI2C_MCFGR1_PINCFG_SHIFT)
+#  define LPI2C_MCFGR1_PINCFG1               (1 << LPI2C_MCFGR1_PINCFG_SHIFT)
+#  define LPI2C_MCFGR1_PINCFG2               (2 << LPI2C_MCFGR1_PINCFG_SHIFT)
+#  define LPI2C_MCFGR1_PINCFG3               (3 << LPI2C_MCFGR1_PINCFG_SHIFT)
+#  define LPI2C_MCFGR1_PINCFG4               (4 << LPI2C_MCFGR1_PINCFG_SHIFT)
+#  define LPI2C_MCFGR1_PINCFG5               (5 << LPI2C_MCFGR1_PINCFG_SHIFT)
+#  define LPI2C_MCFGR1_PINCFG6               (6 << LPI2C_MCFGR1_PINCFG_SHIFT)
+#  define LPI2C_MCFGR1_PINCFG7               (7 << LPI2C_MCFGR1_PINCFG_SHIFT)
+                                                     /* Bits 31-27 Reserved */
+
+/* LPI2C Master Config Register 2  */
+
+#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)
+                                                     /* 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)
+                                                     /* 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)
+                                                     /* Bits 31-28 Reserved */
+
+/* LPI2C Master Config Register 3  */
+
+                                                     /* 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)
+                                                     /* 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)
+                                                     /* 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)
+                                                     /* 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)
+                                                     /* 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)
+                                                     /* 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)
+                                                     /* 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)
+                                                     /* 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)
+                                                     /* 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)
+                                                     /* 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)
+
+                                                     /* 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)
+
+                                                     /* Bits 31-30 Reserved */
+
+/* LPI2C Master FIFO Control Register */
+
+#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 */
+
+                                                     /* 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 */
+
+                                                     /* Bits 31-18 Reserved */
+
+/* LPI2C Master FIFO Status Register */
+
+#define LPI2C_MFSR_TXCOUNT_SHIFT            (0)
+#define LPI2C_MFSR_TXCOUNT_MASK             (3 << LPI2C_MFSR_TXCOUNT_SHIFT)  
/* Transmit FIFO Count */
+
+                                                     /* Bits 15-2 Reserved */
+#define LPI2C_MFSR_RXCOUNT_SHIFT            (16)
+#define LPI2C_MFSR_RXCOUNT_MASK             (3 << LPI2C_MFSR_RXCOUNT_SHIFT)  
/* Receive FIFO Count */
+
+                                                     /* Bits 31-18 Reserved */
+
+/* LPI2C Master Transmit Data Register */
+
+#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_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_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)
+#  define LPI2C_MTDR_CMD_RXD_DISC           (3 << LPI2C_MTDR_CMD_SHIFT)
+#  define LPI2C_MTDR_CMD_START              (4 << LPI2C_MTDR_CMD_SHIFT)
+#  define LPI2C_MTDR_CMD_START_NACK         (5 << LPI2C_MTDR_CMD_SHIFT)
+#  define LPI2C_MTDR_CMD_START_HI           (6 << LPI2C_MTDR_CMD_SHIFT)
+#  define LPI2C_MTDR_CMD_START_HI_NACK      (7 << LPI2C_MTDR_CMD_SHIFT)
+
+                                                     /* Bits 31-11 Reserved */
+
+/* LPI2C Master Receive Data Register */
+
+#define LPI2C_MRDR_DATA_SHIFT               (0)
+#define LPI2C_MRDR_DATA_MASK                (0xff << LPI2C_MRDR_DATA_SHIFT)  
/* Receive Data */
+
+                                                     /* Bits 13-8 Reserved */
+#define LPI2C_MRDR_RXEMPTY_SHIFT            (14)
+#define LPI2C_MRDR_RXEMPTY_MASK             (1 << LPI2C_MRDR_RXEMPTY_SHIFT)  
/* Rx Empty */
+
+                                                     /* Bits 31-15 Reserved */
+
+/* LPI2C Slave Control Register */
+
+#define LPI2C_SCR_SEN                       (1 << 0)  /* Slave Enable Bit */
+#define LPI2C_SCR_RST                       (1 << 1)  /* Software Reset Bit */
+                                                      /* Bits 3-2 Reserved */
+#define LPI2C_SCR_FILTEN                    (1 << 4)  /* Filter Enable Bit */
+#define LPI2C_SCR_FILTDZ                    (1 << 5)  /* Filter Doze Enable 
Bit */
+                                                      /* Bits 7-4 Reserved */
+#define LPI2C_SCR_RTF                       (1 << 8)  /* Reset Transmit FIFO 
Bit */
+#define LPI2C_SCR_RRF                       (1 << 9)  /* Reset Receive FIFO 
Bit */
+                                                      /* Bits 31-10 Reserved */
+
+/* LPI2C Slave Status Register  */
+
+#define LPI2C_SSR_TDF                       (1 << 0)  /* Transmit Data Flag 
Bit */
+#define LPI2C_SSR_RDF                       (1 << 1)  /* Receive Data Flag Bit 
*/
+#define LPI2C_SSR_AVF                       (1 << 2)  /* Address Valid Flag 
Bit */
+#define LPI2C_SSR_TAF                       (1 << 3)  /* Transmit ACK Flag Bit 
*/
+                                                      /* Bits 7-4 Reserved */
+#define LPI2C_SSR_RSF                       (1 << 8)  /* Repeated Start Flag 
Bit */
+#define LPI2C_SSR_SDF                       (1 << 9)  /* STOP Detect Flag Bit 
*/
+#define LPI2C_SSR_BEF                       (1 << 10) /* Bit Error Flag Bit */
+#define LPI2C_SSR_FEF                       (1 << 11) /* FIFO Error Flag Bit */
+#define LPI2C_SSR_AM0F                      (1 << 12) /* Address Match 0 Flag 
Bit */
+#define LPI2C_SSR_AM1F                      (1 << 13) /* Address Match 1 Flag 
Bit */
+#define LPI2C_SSR_GCF                       (1 << 14) /* General Call Flag Bit 
*/
+#define LPI2C_SSR_SARF                      (1 << 15) /* SMBus Alert Response 
Flag Bit */
+                                                      /* Bits 23-16 Reserved */
+#define LPI2C_MSR_SBF                       (1 << 24) /* Slave Busy Flag Bit */
+#define LPI2C_MSR_BBF                       (1 << 25) /* Bus Busy Flag Bit */
+                                                      /* Bits 31-26 Reserved */
+
+/* LPI2C Slave Interrupt Enable Register  */
+
+#define LPI2C_SIER_TDIE                     (1 << 0)  /* Transmit Data 
Interrupt Enable Bit */
+#define LPI2C_SIER_RDIE                     (1 << 1)  /* Receive Data 
Interrupt Enable Bit */
+#define LPI2C_SIER_AVIE                     (1 << 2)  /* Address Valid 
Interrupt Enable Bit */
+#define LPI2C_SIER_TAIE                     (1 << 3)  /* Transmit ACK 
Interrupt Enable Bit */
+                                                      /* Bits 7-4 Reserved */
+#define LPI2C_SIER_RSIE                     (1 << 8)  /* Repeated Start 
Interrupt Enable Bit */
+#define LPI2C_SIER_SDIE                     (1 << 9)  /* STOP Detect Interrupt 
Enable Bit */
+#define LPI2C_SIER_BEIE                     (1 << 10) /* Bit Error Interrupt 
Enable Bit */
+#define LPI2C_SIER_FEIE                     (1 << 11) /* FIFO Error Interrupt 
Enable Bit */
+#define LPI2C_SIER_AM0IE                    (1 << 12) /* Address Match 0 
Interrupt Enable Bit */
+#define LPI2C_SIER_AM1IE                    (1 << 13) /* Address Match 1 
Interrupt Enable Bit */
+#define LPI2C_SIER_GCIE                     (1 << 14) /* General Call 
Interrupt Enable Bit */
+#define LPI2C_SIER_SARIE                    (1 << 15) /* SMBus Alert Response 
Interrupt Enable Bit */
+                                                      /* Bits 31-16 Reserved */
+
+/* LPI2C Slave DMA Enable Register  */
+
+#define LPI2C_SDER_TDDE                     (1 << 0)  /* Transmit Data DMA 
Enable Bit */
+#define LPI2C_SDER_RDDE                     (1 << 1)  /* Transmit Data DMA 
Enable Bit */
+#define LPI2C_SDER_AVDE                     (1 << 2)  /* Address Valid DMA 
Enable Bit */
+                                                      /* Bits 31-3 Reserved */
+
+/* LPI2C Slave Configuration Register 1  */
+
+#define LPI2C_SCFGR1_ADRSTALL               (1 << 0)  /* Address SCL Stall */
+#define LPI2C_SCFGR1_RXSTALL                (1 << 1)  /* RX SCL Stall */
+#define LPI2C_SCFGR1_TXSTALL                (1 << 2)  /* TX Data SCL Stall */
+#define LPI2C_SCFGR1_ACKSTALL               (1 << 3)  /* ACK SCL Stall */
+                                                      /* Bits 7-4 Reserved */
+#define LPI2C_SCFGR1_GCEN                   (1 << 8)  /* General Call Enable */
+#define LPI2C_SCFGR1_SAEN                   (1 << 9)  /* SMBus Alert Enable */
+#define LPI2C_SCFGR1_TXCFG                  (1 << 10) /* Transmit Flag 
Configuration */
+#define LPI2C_SCFGR1_RXCFG                  (1 << 11) /* Receive Data 
Configuration */
+#define LPI2C_SCFGR1_IFNACK                 (1 << 12) /* Ignore NACK */
+#define LPI2C_SCFGR1_HSMEN                  (1 << 13) /* High Speed Mode 
Enable */
+                                                      /* 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_ADDRCFG0              (0 << LPI2C_SCFG1_ADDRCFG_SHIFT)
+#  define LPI2C_SCFG1_ADDRCFG1              (2 << LPI2C_SCFG1_ADDRCFG_SHIFT)
+#  define LPI2C_SCFG1_ADDRCFG2              (2 << LPI2C_SCFG1_ADDRCFG_SHIFT)
+#  define LPI2C_SCFG1_ADDRCFG3              (3 << LPI2C_SCFG1_ADDRCFG_SHIFT)
+#  define LPI2C_SCFG1_ADDRCFG4              (4 << LPI2C_SCFG1_ADDRCFG_SHIFT)
+#  define LPI2C_SCFG1_ADDRCFG5              (5 << LPI2C_SCFG1_ADDRCFG_SHIFT)
+#  define LPI2C_SCFG1_ADDRCFG6              (6 << LPI2C_SCFG1_ADDRCFG_SHIFT)
+#  define LPI2C_SCFG1_ADDRCFG7              (7 << LPI2C_SCFG1_ADDRCFG_SHIFT)
+                                                      /* Bits 31-19 Reserved */
+
+/* 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)
+                                                      /* 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)
+                                                      /* 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)
+                                                      /* 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)
+                                                      /* Bits 31-28 Reserved */
+
+/* LPI2C Slave Address Match Register  */
+
+                                                      /* 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)
+                                                      /* 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)
+                                                      /* Bits 31-27 Reserved */
+
+/* LPI2C Slave Address Status Register  */
+
+#define LPI2C_SASR_RADDR_MASK               (0x7ff << 0) /* Received Address */
+
+/*                                                       Bits 16-11
+ *                                                       Reserved
+ */
+
+#define LPI2C_SASR_ANV                      (1 << 14) /* Address Not Valid */
+                                                      /* Bits 31-15 Reserved */
+
+/* LPI2C Slave Transmit ACK Register  */
+
+#define LPI2C_STAR_TXNACK                   (1 << 0)  /* Transmit NACK */
+                                                      /* Bits 31-1 Reserved */
+
+/* LPI2C Slave Transmit Data Register  */
+
+#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)
+                                                      /* 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)
+                                                      /* Bits 13-8 Reserved */
+#define LPI2C_STAR_SOF                      (1 << 14) /* RX Empty */
+#define LPI2C_STAR_RXEMPTY                  (1 << 15) /* Start Of Frame */
+                                                      /* Bits 31-16 Reserved */
+
+#endif /* __ARCH_ARM_SRC_MCX_NXXX_HARDWARE_NXXX_LPI2C_H */
diff --git a/arch/arm/src/mcx-nxxx/nxxx_lpi2c.c 
b/arch/arm/src/mcx-nxxx/nxxx_lpi2c.c
new file mode 100644
index 0000000000..91afbc1d99
--- /dev/null
+++ b/arch/arm/src/mcx-nxxx/nxxx_lpi2c.c
@@ -0,0 +1,2478 @@
+/****************************************************************************
+ * arch/arm/src/mcx-nxxx/nxxx_lpi2c.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/clock.h>
+#include <nuttx/mutex.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/i2c/i2c_master.h>
+
+#include <arch/board/board.h>
+
+#include "arm_internal.h"
+#include "nxxx_clockconfig.h"
+#include "nxxx_gpio.h"
+#include "nxxx_port.h"
+#include "nxxx_lpi2c.h"
+
+#include "hardware/nxxx_clock.h"
+#include "hardware/nxxx_flexcomm.h"
+#include "hardware/nxxx_lpi2c.h"
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+#  include "chip.h"
+#  include "nxxx_edma.h"
+#  include "hardware/nxxx_dmamux.h"
+#endif
+
+/* At least one I2C peripheral must be enabled */
+
+#ifdef CONFIG_NXXX_LPI2C
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/* CONFIG_I2C_POLLED may be set so that I2C interrupts will not be used.
+ * Instead, CPU-intensive polling will be used.
+ */
+
+/* Interrupt wait timeout in seconds and milliseconds */
+
+#if !defined(CONFIG_NXXX_LPI2C_TIMEOSEC) && \
+    !defined(CONFIG_NXXX_LPI2C_TIMEOMS)
+#  define CONFIG_NXXX_LPI2C_TIMEOSEC 0
+#  define CONFIG_NXXX_LPI2C_TIMEOMS  500   /* Default is 500 milliseconds */
+#elif !defined(CONFIG_NXXX_LPI2C_TIMEOSEC)
+#  define CONFIG_NXXX_LPI2C_TIMEOSEC 0     /* User provided milliseconds */
+#elif !defined(CONFIG_NXXX_LPI2C_TIMEOMS)
+#  define CONFIG_NXXX_LPI2C_TIMEOMS  0     /* User provided seconds */
+#endif
+
+/* Interrupt wait time timeout in system timer ticks */
+
+#ifndef CONFIG_NXXX_LPI2C_TIMEOTICKS
+#  define CONFIG_NXXX_LPI2C_TIMEOTICKS \
+     (SEC2TICK(CONFIG_NXXX_LPI2C_TIMEOSEC) + \
+      MSEC2TICK(CONFIG_NXXX_LPI2C_TIMEOMS))
+#endif
+
+#ifndef CONFIG_NXXX_LPI2C_DYNTIMEO_STARTSTOP
+#  define CONFIG_NXXX_LPI2C_DYNTIMEO_STARTSTOP \
+     TICK2USEC(CONFIG_NXXX_LPI2C_TIMEOTICKS)
+#endif
+
+/* Debug ********************************************************************/
+
+/* I2C event trace logic.  NOTE:  trace uses the internal, non-standard,
+ * low-level debug interface syslog() but does not require that any other
+ * debug is enabled.
+ */
+
+#ifndef CONFIG_I2C_TRACE
+#  define nxxx_lpi2c_tracereset(p)
+#  define nxxx_lpi2c_tracenew(p,s)
+#  define nxxx_lpi2c_traceevent(p,e,a)
+#  define nxxx_lpi2c_tracedump(p)
+#endif
+
+#ifndef CONFIG_I2C_NTRACE
+#  define CONFIG_I2C_NTRACE 32
+#endif
+
+#ifdef CONFIG_I2C_SLAVE
+#  error I2C slave logic is not supported yet for NXXX
+#endif
+
+#define LPI2C_MASTER    1
+#define LPI2C_SLAVE     2
+
+#define LPI2C_MSR_LIMITED_ERROR_MASK (LPI2C_MSR_ERROR_MASK & ~(LPI2C_MSR_FEF))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Interrupt state */
+
+enum nxxx_intstate_e
+{
+  INTSTATE_IDLE = 0,      /* No I2C activity */
+  INTSTATE_WAITING,       /* Waiting for completion of interrupt activity */
+  INTSTATE_DONE,          /* Interrupt activity complete */
+};
+
+/* Trace events */
+
+enum nxxx_trace_e
+{
+  I2CEVENT_NONE = 0,      /* No events have occurred with this status */
+  I2CEVENT_SENDADDR,      /* Start/Master bit set and address sent, param = 
msgc */
+  I2CEVENT_SENDBYTE,      /* Send byte, param = dcnt */
+  I2CEVENT_RCVBYTE,       /* Read more dta, param = dcnt */
+  I2CEVENT_NOSTART,       /* BTF on last byte with no restart, param = msgc */
+  I2CEVENT_STARTRESTART,  /* Last byte sent, re-starting, param = msgc */
+  I2CEVENT_STOP,          /* Last byte sten, send stop, param = 0 */
+  I2CEVENT_ERROR          /* Error occurred, param = 0 */
+};
+
+/* Trace data */
+
+struct nxxx_trace_s
+{
+  uint32_t status;             /* I2C 32-bit SR2|SR1 status */
+  uint32_t count;              /* Interrupt count when status change */
+  enum nxxx_intstate_e event;  /* Last event that occurred with this status */
+  uint32_t parm;               /* Parameter associated with the event */
+  clock_t time;                /* First of event or first status */
+};
+
+/* I2C Device hardware configuration */
+
+struct nxxx_lpi2c_config_s
+{
+  uint32_t base;                    /* LPI2C base address */
+  struct clock_regs_s clk_regs;     /* LPI2C clock regs (SYSCON) */
+  struct clock_gate_reg_s clk_gate; /* LPI2C clock gate */
+  uint32_t clk_source;              /* LPI2C clock source */
+  uint32_t psel_reg;                /* LPI2C psel id */
+  uint16_t busy_idle;               /* LPI2C Bus Idle Timeout */
+  uint8_t filtscl;                  /* Glitch Filter for SCL pin */
+  uint8_t filtsda;                  /* Glitch Filter for SDA pin */
+  port_cfg_t scl_pin;               /* Peripheral configuration for SCL as SCL 
*/
+  port_cfg_t sda_pin;               /* Peripheral configuration for SDA as SDA 
*/
+#if defined(CONFIG_I2C_RESET)
+  gpio_pinset_t reset_scl_pin;      /* GPIO configuration for SCL as GPIO */
+  gpio_pinset_t reset_sda_pin;      /* GPIO configuration for SDA as GPIO */
+#endif
+  uint8_t mode;                     /* Master or Slave mode */
+#ifndef CONFIG_I2C_POLLED
+  uint32_t irq;                     /* Event IRQ */
+#endif
+#ifdef CONFIG_NXXX_LPI2C_DMA
+  uint32_t dma_rxreqsrc;            /* DMA mux rx source */
+  uint32_t dma_txreqsrc;            /* DMA mux tx source */
+#endif
+};
+
+/* I2C Device Private Data */
+
+struct nxxx_lpi2c_priv_s
+{
+  /* Standard I2C operations */
+
+  const struct i2c_ops_s *ops;
+
+  /* Port configuration */
+
+  const struct nxxx_lpi2c_config_s *config;
+
+  int refs;                    /* Reference count */
+  mutex_t lock;                /* Mutual exclusion mutex */
+#ifndef CONFIG_I2C_POLLED
+  sem_t sem_isr;               /* Interrupt wait semaphore */
+#endif
+  volatile uint8_t intstate;   /* Interrupt handshake (see enum 
nxxx_intstate_e) */
+
+  int8_t msgc;                 /* Message count */
+  struct i2c_msg_s *msgv;      /* Message list */
+  uint8_t *ptr;                /* Current message buffer */
+  uint32_t frequency;          /* Current I2C frequency */
+  int dcnt;                    /* Current message length */
+  uint16_t flags;              /* Current message flags */
+
+  /* I2C trace support */
+
+#ifdef CONFIG_I2C_TRACE
+  int tndx;                    /* Trace array index */
+  clock_t start_time;          /* Time when the trace was started */
+
+  /* The actual trace data */
+
+  struct nxxx_trace_s trace[CONFIG_I2C_NTRACE];
+#endif
+
+  uint32_t status;             /* End of transfer SR2|SR1 status */
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+  DMACH_HANDLE rxdma;                               /* rx DMA handle */
+  DMACH_HANDLE txdma;                               /* tx DMA handle */
+  uint16_t     cmnds[CONFIG_NXXX_LPI2C_DMA_MAXMSG]; /* Commands */
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static inline uint32_t
+nxxx_lpi2c_getreg(struct nxxx_lpi2c_priv_s *priv, uint16_t offset);
+static inline void nxxx_lpi2c_putreg(struct nxxx_lpi2c_priv_s *priv,
+                                     uint16_t offset, uint32_t value);
+static inline void nxxx_lpi2c_modifyreg(struct nxxx_lpi2c_priv_s *priv,
+                                        uint16_t offset, uint32_t clearbits,
+                                        uint32_t setbits);
+
+#ifdef CONFIG_NXXX_LPI2C_DYNTIMEO
+static uint32_t nxxx_lpi2c_toticks(int msgc, struct i2c_msg_s *msgs);
+#endif /* CONFIG_NXXX_LPI2C_DYNTIMEO */
+
+static inline int
+nxxx_lpi2c_sem_waitdone(struct nxxx_lpi2c_priv_s *priv);
+
+#ifdef CONFIG_I2C_TRACE
+static void nxxx_lpi2c_tracereset(struct nxxx_lpi2c_priv_s *priv);
+static void nxxx_lpi2c_tracenew(struct nxxx_lpi2c_priv_s *priv,
+                                uint32_t status);
+static void nxxx_lpi2c_traceevent(struct nxxx_lpi2c_priv_s *priv,
+                                  enum nxxx_trace_e event, uint32_t parm);
+static void nxxx_lpi2c_tracedump(struct nxxx_lpi2c_priv_s *priv);
+#endif /* CONFIG_I2C_TRACE */
+
+static void nxxx_lpi2c_setclock(struct nxxx_lpi2c_priv_s *priv,
+                                uint32_t frequency);
+static inline void nxxx_lpi2c_sendstart(struct nxxx_lpi2c_priv_s *priv,
+                                        uint8_t address);
+static inline void nxxx_lpi2c_sendstop(struct nxxx_lpi2c_priv_s *priv);
+static inline uint32_t
+nxxx_lpi2c_getstatus(struct nxxx_lpi2c_priv_s *priv);
+
+static int nxxx_lpi2c_isr_process(struct nxxx_lpi2c_priv_s *priv);
+
+#ifndef CONFIG_I2C_POLLED
+static int nxxx_lpi2c_isr(int irq, void *context, void *arg);
+#endif /* !CONFIG_I2C_POLLED */
+
+static void nxxx_lpi2c_clock_enable(struct nxxx_lpi2c_priv_s *priv);
+static void nxxx_lpi2c_clock_disable(struct nxxx_lpi2c_priv_s *priv);
+static int nxxx_lpi2c_init(struct nxxx_lpi2c_priv_s *priv);
+static int nxxx_lpi2c_deinit(struct nxxx_lpi2c_priv_s *priv);
+static int nxxx_lpi2c_transfer(struct i2c_master_s *dev,
+                               struct i2c_msg_s *msgs, int count);
+#ifdef CONFIG_I2C_RESET
+static int nxxx_lpi2c_reset(struct i2c_master_s *dev);
+#endif
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+static void nxxx_rxdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+                                int result);
+static void nxxx_txdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+                                int result);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trace events strings */
+
+#ifdef CONFIG_I2C_TRACE
+static const char *g_trace_names[] =
+{
+  "NONE           ",
+  "SENDADDR       ",
+  "SENDBYTE       ",
+  "RCVBYTE        ",
+  "NOSTART        ",
+  "START/RESTART  ",
+  "STOP           ",
+  "ERROR          "
+};
+#endif
+
+/* I2C interface */
+
+static const struct i2c_ops_s nxxx_lpi2c_ops =
+{
+  .transfer = nxxx_lpi2c_transfer,
+#ifdef CONFIG_I2C_RESET
+  .reset    = nxxx_lpi2c_reset,
+#endif
+};
+
+/* I2C device structures */
+
+#ifdef CONFIG_NXXX_LPI2C0
+static const struct nxxx_lpi2c_config_s nxxx_lpi2c0_config =
+{
+  .base          = NXXX_LPI2C0_BASE,
+  .clk_regs      = SYSCON_FCCLK0,
+  .clk_gate      = CLOCK_GATE_LPFLEXCOMM0,
+  .clk_source    = FRO12M_TO_FLEXCOMM0,
+  .psel_reg      = NXXX_FLEXCOMM0_PSELID,
+  .busy_idle     = CONFIG_NXXX_LPI2C0_BUSYIDLE,
+  .filtscl       = CONFIG_NXXX_LPI2C0_FILTSCL,
+  .filtsda       = CONFIG_NXXX_LPI2C0_FILTSDA,
+  .scl_pin       = PORT_LPI2C0_SCL,
+  .sda_pin       = PORT_LPI2C0_SDA,
+#if defined(CONFIG_I2C_RESET)
+  .reset_scl_pin = GPIO_LPI2C1_SCL_RESET,
+  .reset_sda_pin = GPIO_LPI2C1_SDA_RESET,
+#endif
+#ifndef CONFIG_I2C_SLAVE
+  .mode          = LPI2C_MASTER,
+#else
+  .mode          = LPI2C_SLAVE,
+#endif
+#ifndef CONFIG_I2C_POLLED
+  .irq           = NXXX_IRQ_LP_FLEXCOMM0,
+#endif
+#ifdef CONFIG_NXXX_LPI2C1_DMA
+  .dma_rxreqsrc  = DMA_REQUEST_MUXLPI2C1RX,
+  .dma_txreqsrc  = DMA_REQUEST_MUXLPI2C1TX,
+#endif
+};
+
+static struct nxxx_lpi2c_priv_s nxxx_lpi2c0_priv =
+{
+  .ops           = &nxxx_lpi2c_ops,
+  .config        = &nxxx_lpi2c0_config,
+  .refs          = 0,
+  .lock          = NXMUTEX_INITIALIZER,
+#ifndef CONFIG_I2C_POLLED
+  .sem_isr       = SEM_INITIALIZER(0),
+#endif
+  .intstate      = INTSTATE_IDLE,
+  .msgc          = 0,
+  .msgv          = NULL,
+  .ptr           = NULL,
+  .dcnt          = 0,
+  .flags         = 0,
+  .status        = 0
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPI2C1
+static const struct nxxx_lpi2c_config_s nxxx_lpi2c1_config =
+{
+  .base          = NXXX_LPI2C1_BASE,
+  .clk_regs      = SYSCON_FCCLK1,
+  .clk_gate      = CLOCK_GATE_LPFLEXCOMM1,
+  .clk_source    = FRO12M_TO_FLEXCOMM1,
+  .psel_reg      = NXXX_FLEXCOMM1_PSELID,
+  .busy_idle     = CONFIG_NXXX_LPI2C1_BUSYIDLE,
+  .filtscl       = CONFIG_NXXX_LPI2C1_FILTSCL,
+  .filtsda       = CONFIG_NXXX_LPI2C1_FILTSDA,
+  .scl_pin       = PORT_LPI2C1_SCL,
+  .sda_pin       = PORT_LPI2C1_SDA,
+#if defined(CONFIG_I2C_RESET)
+  .reset_scl_pin = GPIO_LPI2C1_SCL_RESET,
+  .reset_sda_pin = GPIO_LPI2C1_SDA_RESET,
+#endif
+#ifndef CONFIG_I2C_SLAVE
+  .mode          = LPI2C_MASTER,
+#else
+  .mode          = LPI2C_SLAVE,
+#endif
+#ifndef CONFIG_I2C_POLLED
+  .irq           = NXXX_IRQ_LP_FLEXCOMM1,
+#endif
+#ifdef CONFIG_NXXX_LPI2C1_DMA
+  .dma_rxreqsrc  = DMA_REQUEST_MUXLPI2C1RX,
+  .dma_txreqsrc  = DMA_REQUEST_MUXLPI2C1TX,
+#endif
+};
+
+static struct nxxx_lpi2c_priv_s nxxx_lpi2c1_priv =
+{
+  .ops           = &nxxx_lpi2c_ops,
+  .config        = &nxxx_lpi2c1_config,
+  .refs          = 0,
+  .lock          = NXMUTEX_INITIALIZER,
+#ifndef CONFIG_I2C_POLLED
+  .sem_isr       = SEM_INITIALIZER(0),
+#endif
+  .intstate      = INTSTATE_IDLE,
+  .msgc          = 0,
+  .msgv          = NULL,
+  .ptr           = NULL,
+  .dcnt          = 0,
+  .flags         = 0,
+  .status        = 0
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPI2C2
+static const struct nxxx_lpi2c_config_s nxxx_lpi2c2_config =
+{
+  .base          = NXXX_LPI2C2_BASE,
+  .clk_regs      = SYSCON_FCCLK2,
+  .clk_gate      = CLOCK_GATE_LPFLEXCOMM2,
+  .clk_source    = FRO12M_TO_FLEXCOMM2,
+  .psel_reg      = NXXX_FLEXCOMM2_PSELID,
+  .busy_idle     = CONFIG_NXXX_LPI2C2_BUSYIDLE,
+  .filtscl       = CONFIG_NXXX_LPI2C2_FILTSCL,
+  .filtsda       = CONFIG_NXXX_LPI2C2_FILTSDA,
+  .scl_pin       = PORT_LPI2C2_SCL,
+  .sda_pin       = PORT_LPI2C2_SDA,
+#if defined(CONFIG_I2C_RESET)
+  .reset_scl_pin = GPIO_LPI2C2_SCL_RESET,
+  .reset_sda_pin = GPIO_LPI2C2_SDA_RESET,
+#endif
+#ifndef CONFIG_I2C_SLAVE
+  .mode          = LPI2C_MASTER,
+#else
+  .mode          = LPI2C_SLAVE,
+#endif
+#ifndef CONFIG_I2C_POLLED
+  .irq           = NXXX_IRQ_LP_FLEXCOMM2,
+#endif
+#ifdef CONFIG_NXXX_LPI2C2_DMA
+  .dma_rxreqsrc  = DMA_REQUEST_MUXLPI2C2RX,
+  .dma_txreqsrc  = DMA_REQUEST_MUXLPI2C2TX,
+#endif
+};
+
+static struct nxxx_lpi2c_priv_s nxxx_lpi2c2_priv =
+{
+  .ops           = &nxxx_lpi2c_ops,
+  .config        = &nxxx_lpi2c2_config,
+  .refs          = 0,
+  .lock          = NXMUTEX_INITIALIZER,
+#ifndef CONFIG_I2C_POLLED
+  .sem_isr       = SEM_INITIALIZER(0),
+#endif
+  .intstate      = INTSTATE_IDLE,
+  .msgc          = 0,
+  .msgv          = NULL,
+  .ptr           = NULL,
+  .dcnt          = 0,
+  .flags         = 0,
+  .status        = 0
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPI2C3
+static const struct nxxx_lpi2c_config_s nxxx_lpi2c3_config =
+{
+  .base          = NXXX_LPI2C3_BASE,
+  .clk_regs      = SYSCON_FCCLK3,
+  .clk_gate      = CLOCK_GATE_LPFLEXCOMM3,
+  .clk_source    = FRO12M_TO_FLEXCOMM3,
+  .psel_reg      = NXXX_FLEXCOMM3_PSELID,
+  .busy_idle     = CONFIG_NXXX_LPI2C3_BUSYIDLE,
+  .filtscl       = CONFIG_NXXX_LPI2C3_FILTSCL,
+  .filtsda       = CONFIG_NXXX_LPI2C3_FILTSDA,
+  .scl_pin       = PORT_LPI2C3_SCL,
+  .sda_pin       = PORT_LPI2C3_SDA,
+#if defined(CONFIG_I2C_RESET)
+  .reset_scl_pin = GPIO_LPI2C3_SCL_RESET,
+  .reset_sda_pin = GPIO_LPI2C3_SDA_RESET,
+#endif
+#ifndef CONFIG_I2C_SLAVE
+  .mode          = LPI2C_MASTER,
+#else
+  .mode          = LPI2C_SLAVE,
+#endif
+#ifndef CONFIG_I2C_POLLED
+  .irq           = NXXX_IRQ_LP_FLEXCOMM3,
+#endif
+#ifdef CONFIG_NXXX_LPI2C3_DMA
+  .dma_rxreqsrc  = DMA_REQUEST_MUXLPI2C3RX,
+  .dma_txreqsrc  = DMA_REQUEST_MUXLPI2C3TX,
+#endif
+};
+
+static struct nxxx_lpi2c_priv_s nxxx_lpi2c3_priv =
+{
+  .ops           = &nxxx_lpi2c_ops,
+  .config        = &nxxx_lpi2c3_config,
+  .refs          = 0,
+  .lock          = NXMUTEX_INITIALIZER,
+#ifndef CONFIG_I2C_POLLED
+  .sem_isr       = SEM_INITIALIZER(0),
+#endif
+  .intstate      = INTSTATE_IDLE,
+  .msgc          = 0,
+  .msgv          = NULL,
+  .ptr           = NULL,
+  .dcnt          = 0,
+  .flags         = 0,
+  .status        = 0
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPI2C4
+static const struct nxxx_lpi2c_config_s nxxx_lpi2c4_config =
+{
+  .base          = NXXX_LPI2C4_BASE,
+  .clk_regs      = SYSCON_FCCLK4,
+  .clk_gate      = CLOCK_GATE_LPFLEXCOMM4,
+  .clk_source    = FRO12M_TO_FLEXCOMM4,
+  .psel_reg      = NXXX_FLEXCOMM4_PSELID,
+  .busy_idle     = CONFIG_NXXX_LPI2C4_BUSYIDLE,
+  .filtscl       = CONFIG_NXXX_LPI2C4_FILTSCL,
+  .filtsda       = CONFIG_NXXX_LPI2C4_FILTSDA,
+  .scl_pin       = PORT_LPI2C4_SCL,
+  .sda_pin       = PORT_LPI2C4_SDA,
+#if defined(CONFIG_I2C_RESET)
+  .reset_scl_pin = GPIO_LPI2C4_SCL_RESET,
+  .reset_sda_pin = GPIO_LPI2C4_SDA_RESET,
+#endif
+#ifndef CONFIG_I2C_SLAVE
+  .mode          = LPI2C_MASTER,
+#else
+  .mode          = LPI2C_SLAVE,
+#endif
+#ifndef CONFIG_I2C_POLLED
+  .irq           = NXXX_IRQ_LP_FLEXCOMM4,
+#endif
+#ifdef CONFIG_NXXX_LPI2C4_DMA
+  .dma_rxreqsrc  = DMA_REQUEST_MUXLPI2C4RX,
+  .dma_txreqsrc  = DMA_REQUEST_MUXLPI2C4TX,
+#endif
+};
+
+static struct nxxx_lpi2c_priv_s nxxx_lpi2c4_priv =
+{
+  .ops           = &nxxx_lpi2c_ops,
+  .config        = &nxxx_lpi2c4_config,
+  .refs          = 0,
+  .lock          = NXMUTEX_INITIALIZER,
+#ifndef CONFIG_I2C_POLLED
+  .sem_isr       = SEM_INITIALIZER(0),
+#endif
+  .intstate      = INTSTATE_IDLE,
+  .msgc          = 0,
+  .msgv          = NULL,
+  .ptr           = NULL,
+  .dcnt          = 0,
+  .flags         = 0,
+  .status        = 0
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPI2C5
+static const struct nxxx_lpi2c_config_s nxxx_lpi2c5_config =
+{
+  .base          = NXXX_LPI2C5_BASE,
+  .clk_regs      = SYSCON_FCCLK5,
+  .clk_gate      = CLOCK_GATE_LPFLEXCOMM5,
+  .clk_source    = FRO12M_TO_FLEXCOMM5,
+  .psel_reg      = NXXX_FLEXCOMM5_PSELID,
+  .busy_idle     = CONFIG_NXXX_LPI2C5_BUSYIDLE,
+  .filtscl       = CONFIG_NXXX_LPI2C5_FILTSCL,
+  .filtsda       = CONFIG_NXXX_LPI2C5_FILTSDA,
+  .scl_pin       = PORT_LPI2C5_SCL,
+  .sda_pin       = PORT_LPI2C5_SDA,
+#if defined(CONFIG_I2C_RESET)
+  .reset_scl_pin = GPIO_LPI2C5_SCL_RESET,
+  .reset_sda_pin = GPIO_LPI2C5_SDA_RESET,
+#endif
+#ifndef CONFIG_I2C_SLAVE
+  .mode          = LPI2C_MASTER,
+#else
+  .mode          = LPI2C_SLAVE,
+#endif
+#ifndef CONFIG_I2C_POLLED
+  .irq           = NXXX_IRQ_LP_FLEXCOMM5,
+#endif
+#ifdef CONFIG_NXXX_LPI2C5_DMA
+  .dma_rxreqsrc  = DMA_REQUEST_MUXLPI2C5RX,
+  .dma_txreqsrc  = DMA_REQUEST_MUXLPI2C5TX,
+#endif
+};
+
+static struct nxxx_lpi2c_priv_s nxxx_lpi2c5_priv =
+{
+  .ops           = &nxxx_lpi2c_ops,
+  .config        = &nxxx_lpi2c5_config,
+  .refs          = 0,
+  .lock          = NXMUTEX_INITIALIZER,
+#ifndef CONFIG_I2C_POLLED
+  .sem_isr       = SEM_INITIALIZER(0),
+#endif
+  .intstate      = INTSTATE_IDLE,
+  .msgc          = 0,
+  .msgv          = NULL,
+  .ptr           = NULL,
+  .dcnt          = 0,
+  .flags         = 0,
+  .status        = 0
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPI2C6
+static const struct nxxx_lpi2c_config_s nxxx_lpi2c6_config =
+{
+  .base          = NXXX_LPI2C6_BASE,
+  .clk_regs      = SYSCON_FCCLK6,
+  .clk_gate      = CLOCK_GATE_LPFLEXCOMM6,
+  .clk_source    = FRO12M_TO_FLEXCOMM6,
+  .psel_reg      = NXXX_FLEXCOMM6_PSELID,
+  .busy_idle     = CONFIG_NXXX_LPI2C6_BUSYIDLE,
+  .filtscl       = CONFIG_NXXX_LPI2C6_FILTSCL,
+  .filtsda       = CONFIG_NXXX_LPI2C6_FILTSDA,
+  .scl_pin       = PORT_LPI2C6_SCL,
+  .sda_pin       = PORT_LPI2C6_SDA,
+#if defined(CONFIG_I2C_RESET)
+  .reset_scl_pin = GPIO_LPI2C6_SCL_RESET,
+  .reset_sda_pin = GPIO_LPI2C6_SDA_RESET,
+#endif
+#ifndef CONFIG_I2C_SLAVE
+  .mode          = LPI2C_MASTER,
+#else
+  .mode          = LPI2C_SLAVE,
+#endif
+#ifndef CONFIG_I2C_POLLED
+  .irq           = NXXX_IRQ_LP_FLEXCOMM6,
+#endif
+#ifdef CONFIG_NXXX_LPI2C6_DMA
+  .dma_rxreqsrc  = DMA_REQUEST_MUXLPI2C6RX,
+  .dma_txreqsrc  = DMA_REQUEST_MUXLPI2C6TX,
+#endif
+};
+
+static struct nxxx_lpi2c_priv_s nxxx_lpi2c6_priv =
+{
+  .ops           = &nxxx_lpi2c_ops,
+  .config        = &nxxx_lpi2c6_config,
+  .refs          = 0,
+  .lock          = NXMUTEX_INITIALIZER,
+#ifndef CONFIG_I2C_POLLED
+  .sem_isr       = SEM_INITIALIZER(0),
+#endif
+  .intstate      = INTSTATE_IDLE,
+  .msgc          = 0,
+  .msgv          = NULL,
+  .ptr           = NULL,
+  .dcnt          = 0,
+  .flags         = 0,
+  .status        = 0
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPI2C7
+static const struct nxxx_lpi2c_config_s nxxx_lpi2c7_config =
+{
+  .base          = NXXX_LPI2C7_BASE,
+  .clk_regs      = SYSCON_FCCLK7,
+  .clk_gate      = CLOCK_GATE_LPFLEXCOMM7,
+  .clk_source    = FRO12M_TO_FLEXCOMM7,
+  .psel_reg      = NXXX_FLEXCOMM7_PSELID,
+  .busy_idle     = CONFIG_NXXX_LPI2C7_BUSYIDLE,
+  .filtscl       = CONFIG_NXXX_LPI2C7_FILTSCL,
+  .filtsda       = CONFIG_NXXX_LPI2C7_FILTSDA,
+  .scl_pin       = PORT_LPI2C7_SCL,
+  .sda_pin       = PORT_LPI2C7_SDA,
+#if defined(CONFIG_I2C_RESET)
+  .reset_scl_pin = GPIO_LPI2C7_SCL_RESET,
+  .reset_sda_pin = GPIO_LPI2C7_SDA_RESET,
+#endif
+#ifndef CONFIG_I2C_SLAVE
+  .mode          = LPI2C_MASTER,
+#else
+  .mode          = LPI2C_SLAVE,
+#endif
+#ifndef CONFIG_I2C_POLLED
+  .irq           = NXXX_IRQ_LP_FLEXCOMM7,
+#endif
+#ifdef CONFIG_NXXX_LPI2C7_DMA
+  .dma_rxreqsrc  = DMA_REQUEST_MUXLPI2C7RX,
+  .dma_txreqsrc  = DMA_REQUEST_MUXLPI2C7TX,
+#endif
+};
+
+static struct nxxx_lpi2c_priv_s nxxx_lpi2c7_priv =
+{
+  .ops           = &nxxx_lpi2c_ops,
+  .config        = &nxxx_lpi2c7_config,
+  .refs          = 0,
+  .lock          = NXMUTEX_INITIALIZER,
+#ifndef CONFIG_I2C_POLLED
+  .sem_isr       = SEM_INITIALIZER(0),
+#endif
+  .intstate      = INTSTATE_IDLE,
+  .msgc          = 0,
+  .msgv          = NULL,
+  .ptr           = NULL,
+  .dcnt          = 0,
+  .flags         = 0,
+  .status        = 0
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_getreg
+ *
+ * Description:
+ *   Get a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static inline uint32_t
+nxxx_lpi2c_getreg(struct nxxx_lpi2c_priv_s *priv, uint16_t offset)
+{
+  return getreg32(priv->config->base + offset);
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_putreg
+ *
+ * Description:
+ *  Put a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static inline void nxxx_lpi2c_putreg(struct nxxx_lpi2c_priv_s *priv,
+                                     uint16_t offset, uint32_t value)
+{
+  putreg32(value, priv->config->base + offset);
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_modifyreg
+ *
+ * Description:
+ *   Modify a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static inline void nxxx_lpi2c_modifyreg(struct nxxx_lpi2c_priv_s *priv,
+                                        uint16_t offset, uint32_t clearbits,
+                                        uint32_t setbits)
+{
+  modifyreg32(priv->config->base + offset, clearbits, setbits);
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_toticks
+ *
+ * Description:
+ *   Return a micro-second delay based on the number of bytes left to be
+ *   processed.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXXX_LPI2C_DYNTIMEO
+static uint32_t nxxx_lpi2c_toticks(int msgc, struct i2c_msg_s *msgs)
+{
+  int i;
+  size_t bytecount = 0;
+  uint32_t tick    = 0;
+
+  /* Count the number of bytes left to process */
+
+  for (i = 0; i < msgc; i++)
+    {
+      bytecount += msgs[i].length;
+    }
+
+  /* Then return a number of microseconds based on a user provided scaling
+   * factor.
+   */
+
+  tick = USEC2TICK(CONFIG_NXXX_LPI2C_DYNTIMEO_USECPERBYTE * bytecount);
+  if (tick == 0)
+    {
+      tick = 1;
+    }
+
+  return tick;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_sem_waitdone
+ *
+ * Description:
+ *   Wait for a transfer to complete
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_I2C_POLLED
+static inline int
+nxxx_lpi2c_sem_waitdone(struct nxxx_lpi2c_priv_s *priv)
+{
+  int ret;
+
+#ifdef CONFIG_NXXX_LPI2C_DYNTIMEO
+  ret = nxsem_tickwait_uninterruptible(&priv->sem_isr,
+                                       nxxx_lpi2c_toticks(priv->msgc,
+                                                          priv->msgv));
+#else
+  ret = nxsem_tickwait_uninterruptible(&priv->sem_isr,
+                                       CONFIG_NXXX_LPI2C_TIMEOTICKS);
+#endif
+
+  /* Set the interrupt state back to IDLE */
+
+  priv->intstate = INTSTATE_IDLE;
+
+  return ret;
+}
+#else
+static inline int
+nxxx_lpi2c_sem_waitdone(struct nxxx_lpi2c_priv_s *priv)
+{
+  clock_t timeout;
+  clock_t start;
+  clock_t elapsed;
+  int ret;
+
+  /* Get the timeout value */
+
+#ifdef CONFIG_NXXX_LPI2C_DYNTIMEO
+  timeout = nxxx_lpi2c_toticks(priv->msgc, priv->msgv);
+#else
+  timeout = CONFIG_NXXX_LPI2C_TIMEOTICKS;
+#endif
+  start = clock_systime_ticks();
+
+  do
+    {
+      /* Calculate the elapsed time */
+
+      elapsed = clock_systime_ticks() - start;
+
+      /* Poll by simply calling the timer interrupt handler until it
+       * reports that it is done.
+       */
+
+      nxxx_lpi2c_isr_process(priv);
+    }
+
+  /* Loop until the transfer is complete. */
+
+  while (priv->intstate != INTSTATE_DONE && elapsed < timeout);
+
+  i2cinfo("intstate: %d elapsed: %ld threshold: %ld status: %08x\n",
+          priv->intstate, (long)elapsed, (long)timeout, priv->status);
+
+  /* Set the interrupt state back to IDLE */
+
+  ret = priv->intstate == INTSTATE_DONE ? OK : -ETIMEDOUT;
+  priv->intstate = INTSTATE_IDLE;
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxxx_rxdma_callback
+ *
+ * Description:
+ *   This function performs the next I2C operation
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+static void nxxx_rxdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+                              int result)
+{
+  struct nxxx_lpi2c_priv_s *priv = (struct nxxx_lpi2c_priv_s *)arg;
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MIER_OFFSET, 0,
+                             LPI2C_MIER_SDIE);
+
+  if (result == OK)
+    {
+      if ((priv->flags & I2C_M_NOSTOP) == 0)
+        {
+          nxxx_lpi2c_traceevent(priv, I2CEVENT_STOP, 0);
+          nxxx_lpi2c_sendstop(priv);
+        }
+    }
+  else
+    {
+      uint32_t status = nxxx_lpi2c_getstatus(priv);
+
+      if ((status & LPI2C_MSR_ERROR_MASK) != 0)
+        {
+          i2cerr("ERROR: MSR: status: 0x0%" PRIx32 "\n", status);
+
+          nxxx_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0);
+        }
+    }
+}
+#endif
+
+/****************************************************************************
+ * Name: nxxx_txdma_callback
+ *
+ * Description:
+ *   This function performs the next I2C operation
+ *
+ ****************************************************************************/
+#ifdef CONFIG_NXXX_LPI2C_DMA
+static void nxxx_txdma_callback(DMACH_HANDLE handle, void *arg, bool done,
+                              int result)
+{
+  struct nxxx_lpi2c_priv_s *priv = (struct nxxx_lpi2c_priv_s *)arg;
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MIER_OFFSET, 0,
+                             LPI2C_MIER_SDIE);
+
+  if (result == OK)
+    {
+      if ((priv->flags & I2C_M_NOSTOP) == 0)
+        {
+          nxxx_lpi2c_traceevent(priv, I2CEVENT_STOP, 0);
+          nxxx_lpi2c_sendstop(priv);
+        }
+    }
+  else
+    {
+      uint32_t status = nxxx_lpi2c_getstatus(priv);
+
+      if ((status & LPI2C_MSR_ERROR_MASK) != 0)
+        {
+          i2cerr("ERROR: MSR: status: 0x0%" PRIx32 "\n", status);
+
+          nxxx_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0);
+        }
+    }
+}
+#endif
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_trace*
+ *
+ * Description:
+ *   I2C trace instrumentation
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_TRACE
+static void nxxx_lpi2c_traceclear(struct nxxx_lpi2c_priv_s *priv)
+{
+  struct nxxx_trace_s *trace = &priv->trace[priv->tndx];
+
+  trace->status = 0;              /* I2C 32-bit SR2|SR1 status */
+  trace->count  = 0;              /* Interrupt count when status change */
+  trace->event  = I2CEVENT_NONE;  /* Last event that occurred with this status 
*/
+  trace->parm   = 0;              /* Parameter associated with the event */
+  trace->time   = 0;              /* Time of first status or event */
+}
+
+static void nxxx_lpi2c_tracereset(struct nxxx_lpi2c_priv_s *priv)
+{
+  /* Reset the trace info for a new data collection */
+
+  priv->tndx       = 0;
+  priv->start_time = clock_systime_ticks();
+  nxxx_lpi2c_traceclear(priv);
+}
+
+static void nxxx_lpi2c_tracenew(struct nxxx_lpi2c_priv_s *priv,
+                                uint32_t status)
+{
+  struct nxxx_trace_s *trace = &priv->trace[priv->tndx];
+
+  /* Is the current entry uninitialized?  Has the status changed? */
+
+  if (trace->count == 0 || status != trace->status)
+    {
+      /* Yes.. Was it the status changed?  */
+
+      if (trace->count != 0)
+        {
+          /* Yes.. bump up the trace index (unless out of trace entries) */
+
+          if (priv->tndx >= (CONFIG_I2C_NTRACE - 1))
+            {
+              i2cerr("ERROR: Trace table overflow\n");
+              return;
+            }
+
+          priv->tndx++;
+          trace = &priv->trace[priv->tndx];
+        }
+
+      /* Initialize the new trace entry */
+
+      nxxx_lpi2c_traceclear(priv);
+      trace->status = status;
+      trace->count  = 1;
+      trace->time   = clock_systime_ticks();
+    }
+  else
+    {
+      /* Just increment the count of times that we have seen this status */
+
+      trace->count++;
+    }
+}
+
+static void nxxx_lpi2c_traceevent(struct nxxx_lpi2c_priv_s *priv,
+                                  enum nxxx_trace_e event, uint32_t parm)
+{
+  struct nxxx_trace_s *trace;
+
+  if (event != I2CEVENT_NONE)
+    {
+      trace = &priv->trace[priv->tndx];
+
+      /* Initialize the new trace entry */
+
+      trace->event = event;
+      trace->parm  = parm;
+
+      /* Bump up the trace index (unless we are out of trace entries) */
+
+      if (priv->tndx >= (CONFIG_I2C_NTRACE - 1))
+        {
+          i2cerr("ERROR: Trace table overflow\n");
+          return;
+        }
+
+      priv->tndx++;
+      nxxx_lpi2c_traceclear(priv);
+    }
+}
+
+static void nxxx_lpi2c_tracedump(struct nxxx_lpi2c_priv_s *priv)
+{
+  struct nxxx_trace_s *trace;
+  int i;
+
+  syslog(LOG_DEBUG, "Elapsed time: %ld\n",
+         (long)(clock_systime_ticks() - priv->start_time));
+
+  for (i = 0; i < priv->tndx; i++)
+    {
+      trace = &priv->trace[i];
+      syslog(LOG_DEBUG,
+             "%2d. STATUS: %08x COUNT: %3d EVENT: %s(%2d) PARM: %08x "
+             "TIME: %d\n",
+             i + 1, trace->status, trace->count,
+             g_trace_names[trace->event],
+             trace->event, trace->parm, trace->time - priv->start_time);
+    }
+}
+#endif /* CONFIG_I2C_TRACE */
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_setclock
+ *
+ * Description:
+ *   Set the I2C clock
+ *
+ ****************************************************************************/
+
+static void nxxx_lpi2c_setclock(struct nxxx_lpi2c_priv_s *priv,
+                                uint32_t frequency)
+{
+  uint32_t src_freq = 12000000u;
+  uint32_t regval;
+  uint32_t men;
+  uint32_t prescale = 0;
+  uint32_t best_prescale = 0;
+  uint32_t best_clk_hi = 0;
+  uint32_t abs_error = 0;
+  uint32_t best_error = 0xffffffff;
+  uint32_t clk_hi_cycle;
+  uint32_t computed_rate;
+  uint32_t count;
+
+  /* Has the I2C bus frequency changed? */
+
+  if (priv->config->mode == LPI2C_MASTER)
+    {
+      if (frequency != priv->frequency)
+        {
+          /* Disable the selected LPI2C peripheral to configure the new
+           * clock if it is enabled.
+           */
+
+          men = nxxx_lpi2c_getreg(priv, NXXX_LPI2C_MCR_OFFSET) &
+                LPI2C_MCR_MEN;
+          if (men)
+            {
+              nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCR_OFFSET,
+                                    LPI2C_MCR_MEN, 0);
+            }
+
+          /* LPI2C output frequency = (Source Clock (Hz)/ 2^prescale) /
+           *   (CLKLO + 1 + CLKHI + 1 + ALIGN_DOWN((2 + FILTSCL)/2^prescale)
+           *
+           * Assume  CLKLO = 2 * CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI / 2
+           */
+
+          for (prescale = 1;
+               (prescale <= 128) && (best_error != 0);
+               prescale *= 2)
+            {
+              for (clk_hi_cycle = 1; clk_hi_cycle < 32; clk_hi_cycle++)
+                {
+                  if (clk_hi_cycle == 1)
+                    {
+                      computed_rate = (src_freq / prescale) /
+                                      (6 + (2 / prescale));
+                    }
+                  else
+                    {
+                      computed_rate = (src_freq / prescale) /
+                                      ((3 * clk_hi_cycle + 2) +
+                                      (2 / prescale));
+                    }
+
+                  if (frequency > computed_rate)
+                    {
+                      abs_error = frequency - computed_rate;
+                    }
+                  else
+                    {
+                      abs_error = computed_rate - frequency;
+                    }
+
+                  if (abs_error < best_error)
+                    {
+                      best_prescale = prescale;
+                      best_clk_hi = clk_hi_cycle;
+                      best_error = abs_error;
+
+                      if (abs_error == 0)
+                        {
+                          break;
+                        }
+                    }
+                }
+            }
+
+          regval = LPI2C_MCCR0_CLKHI(best_clk_hi);
+
+          if (best_clk_hi < 2)
+            {
+              regval |= LPI2C_MCCR0_CLKLO(3) | LPI2C_MCCR0_SETHOLD(2) |
+                        LPI2C_MCCR0_DATAVD(1);
+            }
+          else
+            {
+              regval |= LPI2C_MCCR0_CLKLO(2 * best_clk_hi) |
+                        LPI2C_MCCR0_SETHOLD(best_clk_hi) |
+                        LPI2C_MCCR0_DATAVD(best_clk_hi / 2);
+            }
+
+          nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MCCR0_OFFSET, regval);
+
+          for (count = 0; count < 8; count++)
+            {
+              if (best_prescale == (1 << count))
+                {
+                  best_prescale = count;
+                  break;
+                }
+            }
+
+          nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCFGR1_OFFSET,
+                               LPI2C_MCFGR1_PRESCALE_MASK,
+                               LPI2C_MCFGR1_PRESCALE(best_prescale));
+
+          /* Re-enable LPI2C if it was enabled previously */
+
+          if (men)
+            {
+              nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCR_OFFSET, 0,
+                                   LPI2C_MCR_MEN);
+            }
+
+          /* Save the new LPI2C frequency */
+
+          priv->frequency = frequency;
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_sendstart
+ *
+ * Description:
+ *   Send the START conditions/force Master mode
+ *
+ ****************************************************************************/
+
+static inline void nxxx_lpi2c_sendstart(struct nxxx_lpi2c_priv_s *priv,
+                                        uint8_t address)
+{
+  uint32_t txcount = 0;
+  uint32_t status = 0;
+  uint8_t addr;
+
+  /* Disable AUTOSTOP and turn NAK Ignore off */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCFGR1_OFFSET,
+                       LPI2C_MCFGR1_IGNACK | LPI2C_MCFGR1_AUTOSTOP, 0);
+
+  do
+    {
+      txcount = (nxxx_lpi2c_getreg(priv, NXXX_LPI2C_MFSR_OFFSET) &
+                 LPI2C_MFSR_TXCOUNT_MASK) >> LPI2C_MFSR_TXCOUNT_SHIFT;
+      txcount = 4 - txcount;
+
+      status = nxxx_lpi2c_getreg(priv, NXXX_LPI2C_MSR_OFFSET);
+
+      if (status & LPI2C_MSR_ERROR_MASK)
+        {
+          nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MSR_OFFSET,
+                            status & LPI2C_MSR_ERROR_MASK);
+        }
+    }
+  while (txcount == 0);
+
+  if ((priv->flags & I2C_M_READ) != 0)
+    {
+      addr = I2C_READADDR8(address);
+    }
+  else
+    {
+      addr = I2C_WRITEADDR8(address);
+    }
+
+  /* Generate START condition and send the address */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MTDR_OFFSET,
+                    (LPI2C_MTDR_CMD_START | LPI2C_MTDR_DATA(addr)));
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_sendstop
+ *
+ * Description:
+ *   Send the STOP conditions
+ *
+ ****************************************************************************/
+
+static inline void nxxx_lpi2c_sendstop(struct nxxx_lpi2c_priv_s *priv)
+{
+  nxxx_lpi2c_traceevent(priv, I2CEVENT_STOP, 0);
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MTDR_OFFSET, LPI2C_MTDR_CMD_STOP);
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_getstatus
+ *
+ * Description:
+ *   Get 32-bit status
+ *
+ ****************************************************************************/
+
+static inline uint32_t
+nxxx_lpi2c_getstatus(struct nxxx_lpi2c_priv_s *priv)
+{
+  return nxxx_lpi2c_getreg(priv, NXXX_LPI2C_MSR_OFFSET);
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_getenabledints
+ *
+ * Description:
+ *   Get 32-bit status
+ *
+ ****************************************************************************/
+
+static inline uint32_t
+nxxx_lpi2c_getenabledints(struct nxxx_lpi2c_priv_s *priv)
+{
+  return nxxx_lpi2c_getreg(priv, NXXX_LPI2C_MIER_OFFSET);
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_start_message
+ *
+ * Description:
+ *  Start send or receive a new message in interrupt mode
+ *
+ ****************************************************************************/
+
+static int nxxx_lpi2c_start_message(struct nxxx_lpi2c_priv_s *priv)
+{
+  uint32_t irq_config = (LPI2C_MIER_EPIE | LPI2C_MIER_SDIE |
+                         LPI2C_MIER_NDIE | LPI2C_MIER_ALIE |
+                         LPI2C_MIER_FEIE);
+
+  priv->ptr   = priv->msgv->buffer;
+  priv->dcnt  = priv->msgv->length;
+  priv->flags = priv->msgv->flags;
+
+  /* Disable ABORT which may be present after errors */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCFGR0_OFFSET,
+                       LPI2C_MCFG0_ABORT, 0);
+
+  /* Send start + address unless M_NOSTART is defined */
+
+  if ((priv->flags & I2C_M_NOSTART) == 0)
+    {
+      nxxx_lpi2c_traceevent(priv, I2CEVENT_STARTRESTART,
+                            priv->msgc);
+      nxxx_lpi2c_sendstart(priv, priv->msgv->addr);
+    }
+  else
+    {
+      nxxx_lpi2c_traceevent(priv, I2CEVENT_NOSTART, priv->msgc);
+    }
+
+  if ((priv->flags & I2C_M_READ) == 0)
+    {
+      /* Queue the first byte. NB: if start was sent and NACK received,
+       * the byte won't be sent out to the bus.
+       */
+
+      nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MTDR_OFFSET,
+                        LPI2C_MTDR_CMD_TXD |
+                        LPI2C_MTDR_DATA(*priv->ptr++));
+      priv->dcnt--;
+
+      /* Enable TX interrupt */
+
+      irq_config |= LPI2C_MIER_TDIE;
+    }
+  else
+    {
+      /* Set LPI2C in read mode */
+
+      nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MTDR_OFFSET,
+                        LPI2C_MTDR_CMD_RXD |
+                        LPI2C_MTDR_DATA((priv->dcnt - 1)));
+
+      /* Enable RX interrupt */
+
+      irq_config |= LPI2C_MIER_RDIE;
+    }
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MIER_OFFSET, irq_config);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_stop_transfer
+ *
+ * Description:
+ *  Stop an ongoing transfer amd signal the waiting thread
+ *
+ ****************************************************************************/
+
+static int nxxx_lpi2c_stop_transfer(struct nxxx_lpi2c_priv_s *priv)
+{
+  /* Mark that there are mo more messages to transfer */
+
+  priv->ptr = NULL;
+  priv->msgc = 0;
+  priv->dcnt = 0;
+
+#ifndef CONFIG_I2C_POLLED
+
+  /* Disable interrupts */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MIER_OFFSET,
+                       LPI2C_MIER_TDIE | LPI2C_MIER_RDIE |
+                       LPI2C_MIER_NDIE | LPI2C_MIER_ALIE |
+                       LPI2C_MIER_SDIE | LPI2C_MIER_EPIE, 0);
+
+  /* Inform the thread that transfer is complete
+   * and wake it up
+   */
+
+  if (priv->intstate == INTSTATE_WAITING)
+    {
+      nxsem_post(&priv->sem_isr);
+    }
+#endif
+
+  priv->intstate = INTSTATE_DONE;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_isr_process
+ *
+ * Description:
+ *  Common Interrupt Service Routine
+ *
+ ****************************************************************************/
+
+static int nxxx_lpi2c_isr_process(struct nxxx_lpi2c_priv_s *priv)
+{
+  uint32_t status = nxxx_lpi2c_getstatus(priv);
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+  uint32_t current_status = status;
+
+  if (priv->rxdma != NULL || priv->txdma != NULL)
+    {
+      /* Condition the status with only the enabled interrupts */
+
+      status &= nxxx_lpi2c_getenabledints(priv);
+
+      /* Is there an Error condition */
+
+      if (current_status & LPI2C_MSR_LIMITED_ERROR_MASK)
+        {
+          nxxx_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0);
+
+          /* Return the full error status */
+
+          priv->status = current_status;
+        }
+
+      /* End of packet or Stop */
+
+      if ((status & (LPI2C_MSR_SDF | LPI2C_MSR_EPF)) != 0)
+        {
+          nxxx_lpi2c_traceevent(priv, I2CEVENT_STOP, 0);
+
+          /* Acknowledge End of packet or Stop */
+
+          nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MSR_OFFSET, status &
+                                                           (LPI2C_MSR_SDF |
+                                                           LPI2C_MSR_EPF));
+
+          /* Mark that this transaction stopped */
+
+          priv->msgv = NULL;
+          priv->msgc = 0;
+          priv->dcnt = 0;
+
+          if (priv->intstate == INTSTATE_WAITING)
+            {
+              /* inform the thread that transfer is complete
+               * and wake it up
+               */
+
+              nxxx_dmach_stop(priv->txdma);
+              nxxx_dmach_stop(priv->rxdma);
+
+              priv->intstate = INTSTATE_DONE;
+              nxsem_post(&priv->sem_isr);
+            }
+        }
+
+      /* Clear the error */
+
+      nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MSR_OFFSET,
+                        (current_status & (LPI2C_MSR_NDF |
+                                           LPI2C_MSR_ALF |
+                                           LPI2C_MSR_FEF)));
+      return OK;
+    }
+
+#endif
+
+  /* Check for new trace setup */
+
+  nxxx_lpi2c_tracenew(priv, status);
+
+  /* Check for errors */
+
+  /* Ignore NACK on RX last byte - this is normal */
+
+  if ((status & (LPI2C_MSR_RDF | LPI2C_MSR_NDF)) ==
+      (LPI2C_MSR_RDF | LPI2C_MSR_NDF) && priv->dcnt == 1)
+    {
+      nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MSR_OFFSET, LPI2C_MSR_NDF);
+      status &= ~LPI2C_MSR_NDF;
+    }
+
+  /* Handle rest of the errors */
+
+  if ((status & LPI2C_MSR_ERROR_MASK) != 0)
+    {
+      nxxx_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0);
+
+      /* Clear the TX and RX FIFOs */
+
+      nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCR_OFFSET, 0,
+                           LPI2C_MCR_RTF | LPI2C_MCR_RRF);
+
+      /* Clear the error */
+
+      nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MSR_OFFSET,
+                        status & LPI2C_MSR_ERROR_MASK);
+
+      /* If there is no stop condition on the bus, abort (send stop).
+       * Otherwise stop the transfer now.
+       */
+
+      if ((status & LPI2C_MSR_SDF) == 0)
+        {
+          /* Disable RX and TX interrupts */
+
+          nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MIER_OFFSET,
+                               LPI2C_MIER_TDIE | LPI2C_MIER_TDIE, 0);
+
+          /* Abort any ongoing transfer, this also sends stop on the bus */
+
+          nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCFGR0_OFFSET, 0,
+                               LPI2C_MCFG0_ABORT);
+        }
+      else
+        {
+          nxxx_lpi2c_stop_transfer(priv);
+        }
+
+      /* Mark that there are no more messages to process */
+
+      priv->status = status;
+      priv->msgc = 0;
+      priv->dcnt = 0;
+
+      return OK;
+    }
+
+  /* Check for end of packet or stop */
+
+  if (status & (LPI2C_MSR_EPF | LPI2C_MSR_SDF))
+    {
+      /* Reset them both */
+
+      nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MSR_OFFSET,
+                        status & (LPI2C_MSR_EPF | LPI2C_MSR_SDF));
+
+      /* Process more messages or signal the thread */
+
+      if (priv->msgc > 1)
+        {
+          priv->msgc--;
+          priv->msgv++;
+          nxxx_lpi2c_start_message(priv);
+        }
+      else
+        {
+          nxxx_lpi2c_stop_transfer(priv);
+        }
+
+      return OK;
+    }
+
+  /* Check if there are bytes to send */
+
+  if ((priv->flags & I2C_M_READ) == 0 && (status & LPI2C_MSR_TDF) != 0)
+    {
+      if (priv->dcnt > 0)
+        {
+          nxxx_lpi2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->dcnt);
+          nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MTDR_OFFSET,
+                            LPI2C_MTDR_CMD_TXD |
+                            LPI2C_MTDR_DATA(*priv->ptr++));
+          priv->dcnt--;
+        }
+      else if ((priv->flags & I2C_M_NOSTOP) == 0)
+        {
+          nxxx_lpi2c_sendstop(priv);
+        }
+    }
+
+  /* Check if there are received bytes */
+
+  else if ((status & LPI2C_MSR_RDF) != 0 && priv->dcnt > 0)
+    {
+      nxxx_lpi2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->dcnt);
+
+      /* No interrupts or context switches should occur in the
+       * following sequence. Otherwise, additional bytes may be
+       * sent by the device.
+       */
+
+#ifdef CONFIG_I2C_POLLED
+      irqstate_t flags = enter_critical_section();
+#endif
+
+      /* Receive a byte */
+
+      *priv->ptr++ = nxxx_lpi2c_getreg(priv, NXXX_LPI2C_MRDR_OFFSET) &
+        LPI2C_MRDR_DATA_MASK;
+
+      priv->dcnt--;
+      if (priv->dcnt == 0 && (priv->flags & I2C_M_NOSTOP) == 0)
+        {
+          nxxx_lpi2c_sendstop(priv);
+        }
+
+#ifdef CONFIG_I2C_POLLED
+      leave_critical_section(flags);
+#endif
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_isr
+ *
+ * Description:
+ *   Common I2C interrupt service routine
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_I2C_POLLED
+static int nxxx_lpi2c_isr(int irq, void *context, void *arg)
+{
+  struct nxxx_lpi2c_priv_s *priv = (struct nxxx_lpi2c_priv_s *)arg;
+
+  DEBUGASSERT(priv != NULL);
+  return nxxx_lpi2c_isr_process(priv);
+}
+#endif
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_clock_enable
+ *
+ * Description:
+ *   Ungate LPI2C clock
+ *
+ ****************************************************************************/
+
+static void nxxx_lpi2c_clock_enable(struct nxxx_lpi2c_priv_s *priv)
+{
+  nxxx_set_clock_gate(priv->config->clk_gate, true);
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_clock_disable
+ *
+ * Description:
+ *   Gate LPI2C clock
+ *
+ ****************************************************************************/
+
+void nxxx_lpi2c_clock_disable(struct nxxx_lpi2c_priv_s *priv)
+{
+  nxxx_set_clock_gate(priv->config->clk_gate, false);
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_init
+ *
+ * Description:
+ *   Setup the I2C hardware, ready for operation with defaults
+ *
+ ****************************************************************************/
+
+static int nxxx_lpi2c_init(struct nxxx_lpi2c_priv_s *priv)
+{
+  /* Power-up and configure GPIOs */
+
+  /* Configure pins */
+
+  nxxx_port_configure(priv->config->scl_pin);
+  nxxx_port_configure(priv->config->sda_pin);
+
+  /* Enable power and reset the peripheral */
+
+  nxxx_set_periphclock(priv->config->clk_regs, priv->config->clk_source, 1);
+  nxxx_lpi2c_clock_enable(priv);
+
+  /* Set FLEXCOMM as LPI2C */
+
+  putreg32(FLEXCOMM_PSELID_PERSEL_I2C, priv->config->psel_reg);
+
+  /* Reset LPI2C before configuring it */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MCR_OFFSET, LPI2C_MCR_RST);
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MCR_OFFSET, 0);
+
+  /* Disable doze mode (Set DOZEN bit in 1 to disable) */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MCR_OFFSET, LPI2C_MCR_DOZEN);
+
+  /* Disable host request */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCFGR0_OFFSET,
+                       LPI2C_MCFG0_HREN | LPI2C_MCFG0_HRSEL,
+                       LPI2C_MCFG0_HRPOL);
+
+  /* Disable AUTOSTOP and turn NAK Ignore off */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCFGR1_OFFSET,
+                       LPI2C_MCFGR1_IGNACK | LPI2C_MCFGR1_AUTOSTOP, 0);
+
+  /* Set tx and rx watermarks */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MFCR_OFFSET,
+                    LPI2C_MFCR_TXWATER(0) | LPI2C_MFCR_RXWATER(0));
+
+  /* Force a frequency update */
+
+  priv->frequency = 0;
+  nxxx_lpi2c_setclock(priv, 100000);
+
+  /* Set scl, sda glitch filters and busy idle */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MCFGR2_OFFSET,
+                    LPI2C_MCFG2_BUSIDLE(priv->config->busy_idle) |
+                    LPI2C_MCFG2_FILTSCL_CYCLES(priv->config->filtscl) |
+                    LPI2C_MCFG2_FILTSDA_CYCLES(priv->config->filtsda));
+
+  /* Set pin low cycles to 0 (disable) */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MCFGR3_OFFSET,
+                    LPI2C_MCFG3_PINLOW_CYCLES(0));
+
+  /* Attach ISRs */
+
+#ifndef CONFIG_I2C_POLLED
+  irq_attach(priv->config->irq, nxxx_lpi2c_isr, priv);
+  up_enable_irq(priv->config->irq);
+#endif
+
+  /* Enable I2C */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCR_OFFSET, 0, LPI2C_MCR_MEN);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_deinit
+ *
+ * Description:
+ *   Shutdown the I2C hardware
+ *
+ ****************************************************************************/
+
+static int nxxx_lpi2c_deinit(struct nxxx_lpi2c_priv_s *priv)
+{
+  /* Disable I2C */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCR_OFFSET, LPI2C_MCR_MEN, 0);
+
+  /* Reset LPI2C */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MCR_OFFSET, LPI2C_MCR_RST);
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MCR_OFFSET, 0);
+
+  /* Disable and detach interrupts */
+
+#ifndef CONFIG_I2C_POLLED
+  up_disable_irq(priv->config->irq);
+  irq_detach(priv->config->irq);
+#endif
+
+  /* Disable clocking */
+
+  nxxx_lpi2c_clock_disable(priv);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Device Driver Operations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_dma_command_configure
+ *
+ * Description:
+ *   Create a command TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+static int nxxx_lpi2c_dma_command_configure(struct nxxx_lpi2c_priv_s *priv,
+                                            uint16_t *ccmd, uint32_t ncmd)
+{
+  struct nxxx_edma_xfrconfig_s config;
+  memset(&config, 0, sizeof(config));
+
+  config.saddr  = (uintptr_t) ccmd;
+  config.daddr  = priv->config->base + NXXX_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 nxxx_dmach_xfrsetup(priv->txdma, &config);
+}
+#endif
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_dma_data_configure
+ *
+ * Description:
+ *   Create a data TCD
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+static int nxxx_lpi2c_dma_data_configure(struct nxxx_lpi2c_priv_s *priv,
+                                         struct i2c_msg_s *msg)
+{
+  DMACH_HANDLE dma;
+  struct nxxx_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 + NXXX_LPI2C_MRDR_OFFSET;
+      config.daddr  = (uintptr_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  = (uintptr_t) msg->buffer;
+      config.daddr  = priv->config->base + NXXX_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 nxxx_dmach_xfrsetup(dma, &config) ? 0 : msg->length;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_form_command_list
+ *
+ * Description:
+ *   Form the DMA command list
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+static int nxxx_lpi2c_form_command_list(struct nxxx_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: nxxx_lpi2c_dma_transfer
+ *
+ * Description:
+ *   DMA based I2C transfer function
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+static int nxxx_lpi2c_dma_transfer(struct nxxx_lpi2c_priv_s *priv)
+{
+  int m;
+  int ntotcmds = 0;
+  int ncmds = 0;
+  uint16_t *ccmnd = NULL;
+
+  /* Disable Interrupts */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MIER_OFFSET, 0);
+
+  /* Disable DMA */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MDER_OFFSET, LPI2C_MDER_TDDE |
+                                                     LPI2C_MDER_RDDE, 0);
+
+  /* Enable AUTOSTOP and NAK Ignore */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCFGR1_OFFSET, 0,
+                       LPI2C_MCFGR1_IGNACK | LPI2C_MCFGR1_AUTOSTOP);
+
+  /* Form chains of TCDs 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 = nxxx_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 */
+
+          nxxx_lpi2c_dma_command_configure(priv, ccmnd, ncmds - ntotcmds);
+
+          ntotcmds += ncmds;
+
+          DEBUGASSERT(ntotcmds < CONFIG_NXXX_LPI2C_DMA_MAXMSG);
+
+          nxxx_lpi2c_dma_data_configure(priv, &priv->msgv[m]);
+        }
+    }
+
+  /* Clear the TX and RX FIFOs */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCR_OFFSET, 0,
+                       LPI2C_MCR_RTF | LPI2C_MCR_RRF);
+
+  /* Reset the Error bits */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MSR_OFFSET, LPI2C_MSR_NDF |
+                                                 LPI2C_MSR_ALF |
+                                                 LPI2C_MSR_FEF);
+
+  /* Enable the Interrupts */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MIER_OFFSET,
+                    LPI2C_MIER_NDIE | LPI2C_MIER_ALIE |
+                    LPI2C_MIER_PLTIE);
+
+  /* Start The DMA */
+
+  nxxx_dmach_start(priv->rxdma, nxxx_rxdma_callback, (void *)priv);
+  nxxx_dmach_start(priv->txdma, nxxx_txdma_callback, (void *)priv);
+
+  /* Enable the DMA Request */
+
+  nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MDER_OFFSET, 0,
+                       LPI2C_MDER_TDDE | LPI2C_MDER_RDDE);
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_transfer
+ *
+ * Description:
+ *   Generic I2C transfer function
+ *
+ ****************************************************************************/
+
+static int nxxx_lpi2c_transfer(struct i2c_master_s *dev,
+                               struct i2c_msg_s *msgs, int count)
+{
+  struct nxxx_lpi2c_priv_s *priv = (struct nxxx_lpi2c_priv_s *)dev;
+  int ret;
+#ifdef CONFIG_NXXX_LPI2C_DMA
+  int m;
+#endif
+
+  DEBUGASSERT(count > 0);
+
+  /* Ensure that address or flags don't change meanwhile */
+
+  ret = nxmutex_lock(&priv->lock);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  /* Clear any pending error interrupts */
+
+  nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MSR_OFFSET, 0xffffffff);
+
+  /* Old transfers are done */
+
+  /* Reset ptr and dcnt to ensure an unexpected data interrupt doesn't
+   * overwrite stale data.
+   */
+
+  priv->dcnt  = 0;
+  priv->ptr   = NULL;
+
+  priv->msgv  = msgs;
+  priv->msgc  = count;
+  priv->flags = msgs->flags;
+
+  i2cinfo("Flags %x, len %d\n", msgs->flags, msgs->length);
+
+  /* Reset I2C trace logic */
+
+  nxxx_lpi2c_tracereset(priv);
+
+  /* Set I2C clock frequency */
+
+  nxxx_lpi2c_setclock(priv, msgs->frequency);
+
+  priv->status = 0;
+
+  priv->intstate = INTSTATE_WAITING;
+
+  /* Wait for an ISR, if there was a timeout, fetch latest status to get
+   * the BUSY flag.
+   */
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+  if (priv->rxdma || priv->txdma)
+    {
+      nxxx_lpi2c_dma_transfer(priv);
+    }
+  else
+#endif
+    {
+      nxxx_lpi2c_start_message(priv);
+    }
+
+  if (nxxx_lpi2c_sem_waitdone(priv) < 0)
+    {
+#ifdef CONFIG_NXXX_LPI2C_DMA
+      if (priv->rxdma != NULL)
+        {
+          nxxx_dmach_stop(priv->rxdma);
+        }
+
+      if (priv->txdma != NULL)
+        {
+          nxxx_dmach_stop(priv->txdma);
+        }
+
+#endif
+      ret = -ETIMEDOUT;
+      i2cerr("ERROR: Timed out: MSR: status: 0x0%" PRIx32 "\n",
+             priv->status);
+
+      /* Stop the ongoing transfer and clear the FIFOs */
+
+      nxxx_lpi2c_stop_transfer(priv);
+
+      nxxx_lpi2c_modifyreg(priv, NXXX_LPI2C_MCR_OFFSET, 0,
+                           LPI2C_MCR_RTF | LPI2C_MCR_RRF);
+
+      /* Clear any errors */
+
+      nxxx_lpi2c_putreg(priv, NXXX_LPI2C_MSR_OFFSET, LPI2C_MSR_ERROR_MASK);
+
+      /* Reset the semaphore. There is a race between interrupts and
+       * sem_waitdone, and the semaphore is anyhow posted one extra time in
+       * nxxx_lpi2c_stop_transfer above
+       */
+
+      nxsem_reset(&priv->sem_isr, 0);
+    }
+
+  /* Check for error status conditions */
+
+  else if ((priv->status & LPI2C_MSR_ERROR_MASK) != 0)
+    {
+      /* LPI2C_MSR_ERROR_MASK is the 'OR' of the following individual bits: */
+
+      if (priv->status & LPI2C_MSR_ALF)
+        {
+          /* Arbitration Lost (master mode) */
+
+          i2cerr("Arbitration lost\n");
+          ret = -EAGAIN;
+        }
+      else if (priv->status & LPI2C_MSR_NDF)
+        {
+          /* Acknowledge Failure */
+
+          i2cerr("Ack failure\n");
+          ret = -ENXIO;
+        }
+      else
+        {
+          /* FIFO Error */
+
+          i2cerr("FIFO error\n");
+          ret = -EINVAL;
+        }
+    }
+
+  /* Dump the trace result */
+
+  nxxx_lpi2c_tracedump(priv);
+
+  /* Ensure that any ISR happening after we finish can't overwrite any user
+   * data.
+   */
+
+  priv->dcnt = 0;
+  priv->ptr = NULL;
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+  if (priv->rxdma)
+    {
+      for (m = 0; m < count; m++)
+        {
+          if (msgs[m].flags & I2C_M_READ)
+            {
+              up_invalidate_dcache((uintptr_t)msgs[m].buffer,
+                                   (uintptr_t)msgs[m].buffer +
+                                              msgs[m].length);
+            }
+        }
+    }
+#endif
+
+  nxmutex_unlock(&priv->lock);
+  return ret;
+}
+
+/****************************************************************************
+ * Name: nxxx_lpi2c_reset
+ *
+ * Description:
+ *   Perform an I2C bus reset in an attempt to break loose stuck I2C devices.
+ *
+ * Input Parameters:
+ *   dev   - Device-specific state data
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_I2C_RESET
+static int nxxx_lpi2c_reset(struct i2c_master_s *dev)
+{
+  struct nxxx_lpi2c_priv_s *priv = (struct nxxx_lpi2c_priv_s *)dev;
+  unsigned int clock_count;
+  unsigned int stretch_count;
+  uint32_t scl_gpio;
+  uint32_t sda_gpio;
+  uint32_t frequency;
+  int ret;
+
+  DEBUGASSERT(dev);
+
+  /* Our caller must own a ref */
+
+  DEBUGASSERT(priv->refs > 0);
+
+  /* Lock out other clients */
+
+  ret = nxmutex_lock(&priv->lock);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  ret = -EIO;
+
+  /* Save the current frequency */
+
+  frequency = priv->frequency;
+
+  /* De-init the port */
+
+  nxxx_lpi2c_deinit(priv);
+
+  /* Use GPIO configuration to un-wedge the bus */
+
+  nxxx_port_configure(priv->config->scl_pin, true);
+  nxxx_port_configure(priv->config->sda_pin, true);
+
+  scl_gpio = priv->config->reset_scl_pin;
+  sda_gpio = priv->config->reset_sda_pin;
+
+  nxxx_config_gpio(scl_gpio);
+  nxxx_config_gpio(sda_gpio);
+
+  /* Let SDA go high */
+
+  nxxx_gpio_write(sda_gpio, 1);
+
+  /* Clock the bus until any slaves currently driving it let it go. */
+
+  clock_count = 0;
+  while (!nxxx_gpio_read(sda_gpio))
+    {
+      /* Give up if we have tried too hard */
+
+      if (clock_count++ > 10)
+        {
+          goto out;
+        }
+
+      /* Sniff to make sure that clock stretching has finished.
+       *
+       * If the bus never relaxes, the reset has failed.
+       */
+
+      stretch_count = 0;
+      while (!nxxx_gpio_read(scl_gpio))
+        {
+          /* Give up if we have tried too hard */
+
+          if (stretch_count++ > 10)
+            {
+              goto out;
+            }
+
+          up_udelay(10);
+        }
+
+      /* Drive SCL low */
+
+      nxxx_gpio_write(scl_gpio, 0);
+      up_udelay(10);
+
+      /* Drive SCL high again */
+
+      nxxx_gpio_write(scl_gpio, 1);
+      up_udelay(10);
+    }
+
+  /* Generate a start followed by a stop to reset slave
+   * state machines.
+   */
+
+  nxxx_gpio_write(sda_gpio, 0);
+  up_udelay(10);
+  nxxx_gpio_write(scl_gpio, 0);
+  up_udelay(10);
+  nxxx_gpio_write(scl_gpio, 1);
+  up_udelay(10);
+  nxxx_gpio_write(sda_gpio, 1);
+  up_udelay(10);
+
+  /* Re-init the port */
+
+  nxxx_lpi2c_init(priv);
+
+  /* Restore the frequency */
+
+  nxxx_lpi2c_setclock(priv, frequency);
+  ret = OK;
+
+out:
+
+  /* Release the port for reuse by other clients */
+
+  nxmutex_unlock(&priv->lock);
+  return ret;
+}
+#endif /* CONFIG_I2C_RESET */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxxx_i2cbus_initialize
+ *
+ * Description:
+ *   Initialize one I2C bus
+ *
+ ****************************************************************************/
+
+struct i2c_master_s *nxxx_i2cbus_initialize(int port)
+{
+  struct nxxx_lpi2c_priv_s * priv = NULL;
+  irqstate_t flags;
+
+  /* Get I2C private structure */
+
+  switch (port)
+    {
+#ifdef CONFIG_NXXX_LPI2C0
+    case 0:
+      priv = (struct nxxx_lpi2c_priv_s *)&nxxx_lpi2c0_priv;
+      break;
+#endif
+#ifdef CONFIG_NXXX_LPI2C1
+    case 1:
+      priv = (struct nxxx_lpi2c_priv_s *)&nxxx_lpi2c1_priv;
+      break;
+#endif
+#ifdef CONFIG_NXXX_LPI2C2
+    case 2:
+      priv = (struct nxxx_lpi2c_priv_s *)&nxxx_lpi2c2_priv;
+      break;
+#endif
+#ifdef CONFIG_NXXX_LPI2C3
+    case 3:
+      priv = (struct nxxx_lpi2c_priv_s *)&nxxx_lpi2c3_priv;
+      break;
+#endif
+#ifdef CONFIG_NXXX_LPI2C4
+    case 4:
+      priv = (struct nxxx_lpi2c_priv_s *)&nxxx_lpi2c4_priv;
+      break;
+#endif
+#ifdef CONFIG_NXXX_LPI2C5
+    case 5:
+      priv = (struct nxxx_lpi2c_priv_s *)&nxxx_lpi2c5_priv;
+      break;
+#endif
+#ifdef CONFIG_NXXX_LPI2C6
+    case 6:
+      priv = (struct nxxx_lpi2c_priv_s *)&nxxx_lpi2c6_priv;
+      break;
+#endif
+#ifdef CONFIG_NXXX_LPI2C7
+    case 7:
+      priv = (struct nxxx_lpi2c_priv_s *)&nxxx_lpi2c7_priv;
+      break;
+#endif
+    default:
+      return NULL;
+    }
+
+  /* Initialize private data for the first time, increment reference count,
+   * power-up hardware and configure GPIOs.
+   */
+
+  flags = enter_critical_section();
+
+  if ((volatile int)priv->refs++ == 0)
+    {
+      nxxx_lpi2c_init(priv);
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+      if (priv->config->dma_txreqsrc != 0)
+        {
+          priv->txdma = nxxx_dmach_alloc(priv->config->dma_txreqsrc, 0);
+          DEBUGASSERT(priv->txdma != NULL);
+        }
+
+      if (priv->config->dma_rxreqsrc != 0)
+        {
+          priv->rxdma = nxxx_dmach_alloc(priv->config->dma_rxreqsrc, 0);
+          DEBUGASSERT(priv->rxdma != NULL);
+        }
+#endif
+    }
+
+  leave_critical_section(flags);
+
+  return (struct i2c_master_s *)priv;
+}
+
+/****************************************************************************
+ * Name: nxxx_i2cbus_uninitialize
+ *
+ * Description:
+ *   Uninitialize an I2C bus
+ *
+ ****************************************************************************/
+
+int nxxx_i2cbus_uninitialize(struct i2c_master_s *dev)
+{
+  struct nxxx_lpi2c_priv_s *priv = (struct nxxx_lpi2c_priv_s *)dev;
+  irqstate_t flags;
+
+  DEBUGASSERT(dev);
+
+  /* Decrement reference count and check for underflow */
+
+  if (priv->refs == 0)
+    {
+      return ERROR;
+    }
+
+  flags = enter_critical_section();
+
+  if (--priv->refs > 0)
+    {
+      leave_critical_section(flags);
+      return OK;
+    }
+
+  leave_critical_section(flags);
+
+  /* Disable power and other HW resource (GPIO's) */
+
+#ifdef CONFIG_NXXX_LPI2C_DMA
+  if (priv->rxdma != NULL)
+    {
+      nxxx_dmach_stop(priv->rxdma);
+      nxxx_dmach_free(priv->rxdma);
+      priv->rxdma = NULL;
+    }
+
+  if (priv->txdma != NULL)
+    {
+      nxxx_dmach_stop(priv->txdma);
+      nxxx_dmach_free(priv->txdma);
+      priv->txdma = NULL;
+    }
+#endif
+
+  nxxx_lpi2c_deinit(priv);
+
+  return OK;
+}
+
+#endif /* CONFIG_NXXX_LPI2C */
diff --git a/boards/arm/mcx-nxxx/frdm-mcxn236/include/board.h 
b/arch/arm/src/mcx-nxxx/nxxx_lpi2c.h
similarity index 61%
copy from boards/arm/mcx-nxxx/frdm-mcxn236/include/board.h
copy to arch/arm/src/mcx-nxxx/nxxx_lpi2c.h
index 2a6177386c..7634338680 100644
--- a/boards/arm/mcx-nxxx/frdm-mcxn236/include/board.h
+++ b/arch/arm/src/mcx-nxxx/nxxx_lpi2c.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * boards/arm/mcx-nxxx/frdm-mcxn236/include/board.h
+ * arch/arm/src/mcx-nxxx/nxxx_lpi2c.h
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -20,64 +20,54 @@
  *
  ****************************************************************************/
 
-#ifndef __BOARDS_ARM_MCX_NXXX_FRDM_MCXN236_INCLUDE_BOARD_H
-#define __BOARDS_ARM_MCX_NXXX_FRDM_MCXN236_INCLUDE_BOARD_H
+#ifndef __ARCH_ARM_SRC_MCX_NXXX_NXXX_LPI2C_H
+#define __ARCH_ARM_SRC_MCX_NXXX_NXXX_LPI2C_H
 
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
 #include <nuttx/config.h>
+#include <nuttx/i2c/i2c_master.h>
 
 /****************************************************************************
- * Pre-processor Definitions
+ * Public Function Prototypes
  ****************************************************************************/
 
-#define PORT_LPUART4_RX PORT_CFG(1, 8, PORT_PCR_MUX_ALT2 | PORT_PCR_IBE)
-#define PORT_LPUART4_TX PORT_CFG(1, 9, PORT_PCR_MUX_ALT2 | PORT_PCR_IBE)
-
 /****************************************************************************
- * Public Data
+ * Name: nxxx_i2cbus_initialize
+ *
+ * Description:
+ *   Initialize the selected I2C port. And return a unique instance of struct
+ *   struct i2c_master_s.  This function may be called to obtain multiple
+ *   instances of the interface, each of which may be set up with a
+ *   different frequency and slave address.
+ *
+ * Input Parameters:
+ *   Port number (for hardware that has multiple I2C interfaces)
+ *
+ * Returned Value:
+ *   Valid I2C device structure reference on success; a NULL on failure
+ *
  ****************************************************************************/
 
-#ifndef __ASSEMBLY__
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C"
-{
-#else
-#define EXTERN extern
-#endif
+struct i2c_master_s *nxxx_i2cbus_initialize(int port);
 
 /****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Name: nxxx_boardinitialize
+ * Name: nxxx_i2cbus_uninitialize
  *
  * Description:
- *   All architectures must provide the following entry point.  This
- *   entry point is called in the initialization phase -- after
- *   imx_memory_initialize and after all memory has been configured and
- *   mapped but before any devices have been initialized.
+ *   De-initialize the selected I2C port, and power down the device.
  *
  * Input Parameters:
- *   None
+ *   Device structure as returned by the nxxx_i2cbus_initialize()
  *
  * Returned Value:
- *   None
+ *   OK on success, ERROR when internal reference count mismatch or dev
+ *   points to invalid hardware device.
  *
  ****************************************************************************/
 
-void nxxx_boardinitialize(void);
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
+int nxxx_i2cbus_uninitialize(struct i2c_master_s *dev);
 
-#endif /* __ASSEMBLY__ */
-#endif /* __BOARDS_ARM_MCX_NXXX_FRDM_MCXN236_INCLUDE_BOARD_H */
+#endif /* __ARCH_ARM_SRC_MCX_NXXX_LPI2C_H */
diff --git a/boards/arm/mcx-nxxx/frdm-mcxn236/configs/nsh/defconfig 
b/boards/arm/mcx-nxxx/frdm-mcxn236/configs/nsh/defconfig
index 723f80cc0d..d4b1492537 100644
--- a/boards/arm/mcx-nxxx/frdm-mcxn236/configs/nsh/defconfig
+++ b/boards/arm/mcx-nxxx/frdm-mcxn236/configs/nsh/defconfig
@@ -31,6 +31,7 @@ CONFIG_INTELHEX_BINARY=y
 CONFIG_LIBC_LOCALTIME=y
 CONFIG_LPUART4_SERIAL_CONSOLE=y
 CONFIG_NXXX_LPUART4=y
+CONFIG_NXXX_LPI2C0=y
 CONFIG_NSH_ARCHINIT=y
 CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_DISABLE_IFUPDOWN=y
diff --git a/boards/arm/mcx-nxxx/frdm-mcxn236/include/board.h 
b/boards/arm/mcx-nxxx/frdm-mcxn236/include/board.h
index 2a6177386c..8186939cc2 100644
--- a/boards/arm/mcx-nxxx/frdm-mcxn236/include/board.h
+++ b/boards/arm/mcx-nxxx/frdm-mcxn236/include/board.h
@@ -36,6 +36,9 @@
 #define PORT_LPUART4_RX PORT_CFG(1, 8, PORT_PCR_MUX_ALT2 | PORT_PCR_IBE)
 #define PORT_LPUART4_TX PORT_CFG(1, 9, PORT_PCR_MUX_ALT2 | PORT_PCR_IBE)
 
+#define PORT_LPI2C0_SCL PORT_CFG(4, 1, PORT_PCR_MUX_ALT2 | PORT_PCR_IBE)
+#define PORT_LPI2C0_SDA PORT_CFG(4, 0, PORT_PCR_MUX_ALT2 | PORT_PCR_IBE)
+
 /****************************************************************************
  * Public Data
  ****************************************************************************/

Reply via email to