You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2026/04/04 14:18:37 UTC

(nuttx) branch master updated (96005c6a7d8 -> 579684974af)

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

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


    from 96005c6a7d8  boards/risc-v/esp32c3: CMake added XIAO ESP32C3 board
     new 7b590f9c435 espressif/rmt: replace rmtchar with arch-specific lirc adapter
     new 140f2c1c780 docs/rc: document RC/LIRC drivers and remove empty drivers/rmt files
     new 703726849f4 espressif/rmt: guard lirc board registration with DRIVERS_RC
     new 579684974af espressif/ws2812: include esp_rmt.h in ws2812 headers

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


Summary of changes:
 Documentation/components/drivers/character/rc.rst  | 136 +++++++
 arch/risc-v/src/common/espressif/Kconfig           |  12 +-
 arch/risc-v/src/common/espressif/Make.defs         |   3 +
 arch/risc-v/src/common/espressif/esp_lirc.c        | 399 +++++++++++++++++++
 .../src/common/espressif/esp_lirc.h}               |  34 +-
 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/risc-v/src/common/espressif/esp_ws2812.h      |   2 +
 arch/xtensa/src/common/espressif/Kconfig           |  12 +-
 arch/xtensa/src/common/espressif/Make.defs         |   3 +
 arch/xtensa/src/common/espressif/esp_lirc.c        | 441 +++++++++++++++++++++
 .../src/common/espressif/esp_lirc.h}               |  34 +-
 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 -
 arch/xtensa/src/common/espressif/esp_ws2812.h      |   2 +
 boards/risc-v/esp32c3/common/src/esp_board_rmt.c   |  24 +-
 .../esp32c3/esp32c3-devkit/configs/rmt/defconfig   |   8 +-
 boards/risc-v/esp32c6/common/src/esp_board_rmt.c   |  24 +-
 .../esp32c6/esp32c6-devkitc/configs/rmt/defconfig  |   8 +-
 .../esp32c6/esp32c6-devkitm/configs/rmt/defconfig  |   8 +-
 boards/risc-v/esp32h2/common/src/esp_board_rmt.c   |  24 +-
 .../esp32h2/esp32h2-devkit/configs/rmt/defconfig   |   8 +-
 boards/risc-v/esp32p4/common/src/esp_board_rmt.c   |  24 +-
 .../configs/rmt/defconfig                          |   8 +-
 boards/xtensa/esp32/common/src/esp32_board_rmt.c   |  25 +-
 .../esp32/esp32-devkitc/configs/match4/defconfig   |   7 -
 .../esp32/esp32-devkitc/configs/rmt/defconfig      |   7 +-
 .../esp32/esp32-devkitc/configs/snake/defconfig    |   6 -
 .../xtensa/esp32s2/common/src/esp32s2_board_rmt.c  |  16 +-
 .../esp32s2/esp32s2-saola-1/configs/rmt/defconfig  |   7 +-
 .../xtensa/esp32s3/common/src/esp32s3_board_rmt.c  |  24 +-
 .../esp32s3-devkit/configs/python/defconfig        |   2 -
 .../esp32s3/esp32s3-devkit/configs/rmt/defconfig   |   8 +-
 drivers/Kconfig                                    |   1 -
 drivers/Makefile                                   |   1 -
 drivers/rmt/CMakeLists.txt                         |  31 --
 drivers/rmt/Kconfig                                |  47 ---
 drivers/rmt/Make.defs                              |  32 --
 drivers/rmt/rmtchar.c                              | 341 ----------------
 include/nuttx/rmt/rmt.h                            |  98 -----
 include/nuttx/rmt/rmtchar.h                        |  94 -----
 43 files changed, 1233 insertions(+), 796 deletions(-)
 create mode 100644 arch/risc-v/src/common/espressif/esp_lirc.c
 copy arch/{arm/src/cxd56xx/cxd56_emmc.h => risc-v/src/common/espressif/esp_lirc.h} (75%)
 create mode 100644 arch/xtensa/src/common/espressif/esp_lirc.c
 copy arch/{arm/src/cxd56xx/cxd56_emmc.h => xtensa/src/common/espressif/esp_lirc.h} (75%)
 delete mode 100644 drivers/rmt/CMakeLists.txt
 delete mode 100644 drivers/rmt/Kconfig
 delete mode 100644 drivers/rmt/Make.defs
 delete mode 100644 drivers/rmt/rmtchar.c
 delete mode 100644 include/nuttx/rmt/rmt.h
 delete mode 100644 include/nuttx/rmt/rmtchar.h


