Parcourir la source

esp_hw_support/sleep: fix current leakage when hold digital io during deep sleep

jingli il y a 3 ans
Parent
commit
b903a2253b

+ 3 - 1
components/driver/include/driver/gpio.h

@@ -25,7 +25,9 @@ extern "C" {
 /// Check whether it can be a valid GPIO number of output mode
 #define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((gpio_num >= 0) && \
                                               (((1ULL << (gpio_num)) & SOC_GPIO_VALID_OUTPUT_GPIO_MASK) != 0))
-
+/// Check whether it can be a valid digital I/O pad
+#define GPIO_IS_VALID_DIGITAL_IO_PAD(gpio_num) ((gpio_num >= 0) && \
+                                                 (((1ULL << (gpio_num)) & SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK) != 0))
 
 typedef intr_handle_t gpio_isr_handle_t;
 

+ 10 - 0
components/esp_hw_support/include/esp_private/esp_sleep_internal.h

@@ -6,6 +6,7 @@
 
 #pragma once
 #include <stdbool.h>
+#include "sdkconfig.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -20,6 +21,15 @@ extern "C" {
  */
 void esp_sleep_enable_adc_tsens_monitor(bool enable);
 
+// TODO: IDF-6051, IDF-6052
+#if !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C6
+/**
+ * @brief Isolate all digital IOs except those that are held during deep sleep
+ *
+ * Reduce digital IOs current leakage during deep sleep.
+ */
+void esp_sleep_isolate_digital_gpio(void);
+#endif
 
 #ifdef __cplusplus
 }

+ 43 - 0
components/esp_hw_support/sleep_gpio.c

@@ -12,11 +12,13 @@
 #include "esp_attr.h"
 #include "esp_sleep.h"
 #include "esp_log.h"
+#include "esp_memory_utils.h"
 #include "soc/soc_caps.h"
 
 #include "sdkconfig.h"
 
 #include "driver/gpio.h"
+#include "hal/gpio_hal.h"
 #include "esp_private/gpio.h"
 #include "esp_private/sleep_gpio.h"
 #include "esp_private/spi_flash_os.h"
@@ -94,3 +96,44 @@ void esp_sleep_enable_gpio_switch(bool enable)
 }
 
 #endif // SOC_GPIO_SUPPORT_SLP_SWITCH
+
+// TODO: IDF-6051, IDF-6052
+#if !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C6
+IRAM_ATTR void esp_sleep_isolate_digital_gpio(void)
+{
+    gpio_hal_context_t gpio_hal = {
+        .dev = GPIO_HAL_GET_HW(GPIO_PORT_0)
+    };
+
+    /* no need to do isolate if digital IOs are not being held in deep sleep */
+    if (!gpio_hal_deep_sleep_hold_is_en(&gpio_hal)) {
+        return;
+    }
+
+    /**
+     * there is a situation where we cannot isolate digital IO before deep sleep:
+     * - task stack is located in external ram(mspi ram), since we will isolate mspi io
+     *
+     * assert here instead of returning directly, because if digital IO is not isolated,
+     * the bottom current of deep sleep will be higher than light sleep, and there is no
+     * reason to use deep sleep at this time.
+     */
+    assert(esp_ptr_internal(&gpio_hal) && "If hold digital IO, the stack of the task calling esp_deep_sleep_start must be in internal ram!");
+
+    /* isolate digital IO that is not held(keep the configuration of digital IOs held by users) */
+    for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
+        if (GPIO_IS_VALID_DIGITAL_IO_PAD(gpio_num) && !gpio_hal_is_digital_io_hold(&gpio_hal, gpio_num)) {
+            /* disable I/O */
+            gpio_hal_input_disable(&gpio_hal, gpio_num);
+            gpio_hal_output_disable(&gpio_hal, gpio_num);
+
+            /* disable pull up/down */
+            gpio_hal_pullup_dis(&gpio_hal, gpio_num);
+            gpio_hal_pulldown_dis(&gpio_hal, gpio_num);
+
+            /* make pad work as gpio(otherwise, deep sleep bottom current will rise) */
+            gpio_hal_func_sel(&gpio_hal, gpio_num, PIN_FUNC_GPIO);
+        }
+    }
+}
+#endif

+ 6 - 0
components/esp_hw_support/sleep_modes.c

