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

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

commit 7b590f9c4352e6d94acdf8e50b903b9482fb8a1b
Author: Piyush Patle <[email protected]>
AuthorDate: Tue Mar 31 03:21:46 2026 +0530

    espressif/rmt: replace rmtchar with arch-specific lirc adapter
    
    Replace the ESP-specific rmtchar upper-half with arch-local esp_lirc
    adapters for Xtensa and RISC-V.
    
     This moves the RMT upper-half out of drivers/rmt, registers LIRC
     devices from the ESP board bring-up paths, and removes the old common
     rmtchar driver and headers.
    
     Also update the ESP Kconfig and build wiring to build esp_lirc when
     ESP_RMT and DRIVERS_RC are enabled.
    
     Fixes discovered during hardware validation:
      - register TX as /dev/lirc1 so RX and TX do not collide
      - parse the RX worker thread argument from the correct argv slot
      - keep RX devices from advertising TX capability
    
    Signed-off-by: Piyush Patle <[email protected]>
---
 arch/risc-v/src/common/espressif/Kconfig           |  13 +-
 arch/risc-v/src/common/espressif/Make.defs         |   3 +
 arch/risc-v/src/common/espressif/esp_lirc.c        | 399 +++++++++++++++++++
 arch/risc-v/src/common/espressif/esp_lirc.h        |  48 +++
 arch/risc-v/src/common/espressif/esp_rmt.c         |   1 -
 arch/risc-v/src/common/espressif/esp_rmt.h         |  32 ++
 arch/risc-v/src/common/espressif/esp_ws2812.c      |   1 -
 arch/xtensa/src/common/espressif/Kconfig           |  13 +-
 arch/xtensa/src/common/espressif/Make.defs         |   3 +
 arch/xtensa/src/common/espressif/esp_lirc.c        | 441 +++++++++++++++++++++
 arch/xtensa/src/common/espressif/esp_lirc.h        |  56 +++
 arch/xtensa/src/common/espressif/esp_rmt.c         |   1 -
 arch/xtensa/src/common/espressif/esp_rmt.h         |  32 ++
 arch/xtensa/src/common/espressif/esp_ws2812.c      |   1 -
 boards/risc-v/esp32c3/common/src/esp_board_rmt.c   |  18 +-
 .../esp32c3/esp32c3-devkit/configs/rmt/defconfig   |   8 +-
 boards/risc-v/esp32c6/common/src/esp_board_rmt.c   |  18 +-
 .../esp32c6/esp32c6-devkitc/configs/rmt/defconfig  |   8 +-
 .../esp32c6/esp32c6-devkitm/configs/rmt/defconfig  |   8 +-
 boards/risc-v/esp32h2/common/src/esp_board_rmt.c   |  18 +-
 .../esp32h2/esp32h2-devkit/configs/rmt/defconfig   |   8 +-
 boards/risc-v/esp32p4/common/src/esp_board_rmt.c   |  18 +-
 .../configs/rmt/defconfig                          |   8 +-
 boards/xtensa/esp32/common/src/esp32_board_rmt.c   |  19 +-
 .../esp32/esp32-devkitc/configs/rmt/defconfig      |   7 +-
 .../xtensa/esp32s2/common/src/esp32s2_board_rmt.c  |  10 +-
 .../esp32s2/esp32s2-saola-1/configs/rmt/defconfig  |   7 +-
 .../xtensa/esp32s3/common/src/esp32s3_board_rmt.c  |  18 +-
 .../esp32s3/esp32s3-devkit/configs/rmt/defconfig   |   8 +-
 drivers/Kconfig                                    |   1 -
 drivers/rmt/CMakeLists.txt                         |  10 +-
 drivers/rmt/Kconfig                                |  43 --
 drivers/rmt/Make.defs                              |  11 -
 drivers/rmt/rmtchar.c                              | 341 ----------------
 include/nuttx/rmt/rmt.h                            |  98 -----
 include/nuttx/rmt/rmtchar.h                        |  94 -----
 36 files changed, 1124 insertions(+), 699 deletions(-)

diff --git a/arch/risc-v/src/common/espressif/Kconfig 
b/arch/risc-v/src/common/espressif/Kconfig
index 2c888d55f1b..b09c4674268 100644
--- a/arch/risc-v/src/common/espressif/Kconfig
+++ b/arch/risc-v/src/common/espressif/Kconfig
@@ -1288,13 +1288,24 @@ config ESPRESSIF_BROWNOUT_DET
 config ESP_RMT
        bool "Remote Control Module (RMT)"
        default n
-       depends on RMT
+       select DRIVERS_RC
        ---help---
                The RMT (Remote Control Transceiver) peripheral was designed to 
act as
                an infrared transceiver. However, due to the flexibility of its 
data
                format, RMT can be extended to a versatile and general-purpose
                transceiver, transmitting or receiving many other types of 
signals.
 
+if ESP_RMT
+
+config RMT_DEFAULT_RX_BUFFER_SIZE
+       int "Default RX buffer size"
+       default 100
+       ---help---
+               The RMT RX default buffer size. This is the expected buffer size
+               that should be returned on a receive operation.
+
+endif # ESP_RMT
+
 config ESP_SDM
        bool "Sigma-Delta Modulation (SDM) Module"
        default n
diff --git a/arch/risc-v/src/common/espressif/Make.defs 
b/arch/risc-v/src/common/espressif/Make.defs
index 9a204c4d7df..84c7ae7b30d 100644
--- a/arch/risc-v/src/common/espressif/Make.defs
+++ b/arch/risc-v/src/common/espressif/Make.defs
@@ -94,6 +94,9 @@ endif
 
 ifeq ($(CONFIG_ESP_RMT),y)
        CHIP_CSRCS += esp_rmt.c
+       ifeq ($(CONFIG_DRIVERS_RC),y)
+               CHIP_CSRCS += esp_lirc.c
+       endif
        ifeq ($(CONFIG_WS2812_NON_SPI_DRIVER),y)
                CHIP_CSRCS += esp_ws2812.c
        endif