(nuttx) 02/04: docs/rc: document RC/LIRC drivers and remove empty drivers/rmt files

Posted by ac...@apache.org.
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 140f2c1c7801b32f37e9627c7b4e6e4e629cb77a
Author: Piyush Patle <pi...@gmail.com>
AuthorDate: Tue Mar 31 18:39:00 2026 +0530

    docs/rc: document RC/LIRC drivers and remove empty drivers/rmt files
    
    Add documentation for the RC/LIRC character driver subsystem covering
    device registration, the LIRC interface, and usage from user space.
    
    Remove placeholder empty files under drivers/rmt that were left over
    from the rmtchar era and are no longer referenced.
    
    Signed-off-by: Piyush Patle <pi...@gmail.com>
---
 Documentation/components/drivers/character/rc.rst  | 136 +++++++++++++++++++++
 arch/risc-v/src/common/espressif/Kconfig           |   1 -
 arch/risc-v/src/common/espressif/esp_lirc.h        |   8 ++
 arch/xtensa/src/common/espressif/Kconfig           |   1 -
 .../esp32/esp32-devkitc/configs/match4/defconfig   |   7 --
 .../esp32/esp32-devkitc/configs/snake/defconfig    |   6 -
 .../esp32s3-devkit/configs/python/defconfig        |   2 -
 drivers/Makefile                                   |   1 -
 drivers/rmt/CMakeLists.txt                         |  23 ----
 drivers/rmt/Kconfig                                |   4 -
 drivers/rmt/Make.defs                              |  21 ----
 11 files changed, 144 insertions(+), 66 deletions(-)

diff --git a/Documentation/components/drivers/character/rc.rst b/Documentation/components/drivers/character/rc.rst
index 4cb3d02d5e6..aebedd8c1d0 100644
--- a/Documentation/components/drivers/character/rc.rst
+++ b/Documentation/components/drivers/character/rc.rst
@@ -1,3 +1,139 @@
 ======================
 Remote Control Devices
 ======================