@@ -12,6 +12,7 @@
 #include "esp_attr.h"
 #include "esp_memory_utils.h"
 #include "esp_sleep.h"
+#include "esp_private/esp_sleep_internal.h"
 #include "esp_private/esp_timer_private.h"
 #include "esp_private/system_internal.h"
 #include "esp_log.h"
@@ -516,6 +517,11 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
          */
         portENTER_CRITICAL(&spinlock_rtc_deep_sleep);
 
+// TODO: IDF-6051, IDF-6052
+#if !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C6
+        esp_sleep_isolate_digital_gpio();
+#endif
+
 #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
         extern char _rtc_text_start[];
 #if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM

+ 67 - 3
components/hal/esp32/include/hal/gpio_ll.h

@@ -27,6 +27,9 @@
 extern "C" {
 #endif
 
+// the address of esp32's IO_MUX_GPIOx_REGs are not incremented as the gpio number increments(address are out of order)
+extern const uint8_t GPIO_PIN_MUX_REG_OFFSET[SOC_GPIO_PIN_COUNT];
+
 // Get GPIO hardware instance with giving gpio num
 #define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL)
 
@@ -53,9 +56,10 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
+    REG_CLR_BIT(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num], FUN_PU);
 }
 
 /**
@@ -87,9 +91,10 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
+    REG_CLR_BIT(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num], FUN_PD);
 }
 
 /**
@@ -303,9 +308,10 @@ static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
+    PIN_INPUT_DISABLE(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num]);
 }
 
 /**
@@ -325,6 +331,7 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
 {
     if (gpio_num < 32) {
@@ -419,6 +426,18 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num)
     hw->pin[gpio_num].pad_driver = 1;
 }
 
+/**
+ * @brief  Select a function for the pin in the IOMUX
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ * @param  gpio_num GPIO number
+ * @param  func Function to assign to the pin
+ */
+static inline __attribute__((always_inline)) void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
+{
+    PIN_FUNC_SELECT(DR_REG_IO_MUX_BASE + GPIO_PIN_MUX_REG_OFFSET[gpio_num], func);
+}
+
 /**
  * @brief  GPIO set output level
  *
@@ -531,6 +550,21 @@ static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
     CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
 }
 
+/**
+ * @brief  Get deep sleep hold status
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ *
+ * @return
+ *     - true  deep sleep hold is enabled
+ *     - false deep sleep hold is disabled
+ */
+__attribute__((always_inline))
+static inline bool gpio_ll_deep_sleep_hold_is_en(gpio_dev_t *hw)
+{
+    return !GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD) && GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
+}
+
 /**
   * @brief Enable gpio pad hold function.
   *
@@ -553,6 +587,36 @@ static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
     CLEAR_PERI_REG_MASK(RTC_IO_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
 }
 
+/**
+  * @brief Get digital gpio pad hold status.
+  *
+  * @param hw Peripheral GPIO hardware instance address.
+  * @param gpio_num GPIO number, only support output GPIOs
+  *
+  * @note caller must ensure that gpio_num is a digital io pad
+  *
+  * @return
+  *     - true  digital gpio pad is held
+  *     - false digital gpio pad is unheld
+  */
+__attribute__((always_inline))
+static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
+{
+    uint32_t mask = 0;
+
+    switch (gpio_num) {
+    case 1: mask = BIT(1); break;
+    case 3: mask = BIT(0); break;
+    case 5: mask = BIT(8); break;
+    case 6 ... 11 : mask = BIT(gpio_num - 4); break;
+    case 16 ... 19:
+    case 21 ... 23: mask = BIT(gpio_num - 7); break;
+    default: break;
+    }
+
+    return GET_PERI_REG_MASK(RTC_IO_DIG_PAD_HOLD_REG, mask);
+}
+
 /**
   * @brief Set pad input to a peripheral signal through the IOMUX.
   *

+ 54 - 4
components/hal/esp32c2/include/hal/gpio_ll.h

@@ -14,12 +14,13 @@
 
 #pragma once
 
+#include <stdlib.h>
+#include <stdbool.h>
 #include "soc/soc.h"
 #include "soc/gpio_periph.h"
 #include "soc/rtc_cntl_reg.h"
 #include "hal/gpio_types.h"
 #include "hal/assert.h"
-#include "stdlib.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -47,9 +48,10 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
+    REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU);
 }
 
 /**
@@ -69,9 +71,10 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
+    REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD);
 }
 
 /**
@@ -168,9 +171,10 @@ static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
+    PIN_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
 }
 
 /**
@@ -190,6 +194,7 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
 {
     hw->enable_w1tc.enable_w1tc = (0x1 << gpio_num);
@@ -231,6 +236,18 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num)
     hw->pin[gpio_num].pad_driver = 1;
 }
 
+/**
+ * @brief  Select a function for the pin in the IOMUX
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ * @param  gpio_num GPIO number
+ * @param  func Function to assign to the pin
+ */
+static inline __attribute__((always_inline)) void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
+{
+    PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
+}
+
 /**
  * @brief  GPIO set output level
  *
@@ -332,6 +349,21 @@ static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
     SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
 }
 
+/**
+ * @brief  Get deep sleep hold status
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ *
+ * @return
+ *     - true  deep sleep hold is enabled
+ *     - false deep sleep hold is disabled
+ */
+__attribute__((always_inline))
+static inline bool gpio_ll_deep_sleep_hold_is_en(gpio_dev_t *hw)
+{
+    return !GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD) && GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
+}
+
 /**
   * @brief Enable gpio pad hold function.
   *
@@ -362,6 +394,24 @@ static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
     }
 }
 
+/**
+  * @brief Get digital gpio pad hold status.
+  *
+  * @param hw Peripheral GPIO hardware instance address.
+  * @param gpio_num GPIO number, only support output GPIOs
+  *
+  * @note caller must ensure that gpio_num is a digital io pad
+  *
+  * @return
+  *     - true  digital gpio pad is held
+  *     - false digital gpio pad is unheld
+  */
+__attribute__((always_inline))
+static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
+{
+    return GET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, BIT(gpio_num));
+}
+
 /**
   * @brief Set pad input to a peripheral signal through the IOMUX.
   *

+ 58 - 4
components/hal/esp32c3/include/hal/gpio_ll.h

@@ -14,6 +14,8 @@
 
 #pragma once
 
+#include <stdlib.h>
+#include <stdbool.h>
 #include "soc/soc.h"
 #include "soc/gpio_periph.h"
 #include "soc/gpio_struct.h"
@@ -21,7 +23,6 @@
 #include "soc/usb_serial_jtag_reg.h"
 #include "hal/gpio_types.h"
 #include "hal/assert.h"
-#include "stdlib.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -49,6 +50,7 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
 {
     // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value
@@ -57,7 +59,7 @@ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
         SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE);
         CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP);
     }
-    REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
+    REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU);
 }
 
 /**
@@ -77,9 +79,10 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
+    REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD);
 }
 
 /**
@@ -176,9 +179,10 @@ static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
+    PIN_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
 }
 
 /**
@@ -198,6 +202,7 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
 {
     hw->enable_w1tc.enable_w1tc = (0x1 << gpio_num);
@@ -239,6 +244,22 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num)
     hw->pin[gpio_num].pad_driver = 1;
 }
 
+/**
+ * @brief  Select a function for the pin in the IOMUX
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ * @param  gpio_num GPIO number
+ * @param  func Function to assign to the pin
+ */
+static inline __attribute__((always_inline)) void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
+{
+    // Disable USB Serial JTAG if pins 18 or pins 19 needs to select an IOMUX function
+    if (gpio_num == 18 || gpio_num == 19) {
+        CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
+    }
+    PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
+}
+
 /**
  * @brief  GPIO set output level
  *
@@ -340,6 +361,21 @@ static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
     SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
 }
 
+/**
+ * @brief  Get deep sleep hold status
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ *
+ * @return
+ *     - true  deep sleep hold is enabled
+ *     - false deep sleep hold is disabled
+ */
+__attribute__((always_inline))
+static inline bool gpio_ll_deep_sleep_hold_is_en(gpio_dev_t *hw)
+{
+    return !GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD) && GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
+}
+
 /**
   * @brief Enable gpio pad hold function.
   *
@@ -370,6 +406,24 @@ static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
     }
 }
 
+/**
+  * @brief Get digital gpio pad hold status.
+  *
+  * @param hw Peripheral GPIO hardware instance address.
+  * @param gpio_num GPIO number, only support output GPIOs
+  *
+  * @note caller must ensure that gpio_num is a digital io pad
+  *
+  * @return
+  *     - true  digital gpio pad is held
+  *     - false digital gpio pad is unheld
+  */
+__attribute__((always_inline))
+static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
+{
+    return GET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, BIT(gpio_num));
+}
+
 /**
   * @brief Set pad input to a peripheral signal through the IOMUX.
   *

+ 55 - 5
components/hal/esp32s2/include/hal/gpio_ll.h

@@ -14,6 +14,7 @@
 
 #pragma once
 
+#include <stdbool.h>
 #include "soc/soc.h"
 #include "soc/gpio_periph.h"
 #include "soc/rtc_cntl_reg.h"
@@ -49,9 +50,10 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
+    REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU);
 }
 
 /**
@@ -71,9 +73,10 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
+    REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD);
 }
 
 /**
@@ -170,9 +173,10 @@ static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
+    PIN_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
 }
 
 /**
@@ -192,6 +196,7 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
 {
     if (gpio_num < 32) {
@@ -242,6 +247,18 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num)
     hw->pin[gpio_num].pad_driver = 1;
 }
 
+/**
+ * @brief  Select a function for the pin in the IOMUX
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ * @param  gpio_num GPIO number
+ * @param  func Function to assign to the pin
+ */
+static inline __attribute__((always_inline)) void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
+{
+    PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
+}
+
 /**
  * @brief  GPIO set output level
  *
@@ -354,6 +371,21 @@ static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
     SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
 }
 
+/**
+ * @brief  Get deep sleep hold status
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ *
+ * @return
+ *     - true  deep sleep hold is enabled
+ *     - false deep sleep hold is disabled
+ */
+__attribute__((always_inline))
+static inline bool gpio_ll_deep_sleep_hold_is_en(gpio_dev_t *hw)
+{
+    return !GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD) && GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
+}
+
 /**
   * @brief Enable gpio pad hold function.
   *
@@ -376,6 +408,24 @@ static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
     CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
 }
 
+/**
+  * @brief Get digital gpio pad hold status.
+  *
+  * @param hw Peripheral GPIO hardware instance address.
+  * @param gpio_num GPIO number, only support output GPIOs
+  *
+  * @note caller must ensure that gpio_num is a digital io pad
+  *
+  * @return
+  *     - true  digital gpio pad is held
+  *     - false digital gpio pad is unheld
+  */
+__attribute__((always_inline))
+static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
+{
+    return GET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, BIT(gpio_num - 21));
+}
+
 /**
   * @brief Set pad input to a peripheral signal through the IOMUX.
   *
@@ -417,7 +467,7 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func,
 }
 
 /**
-  * @brief Force hold digital and rtc gpio pad.
+  * @brief Force hold digital gpio pad.
   * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
   */
 static inline void gpio_ll_force_hold_all(void)
