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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6a87b85  xtensa/esp32: Add efuse driver
6a87b85 is described below

commit 6a87b852850a446c1fbcc9f9c17d0293a214074a
Author: Alan C. Assis <acas...@gmail.com>
AuthorDate: Tue Jan 19 20:01:59 2021 -0300

    xtensa/esp32: Add efuse driver
---
 arch/xtensa/include/esp32/esp_efuse_table.h        |  69 +++
 arch/xtensa/src/esp32/Kconfig                      |   6 +
 arch/xtensa/src/esp32/Make.defs                    |   6 +
 arch/xtensa/src/esp32/esp32_efuse.c                | 501 ++++++++++++++++
 arch/xtensa/src/esp32/esp32_efuse.h                |  63 ++
 arch/xtensa/src/esp32/esp32_efuse_lowerhalf.c      | 193 +++++++
 arch/xtensa/src/esp32/esp32_efuse_table.c          | 641 +++++++++++++++++++++
 arch/xtensa/src/esp32/hardware/efuse_reg.h         |   6 +
 arch/xtensa/src/esp32/hardware/esp32_soc.h         |   1 +
 .../xtensa/esp32/esp32-devkitc/src/esp32_bringup.c |   8 +
 10 files changed, 1494 insertions(+)

diff --git a/arch/xtensa/include/esp32/esp_efuse_table.h 
b/arch/xtensa/include/esp32/esp_efuse_table.h
new file mode 100644
index 0000000..410d641
--- /dev/null
+++ b/arch/xtensa/include/esp32/esp_efuse_table.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * arch/xtensa/include/esp32/esp_efuse_table.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern const efuse_desc_t *ESP_EFUSE_MAC_FACTORY[];
+extern const efuse_desc_t *ESP_EFUSE_MAC_FACTORY_CRC[];
+extern const efuse_desc_t *ESP_EFUSE_MAC_CUSTOM_CRC[];
+extern const efuse_desc_t *ESP_EFUSE_MAC_CUSTOM[];
+extern const efuse_desc_t *ESP_EFUSE_MAC_CUSTOM_VER[];
+extern const efuse_desc_t *ESP_EFUSE_SECURE_BOOT_KEY[];
+extern const efuse_desc_t *ESP_EFUSE_ABS_DONE_0[];
+extern const efuse_desc_t *ESP_EFUSE_ENCRYPT_FLASH_KEY[];
+extern const efuse_desc_t *ESP_EFUSE_ENCRYPT_CONFIG[];
+extern const efuse_desc_t *ESP_EFUSE_DISABLE_DL_ENCRYPT[];
+extern const efuse_desc_t *ESP_EFUSE_DISABLE_DL_DECRYPT[];
+extern const efuse_desc_t *ESP_EFUSE_DISABLE_DL_CACHE[];
+extern const efuse_desc_t *ESP_EFUSE_FLASH_CRYPT_CNT[];
+extern const efuse_desc_t *ESP_EFUSE_DISABLE_JTAG[];
+extern const efuse_desc_t *ESP_EFUSE_CONSOLE_DEBUG_DISABLE[];
+extern const efuse_desc_t *ESP_EFUSE_UART_DOWNLOAD_DIS[];
+extern const efuse_desc_t *ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT[];
+extern const efuse_desc_t *ESP_EFUSE_WR_DIS_BLK1[];
+extern const efuse_desc_t *ESP_EFUSE_WR_DIS_BLK2[];
+extern const efuse_desc_t *ESP_EFUSE_WR_DIS_BLK3[];
+extern const efuse_desc_t *ESP_EFUSE_RD_DIS_BLK1[];
+extern const efuse_desc_t *ESP_EFUSE_RD_DIS_BLK2[];
+extern const efuse_desc_t *ESP_EFUSE_RD_DIS_BLK3[];
+extern const efuse_desc_t *ESP_EFUSE_CHIP_VER_DIS_APP_CPU[];
+extern const efuse_desc_t *ESP_EFUSE_CHIP_VER_DIS_BT[];
+extern const efuse_desc_t *ESP_EFUSE_CHIP_VER_PKG[];
+extern const efuse_desc_t *ESP_EFUSE_CHIP_CPU_FREQ_LOW[];
+extern const efuse_desc_t *ESP_EFUSE_CHIP_CPU_FREQ_RATED[];
+extern const efuse_desc_t *ESP_EFUSE_CHIP_VER_REV1[];
+extern const efuse_desc_t *ESP_EFUSE_CHIP_VER_REV2[];
+extern const efuse_desc_t *ESP_EFUSE_XPD_SDIO_REG[];
+extern const efuse_desc_t *ESP_EFUSE_SDIO_TIEH[];
+extern const efuse_desc_t *ESP_EFUSE_SDIO_FORCE[];
+extern const efuse_desc_t *ESP_EFUSE_ADC_VREF_AND_SDIO_DREF[];
+extern const efuse_desc_t *ESP_EFUSE_ADC1_TP_LOW[];
+extern const efuse_desc_t *ESP_EFUSE_ADC2_TP_LOW[];
+extern const efuse_desc_t *ESP_EFUSE_ADC1_TP_HIGH[];
+extern const efuse_desc_t *ESP_EFUSE_ADC2_TP_HIGH[];
+extern const efuse_desc_t *ESP_EFUSE_SECURE_VERSION[];
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig
index 927af27..46c734f 100644
--- a/arch/xtensa/src/esp32/Kconfig
+++ b/arch/xtensa/src/esp32/Kconfig
@@ -58,6 +58,12 @@ config ESP32_BT
        ---help---
                No yet implemented
 
+config ESP32_EFUSE
+       bool "EFUSE support"
+       default n
+       ---help---
+               Enable ESP32 efuse support.
+
 config ESP32_EMAC
        bool "Ethernet MAC"
        default n
diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs
index a429446..01165b1 100644
--- a/arch/xtensa/src/esp32/Make.defs
+++ b/arch/xtensa/src/esp32/Make.defs
@@ -128,6 +128,12 @@ CHIP_CSRCS += esp32_psram.c
 CHIP_CSRCS += esp32_himem.c
 endif
 