diff --git a/arch/risc-v/src/common/espressif/esp_lirc.c 
b/arch/risc-v/src/common/espressif/esp_lirc.c
new file mode 100644
index 00000000000..51c7198f42d
--- /dev/null
+++ b/arch/risc-v/src/common/espressif/esp_lirc.c
@@ -0,0 +1,399 @@
+/****************************************************************************
+ * arch/risc-v/src/common/espressif/esp_lirc.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 <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <nuttx/circbuf.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/kthread.h>
+#include <nuttx/lirc.h>
+#include <nuttx/rc/lirc_dev.h>
+#include <nuttx/semaphore.h>
+
+#include "hal/rmt_types.h"
+
+#include "esp_rmt.h"
+#include "esp_lirc.h"
+
+#if defined(CONFIG_ESP_RMT) && defined(CONFIG_DRIVERS_RC)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* RMT channel clock: 10 MHz → 1 tick = 0.1 µs */
+
+#define RMT_TICK_TO_US(t)  ((t) / 10)
+#define RMT_US_TO_TICK(u)  ((u) * 10)
+
+/* DMA receive scratch buffer size (in bytes, must be multiple of 4) */
+
+#define LIRC_RX_BUF_BYTES  CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE
+
+/* Stack size for the RX worker thread */
+
+#define LIRC_RX_THREAD_STACK  2048
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct esp_lirc_dev_s
+{
+  struct lirc_lowerhalf_s lower;   /* Must be first — lirc upper-half iface */
+  FAR struct rmt_dev_s   *rmt;     /* ESP RMT lower-half */
+  volatile bool           running; /* RX thread keep-alive flag */
+  pid_t                   rxpid;   /* RX worker thread PID */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int  esp_lirc_open(FAR struct lirc_lowerhalf_s *lower);
+static void esp_lirc_close(FAR struct lirc_lowerhalf_s *lower);
+static int  esp_lirc_tx_ir(FAR struct lirc_lowerhalf_s *lower,
+                            FAR unsigned int *txbuf, unsigned int n);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct lirc_ops_s g_esp_lirc_rx_ops =
+{
+  .driver_type = LIRC_DRIVER_IR_RAW,
+  .open        = esp_lirc_open,
+  .close       = esp_lirc_close,
+};
+
+static const struct lirc_ops_s g_esp_lirc_tx_ops =
+{
+  .driver_type = LIRC_DRIVER_IR_RAW_TX,
+  .open        = esp_lirc_open,
+  .close       = esp_lirc_close,
+  .tx_ir       = esp_lirc_tx_ir,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_lirc_rx_thread
+ ****************************************************************************/
+
+static int esp_lirc_rx_thread(int argc, FAR char *argv[])
+{
+  FAR struct esp_lirc_dev_s *priv;
+  FAR const char *arg;
+  FAR char *rxbuf;
+  FAR rmt_symbol_word_t *sym;
+  unsigned int sample;
+  int nbytes;
+  int nsyms;
+  int i;
+
+  DEBUGASSERT(argc >= 2 && argv[argc - 1] != NULL);
+
+  arg = argv[argc - 1];
+  priv = (FAR struct esp_lirc_dev_s *)(uintptr_t)strtoul(arg, NULL, 16);
+
+  rxbuf = kmm_malloc(LIRC_RX_BUF_BYTES);
+  if (rxbuf == NULL)
+    {
+      rcerr("ERROR: out of memory for RX buffer\n");
+      return -ENOMEM;
+    }
+
+  while (priv->running)
+    {
+      if (priv->rmt->ops->read)
+        {
+          priv->rmt->ops->read(priv->rmt, rxbuf, LIRC_RX_BUF_BYTES);
+        }
+
+      nxsem_wait_uninterruptible(priv->rmt->recvsem);
+
+      if (!priv->running)
+        {
+          break;
+        }
+
+      while ((nbytes = circbuf_read(priv->rmt->circbuf,
+                                    rxbuf, LIRC_RX_BUF_BYTES)) > 0)
+        {
+          nsyms = nbytes / sizeof(rmt_symbol_word_t);
+          sym   = (FAR rmt_symbol_word_t *)rxbuf;
+
+          for (i = 0; i < nsyms; i++)
+            {
+              uint16_t dur0 = sym[i].duration0;
+              uint8_t  lvl0 = sym[i].level0;
+              uint16_t dur1 = sym[i].duration1;
+              uint8_t  lvl1 = sym[i].level1;
+
+              if (dur0 > 0)
+                {
+                  sample = lvl0 ?
+                    LIRC_PULSE(RMT_TICK_TO_US(dur0)) :
+                    LIRC_SPACE(RMT_TICK_TO_US(dur0));
+                  lirc_sample_event(&priv->lower, sample);
+                }
+
+              if (dur1 > 0)
+                {
+                  sample = lvl1 ?
+                    LIRC_PULSE(RMT_TICK_TO_US(dur1)) :
+                    LIRC_SPACE(RMT_TICK_TO_US(dur1));
+                  lirc_sample_event(&priv->lower, sample);
+                }
+            }
+        }
+    }
+
+  kmm_free(rxbuf);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp_lirc_open
+ ****************************************************************************/
+
+static int esp_lirc_open(FAR struct lirc_lowerhalf_s *lower)
+{
+  FAR struct esp_lirc_dev_s *priv =
+    (FAR struct esp_lirc_dev_s *)lower;
+  FAR char *argv[3];
+  char addrstr[20];
+  int ret = OK;
+
+  if (priv->rxpid > 0)
+    {
+      return OK;
+    }
+
+  if (priv->rmt->recvsem != NULL)
+    {
+      priv->running = true;
+
+      snprintf(addrstr, sizeof(addrstr), "%lx",
+               (unsigned long)(uintptr_t)priv);
+      argv[0] = "esp_lirc_rx";
+      argv[1] = addrstr;
+      argv[2] = NULL;
+
+      ret = kthread_create("esp_lirc_rx", SCHED_PRIORITY_DEFAULT,
+                           LIRC_RX_THREAD_STACK,
+                           esp_lirc_rx_thread, argv);
+      if (ret < 0)
+        {
+          priv->running = false;
+          rcerr("ERROR: kthread_create failed: %d\n", ret);
+          return ret;
+        }
+
+      priv->rxpid = ret;
+      ret = OK;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_lirc_close
+ ****************************************************************************/
+
+static void esp_lirc_close(FAR struct lirc_lowerhalf_s *lower)
+{
+  FAR struct esp_lirc_dev_s *priv =
+    (FAR struct esp_lirc_dev_s *)lower;
+
+  if (priv->rxpid > 0)
+    {
+      priv->running = false;
+
+      if (priv->rmt->recvsem != NULL)
+        {
+          nxsem_post(priv->rmt->recvsem);
+        }
+
+      priv->rxpid = -1;
+    }
+}
+
+/****************************************************************************
+ * Name: esp_lirc_tx_ir
+ ****************************************************************************/
+
+static int esp_lirc_tx_ir(FAR struct lirc_lowerhalf_s *lower,
+                          FAR unsigned int *txbuf, unsigned int n)
+{
+  FAR struct esp_lirc_dev_s *priv =
+    (FAR struct esp_lirc_dev_s *)lower;
+  FAR rmt_symbol_word_t *items;
+  unsigned int nwords;
+  unsigned int i;
+  int ret;
+
+  if (!priv->rmt->ops->write)
+    {
+      return -ENOSYS;
+    }
+
+  nwords = (n + 1) / 2;
+  items  = kmm_zalloc(nwords * sizeof(rmt_symbol_word_t));
+  if (items == NULL)
+    {
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < n; i++)
+    {
+      uint32_t us  = LIRC_VALUE(txbuf[i]);
+      uint8_t  lvl = LIRC_IS_PULSE(txbuf[i]) ? 1 : 0;
+      uint16_t tks = (uint16_t)RMT_US_TO_TICK(us);
+
+      if ((i & 1) == 0)
+        {
+          items[i / 2].duration0 = tks;
+          items[i / 2].level0    = lvl;
+        }
+      else
+        {
+          items[i / 2].duration1 = tks;
+          items[i / 2].level1    = lvl;
+        }
+    }
+
+  ret = priv->rmt->ops->write(priv->rmt,
+                              (FAR const char *)items,
+                              nwords * sizeof(rmt_symbol_word_t));
+
+  kmm_free(items);
+  return (ret < 0) ? ret : (int)n;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_lirc_rx_initialize
+ *
+ * Description:
+ *   Register a pre-initialized RMT RX channel as a LIRC raw IR device.
+ *
+ * Input Parameters:
+ *   devno - The LIRC device number (e.g. 0 for /dev/lirc0)
+ *   rmt   - An already-initialized RMT RX lower-half handle
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int esp_lirc_rx_initialize(int devno, FAR struct rmt_dev_s *rmt)
+{
+  FAR struct esp_lirc_dev_s *priv;
+  int ret;
+
+  DEBUGASSERT(rmt != NULL);
+
+  priv = kmm_zalloc(sizeof(struct esp_lirc_dev_s));
+  if (priv == NULL)
+    {
+      return -ENOMEM;
+    }
+
+  priv->lower.ops           = &g_esp_lirc_rx_ops;
+  priv->lower.buffer_bytes  = LIRC_RX_BUF_BYTES;
+  priv->lower.rx_resolution = 100; /* 0.1 µs = 100 ns */
+  priv->rmt                 = rmt;
+  priv->rxpid               = -1;
+
+  ret = lirc_register(&priv->lower, devno);
+  if (ret < 0)
+    {
+      rcerr("ERROR: lirc_register failed: %d\n", ret);
+      kmm_free(priv);
+      return ret;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp_lirc_tx_initialize
+ *
+ * Description:
+ *   Register a pre-initialized RMT TX channel as a LIRC raw TX device.
+ *
+ * Input Parameters:
+ *   devno - The LIRC device number (e.g. 0 for /dev/lirc0)
+ *   rmt   - An already-initialized RMT TX lower-half handle
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int esp_lirc_tx_initialize(int devno, FAR struct rmt_dev_s *rmt)
+{
+  FAR struct esp_lirc_dev_s *priv;
+  int ret;
+
+  DEBUGASSERT(rmt != NULL);
+
+  priv = kmm_zalloc(sizeof(struct esp_lirc_dev_s));
+  if (priv == NULL)
+    {
+      return -ENOMEM;
+    }
+
+  priv->lower.ops           = &g_esp_lirc_tx_ops;
+  priv->lower.tx_resolution = 100; /* 0.1 µs = 100 ns */
+  priv->rmt                 = rmt;
+  priv->rxpid               = -1;
+
+  ret = lirc_register(&priv->lower, devno);
+  if (ret < 0)
+    {
+      rcerr("ERROR: lirc_register failed: %d\n", ret);
+      kmm_free(priv);
+      return ret;
+    }
+
+  return OK;
+}
+
+#endif /* CONFIG_ESP_RMT && CONFIG_DRIVERS_RC */
diff --git a/arch/risc-v/src/common/espressif/esp_lirc.h 
b/arch/risc-v/src/common/espressif/esp_lirc.h
new file mode 100644
index 00000000000..2289f587c80
--- /dev/null
+++ b/arch/risc-v/src/common/espressif/esp_lirc.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+ * arch/risc-v/src/common/espressif/esp_lirc.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_RISC_V_SRC_COMMON_ESPRESSIF_ESP_LIRC_H
+#define __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_LIRC_H
+
+#include <nuttx/config.h>
+
+#include "esp_rmt.h"
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#if defined(CONFIG_ESP_RMT) && defined(CONFIG_DRIVERS_RC)
+
+int esp_lirc_rx_initialize(int devno, FAR struct rmt_dev_s *rmt);
+int esp_lirc_tx_initialize(int devno, FAR struct rmt_dev_s *rmt);
+
+#endif /* CONFIG_ESP_RMT && CONFIG_DRIVERS_RC */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_LIRC_H */
diff --git a/arch/risc-v/src/common/espressif/esp_rmt.c 
b/arch/risc-v/src/common/espressif/esp_rmt.c
index 83b47e9e9a2..5e7b17451e6 100644
--- a/arch/risc-v/src/common/espressif/esp_rmt.c
+++ b/arch/risc-v/src/common/espressif/esp_rmt.c
@@ -39,7 +39,6 @@
 #include <arch/board/board.h>
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
-#include <nuttx/rmt/rmt.h>
 #include <nuttx/spinlock.h>
 #include <nuttx/circbuf.h>
 
diff --git a/arch/risc-v/src/common/espressif/esp_rmt.h 
b/arch/risc-v/src/common/espressif/esp_rmt.h
index 2956db80b4b..ca40802f6d2 100644
--- a/arch/risc-v/src/common/espressif/esp_rmt.h
+++ b/arch/risc-v/src/common/espressif/esp_rmt.h
@@ -29,6 +29,10 @@
 
 #include <nuttx/config.h>
 #include <semaphore.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <nuttx/circbuf.h>
 #include <nuttx/spinlock.h>
 
 /****************************************************************************
@@ -51,6 +55,34 @@
  * Public Types
  ****************************************************************************/
 
+/* The RMT peripheral vtable */
+
+struct rmt_dev_s;
+
+struct rmt_ops_s
+{
+  CODE int      (*open)(FAR struct rmt_dev_s *dev);
+  CODE int      (*close)(FAR struct rmt_dev_s *dev);
+  CODE ssize_t  (*write)(FAR struct rmt_dev_s *dev,
+                         FAR const char *buffer,
+                         size_t buflen);
+  CODE ssize_t  (*read)(FAR struct rmt_dev_s *dev,
+                        FAR char *buffer,
+                        size_t buflen);
+};
+
+/* RMT device structure — initial fields visible to upper-half drivers.
+ * The ESP lower-half extends this with hardware-specific fields.
+ */
+
+struct rmt_dev_s
+{
+  FAR const struct rmt_ops_s *ops;
+  FAR struct circbuf_s       *circbuf;
+  sem_t                      *recvsem;
+  int                         minor;
+};
+
 /****************************************************************************
  * Public Data
  ****************************************************************************/
diff --git a/arch/risc-v/src/common/espressif/esp_ws2812.c 
b/arch/risc-v/src/common/espressif/esp_ws2812.c
index 1e4f74d9186..df1af76d1cd 100644
--- a/arch/risc-v/src/common/espressif/esp_ws2812.c
+++ b/arch/risc-v/src/common/espressif/esp_ws2812.c
@@ -31,7 +31,6 @@
 #include <nuttx/kmalloc.h>
 #include <nuttx/signal.h>
 #include <nuttx/leds/ws2812.h>
-#include <nuttx/rmt/rmt.h>
 
 #include "hal/rmt_types.h"
 
diff --git a/arch/xtensa/src/common/espressif/Kconfig 
b/arch/xtensa/src/common/espressif/Kconfig
index 91c097d614e..4200e515de3 100644
--- a/arch/xtensa/src/common/espressif/Kconfig
+++ b/arch/xtensa/src/common/espressif/Kconfig
@@ -71,13 +71,24 @@ endmenu # Interrupt Configuration
 config ESP_RMT
        bool "Remote Control Module (RMT)"
        default n
-       depends on RMT
+       select DRIVERS_RC
        ---help---
                The RMT (Remote Control Transceiver) peripheral was designed to 
act as
                an infrared transceiver. However, due to the flexibility of its 
data
                format, RMT can be extended to a versatile and general-purpose
                transceiver, transmitting or receiving many other types of 
signals.
 
+if ESP_RMT
+
+config RMT_DEFAULT_RX_BUFFER_SIZE
+       int "Default RX buffer size"
+       default 100
+       ---help---
+               The RMT RX default buffer size. This is the expected buffer size
+               that should be returned on a receive operation.
+
+endif # ESP_RMT
+
 config ESP_MCPWM
        bool "Motor Control PWM (MCPWM)"
        default n
diff --git a/arch/xtensa/src/common/espressif/Make.defs 
b/arch/xtensa/src/common/espressif/Make.defs
index 2b6f5161a80..57d8dad6a2d 100644
--- a/arch/xtensa/src/common/espressif/Make.defs
+++ b/arch/xtensa/src/common/espressif/Make.defs
@@ -26,6 +26,9 @@ CFLAGS += -Wno-shadow -Wno-undef
 
 ifeq ($(CONFIG_ESP_RMT),y)
 CHIP_CSRCS += esp_rmt.c
+ifeq ($(CONFIG_DRIVERS_RC),y)
+CHIP_CSRCS += esp_lirc.c
+endif
 ifeq ($(CONFIG_WS2812_NON_SPI_DRIVER),y)
 CHIP_CSRCS += esp_ws2812.c
 endif
diff --git a/arch/xtensa/src/common/espressif/esp_lirc.c 
b/arch/xtensa/src/common/espressif/esp_lirc.c
new file mode 100644
index 00000000000..b0a2076310f
--- /dev/null
+++ b/arch/xtensa/src/common/espressif/esp_lirc.c
@@ -0,0 +1,441 @@
+/****************************************************************************
+ * arch/xtensa/src/common/espressif/esp_lirc.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 <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <nuttx/circbuf.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/kthread.h>
+#include <nuttx/lirc.h>
+#include <nuttx/rc/lirc_dev.h>
+#include <nuttx/semaphore.h>
+
+#include "hal/rmt_types.h"
+
+#include "esp_rmt.h"
+#include "esp_lirc.h"
+
+#if defined(CONFIG_ESP_RMT) && defined(CONFIG_DRIVERS_RC)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* RMT channel clock: 10 MHz → 1 tick = 0.1 µs */
+
+#define RMT_TICK_TO_US(t)  ((t) / 10)
+#define RMT_US_TO_TICK(u)  ((u) * 10)
+
+/* DMA receive scratch buffer size (in bytes, must be multiple of 4) */
+
+#define LIRC_RX_BUF_BYTES  CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE
+
+/* Stack size for the RX worker thread */
+
+#define LIRC_RX_THREAD_STACK  2048
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct esp_lirc_dev_s
+{
+  struct lirc_lowerhalf_s lower;   /* Must be first — lirc upper-half iface */
+  FAR struct rmt_dev_s   *rmt;     /* ESP RMT lower-half */
+  volatile bool           running; /* RX thread keep-alive flag */
+  pid_t                   rxpid;   /* RX worker thread PID */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int  esp_lirc_open(FAR struct lirc_lowerhalf_s *lower);
+static void esp_lirc_close(FAR struct lirc_lowerhalf_s *lower);
+static int  esp_lirc_tx_ir(FAR struct lirc_lowerhalf_s *lower,
+                            FAR unsigned int *txbuf, unsigned int n);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct lirc_ops_s g_esp_lirc_rx_ops =
+{
+  .driver_type = LIRC_DRIVER_IR_RAW,
+  .open        = esp_lirc_open,
+  .close       = esp_lirc_close,
+};
+
+static const struct lirc_ops_s g_esp_lirc_tx_ops =
+{
+  .driver_type = LIRC_DRIVER_IR_RAW_TX,
+  .open        = esp_lirc_open,
+  .close       = esp_lirc_close,
+  .tx_ir       = esp_lirc_tx_ir,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_lirc_rx_thread
+ *
+ * Description:
+ *   Kernel thread that continuously arms the RMT receiver, waits for
+ *   received symbols, converts rmt_symbol_word_t items to LIRC pulse/space
+ *   samples, and pushes them upstream via lirc_sample_event().
+ *
+ *   RMT clock is 10 MHz → 1 tick = 0.1 µs.
+ *   rmt_symbol_word_t layout:
+ *     bits [0:14]  duration0   (RMT ticks)
+ *     bit  [15]    level0      (1 = pulse, 0 = space)
+ *     bits [16:30] duration1   (RMT ticks)
+ *     bit  [31]    level1
+ *
+ ****************************************************************************/
+
+static int esp_lirc_rx_thread(int argc, FAR char *argv[])
+{
+  FAR struct esp_lirc_dev_s *priv;
+  FAR const char *arg;
+  FAR char *rxbuf;
+  FAR rmt_symbol_word_t *sym;
+  unsigned int sample;
+  int nbytes;
+  int nsyms;
+  int i;
+
+  DEBUGASSERT(argc >= 2 && argv[argc - 1] != NULL);
+
+  arg = argv[argc - 1];
+  priv = (FAR struct esp_lirc_dev_s *)(uintptr_t)strtoul(arg, NULL, 16);
+
+  rxbuf = kmm_malloc(LIRC_RX_BUF_BYTES);
+  if (rxbuf == NULL)
+    {
+      rcerr("ERROR: out of memory for RX buffer\n");
+      return -ENOMEM;
+    }
+
+  while (priv->running)
+    {
+      /* Arm the RMT receiver — uses rxbuf as DMA scratch buffer.
+       * The actual received symbols land in priv->rmt->circbuf via
+       * the rmt_rx_done_callback in esp_rmt.c.
+       */
+
+      if (priv->rmt->ops->read)
+        {
+          priv->rmt->ops->read(priv->rmt, rxbuf, LIRC_RX_BUF_BYTES);
+        }
+
+      /* Wait until the callback posts the semaphore */
+
+      nxsem_wait_uninterruptible(priv->rmt->recvsem);
+
+      if (!priv->running)
+        {
+          break;
+        }
+
+      /* Drain the circular buffer */
+
+      while ((nbytes = circbuf_read(priv->rmt->circbuf,
+                                    rxbuf, LIRC_RX_BUF_BYTES)) > 0)
+        {
+          nsyms = nbytes / sizeof(rmt_symbol_word_t);
+          sym   = (FAR rmt_symbol_word_t *)rxbuf;
+
+          for (i = 0; i < nsyms; i++)
+            {
+              uint16_t dur0 = sym[i].duration0;
+              uint8_t  lvl0 = sym[i].level0;
+              uint16_t dur1 = sym[i].duration1;
+              uint8_t  lvl1 = sym[i].level1;
+
+              /* First half-symbol */
+
+              if (dur0 > 0)
+                {
+                  sample = lvl0 ?
+                    LIRC_PULSE(RMT_TICK_TO_US(dur0)) :
+                    LIRC_SPACE(RMT_TICK_TO_US(dur0));
+                  lirc_sample_event(&priv->lower, sample);
+                }
+
+              /* Second half-symbol (duration1 == 0 marks end of burst) */
+
+              if (dur1 > 0)
+                {
+                  sample = lvl1 ?
+                    LIRC_PULSE(RMT_TICK_TO_US(dur1)) :
+                    LIRC_SPACE(RMT_TICK_TO_US(dur1));
+                  lirc_sample_event(&priv->lower, sample);
+                }
+            }
+        }
+    }
+
+  kmm_free(rxbuf);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp_lirc_open
+ ****************************************************************************/
+
+static int esp_lirc_open(FAR struct lirc_lowerhalf_s *lower)
+{
+  FAR struct esp_lirc_dev_s *priv =
+    (FAR struct esp_lirc_dev_s *)lower;
+  FAR char *argv[3];
+  char addrstr[20];
+  int ret = OK;
+
+  if (priv->rxpid > 0)
+    {
+      return OK;  /* Already open */
+    }
+
+  if (priv->rmt->recvsem != NULL)
+    {
+      /* RX-capable device: start the receiver thread */
+
+      priv->running = true;
+
+      snprintf(addrstr, sizeof(addrstr), "%lx",
+               (unsigned long)(uintptr_t)priv);
+      argv[0] = "esp_lirc_rx";
+      argv[1] = addrstr;
+      argv[2] = NULL;
+
+      ret = kthread_create("esp_lirc_rx", SCHED_PRIORITY_DEFAULT,
+                           LIRC_RX_THREAD_STACK,
+                           esp_lirc_rx_thread, argv);
+      if (ret < 0)
+        {
+          priv->running = false;
+          rcerr("ERROR: kthread_create failed: %d\n", ret);
+          return ret;
+        }
+
+      priv->rxpid = ret;
+      ret = OK;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_lirc_close
+ ****************************************************************************/
+
+static void esp_lirc_close(FAR struct lirc_lowerhalf_s *lower)
+{
+  FAR struct esp_lirc_dev_s *priv =
+    (FAR struct esp_lirc_dev_s *)lower;
+
+  if (priv->rxpid > 0)
+    {
+      priv->running = false;
+
+      /* Wake the blocked thread so it can exit */
+
+      if (priv->rmt->recvsem != NULL)
+        {
+          nxsem_post(priv->rmt->recvsem);
+        }
+
+      priv->rxpid = -1;
+    }
+}
+
+/****************************************************************************
+ * Name: esp_lirc_tx_ir
+ *
+ * Description:
+ *   Transmit raw IR pulse/space data.  Converts LIRC mode2 unsigned int
+ *   samples (each a LIRC_PULSE or LIRC_SPACE with duration in µs) to pairs
+ *   of rmt_symbol_word_t items and writes them to the RMT TX channel.
+ *
+ *   The RMT clock is 10 MHz so 1 µs = 10 ticks.
+ *
+ ****************************************************************************/
+
+static int esp_lirc_tx_ir(FAR struct lirc_lowerhalf_s *lower,
+                          FAR unsigned int *txbuf, unsigned int n)
+{
+  FAR struct esp_lirc_dev_s *priv =
+    (FAR struct esp_lirc_dev_s *)lower;
+  FAR rmt_symbol_word_t *items;
+  unsigned int nwords;
+  unsigned int i;
+  int ret;
+
+  if (!priv->rmt->ops->write)
+    {
+      return -ENOSYS;
+    }
+
+  /* Each pair of LIRC samples (pulse + space) maps to one rmt_symbol_word_t.
+   * For an odd count we pad the last word with a zero second half-symbol.
+   */
+
+  nwords = (n + 1) / 2;
+  items  = kmm_zalloc(nwords * sizeof(rmt_symbol_word_t));
+  if (items == NULL)
+    {
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < n; i++)
+    {
+      uint32_t us  = LIRC_VALUE(txbuf[i]);
+      uint8_t  lvl = LIRC_IS_PULSE(txbuf[i]) ? 1 : 0;
+      uint16_t tks = (uint16_t)RMT_US_TO_TICK(us);
+
+      if ((i & 1) == 0)
+        {
+          items[i / 2].duration0 = tks;
+          items[i / 2].level0    = lvl;
+        }
+      else
+        {
+          items[i / 2].duration1 = tks;
+          items[i / 2].level1    = lvl;
+        }
+    }
+
+  ret = priv->rmt->ops->write(priv->rmt,
+                              (FAR const char *)items,
+                              nwords * sizeof(rmt_symbol_word_t));
+
+  kmm_free(items);
+  return (ret < 0) ? ret : (int)n;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_lirc_rx_initialize
+ *
+ * Description:
+ *   Register a pre-initialized RMT RX channel as a LIRC raw IR device.
+ *
+ * Input Parameters:
+ *   devno - The LIRC device number (e.g. 0 for /dev/lirc0)
+ *   rmt   - An already-initialized RMT RX lower-half handle
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int esp_lirc_rx_initialize(int devno, FAR struct rmt_dev_s *rmt)
+{
+  FAR struct esp_lirc_dev_s *priv;
+  int ret;
+
+  DEBUGASSERT(rmt != NULL);
+
+  priv = kmm_zalloc(sizeof(struct esp_lirc_dev_s));
+  if (priv == NULL)
+    {
+      return -ENOMEM;
+    }
+
+  priv->lower.ops           = &g_esp_lirc_rx_ops;
+  priv->lower.buffer_bytes  = LIRC_RX_BUF_BYTES;
+  priv->lower.rx_resolution = 100; /* 0.1 µs = 100 ns */
+  priv->rmt                 = rmt;
+  priv->rxpid               = -1;
+
+  ret = lirc_register(&priv->lower, devno);
+  if (ret < 0)
+    {
+      rcerr("ERROR: lirc_register failed: %d\n", ret);
+      kmm_free(priv);
+      return ret;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp_lirc_tx_initialize
+ *
+ * Description:
+ *   Register a pre-initialized RMT TX channel as a LIRC raw TX device.
+ *
+ * Input Parameters:
+ *   devno - The LIRC device number (e.g. 0 for /dev/lirc0)
+ *   rmt   - An already-initialized RMT TX lower-half handle
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int esp_lirc_tx_initialize(int devno, FAR struct rmt_dev_s *rmt)
+{
+  FAR struct esp_lirc_dev_s *priv;
+  int ret;
+
+  DEBUGASSERT(rmt != NULL);
+
+  priv = kmm_zalloc(sizeof(struct esp_lirc_dev_s));
+  if (priv == NULL)
+    {
+      return -ENOMEM;
+    }
+
+  priv->lower.ops           = &g_esp_lirc_tx_ops;
+  priv->lower.tx_resolution = 100; /* 0.1 µs = 100 ns */
+  priv->rmt                 = rmt;
+  priv->rxpid               = -1;
+
+  ret = lirc_register(&priv->lower, devno);
+  if (ret < 0)
+    {
+      rcerr("ERROR: lirc_register failed: %d\n", ret);
+      kmm_free(priv);
+      return ret;
+    }
+
+  return OK;
+}
+
+#endif /* CONFIG_ESP_RMT && CONFIG_DRIVERS_RC */
diff --git a/arch/xtensa/src/common/espressif/esp_lirc.h 
b/arch/xtensa/src/common/espressif/esp_lirc.h
new file mode 100644
index 00000000000..b7b970e056b
--- /dev/null
+++ b/arch/xtensa/src/common/espressif/esp_lirc.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+ * arch/xtensa/src/common/espressif/esp_lirc.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_XTENSA_SRC_COMMON_ESPRESSIF_ESP_LIRC_H
+#define __ARCH_XTENSA_SRC_COMMON_ESPRESSIF_ESP_LIRC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "esp_rmt.h"
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#if defined(CONFIG_ESP_RMT) && defined(CONFIG_DRIVERS_RC)
+
+int esp_lirc_rx_initialize(int devno, FAR struct rmt_dev_s *rmt);
+int esp_lirc_tx_initialize(int devno, FAR struct rmt_dev_s *rmt);
+
+#endif /* CONFIG_ESP_RMT && CONFIG_DRIVERS_RC */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_XTENSA_SRC_COMMON_ESPRESSIF_ESP_LIRC_H */
diff --git a/arch/xtensa/src/common/espressif/esp_rmt.c 
b/arch/xtensa/src/common/espressif/esp_rmt.c
index 2108962474a..8e57f8b3f1f 100644
--- a/arch/xtensa/src/common/espressif/esp_rmt.c
+++ b/arch/xtensa/src/common/espressif/esp_rmt.c
@@ -39,7 +39,6 @@
 #include <arch/board/board.h>
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
-#include <nuttx/rmt/rmt.h>
 #include <nuttx/spinlock.h>
 #include <nuttx/circbuf.h>
 
diff --git a/arch/xtensa/src/common/espressif/esp_rmt.h 
b/arch/xtensa/src/common/espressif/esp_rmt.h
index 943db6a88ba..84bcc626352 100644
--- a/arch/xtensa/src/common/espressif/esp_rmt.h
+++ b/arch/xtensa/src/common/espressif/esp_rmt.h
@@ -29,6 +29,10 @@
 
 #include <nuttx/config.h>
 #include <semaphore.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <nuttx/circbuf.h>
 #include <nuttx/spinlock.h>
 
 /****************************************************************************
@@ -51,6 +55,34 @@
  * Public Types
  ****************************************************************************/
 
+/* The RMT peripheral vtable */
+
+struct rmt_dev_s;
+
+struct rmt_ops_s
+{
+  CODE int      (*open)(FAR struct rmt_dev_s *dev);
+  CODE int      (*close)(FAR struct rmt_dev_s *dev);
+  CODE ssize_t  (*write)(FAR struct rmt_dev_s *dev,
+                         FAR const char *buffer,
+                         size_t buflen);
+  CODE ssize_t  (*read)(FAR struct rmt_dev_s *dev,
+                        FAR char *buffer,
+                        size_t buflen);
+};
+
+/* RMT device structure — initial fields visible to upper-half drivers.
+ * The ESP lower-half extends this with hardware-specific fields.
+ */
+
+struct rmt_dev_s
+{
+  FAR const struct rmt_ops_s *ops;
+  FAR struct circbuf_s       *circbuf;
+  sem_t                      *recvsem;
+  int                         minor;
+};
+
 /****************************************************************************
  * Public Data
  ****************************************************************************/
diff --git a/arch/xtensa/src/common/espressif/esp_ws2812.c 
b/arch/xtensa/src/common/espressif/esp_ws2812.c
index c6104e357c0..638ad1b6338 100644
--- a/arch/xtensa/src/common/espressif/esp_ws2812.c
+++ b/arch/xtensa/src/common/espressif/esp_ws2812.c
@@ -31,7 +31,6 @@
 #include <nuttx/kmalloc.h>
 #include <nuttx/signal.h>
 #include <nuttx/leds/ws2812.h>
-#include <nuttx/rmt/rmt.h>
 
 #include "hal/rmt_types.h"
 #include "soc/soc.h"
diff --git a/boards/risc-v/esp32c3/common/src/esp_board_rmt.c 
b/boards/risc-v/esp32c3/common/src/esp_board_rmt.c
index ddac1b988bd..aeb12505cdc 100644
--- a/boards/risc-v/esp32c3/common/src/esp_board_rmt.c
+++ b/boards/risc-v/esp32c3/common/src/esp_board_rmt.c
@@ -31,7 +31,7 @@
 #include <stdio.h>
 
 #include <nuttx/kmalloc.h>
-#include <nuttx/rmt/rmtchar.h>
+#include "espressif/esp_lirc.h"
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -87,13 +87,19 @@
 int board_rmt_rxinitialize(int pin)
 {
   int ret;
+  struct rmt_dev_s *rmt;
 
-  struct rmt_dev_s *rmt = esp_rmt_rx_init(pin);
+  rmt = esp_rmt_rx_init(pin);
+  if (rmt == NULL)
+    {
+      rmterr("ERROR: esp_rmt_rx_init failed\n");
+      return -ENODEV;
+    }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
 
@@ -129,10 +135,10 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
 
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/rmt/defconfig 
b/boards/risc-v/esp32c3/esp32c3-devkit/configs/rmt/defconfig
index 01335a518b4..c5109e75db7 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/configs/rmt/defconfig
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/rmt/defconfig
@@ -23,11 +23,8 @@ CONFIG_ARCH_STACKDUMP=y
 CONFIG_BOARDCTL_RESET=y
 CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
+CONFIG_DRIVERS_RC=y
 CONFIG_ESP_RMT=y
-CONFIG_EXAMPLES_RMTCHAR=y
-CONFIG_EXAMPLES_RMTCHAR_RX=y
-CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt2"
-CONFIG_EXAMPLES_RMTCHAR_TX=y
 CONFIG_EXAMPLES_WS2812=y
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
@@ -42,9 +39,6 @@ CONFIG_NSH_FILEIOSIZE=512
 CONFIG_NSH_READLINE=y
 CONFIG_NSH_STRERROR=y
 CONFIG_PREALLOC_TIMERS=0
-CONFIG_RMT=y
-CONFIG_RMTCHAR=y
-CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=512
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_BACKTRACE=y
 CONFIG_SCHED_WAITPID=y
diff --git a/boards/risc-v/esp32c6/common/src/esp_board_rmt.c 
b/boards/risc-v/esp32c6/common/src/esp_board_rmt.c
index 8094242d2c3..a92a445c604 100644
--- a/boards/risc-v/esp32c6/common/src/esp_board_rmt.c
+++ b/boards/risc-v/esp32c6/common/src/esp_board_rmt.c
@@ -31,7 +31,7 @@
 #include <stdio.h>
 
 #include <nuttx/kmalloc.h>
-#include <nuttx/rmt/rmtchar.h>
+#include "espressif/esp_lirc.h"
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -87,13 +87,19 @@
 int board_rmt_rxinitialize(int pin)
 {
   int ret;
+  struct rmt_dev_s *rmt;
 
-  struct rmt_dev_s *rmt = esp_rmt_rx_init(pin);
+  rmt = esp_rmt_rx_init(pin);
+  if (rmt == NULL)
+    {
+      rmterr("ERROR: esp_rmt_rx_init failed\n");
+      return -ENODEV;
+    }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
 
@@ -129,10 +135,10 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
 
diff --git a/boards/risc-v/esp32c6/esp32c6-devkitc/configs/rmt/defconfig 
b/boards/risc-v/esp32c6/esp32c6-devkitc/configs/rmt/defconfig
index 8a4aa0b3094..c45f9a4f442 100644
--- a/boards/risc-v/esp32c6/esp32c6-devkitc/configs/rmt/defconfig
+++ b/boards/risc-v/esp32c6/esp32c6-devkitc/configs/rmt/defconfig
@@ -23,11 +23,8 @@ CONFIG_ARCH_STACKDUMP=y
 CONFIG_BOARDCTL_RESET=y
 CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
+CONFIG_DRIVERS_RC=y
 CONFIG_ESP_RMT=y
-CONFIG_EXAMPLES_RMTCHAR=y
-CONFIG_EXAMPLES_RMTCHAR_RX=y
-CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt2"
-CONFIG_EXAMPLES_RMTCHAR_TX=y
 CONFIG_EXAMPLES_WS2812=y
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
@@ -42,9 +39,6 @@ CONFIG_NSH_FILEIOSIZE=512
 CONFIG_NSH_READLINE=y
 CONFIG_NSH_STRERROR=y
 CONFIG_PREALLOC_TIMERS=0
-CONFIG_RMT=y
-CONFIG_RMTCHAR=y
-CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=512
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_BACKTRACE=y
 CONFIG_SCHED_WAITPID=y
diff --git a/boards/risc-v/esp32c6/esp32c6-devkitm/configs/rmt/defconfig 
b/boards/risc-v/esp32c6/esp32c6-devkitm/configs/rmt/defconfig
index b7b9accc8a5..4f7f903e870 100644
--- a/boards/risc-v/esp32c6/esp32c6-devkitm/configs/rmt/defconfig
+++ b/boards/risc-v/esp32c6/esp32c6-devkitm/configs/rmt/defconfig
@@ -23,11 +23,8 @@ CONFIG_ARCH_STACKDUMP=y
 CONFIG_BOARDCTL_RESET=y
 CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
+CONFIG_DRIVERS_RC=y
 CONFIG_ESP_RMT=y
-CONFIG_EXAMPLES_RMTCHAR=y
-CONFIG_EXAMPLES_RMTCHAR_RX=y
-CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt2"
-CONFIG_EXAMPLES_RMTCHAR_TX=y
 CONFIG_EXAMPLES_WS2812=y
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
@@ -42,9 +39,6 @@ CONFIG_NSH_FILEIOSIZE=512
 CONFIG_NSH_READLINE=y
 CONFIG_NSH_STRERROR=y
 CONFIG_PREALLOC_TIMERS=0
-CONFIG_RMT=y
-CONFIG_RMTCHAR=y
-CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=512
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_BACKTRACE=y
 CONFIG_SCHED_WAITPID=y
diff --git a/boards/risc-v/esp32h2/common/src/esp_board_rmt.c 
b/boards/risc-v/esp32h2/common/src/esp_board_rmt.c
index 8c56a262bc0..514fa6d5d17 100644
--- a/boards/risc-v/esp32h2/common/src/esp_board_rmt.c
+++ b/boards/risc-v/esp32h2/common/src/esp_board_rmt.c
@@ -31,7 +31,7 @@
 #include <stdio.h>
 
 #include <nuttx/kmalloc.h>
-#include <nuttx/rmt/rmtchar.h>
+#include "espressif/esp_lirc.h"
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -87,13 +87,19 @@
 int board_rmt_rxinitialize(int pin)
 {
   int ret;
+  struct rmt_dev_s *rmt;
 
-  struct rmt_dev_s *rmt = esp_rmt_rx_init(pin);
+  rmt = esp_rmt_rx_init(pin);
+  if (rmt == NULL)
+    {
+      rmterr("ERROR: esp_rmt_rx_init failed\n");
+      return -ENODEV;
+    }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
 
@@ -129,10 +135,10 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
 
diff --git a/boards/risc-v/esp32h2/esp32h2-devkit/configs/rmt/defconfig 
b/boards/risc-v/esp32h2/esp32h2-devkit/configs/rmt/defconfig
index 53e39e2658b..1d4f9bfee37 100644
--- a/boards/risc-v/esp32h2/esp32h2-devkit/configs/rmt/defconfig
+++ b/boards/risc-v/esp32h2/esp32h2-devkit/configs/rmt/defconfig
@@ -22,11 +22,8 @@ CONFIG_ARCH_STACKDUMP=y
 CONFIG_BOARDCTL_RESET=y
 CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
+CONFIG_DRIVERS_RC=y
 CONFIG_ESP_RMT=y
-CONFIG_EXAMPLES_RMTCHAR=y
-CONFIG_EXAMPLES_RMTCHAR_RX=y
-CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt2"
-CONFIG_EXAMPLES_RMTCHAR_TX=y
 CONFIG_EXAMPLES_WS2812=y
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
@@ -41,9 +38,6 @@ CONFIG_NSH_FILEIOSIZE=512
 CONFIG_NSH_READLINE=y
 CONFIG_NSH_STRERROR=y
 CONFIG_PREALLOC_TIMERS=0
-CONFIG_RMT=y
-CONFIG_RMTCHAR=y
-CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=512
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_BACKTRACE=y
 CONFIG_SCHED_WAITPID=y
diff --git a/boards/risc-v/esp32p4/common/src/esp_board_rmt.c 
b/boards/risc-v/esp32p4/common/src/esp_board_rmt.c
index 2f5ded7a937..e432c914885 100644
--- a/boards/risc-v/esp32p4/common/src/esp_board_rmt.c
+++ b/boards/risc-v/esp32p4/common/src/esp_board_rmt.c
@@ -31,7 +31,7 @@
 #include <stdio.h>
 
 #include <nuttx/kmalloc.h>
-#include <nuttx/rmt/rmtchar.h>
+#include "espressif/esp_lirc.h"
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -87,13 +87,19 @@
 int board_rmt_rxinitialize(int pin)
 {
   int ret;
+  struct rmt_dev_s *rmt;
 
-  struct rmt_dev_s *rmt = esp_rmt_rx_init(pin);
+  rmt = esp_rmt_rx_init(pin);
+  if (rmt == NULL)
+    {
+      rmterr("ERROR: esp_rmt_rx_init failed\n");
+      return -ENODEV;
+    }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
 
@@ -129,10 +135,10 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
 
diff --git 
a/boards/risc-v/esp32p4/esp32p4-function-ev-board/configs/rmt/defconfig 
b/boards/risc-v/esp32p4/esp32p4-function-ev-board/configs/rmt/defconfig
index 05184fcebc6..f6da07a9bb1 100644
--- a/boards/risc-v/esp32p4/esp32p4-function-ev-board/configs/rmt/defconfig
+++ b/boards/risc-v/esp32p4/esp32p4-function-ev-board/configs/rmt/defconfig
@@ -21,11 +21,8 @@ CONFIG_ARCH_RISCV=y
 CONFIG_BOARDCTL_RESET=y
 CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
+CONFIG_DRIVERS_RC=y
 CONFIG_ESP_RMT=y
-CONFIG_EXAMPLES_RMTCHAR=y
-CONFIG_EXAMPLES_RMTCHAR_RX=y
-CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt4"
-CONFIG_EXAMPLES_RMTCHAR_TX=y
 CONFIG_EXAMPLES_WS2812=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_FS_PROCFS=y
@@ -41,9 +38,6 @@ CONFIG_NSH_FILEIOSIZE=512
 CONFIG_NSH_READLINE=y
 CONFIG_NSH_STRERROR=y
 CONFIG_PREALLOC_TIMERS=0
-CONFIG_RMT=y
-CONFIG_RMTCHAR=y
-CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=512
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_BACKTRACE=y
 CONFIG_SCHED_WAITPID=y
diff --git a/boards/xtensa/esp32/common/src/esp32_board_rmt.c 
b/boards/xtensa/esp32/common/src/esp32_board_rmt.c
index 24c3effb9d5..4e8c8864453 100644
--- a/boards/xtensa/esp32/common/src/esp32_board_rmt.c
+++ b/boards/xtensa/esp32/common/src/esp32_board_rmt.c
@@ -33,7 +33,7 @@
 #include "xtensa.h"
 
 #include <nuttx/kmalloc.h>
-#include <nuttx/rmt/rmtchar.h>
+#include "espressif/esp_lirc.h"
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -89,13 +89,19 @@
 int board_rmt_rxinitialize(int pin)
 {
   int ret;
+  struct rmt_dev_s *rmt;
 
-  struct rmt_dev_s *rmt = esp_rmt_rx_init(pin);
+  rmt = esp_rmt_rx_init(pin);
+  if (rmt == NULL)
+    {
+      rmterr("ERROR: esp_rmt_rx_init failed\n");
+      return -ENODEV;
+    }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
 
@@ -125,17 +131,16 @@ int board_rmt_txinitialize(int pin)
 #endif
 
   rmt = esp_rmt_tx_init(pin);
-
   if (rmt == NULL)
     {
       rmterr("ERROR: esp_rmt_tx_init failed\n");
       return -ENODEV;
     }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
 
diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/rmt/defconfig 
b/boards/xtensa/esp32/esp32-devkitc/configs/rmt/defconfig
index 3b39a416e34..8eee4b00833 100644
--- a/boards/xtensa/esp32/esp32-devkitc/configs/rmt/defconfig
+++ b/boards/xtensa/esp32/esp32-devkitc/configs/rmt/defconfig
@@ -22,11 +22,9 @@ CONFIG_ARCH_STACKDUMP=y
 CONFIG_ARCH_XTENSA=y
 CONFIG_BOARD_LOOPSPERMSEC=16717
 CONFIG_BUILTIN=y
+CONFIG_DRIVERS_RC=y
 CONFIG_ESP32_UART0=y
 CONFIG_ESP_RMT=y
-CONFIG_EXAMPLES_RMTCHAR=y
-CONFIG_EXAMPLES_RMTCHAR_RX=y
-CONFIG_EXAMPLES_RMTCHAR_TX=y
 CONFIG_EXAMPLES_WS2812=y
 CONFIG_FS_PROCFS=y
 CONFIG_HAVE_CXX=y
@@ -44,9 +42,6 @@ CONFIG_NSH_READLINE=y
 CONFIG_PREALLOC_TIMERS=4
 CONFIG_RAM_SIZE=114688
 CONFIG_RAM_START=0x20000000
-CONFIG_RMT=y
-CONFIG_RMTCHAR=y
-CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=256
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_WAITPID=y
 CONFIG_START_DAY=6
diff --git a/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c 
b/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c
index 5b06382a579..710af33ebde 100644
--- a/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c
+++ b/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c
@@ -33,7 +33,7 @@
 #include "xtensa.h"
 
 #include <nuttx/kmalloc.h>
-#include <nuttx/rmt/rmtchar.h>
+#include "espressif/esp_lirc.h"
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -98,10 +98,10 @@ int board_rmt_rxinitialize(int pin)
       return -ENODEV;
     }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
 
@@ -137,10 +137,10 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
 
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/configs/rmt/defconfig 
b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/rmt/defconfig
index 9b31d333be9..6811b4c8e0a 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/configs/rmt/defconfig
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/rmt/defconfig
@@ -24,11 +24,9 @@ CONFIG_ARCH_STACKDUMP=y
 CONFIG_ARCH_XTENSA=y
 CONFIG_BOARD_LOOPSPERMSEC=16717
 CONFIG_BUILTIN=y
+CONFIG_DRIVERS_RC=y
 CONFIG_ESP32S2_UART0=y
 CONFIG_ESP_RMT=y
-CONFIG_EXAMPLES_RMTCHAR=y
-CONFIG_EXAMPLES_RMTCHAR_RX=y
-CONFIG_EXAMPLES_RMTCHAR_TX=y
 CONFIG_EXAMPLES_WS2812=y
 CONFIG_FS_PROCFS=y
 CONFIG_HAVE_CXX=y
@@ -45,9 +43,6 @@ CONFIG_NSH_READLINE=y
 CONFIG_PREALLOC_TIMERS=4
 CONFIG_RAM_SIZE=114688
 CONFIG_RAM_START=0x20000000
-CONFIG_RMT=y
-CONFIG_RMTCHAR=y
-CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=256
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_WAITPID=y
 CONFIG_START_DAY=6
diff --git a/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c 
b/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c
index 6c6bd982d24..3d96b8613d3 100644
--- a/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c
+++ b/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c
@@ -33,7 +33,7 @@
 #include "xtensa.h"
 
 #include <nuttx/kmalloc.h>
-#include <nuttx/rmt/rmtchar.h>
+#include "espressif/esp_lirc.h"
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -89,13 +89,19 @@
 int board_rmt_rxinitialize(int pin)
 {
   int ret;
+  struct rmt_dev_s *rmt;
 
-  struct rmt_dev_s *rmt = esp_rmt_rx_init(pin);
+  rmt = esp_rmt_rx_init(pin);
+  if (rmt == NULL)
+    {
+      rmterr("ERROR: esp_rmt_rx_init failed\n");
+      return -ENODEV;
+    }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
 
@@ -131,10 +137,10 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
-  ret = rmtchar_register(rmt);
+  ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
-      rmterr("ERROR: rmtchar_register failed: %d\n", ret);
+      rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
 
diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/rmt/defconfig 
b/boards/xtensa/esp32s3/esp32s3-devkit/configs/rmt/defconfig
index 80fbd79aa00..075cfe1a330 100644
--- a/boards/xtensa/esp32s3/esp32s3-devkit/configs/rmt/defconfig
+++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/rmt/defconfig
@@ -25,12 +25,9 @@ CONFIG_ARCH_STACKDUMP=y
 CONFIG_ARCH_XTENSA=y
 CONFIG_BOARD_LOOPSPERMSEC=16717
 CONFIG_BUILTIN=y
+CONFIG_DRIVERS_RC=y
 CONFIG_ESP32S3_UART0=y
 CONFIG_ESP_RMT=y
-CONFIG_EXAMPLES_RMTCHAR=y
-CONFIG_EXAMPLES_RMTCHAR_RX=y
-CONFIG_EXAMPLES_RMTCHAR_RX_DEVPATH="/dev/rmt4"
-CONFIG_EXAMPLES_RMTCHAR_TX=y
 CONFIG_EXAMPLES_WS2812=y
 CONFIG_FS_PROCFS=y
 CONFIG_HAVE_CXX=y
@@ -47,9 +44,6 @@ CONFIG_NSH_READLINE=y
 CONFIG_PREALLOC_TIMERS=4
 CONFIG_RAM_SIZE=114688
 CONFIG_RAM_START=0x20000000
-CONFIG_RMT=y
-CONFIG_RMTCHAR=y
-CONFIG_RMT_DEFAULT_RX_BUFFER_SIZE=256
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_WAITPID=y
 CONFIG_START_DAY=6
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 7f4cdacba3f..20e77b4a971 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -39,7 +39,6 @@ source "drivers/pinctrl/Kconfig"
 source "drivers/pipes/Kconfig"
 source "drivers/power/Kconfig"
 source "drivers/regmap/Kconfig"
-source "drivers/rmt/Kconfig"
 source "drivers/rpmsg/Kconfig"
 source "drivers/rptun/Kconfig"
 source "drivers/sensors/Kconfig"
diff --git a/drivers/rmt/CMakeLists.txt b/drivers/rmt/CMakeLists.txt
index 8978f4c4d4a..41f66775498 100644
--- a/drivers/rmt/CMakeLists.txt
+++ b/drivers/rmt/CMakeLists.txt
@@ -20,12 +20,4 @@
 #
 # 
##############################################################################
 
-if(CONFIG_RMT)
-  set(SRCS)
-
-  if(CONFIG_RMTCHAR)
-    list(APPEND SRCS rmtchar.c)
-  endif()
-
-  target_sources(drivers PRIVATE ${SRCS})
-endif()
+# RMT character driver removed; RMT upper-half is now arch/espressif/esp_lirc.c
diff --git a/drivers/rmt/Kconfig b/drivers/rmt/Kconfig
index fa7b2891f01..f72f3c094ce 100644
--- a/drivers/rmt/Kconfig
+++ b/drivers/rmt/Kconfig
@@ -2,46 +2,3 @@
 # For a description of the syntax of this configuration file,
 # see the file kconfig-language.txt in the NuttX tools repository.
 #
-
-menuconfig RMT
-       bool "RMT (Remote Control) Driver Support"
-       default n
-       ---help---
-               This option selects common RMT (Remote Control) options and 
should be
-               enabled by the platforms that implement a Remote Control 
Peripheral.
-
-if RMT
-
-config RMTCHAR
-       bool "RMT character driver (for testing only)"
-       default n
-       ---help---
-               The RMT character driver is a simple character driver that 
supports
-               RMT transfers via read() and write(). This driver is primarily
-               intended to support RMT testing. It is not suitable for use in 
any
-               real driver application in its current form because its buffer
-               management heuristics are dependent on the lower half driver
-               (device-specific). Applications that use the RMT peripheral to
-               implement protocols such as NEC (for Remote Control), or use 
this
-               driver to implement other 1-wire protocols such as WS2812 LED 
must
-               provide their specific driver implementation.
-
-config RMT_DEFAULT_RX_BUFFER_SIZE
-       int "Default RX buffer size"
-       default 100
-       ---help---
-               The RMT RX default buffer size. This is the expected buffer size
-               that should be returned on a `read()` operation.
-
-config RMT_LOOP_TEST_MODE
-       bool "RMT character driver loopback test mode (for testing only)"
-       depends on EXPERIMENTAL
-       default n
-       ---help---
-               This enables a lower-half driver-specific loopback test
-               mode that attaches the transmitter to the receiver, being
-               able to test the RMT peripheral without any external
-               connection. This feature depends on lower-half driver
-               implementation.
-
-endif # RMT
diff --git a/drivers/rmt/Make.defs b/drivers/rmt/Make.defs
index 3e4e6691723..5f6b700ac29 100644
--- a/drivers/rmt/Make.defs
+++ b/drivers/rmt/Make.defs
@@ -19,14 +19,3 @@
 # under the License.
 #
 ############################################################################
-
-ifeq ($(CONFIG_RMT),y)
-
-ifeq ($(CONFIG_RMTCHAR),y)
-CSRCS += rmtchar.c
-endif
-
-DEPPATH += --dep-path rmt
-VPATH += :rmt
-
-endif
diff --git a/drivers/rmt/rmtchar.c b/drivers/rmt/rmtchar.c
deleted file mode 100644
index 5f477471c3c..00000000000
--- a/drivers/rmt/rmtchar.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/****************************************************************************
- * drivers/rmt/rmtchar.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 <stdint.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <assert.h>
-#include <debug.h>
-#include <errno.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/kmalloc.h>
-#include <nuttx/circbuf.h>
-#include <nuttx/mutex.h>
-#include <nuttx/rmt/rmt.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#define DEVNAME_FMT    "/dev/rmt%d"
-#define DEVNAME_FMTLEN (8 + 3 + 1)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct rmt_driver_s
-{
-  /* The lower half RMT driver */
-
-  FAR struct rmt_dev_s *rmt;
-
-  /* The minor identification of the driver. It's provided by the lower half
-   * driver and it can represent the channel being used.
-   */
-
-  int minor;
-
-  mutex_t lock;               /* Assures mutually exclusive access */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int rmt_open(FAR struct file *filep);
-static int rmt_close(FAR struct file *filep);
-static ssize_t rmt_read(FAR struct file *filep, FAR char *buffer,
-                        size_t buflen);
-static ssize_t rmt_write(FAR struct file *filep, FAR const char *buffer,
-                         size_t buflen);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations g_rmt_channel_fops =
-{
-  rmt_open,     /* open  */
-  rmt_close,    /* close */
-  rmt_read,     /* read  */
-  rmt_write,    /* write */
-  NULL,         /* seek  */
-  NULL,         /* ioctl */
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: rmt_open
- *
- * Description:
- *   Prepare the RMT peripheral for use. This method just calls the lower
- *   half `open` routine if it exists.
- *
- * Input Parameters:
- *   filep - Pointer system file data
- *
- * Returned Value:
- *   The return code of the lower half `open` routine if it exists.
- *   Please check device-specific driver for more information.
- *
- ****************************************************************************/
-
-static int rmt_open(FAR struct file *filep)
-{
-  FAR struct inode *inode;
-  FAR struct rmt_driver_s *priv;
-  int ret = OK;
-
-  /* Get our private data structure */
-
-  inode = filep->f_inode;
-
-  priv = inode->i_private;
-  DEBUGASSERT(priv);
-
-  if (priv->rmt->ops->open)
-    {
-      ret = priv->rmt->ops->open(priv->rmt);
-    }
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: rmt_close
- *
- * Description:
- *   Close the RMT peripheral after use. This method just calls the lower
- *   half `close` routine if it exists.
- *
- * Input Parameters:
- *   filep - Pointer system file data
- *
- * Returned Value:
- *   The return code of the lower half `close` routine if it exists.
- *   Please check device-specific driver for more information.
- *
- ****************************************************************************/
-
-static int rmt_close(FAR struct file *filep)
-{
-  FAR struct inode *inode;
-  FAR struct rmt_driver_s *priv;
-  int ret = OK;
-
-  /* Get our private data structure */
-
-  inode = filep->f_inode;
-
-  priv = inode->i_private;
-  DEBUGASSERT(priv);
-
-  if (priv->rmt->ops->close)
-    {
-      ret = priv->rmt->ops->close(priv->rmt);
-    }
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: rmt_read
- *
- * Description:
- *   This function reads data from the RMT device into the provided buffer.
- *   The read operation is performed by the read function pointer in the
- *   RMT device's operations structure, if it exists.
- *
- * Input Parameters:
- *   filep   - Pointer to the file structure.
- *   buffer  - Pointer to the buffer where the read data should be stored.
- *   buflen  - The maximum amount of data to be read.
- *
- * Returned Value:
- *   Returns the number of bytes read from the RMT device; a negated errno
- *   value is returned on any failure.
- *
- ****************************************************************************/
-
-static ssize_t rmt_read(FAR struct file *filep, FAR char *buffer,
-                        size_t buflen)
-{
-  FAR struct inode *inode;
-  FAR struct rmt_driver_s *priv;
-  ssize_t nread = 0;
-
-  /* Get our private data structure */
-
-  inode = filep->f_inode;
-
-  priv = inode->i_private;
-  DEBUGASSERT(priv);
-
-  if (priv->rmt->ops->read)
-    {
-      int ret = priv->rmt->ops->read(priv->rmt, buffer, buflen);
-      if (ret < 0)
-        {
-          return ret;
-        }
-
-      for (; ; )
-        {
-          nread = circbuf_read(priv->rmt->circbuf , buffer, buflen);
-          if (nread != 0 || (filep->f_oflags & O_NONBLOCK))
-            {
-              break;
-            }
-
-          while (circbuf_is_empty(priv->rmt->circbuf))
-            {
-              nxsem_wait_uninterruptible(priv->rmt->recvsem);
-            }
-        }
-    }
-
-  return nread;
-}
-
-/****************************************************************************
- * Name: rmt_write
- *
- * Description:
- *   Write to the RMT peripheral. This method just calls the lower half
- *   `write` routine if it exists.
- *
- * Input Parameters:
- *   filep  - Pointer system file data
- *   buffer - Data to write to the RMT device
- *   buflen - Number of bytes requested to write
- *
- * Returned Value:
- *   Number of bytes that has been successfully written, or 0 when no
- *   bytes could be written for any reason.
- *
- ****************************************************************************/
-
-static ssize_t rmt_write(FAR struct file *filep, FAR const char *buffer,
-                         size_t buflen)
-{
-  FAR struct inode *inode;
-  FAR struct rmt_driver_s *priv;
-  ssize_t nwritten = 0;
-
-  /* Get our private data structure */
-
-  inode = filep->f_inode;
-
-  priv = inode->i_private;
-  DEBUGASSERT(priv);
-
-  if (priv->rmt->ops->write)
-    {
-      nwritten = priv->rmt->ops->write(priv->rmt, buffer, buflen);
-    }
-
-  return nwritten;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: rmtchar_register
- *
- * Description:
- *   Create and register the RMT character driver.
- *
- *   The RMT character driver is a simple character driver that supports RMT
- *   transfers via read() and write(). This driver is primarily intended to
- *   support RMT testing. It is not suitable for use in any real driver
- *   application in its current form because its buffer management heuristics
- *   are dependent on the lower half driver (device-specific).
- *
- * Input Parameters:
- *   rmt - An instance of the lower half RMT driver
- *
- * Returned Value:
- *   OK if the driver was successfully registered; A negated errno value is
- *   returned on any failure.
- *
- ****************************************************************************/
-
-int rmtchar_register(FAR struct rmt_dev_s *rmt)
-{
-  FAR struct rmt_driver_s *priv;
-  char devname[DEVNAME_FMTLEN];
-  size_t dev_size = sizeof(struct rmt_driver_s);
-  int ret;
-
-  /* Sanity check */
-
-  DEBUGASSERT(rmt != NULL && (unsigned)rmt->minor < 1000);
-
-  /* Allocate a RMT character device structure */
-
-  priv = kmm_zalloc(dev_size);
-  if (priv)
-    {
-      /* Initialize the RMT character device structure */
-
-      priv->rmt = rmt;
-      priv->minor = rmt->minor;
-      nxmutex_init(&priv->lock);
-
-      /* Create the character device name */
-
-      snprintf(devname, sizeof(devname), DEVNAME_FMT, priv->minor);
-      ret = register_driver(devname, &g_rmt_channel_fops, 0666, priv);
-      if (ret < 0)
-        {
-          /* Free the device structure if we failed to create the character
-           * device.
-           */
-
-          nxmutex_destroy(&priv->lock);
-          kmm_free(priv);
-          return ret;
-        }
-
-      /* Return the result of the registration */
-
-      return ret;
-    }
-
-  return -ENOMEM;
-}
diff --git a/include/nuttx/rmt/rmt.h b/include/nuttx/rmt/rmt.h
deleted file mode 100644
index 5afb391d5c1..00000000000
--- a/include/nuttx/rmt/rmt.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
- * include/nuttx/rmt/rmt.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 __INCLUDE_NUTTX_RMT_RMT_H
-#define __INCLUDE_NUTTX_RMT_RMT_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#ifdef CONFIG_RMT
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-struct rmt_dev_s;
-
-/* The RMT peripheral vtable */
-
-struct rmt_ops_s
-{
-  CODE int      (*open)(FAR struct rmt_dev_s *dev);
-  CODE int      (*close)(FAR struct rmt_dev_s *dev);
-  CODE ssize_t  (*write)(FAR struct rmt_dev_s *dev,
-                         FAR const char *buffer,
-                         size_t buflen);
-  CODE ssize_t  (*read)(FAR struct rmt_dev_s *dev,
-                        FAR char *buffer,
-                        size_t buflen);
-};
-
-/* RMT private data.  This structure only defines the initial fields of the
- * structure visible to the RMT client.  The specific implementation may
- * add additional, device-specific fields.
- */
-
-struct rmt_dev_s
-{
-  FAR const struct rmt_ops_s *ops;
-  FAR struct circbuf_s       *circbuf;
-  sem_t                      *recvsem;
-  int                         minor;
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C"
-{
-#else
-#define EXTERN extern
-#endif
-
-/****************************************************************************
- * Public Functions Prototypes
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* CONFIG_RMT */
-#endif /* __INCLUDE_NUTTX_RMT_RMT_H */
diff --git a/include/nuttx/rmt/rmtchar.h b/include/nuttx/rmt/rmtchar.h
deleted file mode 100644
index af462ff11e8..00000000000
--- a/include/nuttx/rmt/rmtchar.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
- * include/nuttx/rmt/rmtchar.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 __INCLUDE_NUTTX_RMT_RMTCHAR_H
-#define __INCLUDE_NUTTX_RMT_RMTCHAR_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#include <nuttx/rmt/rmt.h>
-
-#ifdef CONFIG_RMTCHAR
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C"
-{
-#else
-#define EXTERN extern
-#endif
-
-/****************************************************************************
- * Public Functions Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Name: rmtchar_register
- *
- * Description:
- *   Create and register the RMT character driver.
- *
- *   The RMT character driver is a simple character driver that supports RMT
- *   transfers via read() and write(). This driver is primarily intended to
- *   support RMT testing. It is not suitable for use in any real driver
- *   application in its current form because its buffer management heuristics
- *   are dependent on the lower half driver (device-specific).
- *
- * Input Parameters:
- *   rmt - An instance of the lower half RMT driver
- *
- * Returned Value:
- *   OK if the driver was successfully registered; A negated errno value is
- *   returned on any failure.
- *
- ****************************************************************************/
-
-int rmtchar_register(FAR struct rmt_dev_s *rmt);
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* CONFIG_RMT */
-#endif /* __INCLUDE_NUTTX_RMT_RMTCHAR_H */

Reply via email to