@@ -427,7 +477,7 @@ static inline void gpio_ll_force_hold_all(void)
 }
 
 /**
-  * @brief Force unhold digital and rtc gpio pad.
+  * @brief Force unhold digital gpio pad.
   * @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
   */
 static inline void gpio_ll_force_unhold_all(void)

+ 58 - 5
components/hal/esp32s3/include/hal/gpio_ll.h

@@ -14,6 +14,7 @@
 
 #pragma once
 
+#include <stdbool.h>
 #include "soc/soc.h"
 #include "soc/gpio_periph.h"
 #include "soc/rtc_cntl_reg.h"
@@ -50,6 +51,7 @@ static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
 {
     // The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value
@@ -60,7 +62,7 @@ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
         SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE);
         CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP);
     }
-    REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
+    REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU);
 }
 
 /**
@@ -80,9 +82,10 @@ static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
+    REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD);
 }
 
 /**
@@ -183,9 +186,10 @@ static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
 {
-    PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
+    PIN_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
 }
 
 /**
@@ -205,6 +209,7 @@ static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
   * @param hw Peripheral GPIO hardware instance address.
   * @param gpio_num GPIO number
   */
+__attribute__((always_inline))
 static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
 {
     if (gpio_num < 32) {
@@ -255,6 +260,21 @@ static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num)
     hw->pin[gpio_num].pad_driver = 1;
 }
 