+
+NuttX provides a Remote Control (RC) framework for infrared style input and
+output devices. The userspace interface follows the LIRC model and exposes
+each device as a character node such as ``/dev/lirc0``.
+
+Like many NuttX drivers, the RC subsystem is split into two parts:
+
+#. a generic upper half in ``drivers/rc/lirc_dev.c``, and
+#. a lower half supplied by platform or device specific code.
+
+The upper half handles the character driver registration, per-open buffering,
+``poll()`` support, and the common ``ioctl()`` interface. The lower half is
+responsible for the hardware specific work such as receiving pulse timings,
+transmitting IR data, or reporting decoded scancodes.
+
+Files related to the RC framework are located in:
+
+- ``include/nuttx/lirc.h``
+- ``include/nuttx/rc/lirc_dev.h``
+- ``drivers/rc/lirc_dev.c``
+
+Application Programming Interface
+=================================
+
+Applications should include the following header files:
+
+.. code-block:: c
+
+  #include <nuttx/lirc.h>
+  #include <sys/ioctl.h>
+
+Each RC device is registered as a POSIX character device in ``/dev``.
+Applications open the device with the standard ``open()`` call and then use
+``read()``, ``write()``, ``poll()``, and ``ioctl()`` just like other character
+drivers.
+
+The RC framework supports three kinds of lower-half devices:
+
+- ``LIRC_DRIVER_SCANCODE`` for devices that report decoded scancodes
+- ``LIRC_DRIVER_IR_RAW`` for devices that report raw pulse/space timings
+- ``LIRC_DRIVER_IR_RAW_TX`` for transmit-only raw devices
+
+Raw Pulse/Space Format
+======================
+
+Raw IR timing is transferred in the LIRC ``mode2`` format. Each sample is a
+32-bit ``unsigned int`` value. The upper 8 bits describe the sample type and
+the lower 24 bits carry the payload, usually a duration in microseconds.
+
+The helpers in ``include/nuttx/lirc.h`` are intended to build and inspect
+these values:
+
+- ``LIRC_PULSE(usec)``
+- ``LIRC_SPACE(usec)``
+- ``LIRC_FREQUENCY(value)``
+- ``LIRC_TIMEOUT(usec)``
+- ``LIRC_IS_PULSE(sample)``
+- ``LIRC_IS_SPACE(sample)``
+- ``LIRC_VALUE(sample)``
+
+Typical raw transmit data looks like this:
+
+.. code-block:: c
+
+  unsigned int txbuf[] =
+  {
+    LIRC_PULSE(9000),
+    LIRC_SPACE(4500),
+    LIRC_PULSE(560),
+    LIRC_SPACE(560),
+    LIRC_PULSE(560),
+  };
+
+For raw transmit, ``write()`` expects an odd number of ``unsigned int``
+samples. The upper half forwards the pulse/space sequence to the lower-half
+``tx_ir()`` callback.
+
+IOCTL Commands
+==============
+
+The RC upper half supports the standard LIRC ``ioctl()`` commands defined in
+``include/nuttx/lirc.h``. Commonly used commands include:
+
+- ``LIRC_GET_FEATURES``
+- ``LIRC_GET_SEND_MODE``
+- ``LIRC_GET_REC_MODE``
+- ``LIRC_SET_SEND_MODE``
+- ``LIRC_SET_REC_MODE``
+- ``LIRC_GET_REC_RESOLUTION``
+- ``LIRC_SET_SEND_CARRIER``
+- ``LIRC_SET_SEND_DUTY_CYCLE``
+- ``LIRC_SET_REC_TIMEOUT``
+
+Support for a specific command depends on the lower-half capabilities. In
+practice, applications usually start by querying ``LIRC_GET_FEATURES`` and
+then only use the operations that the device advertises.
+
+Lower-Half Registration
+=======================
+
+Platform code registers an RC lower half by filling ``struct lirc_lowerhalf_s``
+and calling ``lirc_register()``.
+
+.. code-block:: c
+
+  int ret = lirc_register(lower, devno);
+
+The lower half provides a ``struct lirc_ops_s`` callback table. Depending on
+the hardware, it may implement open/close callbacks, raw transmit via
+``tx_ir()``, scancode transmit via ``tx_scancode()``, carrier and duty-cycle
+configuration, or receive timeout handling.
+
+Testing
+-------
+
+The ``irtest`` application in ``nuttx-apps/system/irtest`` can be used to
+exercise RC devices from NSH. A typical validation sequence is:
+
+#. open ``/dev/lircN``
+#. query ``LIRC_GET_FEATURES``
+#. query or set send / receive mode
+#. write raw mode2 samples on transmit-capable devices
+#. read back mode2 samples from receive-capable devices
+
+Espressif RMT LIRC Adapter
+==========================
+
+Espressif targets may provide an arch-local LIRC adapter built on top of the
+RMT peripheral:
+
+- ``arch/xtensa/src/common/espressif/esp_lirc.c``
+- ``arch/risc-v/src/common/espressif/esp_lirc.c``
+
+These adapters expose the RMT peripheral through the RC framework as
+``/dev/lircN`` devices while keeping the hardware specific RMT implementation
+in the Espressif lower-half driver.
diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig
index b09c4674268..4d9d6320a5a 100644
--- a/arch/risc-v/src/common/espressif/Kconfig
+++ b/arch/risc-v/src/common/espressif/Kconfig
@@ -1288,7 +1288,6 @@ config ESPRESSIF_BROWNOUT_DET
 config ESP_RMT
 	bool "Remote Control Module (RMT)"
 	default n
-	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
diff --git a/arch/risc-v/src/common/espressif/esp_lirc.h b/arch/risc-v/src/common/espressif/esp_lirc.h
index 2289f587c80..b86705d30fa 100644
--- a/arch/risc-v/src/common/espressif/esp_lirc.h
+++ b/arch/risc-v/src/common/espressif/esp_lirc.h
@@ -23,10 +23,18 @@
 #ifndef __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_LIRC_H
 #define __ARCH_RISC_V_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"
diff --git a/arch/xtensa/src/common/espressif/Kconfig b/arch/xtensa/src/common/espressif/Kconfig
index 4200e515de3..3a9b16cd316 100644
--- a/arch/xtensa/src/common/espressif/Kconfig
+++ b/arch/xtensa/src/common/espressif/Kconfig
@@ -71,7 +71,6 @@ endmenu # Interrupt Configuration
 config ESP_RMT
 	bool "Remote Control Module (RMT)"
 	default n
