You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/09/23 02:36:39 UTC

[incubator-nuttx] branch master updated: S32K1XX: Add LPI2C slave support

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

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


The following commit(s) were added to refs/heads/master by this push:
     new bbb2f1f  S32K1XX: Add LPI2C slave support
bbb2f1f is described below

commit bbb2f1f8c7091c33ada7cbedd75a2fa177286411
Author: Jari van Ewijk <ja...@nxp.com>
AuthorDate: Wed Sep 22 10:26:45 2021 +0200

    S32K1XX: Add LPI2C slave support
---
 arch/arm/src/s32k1xx/Kconfig               |  46 +-
 arch/arm/src/s32k1xx/Make.defs             |   1 +
 arch/arm/src/s32k1xx/s32k1xx_lpi2c.c       |  65 +-
 arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c | 931 +++++++++++++++++++++++++++++
 arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.h |  90 +++
 5 files changed, 1086 insertions(+), 47 deletions(-)

diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig
index 386aab3..ded70be 100644
--- a/arch/arm/src/s32k1xx/Kconfig
+++ b/arch/arm/src/s32k1xx/Kconfig
@@ -272,12 +272,12 @@ config S32K1XX_FTM7
 	select S32K1XX_FTM
 	depends on S32K1XX_HAVE_FTM7
 
-menuconfig S32K1XX_LPI2C0
+config S32K1XX_LPI2C0
 	bool "LPI2C0"
 	default n
 	select S32K1XX_LPI2C
 
-menuconfig S32K1XX_LPI2C1
+config S32K1XX_LPI2C1
 	bool "LPI2C1"
 	default n
 	select S32K1XX_LPI2C
@@ -627,7 +627,7 @@ config S32K1XX_LPSPI_DWORD
 	
 endmenu # LPSPI Configuration
 
-menu "LPI2C0 Configuration"
+menu "LPI2C0 Master Configuration"
 	depends on S32K1XX_LPI2C0
 
 config LPI2C0_BUSYIDLE
@@ -642,9 +642,26 @@ config LPI2C0_FILTSDA
 	int "I2C master digital glitch filters for SDA input in clock cycles"
 	default 0
 
-endmenu # LPI2C0 Configuration
+endmenu # LPI2C0 Master Configuration
 
-menu "LPI2C1 Configuration"
+menu "LPI2C0 Slave Configuration"
+	depends on S32K1XX_LPI2C0
+
+config LPI2C0_SLAVE_ADDRESS
+	int "7-bit I2C address in decimal"
+	default 8
+	range 8 119
+
+config LPI2C0_SLAVE_BUS
+	bool "Separate I2C slave bus"
+	default n
+	---help---
+		When selected, the LPI2C slave will use separate SDA/SCL pins from
+		the LPI2C master.  These pins need to be defined in the board.h.
+
+endmenu # LPI2C0 Slave Configuration
+
+menu "LPI2C1 Master Configuration"
 	depends on S32K1XX_LPI2C1
 
 config LPI2C1_BUSYIDLE
@@ -659,7 +676,24 @@ config LPI2C1_FILTSDA
 	int "I2C master digital glitch filters for SDA input in clock cycles"
 	default 0
 
-endmenu # LPI2C1 Configuration
+endmenu # LPI2C1 Master Configuration
+
+menu "LPI2C1 Slave Configuration"
+	depends on S32K1XX_LPI2C1
+
+config LPI2C1_SLAVE_ADDRESS
+	int "7-bit I2C address in decimal"
+	default 9
+	range 8 119
+
+config LPI2C1_SLAVE_BUS
+	bool "Separate I2C slave bus"
+	default n
+	---help---
+		When selected, the LPI2C slave will use separate SDA/SCL pins from
+		the LPI2C master.  These pins need to be defined in the board.h.
+
+endmenu # LPI2C1 Slave Configuration
 
 menu "Ethernet Configuration"
 	depends on S32K1XX_ENET
diff --git a/arch/arm/src/s32k1xx/Make.defs b/arch/arm/src/s32k1xx/Make.defs
index fb252ea..1362f46 100644
--- a/arch/arm/src/s32k1xx/Make.defs
+++ b/arch/arm/src/s32k1xx/Make.defs
@@ -67,6 +67,7 @@ endif
 
 ifeq ($(CONFIG_S32K1XX_LPI2C),y)
 CHIP_CSRCS += s32k1xx_lpi2c.c
+CHIP_CSRCS += s32k1xx_lpi2c_slave.c
 endif
 
 ifeq ($(CONFIG_S32K1XX_LPSPI),y)
diff --git a/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c b/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c
index e820688..690f5d4 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_lpi2c.c
@@ -105,22 +105,11 @@
 #  define CONFIG_I2C_NTRACE 32
 #endif
 
-#ifdef CONFIG_I2C_SLAVE
-#  error I2C slave logic is not supported yet for S32K1XX
-#endif
-
 #define LPI2C_MASTER    1
 #define LPI2C_SLAVE     2
 