+/**
+ * @brief  Select a function for the pin in the IOMUX
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ * @param  gpio_num GPIO number
+ * @param  func Function to assign to the pin
+ */
+static inline __attribute__((always_inline)) void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
+{
+    if (gpio_num == 19 || gpio_num == 20) {
+        CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
+    }
+    PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
+}
+
 /**
  * @brief  GPIO set output level
  *
@@ -367,6 +387,21 @@ static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
     SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
 }
 
+/**
+ * @brief  Get deep sleep hold status
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ *
+ * @return
+ *     - true  deep sleep hold is enabled
+ *     - false deep sleep hold is disabled
+ */
+__attribute__((always_inline))
+static inline bool gpio_ll_deep_sleep_hold_is_en(gpio_dev_t *hw)
+{
+    return !GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD) && GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
+}
+
 /**
   * @brief Enable gpio pad hold function.
   *
@@ -389,6 +424,24 @@ static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
     CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
 }
 
+/**
+  * @brief Get gpio pad hold status.
+  *
+  * @param hw Peripheral GPIO hardware instance address.
+  * @param gpio_num GPIO number, only support output GPIOs
+  *
+  * @note caller must ensure that gpio_num is a digital io pad
+  *
+  * @return
+  *     - true  digital gpio pad is held
+  *     - false digital gpio pad is unheld
+  */
+__attribute__((always_inline))
+static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
+{
+    return GET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, BIT(gpio_num - 21));
+}
+
 /**
   * @brief Set pad input to a peripheral signal through the IOMUX.
   *
@@ -433,7 +486,7 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func,
 }
 
 /**
-  * @brief Force hold digital and rtc gpio pad.
+  * @brief Force hold digital gpio pad.
   * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
   */
 static inline void gpio_ll_force_hold_all(void)