-	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
diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/match4/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/match4/defconfig
index 4d7d8567714..3de79d233ca 100644
--- a/boards/xtensa/esp32/esp32-devkitc/configs/match4/defconfig
+++ b/boards/xtensa/esp32/esp32-devkitc/configs/match4/defconfig
@@ -26,11 +26,7 @@ CONFIG_BUILTIN=y
 CONFIG_DEV_GPIO=y
 CONFIG_ESP32_UART0=y
 CONFIG_ESPRESSIF_GPIO_IRQ=y
-CONFIG_ESP_RMT=y
 CONFIG_EXAMPLES_GPIO=y
-CONFIG_EXAMPLES_RMTCHAR=y
-CONFIG_EXAMPLES_RMTCHAR_RX=y
-CONFIG_EXAMPLES_RMTCHAR_TX=y
 CONFIG_EXAMPLES_WS2812=y
 CONFIG_FS_PROCFS=y
 CONFIG_GAMES_MATCH4=y
@@ -50,9 +46,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_LPWORK=y
 CONFIG_SCHED_WAITPID=y
diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/snake/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/snake/defconfig
index 59ee3080301..2811e201e7a 100644
--- a/boards/xtensa/esp32/esp32-devkitc/configs/snake/defconfig
+++ b/boards/xtensa/esp32/esp32-devkitc/configs/snake/defconfig
@@ -28,9 +28,6 @@ CONFIG_ESP32_UART0=y
 CONFIG_ESPRESSIF_GPIO_IRQ=y
 CONFIG_ESP_RMT=y
 CONFIG_EXAMPLES_GPIO=y
-CONFIG_EXAMPLES_RMTCHAR=y
-CONFIG_EXAMPLES_RMTCHAR_RX=y
-CONFIG_EXAMPLES_RMTCHAR_TX=y
 CONFIG_EXAMPLES_WS2812=y
 CONFIG_FS_PROCFS=y
 CONFIG_GAMES_SNAKE=y
@@ -50,9 +47,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_LPWORK=y
 CONFIG_SCHED_WAITPID=y
diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/python/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/python/defconfig
index 5889128709b..2b5342cb3c0 100644
--- a/boards/xtensa/esp32s3/esp32s3-devkit/configs/python/defconfig
+++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/python/defconfig
@@ -91,8 +91,6 @@ CONFIG_PSEUDOFS_SOFTLINKS=y
 CONFIG_PTHREAD_MUTEX_TYPES=y
 CONFIG_RAM_SIZE=114688
 CONFIG_RAM_START=0x20000000
-CONFIG_RMT=y
-CONFIG_RMTCHAR=y
 CONFIG_RR_INTERVAL=200
 CONFIG_RTC=y
 CONFIG_RTC_DRIVER=y
diff --git a/drivers/Makefile b/drivers/Makefile
index 72f4a0c4367..adeb7a25f02 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -59,7 +59,6 @@ include pinctrl/Make.defs
 include pipes/Make.defs
 include power/Make.defs
 include regmap/Make.defs
-include rmt/Make.defs
 include rpmsg/Make.defs
 include rptun/Make.defs
 include sensors/Make.defs
diff --git a/drivers/rmt/CMakeLists.txt b/drivers/rmt/CMakeLists.txt
deleted file mode 100644
index 41f66775498..00000000000
--- a/drivers/rmt/CMakeLists.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-# ##############################################################################
-# drivers/rmt/CMakeLists.txt
-#
-# 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.
-#
-# ##############################################################################
-
-# RMT character driver removed; RMT upper-half is now arch/espressif/esp_lirc.c
diff --git a/drivers/rmt/Kconfig b/drivers/rmt/Kconfig
deleted file mode 100644
index f72f3c094ce..00000000000
--- a/drivers/rmt/Kconfig
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see the file kconfig-language.txt in the NuttX tools repository.
-#
diff --git a/drivers/rmt/Make.defs b/drivers/rmt/Make.defs
deleted file mode 100644
index 5f6b700ac29..00000000000
--- a/drivers/rmt/Make.defs
+++ /dev/null
@@ -1,21 +0,0 @@
-############################################################################
-# drivers/rmt/Make.defs
-#
-# 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.
-#
-############################################################################