+ifeq ($(CONFIG_ESP32_EFUSE),y)
+CHIP_CSRCS += esp32_efuse.c
+CHIP_CSRCS += esp32_efuse_table.c
+CHIP_CSRCS += esp32_efuse_lowerhalf.c
+endif
+
 ifeq ($(CONFIG_ESP32_EMAC),y)
 CHIP_CSRCS += esp32_emac.c
 endif
diff --git a/arch/xtensa/src/esp32/esp32_efuse.c 
b/arch/xtensa/src/esp32/esp32_efuse.c
new file mode 100644
index 0000000..9dd9f36
--- /dev/null
+++ b/arch/xtensa/src/esp32/esp32_efuse.c
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_efuse_utils.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <debug.h>
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+#include <nuttx/efuse/efuse.h>
+
+#include "xtensa.h"
+#include "esp32_efuse.h"
+#include "esp32_clockconfig.h"
+#include "hardware/efuse_reg.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define EFUSE_CONF_WRITE   0x5a5a /* eFuse_pgm_op_ena, force no rd/wr dis. */
+#define EFUSE_CONF_READ    0x5aa5 /* eFuse_read_op_ena, release force. */
+#define EFUSE_CMD_PGM      0x02   /* Command to program. */
+#define EFUSE_CMD_READ     0x01   /* Command to read. */
+
+#define MIN(a, b)          ((a) < (b) ? (a) : (b))
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+uint32_t g_start_efuse_rdreg[4] =
+{
+  EFUSE_BLK0_RDATA0_REG,
+  EFUSE_BLK1_RDATA0_REG,
+  EFUSE_BLK2_RDATA0_REG,
+  EFUSE_BLK3_RDATA0_REG
+};
+
+uint32_t g_start_efuse_wrreg[4] =
+{
+  EFUSE_BLK0_WDATA0_REG,
+  EFUSE_BLK1_WDATA0_REG,
+  EFUSE_BLK2_WDATA0_REG,
+  EFUSE_BLK3_WDATA0_REG
+};
+
+/****************************************************************************
+ * Private Prototypes
+ ****************************************************************************/
+
+static int esp_efuse_set_timing(void);
+void esp_efuse_burn_efuses(void);
+static uint32_t get_mask(uint32_t bit_count, uint32_t shift);
+static int get_reg_num(int bit_offset, int bit_count, int i_reg);
+static int get_count_bits_in_reg(int bit_offset, int bit_count, int i_reg);
+static int esp_efuse_get_field_size(const efuse_desc_t *field[]);
+static bool check_range_of_bits(int offset_in_bits, int size_bits);
+static int esp_efuse_get_number_of_items(int bits, int size_of_base);
+static uint32_t fill_reg(int bit_start_in_reg, int bit_count_in_reg,
+                         uint8_t *blob, int *filled_bits_blob);
+static int esp_efuse_process(const efuse_desc_t *field[], void *ptr,
+                             size_t ptr_size_bits,
+                             efuse_func_proc_t func_proc);
+static uint32_t esp_efuse_read_reg(uint32_t blk, uint32_t num_reg);
+static int esp_efuse_write_blob(uint32_t num_reg, int bit_offset,
+                                int bit_count, void *arr_in,
+                                int *bits_counter);
+static int esp_efuse_fill_buff(uint32_t num_reg, int bit_offset,
+                               int bit_count, void *arr_out,
+                               int *bits_counter);
+static void esp_efuse_write_reg(uint32_t blk, uint32_t num_reg,
+                                uint32_t value);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int esp_efuse_set_timing(void)
+{
+  uint32_t apb_freq_mhz = esp_clk_apb_freq() / 1000000;
+  uint32_t clk_sel0;
+  uint32_t clk_sel1;
+  uint32_t dac_clk_div;
+
+  if (apb_freq_mhz <= 26)
+    {
+      clk_sel0 = 250;
+      clk_sel1 = 255;
+      dac_clk_div = 52;
+    }
+  else
+    {
+      if (apb_freq_mhz <= 40)
+        {
+          clk_sel0 = 160;
+          clk_sel1 = 255;
+          dac_clk_div = 80;
+        }
+      else
+        {
+          clk_sel0 = 80;
+          clk_sel1 = 128;
+          dac_clk_div = 100;
+        }
+    }
+
+  REG_SET_FIELD(EFUSE_DAC_CONF_REG, EFUSE_DAC_CLK_DIV, dac_clk_div);
+  REG_SET_FIELD(EFUSE_CLK_REG, EFUSE_CLK_SEL0, clk_sel0);
+  REG_SET_FIELD(EFUSE_CLK_REG, EFUSE_CLK_SEL1, clk_sel1);
+  return OK;
+}
+
+/* return mask with required the number of ones with shift */
+
+static uint32_t get_mask(uint32_t bit_count, uint32_t shift)
+{
+  uint32_t mask;
+
+  if (bit_count != 32)
+    {
+      mask = (1 << bit_count) - 1;
+    }
+  else
+    {
+      mask = 0xffffffff;
+    }
+
+  return mask << shift;
+}
+
+/* return the register number in the array
+ * return -1 if all registers for field was selected
+ */
+
+static int get_reg_num(int bit_offset, int bit_count, int i_reg)
+{
+  uint32_t bit_start = (bit_offset % 256);
+  int num_reg = i_reg + bit_start / 32;
+
+  if (num_reg > (bit_start + bit_count - 1) / 32)
+    {
+      return -1;
+    }
+
+  return num_reg;
+}
+
+/* Returns the number of bits in the register */
+
+static int get_count_bits_in_reg(int bit_offset, int bit_count, int i_reg)
+{
+  int ret_count = 0;
+  int num_reg = 0;
+  int num_bit;
+  int bit_start = (bit_offset % 256);
+  int last_used_bit = (bit_start + bit_count - 1);
+
+  for (num_bit = bit_start; num_bit <= last_used_bit; ++num_bit)
+    {
+      ++ret_count;
+      if ((((num_bit + 1) % 32) == 0) || (num_bit == last_used_bit))
+        {
+          if (i_reg == num_reg++)
+            {
+              return ret_count;
+            }
+
+          ret_count = 0;
+        }
+    }
+
+  return 0;
+}
+
+/* get the length of the field in bits */
+
+static int esp_efuse_get_field_size(const efuse_desc_t *field[])
+{
+  int bits_counter = 0;
+
+  if (field != NULL)
+    {
+      int i = 0;
+
+      while (field[i] != NULL)
+        {
+          bits_counter += field[i]->bit_count;
+          ++i;
+        }
+    }
+
+  return bits_counter;
+}
+
+/* check range of bits for any coding scheme */
+
+static bool check_range_of_bits(int offset_in_bits, int size_bits)
+{
+  int blk_offset = offset_in_bits % 256;
+  int max_num_bit = blk_offset + size_bits;
+
+  if (max_num_bit > 256)
+    {
+      return false;
+    }
+
+  return true;
+}
+
+/* Returns the number of array elements for placing these bits in an array
+ * with the length of each element equal to size_of_base.
+ */
+
+static int esp_efuse_get_number_of_items(int bits, int size_of_base)
+{
+  return  bits / size_of_base + (bits % size_of_base > 0 ? 1 : 0);
+}
+
+/* fill efuse register from array */
+
+static uint32_t fill_reg(int bit_start_in_reg, int bit_count_in_reg,
+                         uint8_t *blob, int *filled_bits_blob)
+{
+  uint32_t reg_to_write = 0;
+  uint32_t temp_blob_32;
+  int shift_reg;
+  int shift_bit = (*filled_bits_blob) % 8;
+
+  if (shift_bit != 0)
+    {
+      temp_blob_32 = blob[(*filled_bits_blob) / 8] >> shift_bit;
+      shift_bit = ((8 - shift_bit) < bit_count_in_reg) ?
+                   (8 - shift_bit) : bit_count_in_reg;
+
+      reg_to_write = temp_blob_32 & get_mask(shift_bit, 0);
+      (*filled_bits_blob) += shift_bit;
+      bit_count_in_reg -= shift_bit;
+    }
+
+  shift_reg = shift_bit;
+
+  while (bit_count_in_reg > 0)
+    {
+      temp_blob_32 = blob[(*filled_bits_blob) / 8];
+      shift_bit = (bit_count_in_reg > 8) ? 8 : bit_count_in_reg;
+      reg_to_write |= (temp_blob_32 & get_mask(shift_bit, 0)) << shift_reg;
+      (*filled_bits_blob) += shift_bit;
+      bit_count_in_reg -= shift_bit;
+      shift_reg += 8;
+    };
+
+  return reg_to_write << bit_start_in_reg;
+}
+
+/* This function processes the field by calling the passed function */
+
+static int esp_efuse_process(const efuse_desc_t *field[], void *ptr,
+                             size_t ptr_size_bits,
+                             efuse_func_proc_t func_proc)
+{
+  int err = OK;
+  int bits_counter = 0;
+  int field_len;
+  int req_size;
+  int i = 0;
+
+  /* get and check size */
+
+  field_len = esp_efuse_get_field_size(field);
+  req_size = (ptr_size_bits == 0) ? field_len : \
+              MIN(ptr_size_bits, field_len);
+
+  while (err == OK && req_size > bits_counter && field[i] != NULL)
+    {
+      int i_reg = 0;
+      int num_reg;
+
+      if (check_range_of_bits(field[i]->bit_offset,
+                              field[i]->bit_count) == false)
+        {
+          minfo("Range of data does not match the coding scheme");
+          err = -EINVAL;
+        }
+
+      while (err == OK && req_size > bits_counter &&
+             (num_reg = get_reg_num(field[i]->bit_offset,
+                                    field[i]->bit_count, i_reg)) != -1)
+        {
+          int num_bits = get_count_bits_in_reg(field[i]->bit_offset,
+                                               field[i]->bit_count,
+                                               i_reg);
+          int bit_offset = field[i]->bit_offset;
+
+          if ((bits_counter + num_bits) > req_size)
+            {
+              /* Limits the length of the field */
+
+              num_bits = req_size - bits_counter;
+            }
+
+          err = func_proc(num_reg, bit_offset, num_bits, ptr, &bits_counter);
+          ++i_reg;
+        }
+
+      i++;
+    }
+
+  DEBUGASSERT(bits_counter <= req_size);
+  return err;
+}
+
+/* Fill registers from array for writing */
+
+static int esp_efuse_write_blob(uint32_t num_reg, int bit_offset,
+                         int bit_count, void *arr_in, int *bits_counter)
+{
+  uint32_t block = (bit_offset / 256);
+  uint32_t bit_start = (bit_offset % 256);
+  uint32_t reg_to_write = fill_reg(bit_start, bit_count, (uint8_t *) arr_in,
+                                   bits_counter);
+
+  esp_efuse_write_reg(block, num_reg, reg_to_write);
+
+  return OK;
+}
+
+/* Read efuse register */
+
+static uint32_t esp_efuse_read_reg(uint32_t blk, uint32_t num_reg)
+{
+  DEBUGASSERT(blk >= 0 && blk < EFUSE_BLK_MAX);
+  uint32_t value;
+  uint32_t blk_start = g_start_efuse_rdreg[blk];
+
+  DEBUGASSERT(num_reg <= 7);
+
+  value = getreg32(blk_start + num_reg * 4);
+  return value;
+}
+
+/* Read efuse register and write this value to array. */
+
+static int esp_efuse_fill_buff(uint32_t num_reg, int bit_offset,
+                               int bit_count, void *arr_out,
+                               int *bits_counter)
+{
+  uint8_t *blob = (uint8_t *) arr_out;
+  uint32_t efuse_block = (bit_offset / 256);
+  uint32_t bit_start = (bit_offset % 256);
+  uint32_t reg = esp_efuse_read_reg(efuse_block, num_reg);
+  uint64_t reg_of_aligned_bits = (reg >> bit_start) & get_mask(bit_count, 0);
+  int sum_shift = 0;
+  int shift_bit = (*bits_counter) % 8;
+
+  minfo("block = %d | num_reg = %d | bit_start = %d | bit_count = %d\n",
+        efuse_block, num_reg, bit_start, bit_count);
+
+  if (shift_bit != 0)
+    {
+      blob[(*bits_counter) / 8] |= (uint8_t)(reg_of_aligned_bits << \
+                                   shift_bit);
+      shift_bit = ((8 - shift_bit) < bit_count) ? (8 - shift_bit) : \
+                  bit_count;
+      (*bits_counter) += shift_bit;
+      bit_count -= shift_bit;
+    }
+
+  while (bit_count > 0)
+    {
+      sum_shift += shift_bit;
+      blob[(*bits_counter) / 8] |= (uint8_t)(reg_of_aligned_bits >> \
+                                   sum_shift);
+      shift_bit = (bit_count > 8) ? 8 : bit_count;
+      (*bits_counter) += shift_bit;
+      bit_count -= shift_bit;
+    };
+
+  return OK;
+}
+
+/* Write efuse register */
+
+static void esp_efuse_write_reg(uint32_t blk, uint32_t num_reg,
+                                uint32_t value)
+{
+  uint32_t addr_wr_reg;
+  uint32_t reg_to_write;
+  uint32_t blk_start = g_start_efuse_wrreg[blk];
+
+  DEBUGASSERT(blk >= 0 && blk < EFUSE_BLK_MAX);
+
+  DEBUGASSERT(num_reg <= 7);
+
+  /* The block 0 and register 7 doesn't exist */
+
+  if (blk == 0 && num_reg == 7)
+    {
+      merr("Block 0 Register 7 doesn't exist!\n");
+      return;
+    }
+
+  addr_wr_reg = blk_start + num_reg * 4;
+  reg_to_write = getreg32(addr_wr_reg) | value;
+
+  /* The register can be written in parts so we combine the new value
+   * with the one already available.
+   */
+
+  putreg32(reg_to_write, addr_wr_reg);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/* Read value from EFUSE, writing it into an array */
+
+int esp_efuse_read_field(const efuse_desc_t *field[], void *dst,
+                         size_t dst_size_bits)
+{
+  int err = OK;
+
+  if (field == NULL || dst == NULL || dst_size_bits == 0)
+    {
+      err = -EINVAL;
+    }
+  else
+    {
+      memset((uint8_t *)dst, 0,
+             esp_efuse_get_number_of_items(dst_size_bits, 8));
+
+      err = esp_efuse_process(field, dst, dst_size_bits,
+                              esp_efuse_fill_buff);
+    }
+
+  return err;
+}
+
+/* Write array to EFUSE */
+
+int esp_efuse_write_field(const efuse_desc_t *field[],
+                          const void *src, size_t src_size_bits)
+{
+  int  err = OK;
+
+  if (field == NULL || src == NULL || src_size_bits == 0)
+    {
+      err = -EINVAL;
+    }
+  else
+    {
+      err = esp_efuse_process(field, (void *)src, src_size_bits,
+                              esp_efuse_write_blob);
+    }
+
+  return err;
+}
+
+/* Burn values written to the efuse write registers */
+
+void esp_efuse_burn_efuses(void)
+{
+  esp_efuse_set_timing();
+
+  /* Permanently update values written to the efuse write registers */
+
+  putreg32(EFUSE_CONF_WRITE, EFUSE_CONF_REG);
+  putreg32(EFUSE_CMD_PGM, EFUSE_CMD_REG);
+
+  while (getreg32(EFUSE_CMD_REG) != 0)
+    {
+    };
+
+  putreg32(EFUSE_CONF_READ, EFUSE_CONF_REG);
+  putreg32(EFUSE_CMD_READ, EFUSE_CMD_REG);
+
+  while (getreg32(EFUSE_CMD_REG) != 0)
+    {
+    };
+}
+
diff --git a/arch/xtensa/src/esp32/esp32_efuse.h 
b/arch/xtensa/src/esp32/esp32_efuse.h
new file mode 100644
index 0000000..dc1f06d
--- /dev/null
+++ b/arch/xtensa/src/esp32/esp32_efuse.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_efuse.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* Type of eFuse blocks for ESP32 */
+
+typedef enum
+{
+  EFUSE_BLK0 = 0,     /* Reserved. */
+  EFUSE_BLK1 = 1,     /* Used for Flash Encryption. */
+  EFUSE_BLK2 = 2,     /* Used for Secure Boot. */
+  EFUSE_BLK3 = 3,     /* Uses for the purpose of the user. */
+  EFUSE_BLK_MAX
+} esp_efuse_block_t;
+
+/* This is type of function that will handle the efuse field register.
+ *
+ *  num_reg          The register number in the block.
+ *  efuse_block      Block number.
+ *  bit_start        Start bit in the register.
+ *  bit_count        The number of bits used in the register.
+ *  arr              A pointer to an array or variable.
+ *  bits_counter     Counter bits.
+ *
+ * return
+ *  - OK: The operation was successfully completed.
+ *  - other efuse component errors.
+ */
+
+typedef int (*efuse_func_proc_t) (unsigned int num_reg,
+                                  int starting_bit_num_in_reg,
+                                  int num_bits_used_in_reg,
+                                  void *arr, int *bits_counter);
+
+/****************************************************************************
+ * Public Functions Prototypes
+ ****************************************************************************/
+
+int esp_efuse_read_field(const efuse_desc_t *field[], void *dst,
+                         size_t dst_size_bits);
+
+int esp_efuse_write_field(const efuse_desc_t *field[],
+                          const void *src, size_t src_size_bits);
+
+void esp_efuse_burn_efuses(void);
+
+int esp32_efuse_initialize(FAR const char *devpath);
diff --git a/arch/xtensa/src/esp32/esp32_efuse_lowerhalf.c 
b/arch/xtensa/src/esp32/esp32_efuse_lowerhalf.c
new file mode 100644
index 0000000..7576674
--- /dev/null
+++ b/arch/xtensa/src/esp32/esp32_efuse_lowerhalf.c
@@ -0,0 +1,193 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_efuse.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdlib.h>
+#include <debug.h>
+#include <assert.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/efuse/efuse.h>
+
+#include "hardware/esp32_soc.h"
+#include "esp32_efuse.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct esp32_efuse_lowerhalf_s
+{
+  FAR const struct efuse_ops_s *ops; /* Lower half operations */
+  void *upper;                       /* Pointer to efuse_upperhalf_s */
+};
+
+/****************************************************************************
+ * Private Functions Prototypes
+ ****************************************************************************/
+
+/* "Lower half" driver methods **********************************************/
+
+static int      esp32_efuse_read_field(FAR struct efuse_lowerhalf_s *lower,
+                                       const efuse_desc_t *field[],
+                                       FAR uint8_t *data, size_t size);
+static int      esp32_efuse_write_field(FAR struct efuse_lowerhalf_s *lower,
+                                        const efuse_desc_t *field[],
+                                        FAR const uint8_t *data,
+                                        size_t size);
+static int      efuse_ioctl(FAR struct efuse_lowerhalf_s *lower, int cmd,
+                            unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* "Lower half" driver methods */
+
+static const struct efuse_ops_s g_esp32_efuse_ops =
+{
+  .read_field   = esp32_efuse_read_field,
+  .write_field  = esp32_efuse_write_field,
+  .ioctl        = efuse_ioctl,
+};
+
+/* EFUSE lower-half */
+
+static struct esp32_efuse_lowerhalf_s g_esp32_efuse_lowerhalf =
+{
+  .ops = &g_esp32_efuse_ops,
+  .upper = NULL,
+};
+
+/****************************************************************************
+ * Private functions
+ ****************************************************************************/
+
+static int esp32_efuse_read_field(FAR struct efuse_lowerhalf_s *lower,
+                                  const efuse_desc_t *field[],
+                                  uint8_t *data, size_t bits_len)
+{
+  int ret = OK;
+
+  /* Read the requested field */
+
+  ret = esp_efuse_read_field(field, data, bits_len);
+
+  return ret;
+}
+
+static int esp32_efuse_write_field(FAR struct efuse_lowerhalf_s *lower,
+                                   const efuse_desc_t *field[],
+                                   const uint8_t *data, size_t bits_len)
+{
+  irqstate_t flags;
+  int ret = OK;
+
+  flags = enter_critical_section();
+
+  /* Write the blob data to the field */
+
+  ret = esp_efuse_write_field(field, data, bits_len);
+
+  /* Burn the EFUSEs */
+
+  esp_efuse_burn_efuses();
+
+  leave_critical_section(flags);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: efuse_ioctl
+ ****************************************************************************/
+
+static int efuse_ioctl(FAR struct efuse_lowerhalf_s *lower,
+                       int cmd, unsigned long arg)
+{
+  int ret = OK;
+
+  switch (cmd)
+    {
+      /* We don't have proprietary EFUSE ioctls */
+
+      default:
+        {
+          minfo("Unrecognized cmd: %d\n", cmd);
+          ret = -ENOTTY;
+        }
+        break;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_efuse_initialize
+ *
+ * Description:
+ *   Initialize the efuse driver.  The efuse is initialized
+ *   and registered as 'devpath'.
+ *
+ * Input Parameters:
+ *   devpath                 - The full path to the efuse.  This should
+ *                             be of the form /dev/efuse
+ *
+ * Returned Values:
+ *   Zero (OK) is returned on success; a negated errno value is returned on
+ *   any failure.
+ *
+ ****************************************************************************/
+
+int esp32_efuse_initialize(FAR const char *devpath)
+{
+  struct esp32_efuse_lowerhalf_s *lower = NULL;
+  int ret = OK;
+
+  DEBUGASSERT(devpath);
+
+  lower = &g_esp32_efuse_lowerhalf;
+
+  /* Register the efuser upper driver */
+
+  lower->upper = efuse_register(devpath,
+                                (FAR struct efuse_lowerhalf_s *)lower);
+
+  if (lower->upper == NULL)
+    {
+      /* The actual cause of the failure may have been a failure to allocate
+       * perhaps a failure to register the efuser driver (such as if the
+       * 'devpath' were not unique).  We know here but we return EEXIST to
+       * indicate the failure (implying the non-unique devpath).
+       */
+
+      ret = -EEXIST;
+      goto errout;
+    }
+
+errout:
+  return ret;
+}
diff --git a/arch/xtensa/src/esp32/esp32_efuse_table.c 
b/arch/xtensa/src/esp32/esp32_efuse_table.c
new file mode 100644
index 0000000..b923099
--- /dev/null
+++ b/arch/xtensa/src/esp32/esp32_efuse_table.c
@@ -0,0 +1,641 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_efuse_table.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stddef.h>
+#include <nuttx/efuse/efuse.h>
+#include "esp32_efuse.h"
+
+#define MAX_BLK_LEN 256
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* The last free bit in the block is counted over the entire file */
+
+#define LAST_FREE_BIT_BLK1 MAX_BLK_LEN
+#define LAST_FREE_BIT_BLK2 MAX_BLK_LEN
+#define LAST_FREE_BIT_BLK3 192
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+static const efuse_desc_t MAC_FACTORY[] =
+{
+  {
+    72, 8    /* Factory MAC addr [0], */
+  },
+  {
+    64, 8    /* Factory MAC addr [1], */
+  },
+  {
+    56, 8    /* Factory MAC addr [2], */
+  },
+  {
+    48, 8    /* Factory MAC addr [3], */
+  },
+  {
+    40, 8    /* Factory MAC addr [4], */
+  },
+  {
+    32, 8    /* Factory MAC addr [5], */
+  },
+};
+
+static const efuse_desc_t MAC_FACTORY_CRC[] =
+{
+  {
+    80, 8    /* CRC8 for factory MAC address */
+  },
+};
+
+static const efuse_desc_t MAC_CUSTOM_CRC[] =
+{
+  {
+    768, 8     /* CRC8 for custom MAC address */
+  },
+};
+
+static const efuse_desc_t MAC_CUSTOM[] =
+{
+  {
+    776, 48    /* Custom MAC */
+  },
+};
+
+static const efuse_desc_t MAC_CUSTOM_VER[] =
+{
+  {
+    952, 8   /* Custom MAC version */
+  },
+};
+
+static const efuse_desc_t SECURE_BOOT_KEY[] =
+{
+  {
+    512, MAX_BLK_LEN  /* Security boot key */
+  },
+};
+
+static const efuse_desc_t ABS_DONE_0[] =
+{
+  {
+    196, 1   /* Secure boot is enabled for bootloader image.
+              * EFUSE_RD_ABS_DONE_0
+              */
+  },
+};
+
+static const efuse_desc_t ENCRYPT_FLASH_KEY[] =
+{
+  {
+    256, MAX_BLK_LEN   /* Flash encrypt key */
+  },
+};
+
+static const efuse_desc_t ENCRYPT_CONFIG[] =
+{
+  {
+    188, 4   /* Flash encrypt. EFUSE_FLASH_CRYPT_CONFIG_M */
+  },
+};
+
+static const efuse_desc_t DISABLE_DL_ENCRYPT[] =
+{
+  {
+    199, 1   /* Flash encrypt. Disable UART bootloader
+              * encryption. EFUSE_DISABLE_DL_ENCRYPT
+              */
+  },
+};
+
+static const efuse_desc_t DISABLE_DL_DECRYPT[] =
+{
+  {
+    200, 1   /* Flash encrypt. Disable UART bootloader
+              * decryption. EFUSE_DISABLE_DL_DECRYPT
+              */
+  },
+};
+
+static const efuse_desc_t DISABLE_DL_CACHE[] =
+{
+  {
+    201, 1   /* Flash encrypt. Disable UART bootloader MMU
+              * cache. EFUSE_DISABLE_DL_CACHE
+              */
+  },
+};
+
+static const efuse_desc_t FLASH_CRYPT_CNT[] =
+{
+  {
+    20, 7    /* Flash encrypt. Flash encryption is enabled
+              * if this field has an odd number of bits set.
+              * EFUSE_FLASH_CRYPT_CNT
+              */
+  },
+};
+
+static const efuse_desc_t DISABLE_JTAG[] =
+{
+  {
+    198, 1   /* Disable JTAG. EFUSE_RD_DISABLE_JTAG */
+  },
+};
+
+static const efuse_desc_t CONSOLE_DEBUG_DISABLE[] =
+{
+  {
+    194, 1   /* Disable ROM BASIC interpreter fallback.
+              * EFUSE_RD_CONSOLE_DEBUG_DISABLE
+              */
+  },
+};
+
+static const efuse_desc_t UART_DOWNLOAD_DIS[] =
+{
+  {
+    27, 1    /* Disable UART download mode.
+              * Valid for ESP32 V3 and newer
+              */
+  },
+};
+
+static const efuse_desc_t WR_DIS_FLASH_CRYPT_CNT[] =
+{
+  {
+    2, 1     /* Flash encrypt. Write protection
+                          * FLASH_CRYPT_CNT
+                          */
+  },
+};
+
+static const efuse_desc_t WR_DIS_BLK1[] =
+{
+  {
+    7, 1     /* Flash encrypt. Write protection encryption key.
+                          * EFUSE_WR_DIS_BLK1
+                          */
+  },
+};
+
+static const efuse_desc_t WR_DIS_BLK2[] =
+{
+  {
+    8, 1     /* Security boot. Write protection security key.
+                          * EFUSE_WR_DIS_BLK2
+                          */
+  },
+};
+
+static const efuse_desc_t WR_DIS_BLK3[] =
+{
+  {
+    9, 1     /* Write protection for EFUSE_BLK3.
+                          * EFUSE_WR_DIS_BLK3
+                          */
+  },
+};
+
+static const efuse_desc_t RD_DIS_BLK1[] =
+{
+  {
+    16, 1    /* Flash encrypt. efuse_key_read_protected.
+                          * EFUSE_RD_DIS_BLK1
+                          */
+  },
+};
+
+static const efuse_desc_t RD_DIS_BLK2[] =
+{
+  {
+    17, 1    /* Security boot. efuse_key_read_protected.
+                          * EFUSE_RD_DIS_BLK2
+                          */
+  },
+};
+
+static const efuse_desc_t RD_DIS_BLK3[] =
+{
+  {
+    18, 1    /* Read protection for EFUSE_BLK3.
+                          * EFUSE_RD_DIS_BLK3
+                          */
+  },
+};
+
+static const efuse_desc_t CHIP_VER_DIS_APP_CPU[] =
+{
+  {
+    96, 1    /* EFUSE_RD_CHIP_VER_DIS_APP_CPU */
+  },
+};
+
+static const efuse_desc_t CHIP_VER_DIS_BT[] =
+{
+  {
+    97, 1    /* EFUSE_RD_CHIP_VER_DIS_BT */
+  },
+};
+
+static const efuse_desc_t CHIP_VER_PKG[] =
+{
+  {
+    105, 3   /* EFUSE_RD_CHIP_VER_PKG */
+  },
+};
+
+static const efuse_desc_t CHIP_CPU_FREQ_LOW[] =
+{
+  {
+    108, 1   /* EFUSE_RD_CHIP_CPU_FREQ_LOW */
+  },
+};
+
+static const efuse_desc_t CHIP_CPU_FREQ_RATED[] =
+{
+  {
+    109, 1   /* EFUSE_RD_CHIP_CPU_FREQ_RATED */
+  },
+};
+
+static const efuse_desc_t CHIP_VER_REV1[] =
+{
+  {
+    111, 1   /* EFUSE_RD_CHIP_VER_REV1 */
+  },
+};
+
+static const efuse_desc_t CHIP_VER_REV2[] =
+{
+  {
+    180, 1   /* EFUSE_RD_CHIP_VER_REV2 */
+  },
+};
+
+static const efuse_desc_t XPD_SDIO_REG[] =
+{
+  {
+    142, 1   /* EFUSE_RD_XPD_SDIO_REG */
+  },
+};
+
+static const efuse_desc_t SDIO_TIEH[] =
+{
+  {
+    143, 1   /* EFUSE_RD_SDIO_TIEH */
+  },
+};
+
+static const efuse_desc_t SDIO_FORCE[] =
+{
+  {
+    144, 1   /* EFUSE_RD_SDIO_FORCE */
+  },
+};
+
+static const efuse_desc_t ADC_VREF_AND_SDIO_DREF[] =
+{
+  {
+    136, 6   /* EFUSE_RD_ADC_VREF[0..4] or SDIO_DREFH[0 1] */
+  },
+};
+
+static const efuse_desc_t ADC1_TP_LOW[] =
+{
+  {
+    864, 7    /* TP_REG EFUSE_RD_ADC1_TP_LOW */
+  },
+};
+
+static const efuse_desc_t ADC2_TP_LOW[] =
+{
+  {
+    880, 7   /* TP_REG EFUSE_RD_ADC2_TP_LOW */
+  },
+};
+
+static const efuse_desc_t ADC1_TP_HIGH[] =
+{
+  {
+    871, 9   /* TP_REG EFUSE_RD_ADC1_TP_HIGH */
+  },
+};
+
+static const efuse_desc_t ADC2_TP_HIGH[] =
+{
+  {
+    887, 9   /* TP_REG EFUSE_RD_ADC2_TP_HIGH */
+  },
+};
+
+static const efuse_desc_t SECURE_VERSION[] =
+{
+  {
+    896, 32  /* Secure version for anti-rollback */
+  },
+};
+
+/* */
+
+const efuse_desc_t *ESP_EFUSE_MAC_FACTORY[] =
+{
+  &MAC_FACTORY[0],      /* Factory MAC addr [0] */
+  &MAC_FACTORY[1],      /* Factory MAC addr [1] */
+  &MAC_FACTORY[2],      /* Factory MAC addr [2] */
+  &MAC_FACTORY[3],      /* Factory MAC addr [3] */
+  &MAC_FACTORY[4],      /* Factory MAC addr [4] */
+  &MAC_FACTORY[5],      /* Factory MAC addr [5] */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_MAC_FACTORY_CRC[] =
+{
+  &MAC_FACTORY_CRC[0],  /* CRC8 for factory MAC address */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_MAC_CUSTOM_CRC[] =
+{
+  &MAC_CUSTOM_CRC[0],   /* CRC8 for custom MAC address. */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_MAC_CUSTOM[] =
+{
+  &MAC_CUSTOM[0],       /* Custom MAC */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_MAC_CUSTOM_VER[] =
+{
+  &MAC_CUSTOM_VER[0],   /* Custom MAC version */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_SECURE_BOOT_KEY[] =
+{
+  &SECURE_BOOT_KEY[0],  /* Security boot. Key.
+                         * (length = "None" - 256.
+                         * "3/4" - 192. "REPEAT" - 128)
+                         */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_ABS_DONE_0[] =
+{
+  &ABS_DONE_0[0],       /* Secure boot is enabled for bootloader image.
+                         * EFUSE_RD_ABS_DONE_0
+                         */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_ENCRYPT_FLASH_KEY[] =
+{
+  &ENCRYPT_FLASH_KEY[0], /* Flash encrypt. Key.
+                          * (length = "None" - 256.
+                          * "3/4" - 192. "REPEAT" - 128)
+                          */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_ENCRYPT_CONFIG[] =
+{
+  &ENCRYPT_CONFIG[0],   /* Flash encrypt. EFUSE_FLASH_CRYPT_CONFIG_M */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_DISABLE_DL_ENCRYPT[] =
+{
+  &DISABLE_DL_ENCRYPT[0],  /* Flash encrypt. Disable UART bootloader
+                            * encryption. EFUSE_DISABLE_DL_ENCRYPT.
+                            */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_DISABLE_DL_DECRYPT[] =
+{
+  &DISABLE_DL_DECRYPT[0],  /* Flash encrypt. Disable UART bootloader
+                            * decryption. EFUSE_DISABLE_DL_DECRYPT.
+                            */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_DISABLE_DL_CACHE[] =
+{
+  &DISABLE_DL_CACHE[0],    /* Flash encrypt. Disable UART bootloader
+                            * MMU cache. EFUSE_DISABLE_DL_CACHE.
+                            */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_FLASH_CRYPT_CNT[] =
+{
+  &FLASH_CRYPT_CNT[0],     /* Flash encrypt. Flash encryption is enabled
+                            * if this field has an odd number of bits set.
+                            * EFUSE_FLASH_CRYPT_CNT.
+                            */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_DISABLE_JTAG[] =
+{
+  &DISABLE_JTAG[0],        /* Disable JTAG. EFUSE_RD_DISABLE_JTAG. */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_CONSOLE_DEBUG_DISABLE[] =
+{
+  &CONSOLE_DEBUG_DISABLE[0],    /* Disable ROM BASIC interpreter fallback.
+                                 * EFUSE_RD_CONSOLE_DEBUG_DISABLE.
+                                 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_UART_DOWNLOAD_DIS[] =
+{
+  &UART_DOWNLOAD_DIS[0],        /* Disable UART download mode. Valid for
+                                 * ESP32 V3 and newer
+                                 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT[] =
+{
+  &WR_DIS_FLASH_CRYPT_CNT[0],   /* Flash encrypt. Write protection
+                                 * FLASH_CRYPT_CNT
+                                 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_WR_DIS_BLK1[] =
+{
+  &WR_DIS_BLK1[0],              /* Flash encrypt. Write protection
+                                 * encryption key. EFUSE_WR_DIS_BLK1 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_WR_DIS_BLK2[] =
+{
+  &WR_DIS_BLK2[0],              /* Security boot. Write protection security
+                                 * key. EFUSE_WR_DIS_BLK2 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_WR_DIS_BLK3[] =
+{
+  &WR_DIS_BLK3[0],              /* Write protection for EFUSE_BLK3.
+                                 * EFUSE_WR_DIS_BLK3
+                                 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_RD_DIS_BLK1[] =
+{
+  &RD_DIS_BLK1[0],              /* Flash encrypt. efuse_key_read_protected.
+                                 * EFUSE_RD_DIS_BLK1
+                                 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_RD_DIS_BLK2[] =
+{
+  &RD_DIS_BLK2[0],              /* Security boot. efuse_key_read_protected.
+                                 * EFUSE_RD_DIS_BLK2
+                                 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_RD_DIS_BLK3[] =
+{
+  &RD_DIS_BLK3[0],              /* Read protection for EFUSE_BLK3.
+                                 * EFUSE_RD_DIS_BLK3
+                                 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_CHIP_VER_DIS_APP_CPU[] =
+{
+  &CHIP_VER_DIS_APP_CPU[0],     /* EFUSE_RD_CHIP_VER_DIS_APP_CPU */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_CHIP_VER_DIS_BT[] =
+{
+  &CHIP_VER_DIS_BT[0],          /* EFUSE_RD_CHIP_VER_DIS_BT */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_CHIP_VER_PKG[] =
+{
+  &CHIP_VER_PKG[0],             /* EFUSE_RD_CHIP_VER_PKG */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_CHIP_CPU_FREQ_LOW[] =
+{
+  &CHIP_CPU_FREQ_LOW[0],        /* EFUSE_RD_CHIP_CPU_FREQ_LOW */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_CHIP_CPU_FREQ_RATED[] =
+{
+  &CHIP_CPU_FREQ_RATED[0],      /* EFUSE_RD_CHIP_CPU_FREQ_RATED */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_CHIP_VER_REV1[] =
+{
+  &CHIP_VER_REV1[0],            /* EFUSE_RD_CHIP_VER_REV1 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_CHIP_VER_REV2[] =
+{
+  &CHIP_VER_REV2[0],            /* EFUSE_RD_CHIP_VER_REV2 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_XPD_SDIO_REG[] =
+{
+  &XPD_SDIO_REG[0],             /* EFUSE_RD_XPD_SDIO_REG */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_SDIO_TIEH[] =
+{
+  &SDIO_TIEH[0],                /* EFUSE_RD_SDIO_TIEH */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_SDIO_FORCE[] =
+{
+  &SDIO_FORCE[0],               /* EFUSE_RD_SDIO_FORCE */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_ADC_VREF_AND_SDIO_DREF[] =
+{
+  &ADC_VREF_AND_SDIO_DREF[0],   /* EFUSE_RD_ADC_VREF[0..4] or
+                                 * SDIO_DREFH[0 1]
+                                 */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_ADC1_TP_LOW[] =
+{
+  &ADC1_TP_LOW[0],              /* TP_REG EFUSE_RD_ADC1_TP_LOW */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_ADC2_TP_LOW[] =
+{
+  &ADC2_TP_LOW[0],              /* TP_REG EFUSE_RD_ADC2_TP_LOW */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_ADC1_TP_HIGH[] =
+{
+  &ADC1_TP_HIGH[0],             /* TP_REG EFUSE_RD_ADC1_TP_HIGH */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_ADC2_TP_HIGH[] =
+{
+  &ADC2_TP_HIGH[0],             /* TP_REG EFUSE_RD_ADC2_TP_HIGH */
+  NULL
+};
+
+const efuse_desc_t *ESP_EFUSE_SECURE_VERSION[] =
+{
+  &SECURE_VERSION[0],           /* Secure version for anti-rollback */
+  NULL
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
diff --git a/arch/xtensa/src/esp32/hardware/efuse_reg.h 
b/arch/xtensa/src/esp32/hardware/efuse_reg.h
index 89551cc..09ad8e3 100644
--- a/arch/xtensa/src/esp32/hardware/efuse_reg.h
+++ b/arch/xtensa/src/esp32/hardware/efuse_reg.h
@@ -21,6 +21,12 @@
 #ifndef __ARCH_XTENSA_INCLUDE_EFUSE_REG_H
 #define __ARCH_XTENSA_INCLUDE_EFUSE_REG_H
 
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32_soc.h"
+
 #define EFUSE_BLK0_RDATA0_REG          (DR_REG_EFUSE_BASE + 0x000)
 
 /* EFUSE_RD_FLASH_CRYPT_CNT : RO ;bitpos:[26:20] ;default: 7'b0 ;
diff --git a/arch/xtensa/src/esp32/hardware/esp32_soc.h 
b/arch/xtensa/src/esp32/hardware/esp32_soc.h
index e361c72..9b283ea 100644
--- a/arch/xtensa/src/esp32/hardware/esp32_soc.h
+++ b/arch/xtensa/src/esp32/hardware/esp32_soc.h
@@ -215,6 +215,7 @@
 #define DR_REG_RTCIO_BASE                       0x3ff48400
 #define DR_REG_SARADC_BASE                      0x3ff48800
 #define DR_REG_IO_MUX_BASE                      0x3ff49000
+#define DR_REG_EFUSE_BASE                       0x3ff5a000
 #define DR_REG_RTCMEM0_BASE                     0x3ff61000
 #define DR_REG_RTCMEM1_BASE                     0x3ff62000
 #define DR_REG_RTCMEM2_BASE                     0x3ff63000
diff --git a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c 
b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c
index 2b17b03..ee3a1cb 100644
--- a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c
+++ b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c
@@ -170,6 +170,14 @@ int esp32_bringup(void)
     }
 #endif
 
+#if defined(CONFIG_ESP32_EFUSE)
+  ret = esp32_efuse_initialize("/dev/efuse");
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to init EFUSE: %d\n", ret);
+    }
+#endif
+
 #ifdef CONFIG_FS_PROCFS
   /* Mount the procfs file system */
 

Reply via email to