@@ -443,7 +496,7 @@ static inline void gpio_ll_force_hold_all(void)
 }
 
 /**
-  * @brief Force unhold digital and rtc gpio pad.
+  * @brief Force unhold digital gpio pad.
   * @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
   */
 static inline void gpio_ll_force_unhold_all(void)

+ 38 - 2
components/hal/include/hal/gpio_hal.h

@@ -168,6 +168,15 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num);
   */
 #define gpio_hal_od_enable(hal, gpio_num) gpio_ll_od_enable((hal)->dev, gpio_num)
 
+/**
+ * @brief  Select a function for the pin in the IOMUX
+ *
+ * @param  hw Peripheral GPIO hardware instance address.
+ * @param  gpio_num GPIO number
+ * @param  func Function to assign to the pin
+ */
+#define gpio_hal_func_sel(hal, gpio_num, func)  gpio_ll_func_sel((hal)->dev, gpio_num, func)
+
 /**
  * @brief  GPIO set output level
  *
@@ -260,6 +269,22 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num);
   */
 #define gpio_hal_hold_dis(hal, gpio_num) gpio_ll_hold_dis((hal)->dev, gpio_num)
 
+/**
+  * @brief Get wether digital gpio pad is held
+  *
+  * @param hal Context of the HAL layer
+  * @param gpio_num GPIO number, only support output GPIOs
+  *
+  * @note digital io means io pad powered by VDD3P3_CPU or VDD_SPI
+  *       rtc io means io pad powered by VDD3P3_RTC
+  *       caller must ensure that gpio_num is a digital io pad
+  *
+  * @return
+  *     - true  digital gpio pad is held
+  *     - false digital gpio pad is unheld
+  */
+#define gpio_hal_is_digital_io_hold(hal, gpio_num) gpio_ll_is_digital_io_hold((hal)->dev, gpio_num)
+
 /**
   * @brief Enable all digital gpio pad hold function during Deep-sleep.
   *
@@ -280,6 +305,17 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num);
   */
 #define gpio_hal_deep_sleep_hold_dis(hal) gpio_ll_deep_sleep_hold_dis((hal)->dev)
 
+/**
+  * @brief Get whether all digital gpio pad hold function during Deep-sleep is enabled.
+  *
+  * @param hal Context of the HAL layer
+  *
+  * @return
+  *     - true  deep sleep hold is enabled
+  *     - false deep sleep hold is disabled
+  */
+#define gpio_hal_deep_sleep_hold_is_en(hal) gpio_ll_deep_sleep_hold_is_en((hal)->dev)
+
 /**
   * @brief Set pad input to a peripheral signal through the IOMUX.
   *
@@ -302,13 +338,13 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num);
 
 #if SOC_GPIO_SUPPORT_FORCE_HOLD
 /**
-  * @brief Force hold digital and rtc gpio pad.
+  * @brief Force hold digital gpio pad.
   * @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
   */
 #define gpio_hal_force_hold_all() gpio_ll_force_hold_all()
 
 /**
-  * @brief Force unhold digital and rtc gpio pad.
+  * @brief Force unhold digital gpio pad.
   * @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
   */
 #define gpio_hal_force_unhold_all() gpio_ll_force_unhold_all()