(nuttx) 01/04: espressif/rmt: replace rmtchar with arch-specific lirc adapter

Posted by ac...@apache.org.
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 <pi...@gmail.com>
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 <pi...@gmail.com>
---
 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 */


(nuttx) 04/04: espressif/ws2812: include esp_rmt.h in ws2812 headers

Posted by ac...@apache.org.
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 579684974afa70067c6aad36476a48dac3651b00
Author: Piyush Patle <pi...@gmail.com>
AuthorDate: Fri Apr 3 03:08:27 2026 +0530

    espressif/ws2812: include esp_rmt.h in ws2812 headers
    
    esp_ws2812.h exposes esp_ws2812_setup() with a struct rmt_dev_s * argument
    but did not include esp_rmt.h directly.
    
    After guarding the LIRC board registration path with CONFIG_DRIVERS_RC,
    non-RC ESP configs no longer pulled in the RMT type indirectly and CI
    started failing with an incomplete struct rmt_dev_s declaration.
    
    Include esp_rmt.h in the Xtensa and RISC-V ws2812 headers.
    
    Signed-off-by: Piyush Patle <pi...@gmail.com>
---
 arch/risc-v/src/common/espressif/esp_ws2812.h | 2 ++
 arch/xtensa/src/common/espressif/esp_ws2812.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/risc-v/src/common/espressif/esp_ws2812.h b/arch/risc-v/src/common/espressif/esp_ws2812.h
index 098a3f05924..119241d16bf 100644
--- a/arch/risc-v/src/common/espressif/esp_ws2812.h
+++ b/arch/risc-v/src/common/espressif/esp_ws2812.h
@@ -31,6 +31,8 @@
 #include <debug.h>
 #include <stdbool.h>
 
+#include "esp_rmt.h"
+
 #ifndef __ASSEMBLY__
 #if defined(__cplusplus)
 #define EXTERN extern "C"
diff --git a/arch/xtensa/src/common/espressif/esp_ws2812.h b/arch/xtensa/src/common/espressif/esp_ws2812.h
index 2f769d22759..e307fff5521 100644
--- a/arch/xtensa/src/common/espressif/esp_ws2812.h
+++ b/arch/xtensa/src/common/espressif/esp_ws2812.h
@@ -31,6 +31,8 @@
 #include <debug.h>
 #include <stdbool.h>
 
+#include "esp_rmt.h"
+
 #ifndef __ASSEMBLY__
 #if defined(__cplusplus)
 #define EXTERN extern "C"


(nuttx) 03/04: espressif/rmt: guard lirc board registration with DRIVERS_RC

Posted by ac...@apache.org.
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 703726849f462adacf609abce6bb38811c646365
Author: Piyush Patle <pi...@gmail.com>
AuthorDate: Fri Apr 3 00:45:05 2026 +0530

    espressif/rmt: guard lirc board registration with DRIVERS_RC
    
    The common ESP board RMT bring-up files are built whenever ESP_RMT is
    enabled, but the esp_lirc declarations are only visible when DRIVERS_RC
    is enabled.
    
    Guard the esp_lirc header include and esp_lirc_rx_initialize() /
    esp_lirc_tx_initialize() calls with CONFIG_DRIVERS_RC so non-RC ESP
    configs continue to build while keeping the LIRC registration path for
    the rmt configs.
    
    Signed-off-by: Piyush Patle <pi...@gmail.com>
---
 boards/risc-v/esp32c3/common/src/esp_board_rmt.c     | 6 ++++++
 boards/risc-v/esp32c6/common/src/esp_board_rmt.c     | 6 ++++++
 boards/risc-v/esp32h2/common/src/esp_board_rmt.c     | 6 ++++++
 boards/risc-v/esp32p4/common/src/esp_board_rmt.c     | 6 ++++++
 boards/xtensa/esp32/common/src/esp32_board_rmt.c     | 6 ++++++
 boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c | 6 ++++++
 boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c | 6 ++++++
 7 files changed, 42 insertions(+)

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 aeb12505cdc..ed0cecc3521 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,9 @@
 #include <stdio.h>
 
 #include <nuttx/kmalloc.h>
+#ifdef CONFIG_DRIVERS_RC
 #include "espressif/esp_lirc.h"
+#endif
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -96,12 +98,14 @@ int board_rmt_rxinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
   return ret;
 }