-#define MKI2C_OUTPUT(p) (((p) & GPIO_PADMUX_MASK) | \
-                         IOMUX_OPENDRAIN | IOMUX_DRIVE_33OHM | \
-                         IOMUX_SLEW_SLOW | (5 << GPIO_ALT_SHIFT) | \
-                         IOMUX_PULL_NONE | GPIO_OUTPUT_ONE)
-
-#define MKI2C_INPUT(p) (((p) & GPIO_PADMUX_MASK) | \
-                        IOMUX_DRIVE_HIZ | IOMUX_SLEW_SLOW | \
-                        IOMUX_CMOS_INPUT | (5 << GPIO_ALT_SHIFT) | \
-                        IOMUX_PULL_NONE)
+#define MKI2C_OUTPUT(p) (((p) & (~_PIN_MODE_MASK)) | GPIO_OUTPUT | GPIO_OUTPUT_ONE)
+#define MKI2C_INPUT(p)  (((p) & (~_PIN_MODE_MASK)) | GPIO_INPUT)
 
 /****************************************************************************
  * Private Types
@@ -142,10 +131,10 @@ enum s32k1xx_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_RCVBYTE,       /* Read more data, 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_STOP,          /* Last byte sent, send stop, param = 0 */
   I2CEVENT_ERROR          /* Error occurred, param = 0 */
 };
 
@@ -160,7 +149,7 @@ struct s32k1xx_trace_s
   clock_t time;                  /* First of event or first status */
 };
 
-/* I2C Device hardware configuration */
+/* I2C device hardware configuration */
 
 struct s32k1xx_lpi2c_config_s
 {
@@ -270,7 +259,7 @@ static inline void
 static inline uint32_t
   s32k1xx_lpi2c_getstatus(FAR struct s32k1xx_lpi2c_priv_s *priv);
 
-static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s * priv);
+static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s *priv);
 
 #ifndef CONFIG_I2C_POLLED
 static int s32k1xx_lpi2c_isr(int irq, void *context, FAR void *arg);
@@ -308,9 +297,9 @@ static const char *g_trace_names[] =
 
 static const struct i2c_ops_s s32k1xx_lpi2c_ops =
 {
-  .transfer = s32k1xx_lpi2c_transfer
+  .transfer = s32k1xx_lpi2c_transfer,
 #ifdef CONFIG_I2C_RESET
-  , .reset  = s32k1xx_lpi2c_reset
+  .reset  = s32k1xx_lpi2c_reset,
 #endif
 };
 
@@ -325,11 +314,7 @@ static const struct s32k1xx_lpi2c_config_s s32k1xx_lpi2c0_config =
   .filtsda    = CONFIG_LPI2C0_FILTSDA,
   .scl_pin    = PIN_LPI2C0_SCL,
   .sda_pin    = PIN_LPI2C0_SDA,
-#ifndef CONFIG_I2C_SLAVE
   .mode       = LPI2C_MASTER,
-#else
-  .mode       = LPI2C_SLAVE,
-#endif
 #ifndef CONFIG_I2C_POLLED
   .irq        = S32K1XX_IRQ_LPI2C0M,
 #endif
@@ -346,9 +331,9 @@ static struct s32k1xx_lpi2c_priv_s s32k1xx_lpi2c0_priv =
   .ptr        = NULL,
   .dcnt       = 0,
   .flags      = 0,
-  .status     = 0
+  .status     = 0,
 };
-#endif
+#endif /* CONFIG_S32K1XX_LPI2C0 */
 
 #ifdef CONFIG_S32K1XX_LPI2C1
 static const struct s32k1xx_lpi2c_config_s s32k1xx_lpi2c1_config =
@@ -359,11 +344,7 @@ static const struct s32k1xx_lpi2c_config_s s32k1xx_lpi2c1_config =
   .filtsda    = CONFIG_LPI2C1_FILTSDA,
   .scl_pin    = PIN_LPI2C1_SCL,
   .sda_pin    = PIN_LPI2C1_SDA,
-#ifndef CONFIG_I2C_SLAVE
   .mode       = LPI2C_MASTER,
-#else
-  .mode       = LPI2C_SLAVE,
-#endif
 #ifndef CONFIG_I2C_POLLED
   .irq        = S32K1XX_IRQ_LPI2C1M,
 #endif
@@ -380,9 +361,9 @@ static struct s32k1xx_lpi2c_priv_s s32k1xx_lpi2c1_priv =
   .ptr        = NULL,
   .dcnt       = 0,
   .flags      = 0,
-  .status     = 0
+  .status     = 0,
 };
-#endif
+#endif /* CONFIG_S32K1XX_LPI2C1 */
 
 /****************************************************************************
  * Private Functions
@@ -592,12 +573,14 @@ static inline int
       s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MIER_OFFSET, 0);
     }
 
+#if 0
   /* Enable Interrupts when slave mode */
 
   else
     {
       s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_SIER_OFFSET, 0);
     }
+#endif
 
   leave_critical_section(flags);
   return ret;
@@ -1199,7 +1182,7 @@ static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s *priv)
 
   s32k1xx_lpi2c_tracenew(priv, status);
 
-  /* After an error we can get an SDF  */
+  /* After an error we can get a STOP Detect Flag  */
 
   if (priv->intstate == INTSTATE_DONE && (status & LPI2C_MSR_SDF) != 0)
     {
@@ -1238,7 +1221,7 @@ static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s *priv)
         {
           s32k1xx_lpi2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->dcnt);
 
-          /* No interrupts or context switches should occur in the following
+          /* No interrupts or contex switches should occur in the following
            * sequence. Otherwise, additional bytes may be sent by the device.
            */
 