+ 44 - 0
components/soc/esp32/gpio_periph.c

@@ -5,6 +5,7 @@
  */
 
 #include "soc/gpio_periph.h"
+#include "esp_attr.h"
 
 const uint32_t GPIO_PIN_MUX_REG[] = {
     IO_MUX_GPIO0_REG,
@@ -49,6 +50,49 @@ const uint32_t GPIO_PIN_MUX_REG[] = {
     IO_MUX_GPIO39_REG,
 };
 
+DRAM_ATTR const uint8_t GPIO_PIN_MUX_REG_OFFSET[] = {
+    0x44,
+    0x88,
+    0x40,
+    0x84,
+    0x48,
+    0x6c,
+    0x60,
+    0x64,
+    0x68,
+    0x54,
+    0x58,
+    0x5c,
+    0x34,
+    0x38,
+    0x30,
+    0x3c,
+    0x4c,
+    0x50,
+    0x70,
+    0x74,
+    0x78,
+    0x7c,
+    0x80,
+    0x8c,
+    0xFF, // 24
+    0x24,
+    0x28,
+    0x2c,
+    0xFF, // 28
+    0xFF, // 29
+    0xFF, // 30
+    0xFF, // 31
+    0x1c,
+    0x20,
+    0x14,
+    0x18,
+    0x04,
+    0x08,
+    0x0c,
+    0x10,
+};
+
 _Static_assert(sizeof(GPIO_PIN_MUX_REG) == SOC_GPIO_PIN_COUNT * sizeof(uint32_t), "Invalid size of GPIO_PIN_MUX_REG");
 
 const uint32_t GPIO_HOLD_MASK[] = {

+ 4 - 0
components/soc/esp32/include/soc/Kconfig.soc_caps.in

@@ -263,6 +263,10 @@ config SOC_GPIO_VALID_GPIO_MASK
     hex
     default 0xFFFFFFFFFF
 
+config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
+    hex
+    default 0xEF0FEA
+
 config SOC_GPIO_SUPPORT_SLP_SWITCH
     bool
     default y

+ 3 - 0
components/soc/esp32/include/soc/soc_caps.h

@@ -165,6 +165,9 @@
 // GPIO >= 34 are input only
 #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK (SOC_GPIO_VALID_GPIO_MASK & ~(0ULL | BIT34 | BIT35 | BIT36 | BIT37 | BIT38 | BIT39))
 
+// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM: 1, 3, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 21, 22, 23)
+#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0xEF0FEAULL
+
 // Support to configure slept status
 #define SOC_GPIO_SUPPORT_SLP_SWITCH  (1)
 

+ 4 - 0
components/soc/esp32c2/include/soc/Kconfig.soc_caps.in

@@ -223,6 +223,10 @@ config SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK
     int
     default 0
 
+config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
+    hex
+    default 0x00000000001FFFC0
+
 config SOC_GPIO_SUPPORT_SLP_SWITCH
     bool
     default y

+ 3 - 0
components/soc/esp32c2/include/soc/soc_caps.h

@@ -115,6 +115,9 @@
 #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK SOC_GPIO_VALID_GPIO_MASK
 #define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK        (0ULL | BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5)
 
+// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_6~GPIO_NUM_20)
+#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x00000000001FFFC0ULL
+
 // Support to configure sleep status
 #define SOC_GPIO_SUPPORT_SLP_SWITCH  (1)
 

+ 4 - 0
components/soc/esp32c3/include/soc/Kconfig.soc_caps.in

@@ -315,6 +315,10 @@ config SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK
     int
     default 0
 
+config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
+    hex
+    default 0x00000000003FFFC0
+
 config SOC_GPIO_SUPPORT_SLP_SWITCH
     bool
     default y

+ 3 - 0
components/soc/esp32c3/include/soc/soc_caps.h

@@ -155,6 +155,9 @@
 #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK SOC_GPIO_VALID_GPIO_MASK
 #define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK        (0ULL | BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5)
 
+// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_6~GPIO_NUM_21)
+#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x00000000003FFFC0ULL
+
 // Support to configure sleep status
 #define SOC_GPIO_SUPPORT_SLP_SWITCH  (1)
 

+ 4 - 0
components/soc/esp32c6/include/soc/Kconfig.soc_caps.in

@@ -247,6 +247,10 @@ config SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK
     int
     default 0
 
+config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
+    hex
+    default 0x000000007FFFFF00
+
 config SOC_GPIO_SUPPORT_SLP_SWITCH
     bool
     default y

+ 3 - 0
components/soc/esp32c6/include/soc/soc_caps.h

@@ -157,6 +157,9 @@
 #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK SOC_GPIO_VALID_GPIO_MASK
 #define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK        (0ULL | BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5)
 
+// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_8~GPIO_NUM_30)
+#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x000000007FFFFF00ULL
+
 // Support to configure sleep status
 #define SOC_GPIO_SUPPORT_SLP_SWITCH  (1)
 

+ 4 - 0
components/soc/esp32h2/include/soc/Kconfig.soc_caps.in

@@ -291,6 +291,10 @@ config SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK
     int
     default 0
 
+config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
+    hex
+    default 0x000001FFFFFFFFC0
+
 config SOC_GPIO_SUPPORT_SLP_SWITCH
     bool
     default y

+ 4 - 0
components/soc/esp32h2/include/soc/soc_caps.h

@@ -156,8 +156,12 @@
 #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK SOC_GPIO_VALID_GPIO_MASK
 #if CONFIG_IDF_TARGET_ESP32H2_BETA_VERSION_1
 #define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK        (0ULL | BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5)
+// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_6~GPIO_NUM_40)
+#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x000001FFFFFFFFC0ULL
 #elif CONFIG_IDF_TARGET_ESP32H2_BETA_VERSION_2
 #define SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK        (0ULL | BIT7 | BIT8 | BIT9 | BIT10 | BIT11 | BIT12)
+// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_0~6, GPIO_NUM_13~25)
+#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x0000000003FFE07FULL
 #endif
 
 // Support to configure sleep status

+ 4 - 0
components/soc/esp32s2/include/soc/Kconfig.soc_caps.in

@@ -299,6 +299,10 @@ config SOC_GPIO_VALID_GPIO_MASK
     hex
     default 0x7FFFFFFFFFFF
 
+config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
+    hex
+    default 0x00007FFFFC000000
+
 config SOC_GPIO_SUPPORT_SLP_SWITCH
     bool
     default y

+ 3 - 0
components/soc/esp32s2/include/soc/soc_caps.h

@@ -149,6 +149,9 @@
 // GPIO 46 is input only
 #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK     (SOC_GPIO_VALID_GPIO_MASK & ~(0ULL | BIT46))
 
+// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_26~GPIO_NUM_46)
+#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK  0x00007FFFFC000000ULL
+
 // Support to configure slept status
 #define SOC_GPIO_SUPPORT_SLP_SWITCH  (1)
 

+ 4 - 0
components/soc/esp32s3/include/soc/Kconfig.soc_caps.in

@@ -383,6 +383,10 @@ config SOC_GPIO_VALID_GPIO_MASK
     hex
     default 0x1FFFFFFFFFFFF
 
+config SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK
+    hex
+    default 0x0001FFFFFC000000
+
 config SOC_GPIO_SUPPORT_SLP_SWITCH
     bool
     default y

+ 2 - 0
components/soc/esp32s3/include/soc/soc_caps.h

@@ -155,6 +155,8 @@
 #define SOC_GPIO_VALID_GPIO_MASK         (0x1FFFFFFFFFFFFULL & ~(0ULL | BIT22 | BIT23 | BIT24 | BIT25))
 // No GPIO is input only
 #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK  (SOC_GPIO_VALID_GPIO_MASK)
+// digital I/O pad powered by VDD3P3_CPU or VDD_SPI(GPIO_NUM_26~GPIO_NUM_48)
+#define SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK 0x0001FFFFFC000000ULL
 
 // Support to configure slept status
 #define SOC_GPIO_SUPPORT_SLP_SWITCH  (1)