@@ -135,12 +139,14 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
   led = esp_ws2812_setup("/dev/leds0", rmt, CONFIG_WS2812_LED_COUNT, false);
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 a92a445c604..7be1f4ddc7b 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,9 @@
 #include <stdio.h>
 
 #include <nuttx/kmalloc.h>
+#ifdef CONFIG_DRIVERS_RC
 #include "espressif/esp_lirc.h"
+#endif
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -96,12 +98,14 @@ int board_rmt_rxinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
   return ret;
 }
@@ -135,12 +139,14 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
   led = esp_ws2812_setup("/dev/leds0", rmt, CONFIG_WS2812_LED_COUNT, false);
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 514fa6d5d17..a73489c381e 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,9 @@
 #include <stdio.h>
 
 #include <nuttx/kmalloc.h>
+#ifdef CONFIG_DRIVERS_RC
 #include "espressif/esp_lirc.h"
+#endif
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -96,12 +98,14 @@ int board_rmt_rxinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
   return ret;
 }
@@ -135,12 +139,14 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
   led = esp_ws2812_setup("/dev/leds0", rmt, CONFIG_WS2812_LED_COUNT, false);
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 e432c914885..1e69828d874 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,9 @@
 #include <stdio.h>
 
 #include <nuttx/kmalloc.h>
+#ifdef CONFIG_DRIVERS_RC
 #include "espressif/esp_lirc.h"
+#endif
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -96,12 +98,14 @@ int board_rmt_rxinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
   return ret;
 }
@@ -135,12 +139,14 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
   led = esp_ws2812_setup("/dev/leds0", rmt, CONFIG_WS2812_LED_COUNT, false);
diff --git a/boards/xtensa/esp32/common/src/esp32_board_rmt.c b/boards/xtensa/esp32/common/src/esp32_board_rmt.c
index 4e8c8864453..b4eb9172db3 100644
--- a/boards/xtensa/esp32/common/src/esp32_board_rmt.c
+++ b/boards/xtensa/esp32/common/src/esp32_board_rmt.c
@@ -33,7 +33,9 @@
 #include "xtensa.h"
 
 #include <nuttx/kmalloc.h>
+#ifdef CONFIG_DRIVERS_RC
 #include "espressif/esp_lirc.h"
+#endif
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -98,12 +100,14 @@ int board_rmt_rxinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
   return ret;
 }
@@ -137,12 +141,14 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
   led = esp_ws2812_setup("/dev/leds0", rmt,
diff --git a/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c b/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c
index 710af33ebde..6a4328d195f 100644
--- a/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c
+++ b/boards/xtensa/esp32s2/common/src/esp32s2_board_rmt.c
@@ -33,7 +33,9 @@
 #include "xtensa.h"
 
 #include <nuttx/kmalloc.h>
+#ifdef CONFIG_DRIVERS_RC
 #include "espressif/esp_lirc.h"
+#endif
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -98,12 +100,14 @@ int board_rmt_rxinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
   return ret;
 }
@@ -137,12 +141,14 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
   led = esp_ws2812_setup("/dev/leds0", rmt, CONFIG_WS2812_LED_COUNT, false);
diff --git a/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c b/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c
index 3d96b8613d3..be1d8f2ca71 100644
--- a/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c
+++ b/boards/xtensa/esp32s3/common/src/esp32s3_board_rmt.c
@@ -33,7 +33,9 @@
 #include "xtensa.h"
 
 #include <nuttx/kmalloc.h>
+#ifdef CONFIG_DRIVERS_RC
 #include "espressif/esp_lirc.h"
+#endif
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
 #include <nuttx/leds/ws2812.h>
 
@@ -98,12 +100,14 @@ int board_rmt_rxinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_rx_initialize(0, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_rx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
   return ret;
 }
@@ -137,12 +141,14 @@ int board_rmt_txinitialize(int pin)
       return -ENODEV;
     }
 
+#ifdef CONFIG_DRIVERS_RC
   ret = esp_lirc_tx_initialize(1, rmt);
   if (ret < 0)
     {
       rmterr("ERROR: esp_lirc_tx_initialize failed: %d\n", ret);
       return ret;
     }
+#endif
 
 #ifdef CONFIG_WS2812_NON_SPI_DRIVER
   led = esp_ws2812_setup("/dev/leds0", rmt, CONFIG_WS2812_LED_COUNT, false);