@@ -1272,9 +1255,9 @@ static int s32k1xx_lpi2c_isr_process(struct s32k1xx_lpi2c_priv_s *priv)
     {
       if (priv->msgc > 0 && priv->msgv != NULL)
         {
-          priv->ptr        = priv->msgv->buffer;
-          priv->dcnt    = priv->msgv->length;
-          priv->flags    = priv->msgv->flags;
+          priv->ptr   = priv->msgv->buffer;
+          priv->dcnt  = priv->msgv->length;
+          priv->flags = priv->msgv->flags;
 
           if ((priv->msgv->flags & I2C_M_NOSTART) == 0)
             {
@@ -1431,9 +1414,9 @@ static int s32k1xx_lpi2c_isr(int irq, void *context, FAR void *arg)
 
 static int s32k1xx_lpi2c_init(FAR struct s32k1xx_lpi2c_priv_s *priv)
 {
-  /* Power-up and configure GPIOs .
+  /* Power-up and configure pins.
    *
-   * NOTE: Clocking to the LPSPI peripheral must be provided by
+   * NOTE: Clocking to the LPI2C peripheral must be provided by
    * board-specific logic as part of the clock configuration logic.
    */
 
@@ -1447,7 +1430,7 @@ static int s32k1xx_lpi2c_init(FAR struct s32k1xx_lpi2c_priv_s *priv)
   s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MCR_OFFSET, LPI2C_MCR_RST);
   s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MCR_OFFSET, 0);
 
-  /* Disable doze mode (Set DOZEN bit in 1 to disable) */
+  /* Disable doze mode (Set DOZEN bit to 1 to disable) */
 
   s32k1xx_lpi2c_putreg(priv, S32K1XX_LPI2C_MCR_OFFSET, LPI2C_MCR_DOZEN);
 
@@ -1585,7 +1568,7 @@ static int s32k1xx_lpi2c_transfer(FAR struct i2c_master_s *dev,
 
   priv->status = 0;
 
-  /* Wait for an ISR, if there was a timeout, fetch latest status to get
+  /* Wait for ISR. If there was a timeout, fetch latest status to get
    * the BUSY flag.
    */
 
@@ -1820,7 +1803,7 @@ FAR struct i2c_master_s *s32k1xx_i2cbus_initialize(int port)
     }
 
   /* Initialize private data for the first time, increment reference count,
-   * power-up hardware and configure GPIOs.
+   * power-up hardware and configure pins.
    */
 
   flags = enter_critical_section();
diff --git a/arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c b/arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c
new file mode 100644
index 0000000..18a839d
--- /dev/null
+++ b/arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c
@@ -0,0 +1,931 @@
+/****************************************************************************
+ * arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.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/i2c/i2c_slave.h>
+
+#include <arch/irq.h>
+
+#include "arm_arch.h"
+
+#include "s32k1xx_pin.h"
+#include "hardware/s32k1xx_pinmux.h"
+#include "s32k1xx_lpi2c.h"
+#include "s32k1xx_lpi2c_slave.h"
+#include "s32k1xx_periphclocks.h"
+
+#include <arch/board/board.h>
+
+/* At least one I2C peripheral must be enabled, as well as the I2C slave */
+
+#if defined(CONFIG_S32K1XX_LPI2C) && defined(CONFIG_I2C_SLAVE)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_CHIP_S32K11X
+#warning LPI2C slave logic does not support S32K11X (yet)
+#endif
+
+#ifdef CONFIG_I2C_POLLED
+#warning LPI2C slave logic does not support polling (yet)
+#endif
+
+#ifdef CONFIG_I2C_TRACE
+#warning LPI2C slave logic does not support I2C trace debugging (yet)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* I2C slave device hardware configuration */
+
+struct s32k1xx_lpi2c_slave_config_s
+{
+  uint32_t base;      /* LPI2C base address */
+  bool     slave_bus; /* Separate I2C slave bus? */
+  uint32_t scl_pin;   /* GPIO configuration for SCL as SCL */
+  uint32_t sda_pin;   /* GPIO configuration for SDA as SDA */
+  uint32_t irq;       /* Event IRQ */
+};
+
+/* I2C slave device private data */
+
+struct s32k1xx_lpi2c_slave_priv_s
+{
+  const struct i2c_slaveops_s *ops;                  /* I2C slave operations */
+  const struct s32k1xx_lpi2c_slave_config_s *config; /* LPI2C slave configuration */
+
+  int slave_addr; /* I2C address of the slave */
+  int addr_nbits; /* 7- or 10-bit addressing */
+
+  uint8_t *read_buffer; /* Read buffer (master wants to write, slave will read data) */
+  int read_buflen;      /* Read buffer size */
+  int read_bufindex;    /* Read buffer index */
+
+  const uint8_t *write_buffer; /* Write buffer (master wants to read, slave will write data) */
+  int write_buflen;            /* Write buffer size */
+  int write_bufindex;          /* Write buffer index */
+
+  int (*callback)(FAR void *arg); /* Callback function when data has been received */
+  void *callback_arg;             /* Argument of callback function */
+
+  int refs; /* Reference count */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static inline uint32_t s32k1xx_lpi2c_slave_getreg(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv, uint16_t offset);
+static inline void s32k1xx_lpi2c_slave_putreg(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv, uint16_t offset,
+  uint32_t value);
+static inline void s32k1xx_lpi2c_slave_modifyreg(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv, uint16_t offset,
+  uint32_t clearbits, uint32_t setbits);
+
+static int s32k1xx_lpi2c_slave_isr_process(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv);
+static int s32k1xx_lpi2c_slave_isr(int irq, void *context, FAR void *arg);
+
+static int s32k1xx_lpi2c_slave_init(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv);
+static int s32k1xx_lpi2c_slave_deinit(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv);
+
+static int s32k1xx_lpi2c_setownaddress(FAR struct i2c_slave_s *dev, int addr,
+                                       int nbits);
+static int s32k1xx_lpi2c_write(FAR struct i2c_slave_s *dev,
+                               FAR const uint8_t *buffer, int buflen);
+static int s32k1xx_lpi2c_read(FAR struct i2c_slave_s *dev,
+                              FAR uint8_t *buffer, int buflen);
+static int s32k1xx_lpi2c_registercallback(FAR struct i2c_slave_s *dev,
+                                          int (*callback)(FAR void *arg),
+                                          FAR void *arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* I2C slave interface */
+
+static const struct i2c_slaveops_s s32k1xx_lpi2c_slaveops =
+{
+  .setownaddress    = s32k1xx_lpi2c_setownaddress,
+  .write            = s32k1xx_lpi2c_write,
+  .read             = s32k1xx_lpi2c_read,
+  .registercallback = s32k1xx_lpi2c_registercallback,
+};
+
+/* I2C device structures */
+
+#ifdef CONFIG_S32K1XX_LPI2C0
+static const struct s32k1xx_lpi2c_slave_config_s s32k1xx_lpi2c0s_config =
+{
+  .base      = S32K1XX_LPI2C0_BASE,
+
+#ifdef CONFIG_LPI2C0_SLAVE_BUS
+  .slave_bus = true,
+  .scl_pin   = PIN_LPI2C0_SCLS,
+  .sda_pin   = PIN_LPI2C0_SDAS,
+#else
+  .slave_bus = false,
+  .scl_pin   = PIN_LPI2C0_SCL,
+  .sda_pin   = PIN_LPI2C0_SDA,
+#endif
+
+  .irq       = S32K1XX_IRQ_LPI2C0S,
+};
+
+static struct s32k1xx_lpi2c_slave_priv_s s32k1xx_lpi2c0s_priv =
+{
+  .ops            = &s32k1xx_lpi2c_slaveops,
+  .config         = &s32k1xx_lpi2c0s_config,
+  .slave_addr     = CONFIG_LPI2C0_SLAVE_ADDRESS,
+  .addr_nbits     = 7,
+  .read_buffer    = NULL,
+  .read_buflen    = 0,
+  .read_bufindex  = 0,
+  .write_buffer   = NULL,
+  .write_buflen   = 0,
+  .write_bufindex = 0,
+  .callback       = NULL,
+  .callback_arg   = NULL,
+  .refs           = 0,
+};
+#endif /* CONFIG_S32K1XX_LPI2C0 */
+
+#ifdef CONFIG_S32K1XX_LPI2C1
+static const struct s32k1xx_lpi2c_slave_config_s s32k1xx_lpi2c1s_config =
+{
+  .base      = S32K1XX_LPI2C1_BASE,
+
+#ifdef CONFIG_LPI2C1_SLAVE_BUS
+  .slave_bus = true,
+  .scl_pin   = PIN_LPI2C1S_SCL,
+  .sda_pin   = PIN_LPI2C1S_SDA,
+#else
+  .slave_bus = false,
+  .scl_pin   = PIN_LPI2C1_SCL,
+  .sda_pin   = PIN_LPI2C1_SDA,
+#endif
+
+  .irq       = S32K1XX_IRQ_LPI2C1S,
+};
+
+static struct s32k1xx_lpi2c_slave_priv_s s32k1xx_lpi2c1s_priv =
+{
+  .ops            = &s32k1xx_lpi2c_slaveops,
+  .config         = &s32k1xx_lpi2c1s_config,
+  .slave_addr     = CONFIG_LPI2C1_SLAVE_ADDRESS,
+  .addr_nbits     = 7,
+  .read_buffer    = NULL,
+  .read_buflen    = 0,
+  .read_bufindex  = 0,
+  .write_buffer   = NULL,
+  .write_buflen   = 0,
+  .write_bufindex = 0,
+  .callback       = NULL,
+  .callback_arg   = NULL,
+  .refs           = 0,
+};
+#endif /* CONFIG_S32K1XX_LPI2C1 */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_slave_getreg
+ *
+ * Description:
+ *   Get a 32-bit register value by offset
+ *
+ * Input Parameters:
+ *   priv   - I2C slave device private data
+ *   offset - Register offset with respect to the base address of the I2C
+ *            peripheral
+ *
+ * Returned Value:
+ *   The 32-bit value retrieved from the register
+ *
+ ****************************************************************************/
+
+static inline uint32_t s32k1xx_lpi2c_slave_getreg(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv, uint16_t offset)
+{
+  return getreg32(priv->config->base + offset);
+}
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_slave_putreg
+ *
+ * Description:
+ *  Put a 32-bit register value by offset
+ *
+ * Input Parameters:
+ *   priv   - I2C slave device private data
+ *   offset - Register offset with respect to the base address of the I2C
+ *            peripheral
+ *   value  - The 32-bit value that should be put into the register
+ *
+ ****************************************************************************/
+
+static inline void s32k1xx_lpi2c_slave_putreg(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv, uint16_t offset,
+  uint32_t value)
+{
+  putreg32(value, priv->config->base + offset);
+}
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_slave_modifyreg
+ *
+ * Description:
+ *   Modify a 32-bit register value by offset
+ *
+ * Input Parameters:
+ *   priv      - I2C slave device private data
+ *   offset    - Register offset with respect to the base address of the I2C
+ *               peripheral
+ *   clearbits - Bitmask with the bits that should be cleared (put to 0)
+ *   setbits   - Bitmask with the bits that should be set (put to 1)
+ *
+ ****************************************************************************/
+
+static inline void s32k1xx_lpi2c_slave_modifyreg(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv, uint16_t offset,
+  uint32_t clearbits, uint32_t setbits)
+{
+  modifyreg32(priv->config->base + offset, clearbits, setbits);
+}
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_slave_isr_process
+ *
+ * Description:
+ *   Process LPI2C slave interrupts.  Check for relevant flags and read or
+ *   write data to buffers.  After a block of data has been received a
+ *   callback function (if any) may be invoked, which might install a new
+ *   write buffer to transmit data when requested.
+ *
+ * Input Parameters:
+ *   priv - I2C slave device private data
+ *
+ * Returned Value:
+ *   OK when successful, or a negated errno when there is an error.
+ *
+ ****************************************************************************/
+
+static int s32k1xx_lpi2c_slave_isr_process(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv)
+{
+  uint32_t status = s32k1xx_lpi2c_slave_getreg(priv,
+                                               S32K1XX_LPI2C_SSR_OFFSET);
+
+  /* Slave Address Valid Flag */
+
+  if (status & LPI2C_SSR_AVF)
+    {
+      /* A new transfer was initiated by a bus master.  The transfer request
+       * was addressed to this particular device.  It needs to be checked if
+       * the master wants to read or write.
+       */
+
+      uint16_t address = (uint16_t) (s32k1xx_lpi2c_slave_getreg(priv,
+        S32K1XX_LPI2C_SASR_OFFSET) & LPI2C_SASR_RADDR_MASK);
+
+      if (address & I2CS_READBIT)
+        {
+          /* Master wants to read, so the slave needs to write/transmit.
+           * The Transmit Data Interrupt will only be enabled now, see
+           * erratum 10792.  Also reset the buffer index back to zero to
+           * start sending again from the beginning.
+           */
+
+          s32k1xx_lpi2c_slave_modifyreg(priv, S32K1XX_LPI2C_SIER_OFFSET, 0,
+                                        LPI2C_SIER_TDIE);
+
+          priv->write_bufindex = 0;
+        }
+      else
+        {
+          /* Master wants to write, so the slave needs to read.  The Receive
+           * Data Interrupt remains enabled, so just reset the buffer index.
+           */
+
+          priv->read_bufindex = 0;
+        }
+    }
+
+  /* Slave Transmits Data Flag (master wants to read) */
+
+  if (status & LPI2C_SSR_TDF)
+    {
+      /* Make sure that interrupts are enabled for this event */
+
+      if (s32k1xx_lpi2c_slave_getreg(priv,
+        S32K1XX_LPI2C_SIER_OFFSET) & LPI2C_SIER_TDIE)
+        {
+          if (priv->write_buflen > priv->write_bufindex)
+            {
+              /* Transmit data from buffer */
+
+              s32k1xx_lpi2c_slave_putreg(priv, S32K1XX_LPI2C_STDR_OFFSET,
+                (uint32_t) priv->write_buffer[priv->write_bufindex]);
+              priv->write_bufindex++;
+            }
+          else
+            {
+              /* Beyond the buffer length.  Transmit dummy data... */
+
+              s32k1xx_lpi2c_slave_putreg(priv, S32K1XX_LPI2C_STDR_OFFSET, 0);
+            }
+        }
+    }
+
+  /* Slave Receives Data (master wants to write) */
+
+  if (status & LPI2C_SSR_RDF)
+    {
+      /* Make sure that interrupts are enabled for this event */
+
+      if (s32k1xx_lpi2c_slave_getreg(priv,
+        S32K1XX_LPI2C_SIER_OFFSET) & LPI2C_SIER_RDIE)
+        {
+          if (priv->read_buflen > priv->read_bufindex)
+            {
+              /* Read data into buffer */
+
+              priv->read_buffer[priv->read_bufindex] =
+                (uint8_t) s32k1xx_lpi2c_slave_getreg(priv,
+                  S32K1XX_LPI2C_SRDR_OFFSET);
+              priv->read_bufindex++;
+            }
+          else
+            {
+              /* Dummy read, throw away the data */
+
+              s32k1xx_lpi2c_slave_getreg(priv, S32K1XX_LPI2C_SRDR_OFFSET);
+            }
+        }
+    }
+
+  /* Stop or Repeated Start (current transfer is over) */
+
+  if (s32k1xx_lpi2c_slave_getreg(priv, S32K1XX_LPI2C_SSR_OFFSET) & \
+      (LPI2C_SSR_SDF | LPI2C_SSR_RSF))
+    {
+      /* Clear Stop Detect / Repeated Start Flags */
+
+      s32k1xx_lpi2c_slave_putreg(priv, S32K1XX_LPI2C_SSR_OFFSET,
+                                 LPI2C_SSR_SDF | LPI2C_SSR_RSF);
+
+      /* Disable the Transmit Data Interrupt again, see erratum 10792 */
+
+      s32k1xx_lpi2c_slave_modifyreg(priv, S32K1XX_LPI2C_SIER_OFFSET,
+                                    LPI2C_SIER_TDIE, 0);
+
+      /* Execute the registered callback function if data was received */
+
+      if ((priv->read_bufindex > 0) && (priv->callback != NULL))
+        {
+          priv->callback(priv->callback_arg);
+        }
+    }
+
+  /* Slave Bit Error (abort current transfer) */
+
+  if (s32k1xx_lpi2c_slave_getreg(priv, S32K1XX_LPI2C_SSR_OFFSET) & \
+      LPI2C_SSR_BEF)
+    {
+      /* Clear Bit Error Flag */
+
+      s32k1xx_lpi2c_slave_putreg(priv, S32K1XX_LPI2C_SSR_OFFSET,
+                                 LPI2C_SSR_BEF);
+
+      /* Disable the Transmit Data Interrupt again, see erratum 10792 */
+
+      s32k1xx_lpi2c_slave_modifyreg(priv, S32K1XX_LPI2C_SIER_OFFSET,
+                                    LPI2C_SIER_TDIE, 0);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_slave_isr
+ *
+ * Description:
+ *   Interrupt Service Routine for LPI2C slave devices.  Retrieves the
+ *   private data from the argument, further processing is done by
+ *   s32k1xx_lpi2c_slave_isr_process().
+ *
+ * Input Parameters:
+ *   irq     - Number of the IRQ that generated the interrupt
+ *   context - Interrupt register state save info (architecture-specific)
+ *   arg     - I2C slave device private data
+ *
+ * Returned Value:
+ *   OK when successful, or a negated errno when there is an error.
+ *
+ ****************************************************************************/
+
+static int s32k1xx_lpi2c_slave_isr(int irq, void *context, FAR void *arg)
+{
+  struct s32k1xx_lpi2c_slave_priv_s *priv =
+    (struct s32k1xx_lpi2c_slave_priv_s *)arg;
+
+  DEBUGASSERT(priv != NULL);
+
+  return s32k1xx_lpi2c_slave_isr_process(priv);
+}
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_slave_init
+ *
+ * Description:
+ *   Initialize the LPI2C slave device.  Enable and configure the peripheral
+ *   and enable the interrupts and attach handlers.
+ *
+ * Input Parameters:
+ *   priv - I2C slave device private data
+ *
+ * Returned Value:
+ *   OK when successful, or a negated errno when there is an error.
+ *
+ ****************************************************************************/
+
+static int s32k1xx_lpi2c_slave_init(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv)
+{
+  int ret;
+
+  /* Reset LPI2C slave mode logic before configuring it */
+
+  s32k1xx_lpi2c_slave_putreg(priv, S32K1XX_LPI2C_SCR_OFFSET, LPI2C_SCR_RST);
+  s32k1xx_lpi2c_slave_putreg(priv, S32K1XX_LPI2C_SCR_OFFSET, 0);
+
+  /* Configure pins and power up peripheral.
+   *
+   * NOTE: Clocking to the LPI2C peripheral must be provided by
+   * board-specific logic as part of the clock configuration logic.
+   */
+
+  ret = s32k1xx_pinconfig(priv->config->scl_pin);
+  if (ret != OK)
+    {
+      return ret;
+    }
+
+  ret = s32k1xx_pinconfig(priv->config->sda_pin);
+  if (ret != OK)
+    {
+      return ret;
+    }
+
+  /* Choose between a combined or separated LPI2C master and slave.  When a
+   * separate slave bus is selected, the LPI2C slave will use different pins
+   * than the LPI2C master.  These pins should be defined in board.h
+   */
+
+  if (priv->config->slave_bus)
+    {
+      s32k1xx_lpi2c_slave_modifyreg(priv, S32K1XX_LPI2C_MCFGR1_OFFSET,
+        LPI2C_MCFGR1_PINCFG_MASK, LPI2C_MCFGR1_PINCFG4);
+    }
+  else
+    {
+      s32k1xx_lpi2c_slave_modifyreg(priv, S32K1XX_LPI2C_MCFGR1_OFFSET,
+        LPI2C_MCFGR1_PINCFG_MASK, LPI2C_MCFGR1_PINCFG0);
+    }
+
+  /* Configure slave address
+   *
+   * TO DO: Allow 10-bit addressing
+   */
+
+  s32k1xx_lpi2c_slave_modifyreg(priv, S32K1XX_LPI2C_SAMR_OFFSET, 0,
+                                LPI2C_SAMR_ADDR0(priv->slave_addr));
+
+  /* Enable clock stretching */
+
+  s32k1xx_lpi2c_slave_modifyreg(priv, S32K1XX_LPI2C_SCFGR1_OFFSET, 0,
+    LPI2C_SCFGR1_ADRSTALL | LPI2C_SCFGR1_RXSTALL | LPI2C_SCFGR1_TXSTALL);
+
+  /* Configure LPI2C slave interrupts */
+
+  s32k1xx_lpi2c_slave_modifyreg(priv, S32K1XX_LPI2C_SIER_OFFSET, 0,
+    LPI2C_SIER_RDIE | LPI2C_SIER_AVIE | LPI2C_SIER_RSIE | LPI2C_SIER_SDIE | \
+    LPI2C_SIER_BEIE);
+
+  /* Attach ISR and enable interrupt */
+
+  ret = irq_attach(priv->config->irq, s32k1xx_lpi2c_slave_isr, priv);
+  if (ret != OK)
+    {
+      return ret;
+    }
+
+  up_enable_irq(priv->config->irq);
+
+  /* Enable I2C slave */
+
+  s32k1xx_lpi2c_slave_modifyreg(priv, S32K1XX_LPI2C_SCR_OFFSET, 0,
+                                LPI2C_SCR_SEN);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_slave_deinit
+ *
+ * Description:
+ *   Deinitialize the LPI2C slave device.  Disable and reset the peripheral
+ *   and disable the interrupts and attached handlers.
+ *
+ * Input Parameters:
+ *   priv - I2C slave device private data
+ *
+ * Returned Value:
+ *   OK when successful, or a negated errno when there is an error.
+ *
+ ****************************************************************************/
+
+static int s32k1xx_lpi2c_slave_deinit(
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv)
+{
+  int ret;
+
+  /* Disable LPI2C slave */
+
+  s32k1xx_lpi2c_slave_modifyreg(priv, S32K1XX_LPI2C_SCR_OFFSET,
+                                LPI2C_SCR_SEN, 0);
+
+  /* Reset LPI2C slave */
+
+  s32k1xx_lpi2c_slave_putreg(priv, S32K1XX_LPI2C_SCR_OFFSET, LPI2C_SCR_RST);
+  s32k1xx_lpi2c_slave_putreg(priv, S32K1XX_LPI2C_SCR_OFFSET, 0);
+
+  /* Disable and detach interrupts */
+
+  up_disable_irq(priv->config->irq);
+  ret = irq_detach(priv->config->irq);
+  if (ret != OK)
+    {
+      return ret;
+    }
+
+  /* NOTE that clocking is left enabled */
+
+  return OK;
+}
+
+/****************************************************************************
+ * Device Driver Operations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_setownaddress
+ *
+ * Description:
+ *   Set our own I2C address.
+ *
+ *   One may register a callback to be notified about reception. During the
+ *   slave mode reception, the methods READ and WRITE must be used to
+ *   to handle reads and writes from a master.
+ *
+ * Input Parameters:
+ *   dev     - I2C slave device-specific state data
+ *   address - Our own slave address
+ *   nbits   - The number of address bits provided (7 or 10)
+ *
+ * Returned Value:
+ *   OK when successful, or a negated errno when there is an error.
+ *
+ ****************************************************************************/
+
+static int s32k1xx_lpi2c_setownaddress(FAR struct i2c_slave_s *dev, int addr,
+                                       int nbits)
+{
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv;
+  irqstate_t flags;
+
+  DEBUGASSERT(dev);
+  priv = (FAR struct s32k1xx_lpi2c_slave_priv_s *)dev;
+
+  flags = enter_critical_section();
+
+  /* Deinit slave before we change its configuration */
+
+  int ret = s32k1xx_lpi2c_slave_deinit(priv);
+  if (ret != OK)
+    {
+      leave_critical_section(flags);
+      return ret;
+    }
+
+  /* Modify configuration */
+
+  switch (nbits)
+    {
+      case 7:
+        {
+          priv->slave_addr = (addr & 0x7f);
+          priv->addr_nbits = 7;
+        }
+        break;
+
+      case 10:
+        {
+          priv->slave_addr = (addr & 0x03ff);
+          priv->addr_nbits = 10;
+        }
+        break;
+
+      default:
+        {
+          leave_critical_section(flags);
+          return ERROR;
+        }
+        break;
+    }
+
+  /* Reinitialize slave with the changed config */
+
+  s32k1xx_lpi2c_slave_init(priv);
+
+  leave_critical_section(flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_write
+ *
+ * Description:
+ *   Send a block of data on I2C when a bus master wants to read data from
+ *   this particular device.
+ *
+ * Input Parameters:
+ *   dev    - I2C slave device-specific state data
+ *   buffer - A pointer to the read-only buffer of data to be written to the
+ *            device
+ *   buflen - The number of bytes to send from the buffer
+ *
+ * Returned Value:
+ *   OK when successful, or a negated errno when there is an error.
+ *
+ ****************************************************************************/
+
+static int s32k1xx_lpi2c_write(FAR struct i2c_slave_s *dev,
+                               FAR const uint8_t *buffer, int buflen)
+{
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv;
+  irqstate_t flags;
+
+  DEBUGASSERT(dev);
+  priv = (FAR struct s32k1xx_lpi2c_slave_priv_s *)dev;
+
+  flags = enter_critical_section();
+
+  /* Update the registered buffer and length */
+
+  priv->write_buffer = buffer;
+  priv->write_buflen = buflen;
+
+  leave_critical_section(flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_read
+ *
+ * Description:
+ *   Receive a block of data from I2C when a bus master writes data addressed
+ *   to this particular device.
+ *
+ * Input Parameters:
+ *   dev    - I2C slave device-specific state data
+ *   buffer - A pointer to a buffer of data to receive the data from the
+ *            device
+ *   buflen - The maximum size of the buffer
+ *
+ * Returned Value:
+ *   OK when successful, or a negated errno when there is an error.
+ *
+ ****************************************************************************/
+
+static int s32k1xx_lpi2c_read(FAR struct i2c_slave_s *dev,
+                              FAR uint8_t *buffer, int buflen)
+{
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv;
+  irqstate_t flags;
+
+  DEBUGASSERT(dev);
+  priv = (FAR struct s32k1xx_lpi2c_slave_priv_s *)dev;
+
+  flags = enter_critical_section();
+
+  /* Update the registered buffer and length */
+
+  priv->read_buffer = buffer;
+  priv->read_buflen = buflen;
+
+  leave_critical_section(flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: s32k1xx_lpi2c_registercallback
+ *
+ * Description:
+ *   Register a callback function that will be invoked when something is
+ *   received on I2C.
+ *
+ * Input Parameters:
+ *   dev      - I2C slave device-specific state data
+ *   callback - The function to be called when something has been received.
+ *   arg      - User provided argument to be used with the callback
+ *
+ * Returned Value:
+ *   OK when successful, or a negated errno when there is an error.
+ *
+ ****************************************************************************/
+
+static int s32k1xx_lpi2c_registercallback(FAR struct i2c_slave_s *dev,
+  int (*callback)(FAR void *arg), FAR void *arg)
+{
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv;
+  irqstate_t flags;
+
+  DEBUGASSERT(dev);
+  priv = (FAR struct s32k1xx_lpi2c_slave_priv_s *)dev;
+
+  flags = enter_critical_section();
+
+  /* Update the registered callback and argument */
+
+  priv->callback = callback;
+  priv->callback_arg = arg;
+
+  leave_critical_section(flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: s32k1xx_i2cbus_slave_initialize
+ *
+ * Description:
+ *   Initialize the I2C slave device and increase the reference counter.
+ *   If the device has already been initialized only the reference counter
+ *   will be increased.
+ *
+ * Input Parameters:
+ *   port - Port number (for hardware that has multiple I2C interfaces).
+ *
+ * Returned Value:
+ *   A valid I2C device structure reference on success; a NULL on failure.
+ *
+ ****************************************************************************/
+
+FAR struct i2c_slave_s *s32k1xx_i2cbus_slave_initialize(int port)
+{
+  struct s32k1xx_lpi2c_slave_priv_s *priv;
+  irqstate_t flags;
+
+  /* Get I2C private structure */
+
+  switch (port)
+    {
+#ifdef CONFIG_S32K1XX_LPI2C0
+      case 0:
+        priv = (struct s32k1xx_lpi2c_slave_priv_s *)&s32k1xx_lpi2c0s_priv;
+        break;
+#endif
+
+#ifdef CONFIG_S32K1XX_LPI2C1
+      case 1:
+        priv = (struct s32k1xx_lpi2c_slave_priv_s *)&s32k1xx_lpi2c1s_priv;
+        break;
+#endif
+
+      default:
+        return NULL;
+    }
+
+  flags = enter_critical_section();
+
+  if ((volatile int) priv->refs == 0)
+    {
+      /* Initialize private data for the first time, increment reference
+       * count, power-up hardware and configure pins.
+       */
+
+      s32k1xx_lpi2c_slave_init(priv);
+    }
+
+  priv->refs++;
+
+  leave_critical_section(flags);
+
+  return (struct i2c_slave_s *)priv;
+}
+
+/****************************************************************************
+ * Name: s32k1xx_i2cbus_slave_uninitialize
+ *
+ * Description:
+ *   Decrease the reference counter of the I2C slave device.  When there are
+ *   no more references left the I2C slave device is unitialized.
+ *
+ * Input Parameters:
+ *   dev - Device structure as returned by s32k1xx_i2cbus_slave_initialize().
+ *
+ * Returned Value:
+ *   OK on success, ERROR when there is an internal reference count mismatch
+ *   or dev points to an invalid hardware device.
+ *
+ ****************************************************************************/
+
+int s32k1xx_i2cbus_slave_uninitialize(FAR struct i2c_slave_s *dev)
+{
+  FAR struct s32k1xx_lpi2c_slave_priv_s *priv =
+    (struct s32k1xx_lpi2c_slave_priv_s *)dev;
+  irqstate_t flags;
+
+  DEBUGASSERT(dev);
+
+  /* Check reference count for underflow, then decrement */
+
+  flags = enter_critical_section();
+
+  if (priv->refs == 0)
+    {
+      leave_critical_section(flags);
+      return ERROR;
+    }
+
+  priv->refs--;
+
+  if (priv->refs > 0)
+    {
+      leave_critical_section(flags);
+      return OK;
+    }
+
+  leave_critical_section(flags);
+
+  /* Disable power and other HW resources (pins) */
+
+  s32k1xx_lpi2c_slave_deinit(priv);
+
+  return OK;
+}
+
+#endif /* CONFIG_S32K1XX_LPI2C && CONFIG_I2C_SLAVE */
diff --git a/arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.h b/arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.h
new file mode 100644
index 0000000..d7839b1
--- /dev/null
+++ b/arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+ * arch/arm/src/s32k1xx/s32k1xx_lpi2c_slave.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_S32K1XX_S32K1XX_LPI2C_SLAVE_H
+#define __ARCH_ARM_SRC_S32K1XX_S32K1XX_LPI2C_SLAVE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/i2c/i2c_slave.h>
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: s32k1xx_i2cbus_slave_initialize
+ *
+ * Description:
+ *   Initialize the I2C slave device and increase the reference counter.
+ *   If the device has already been initialized only the reference counter
+ *   will be increased.
+ *
+ * Input Parameters:
+ *   port - Port number (for hardware that has multiple I2C interfaces).
+ *
+ * Returned Value:
+ *   A valid I2C device structure reference on success; a NULL on failure.
+ *
+ ****************************************************************************/
+
+FAR struct i2c_slave_s *s32k1xx_i2cbus_slave_initialize(int port);
+
+/****************************************************************************
+ * Name: s32k1xx_i2cbus_slave_uninitialize
+ *
+ * Description:
+ *   Decrease the reference counter of the I2C slave device.  When there are
+ *   no more references left the I2C slave device is unitialized.
+ *
+ * Input Parameters:
+ *   dev - Device structure as returned by s32k1xx_i2cbus_slave_initialize().
+ *
+ * Returned Value:
+ *   OK on success, ERROR when there is an internal reference count mismatch
+ *   or dev points to an invalid hardware device.
+ *
+ ****************************************************************************/
+
+int s32k1xx_i2cbus_slave_uninitialize(FAR struct i2c_slave_s *dev);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_S32K1XX_S32K1XX_LPI2C_SLAVE_H */