/*
 * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT espressif_esp32_flash_controller
#define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash)

#define FLASH_WRITE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, write_block_size)
#define FLASH_ERASE_BLK_SZ DT_PROP(SOC_NV_FLASH_NODE, erase_block_size)

/*
 * HAL includes go first to
 * avoid BIT macro redefinition
 */
#include <esp_spi_flash.h>
#include <hal/spi_ll.h>
#include <hal/spi_flash_ll.h>
#include <hal/spi_flash_hal.h>
#include <soc/spi_struct.h>
#include <spi_flash_defs.h>

#include <kernel.h>
#include <device.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <drivers/flash.h>
#include <soc.h>

#if defined(CONFIG_SOC_ESP32)
#include "soc/dport_reg.h"
#include "esp32/rom/cache.h"
#include "esp32/rom/spi_flash.h"
#include "esp32/spiram.h"
#elif defined(CONFIG_SOC_ESP32S2)
#include "soc/spi_mem_reg.h"
#include "esp32s2/rom/cache.h"
#include "esp32s2/rom/spi_flash.h"
#elif defined(CONFIG_SOC_ESP32C3)
#include "soc/spi_periph.h"
#include "soc/spi_mem_reg.h"
#include "soc/dport_access.h"
#include "esp32c3/dport_access.h"
#include "esp32c3/rom/cache.h"
#include "esp32c3/rom/spi_flash.h"
#endif

#include "soc/mmu.h"

#include <logging/log.h>
LOG_MODULE_REGISTER(flash_esp32, CONFIG_FLASH_LOG_LEVEL);

struct flash_esp32_dev_config {
	spi_dev_t *controller;
	esp_rom_spiflash_chip_t *chip;
};

struct flash_esp32_dev_data {
	struct k_sem sem;
};

static const struct flash_parameters flash_esp32_parameters = {
	.write_block_size = FLASH_WRITE_BLK_SZ,
	.erase_value = 0xff,
};

#define DEV_DATA(dev) ((struct flash_esp32_dev_data *const)(dev)->data)
#define DEV_CFG(dev) ((const struct flash_esp32_dev_config *const)(dev)->config)

#if !defined(CONFIG_SOC_ESP32C3)
#define SPI1_EXTRA_DUMMIES (g_rom_spiflash_dummy_len_plus[1])
#else
#define SPI1_EXTRA_DUMMIES ((uint8_t)((rom_spiflash_legacy_data->dummy_len_plus)[1]))
#define SPI_FREAD_QIO 0
#define SPI_FREAD_DIO 0
#endif

#define MAX_BUFF_ALLOC_RETRIES 5
#define MAX_READ_CHUNK 16384
#define MAX_WRITE_CHUNK 8192
#define ADDRESS_MASK_24BIT 0xFFFFFF
#define SPI_TIMEOUT_MSEC 500

#if defined(CONFIG_SOC_ESP32)
#define HOST_FLASH_CONTROLLER SPI0
#define HOST_FLASH_RDSR SPI_FLASH_RDSR
#define HOST_FLASH_FASTRD SPI_FASTRD_MODE
#elif defined(CONFIG_SOC_ESP32S2) || defined(CONFIG_SOC_ESP32C3)
#define HOST_FLASH_CONTROLLER SPIMEM0
#define HOST_FLASH_RDSR SPI_MEM_FLASH_RDSR
#define HOST_FLASH_FASTRD SPI_MEM_FASTRD_MODE
#endif

#if defined(CONFIG_SOC_ESP32C3)
static esp_rom_spiflash_chip_t esp_flashchip_info;
#else
#define esp_flashchip_info g_rom_flashchip
#endif

static inline void flash_esp32_sem_take(const struct device *dev)
{
	k_sem_take(&DEV_DATA(dev)->sem, K_FOREVER);
}

static inline void flash_esp32_sem_give(const struct device *dev)
{
	k_sem_give(&DEV_DATA(dev)->sem);
}

static inline int flash_esp32_wait_cmd_done(const spi_dev_t *hw)
{
	int64_t timeout = k_uptime_get() + SPI_TIMEOUT_MSEC;

	while (!spi_flash_ll_cmd_is_done(hw)) {
		if (k_uptime_get() > timeout) {
			LOG_ERR("controller has timed out");
			return -ETIMEDOUT;
		}
	}

	return 0;
}

static inline bool points_to_dram(const void *ptr)
{
	return ((intptr_t)ptr >= SOC_DRAM_LOW && (intptr_t)ptr < SOC_DRAM_HIGH);
}

int configure_read_mode(spi_dev_t *hw,
			uint32_t cmd,
			uint32_t addr_bitlen,
			int dummy_len,
			bool byte_cmd)
{
	if (dummy_len) {
		spi_flash_ll_set_dummy(hw, dummy_len);
	}

	spi_flash_ll_set_addr_bitlen(hw, addr_bitlen);

	if (!byte_cmd) {
		REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_USR_COMMAND_VALUE, cmd);
	} else {
		spi_flash_ll_set_command(hw, (uint8_t) cmd, 8);
	}

	return 0;
}

static bool IRAM_ATTR flash_esp32_mapped_in_cache(uint32_t phys_page, const void **out_ptr)
{
	int start[2], end[2];

	*out_ptr = NULL;

	/* SPI_FLASH_MMAP_DATA */
	start[0] = SOC_MMU_DROM0_PAGES_START;
	end[0] = SOC_MMU_DROM0_PAGES_END;

	/* SPI_FLASH_MMAP_INST */
	start[1] = SOC_MMU_PRO_IRAM0_FIRST_USABLE_PAGE;
	end[1] = SOC_MMU_IROM0_PAGES_END;

	DPORT_INTERRUPT_DISABLE();
	for (int j = 0; j < 2; j++) {
		for (int i = start[j]; i < end[j]; i++) {
			if (DPORT_SEQUENCE_REG_READ(
				     (uint32_t)&SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE[i]) ==
				     SOC_MMU_PAGE_IN_FLASH(phys_page)) {
#if !defined(CONFIG_SOC_ESP32)
				if (j == 0) { /* SPI_FLASH_MMAP_DATA */
					*out_ptr = (const void *)(SOC_MMU_VADDR0_START_ADDR +
							SPI_FLASH_MMU_PAGE_SIZE * (i - start[0]));
				} else {
					*out_ptr = (const void *)(SOC_MMU_VADDR1_FIRST_USABLE_ADDR +
							SPI_FLASH_MMU_PAGE_SIZE * (i - start[1]));
				}
#endif
				DPORT_INTERRUPT_RESTORE();
				return true;
			}
		}
	}
	DPORT_INTERRUPT_RESTORE();

	return false;
}

/* Validates if flash address has corresponding cache mapping, if yes, flushes cache memories */
static void IRAM_ATTR flash_esp32_flush_cache(size_t start_addr, size_t length)
{
	/* align start_addr & length to full MMU pages */
	uint32_t page_start_addr = start_addr & ~(SPI_FLASH_MMU_PAGE_SIZE-1);

	length += (start_addr - page_start_addr);
	length = (length + SPI_FLASH_MMU_PAGE_SIZE - 1) & ~(SPI_FLASH_MMU_PAGE_SIZE-1);
	for (uint32_t addr = page_start_addr;
		addr < page_start_addr + length;
		addr += SPI_FLASH_MMU_PAGE_SIZE) {

		uint32_t page = addr / SPI_FLASH_MMU_PAGE_SIZE;

		if (page >= 256) {
			return;
		}

		const void *vaddr = NULL;

		if (flash_esp32_mapped_in_cache(page, &vaddr)) {
#if defined(CONFIG_SOC_ESP32)
#if CONFIG_ESP_SPIRAM
			esp_spiram_writeback_cache();
#endif
			esp_rom_Cache_Flush(0);
#ifdef CONFIG_SMP
			esp_rom_Cache_Flush(1);
#endif
			return;
#else /* CONFIG_SOC_ESP32 */
			if (vaddr != NULL) {
				esp_rom_Cache_Invalidate_Addr((uint32_t)vaddr,
								SPI_FLASH_MMU_PAGE_SIZE);
			}
#endif /* CONFIG_SOC_ESP32 */
		}
	}
	return;
}

static int set_read_options(const struct device *dev)
{
	spi_dev_t *hw = DEV_CFG(dev)->controller;
	uint32_t dummy_len = 0;
	uint32_t addr_len;
	uint8_t read_cmd;
	bool byte_cmd = true;
	uint32_t read_mode = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL);

	if ((read_mode & SPI_FREAD_QIO) && (read_mode & HOST_FLASH_FASTRD)) {
		spi_ll_enable_mosi(hw, 0);
		spi_ll_enable_miso(hw, 1);
		dummy_len = 1 + SPI1_R_QIO_DUMMY_CYCLELEN + SPI1_EXTRA_DUMMIES;
		addr_len = SPI1_R_QIO_ADDR_BITSLEN + 1;
		read_cmd = CMD_FASTRD_QIO;
	} else if (read_mode & HOST_FLASH_FASTRD) {
		spi_ll_enable_mosi(hw, 0);
		spi_ll_enable_miso(hw, 1);
		if (read_mode & SPI_FREAD_DIO) {
			read_cmd = CMD_FASTRD_DIO;
			if (SPI1_EXTRA_DUMMIES == 0) {
				spi_flash_ll_set_dummy(hw, 0);
				addr_len = SPI1_R_DIO_ADDR_BITSLEN + 1;
			} else {
				byte_cmd = false;
				dummy_len = SPI1_EXTRA_DUMMIES;
				addr_len = SPI1_R_DIO_ADDR_BITSLEN + 1;
			}
		} else {
			if ((read_mode & SPI_FREAD_QUAD)) {
				read_cmd = CMD_FASTRD_QUAD;
			} else if ((read_mode & SPI_FREAD_DUAL)) {
				read_cmd = CMD_FASTRD_DUAL;
			} else {
				read_cmd = CMD_FASTRD;
			}
			dummy_len = 1 + SPI1_R_FAST_DUMMY_CYCLELEN + SPI1_EXTRA_DUMMIES;
			addr_len = SPI1_R_FAST_ADDR_BITSLEN + 1;
		}
	} else {
		spi_ll_enable_mosi(hw, 0);
		if (SPI1_EXTRA_DUMMIES == 0) {
			spi_flash_ll_set_dummy(hw, 0);
		} else {
			dummy_len = SPI1_EXTRA_DUMMIES;
		}
		spi_ll_enable_miso(hw, 1);
		addr_len = SPI1_R_SIO_ADDR_BITSLEN + 1;
		read_cmd = CMD_READ;
	}

	return configure_read_mode(hw, read_cmd, addr_len, dummy_len, byte_cmd);
}

static int read_once(const struct device *dev, void *buffer, uint32_t address, uint32_t read_len)
{
	spi_dev_t *hw = DEV_CFG(dev)->controller;
	int bitlen = spi_flash_ll_get_addr_bitlen(hw);

	spi_flash_ll_set_usr_address(hw, address << (bitlen - 24), bitlen);
	spi_flash_ll_set_miso_bitlen(hw, read_len * 8);
	spi_flash_ll_user_start(hw);

	int rc = flash_esp32_wait_cmd_done(hw);

	if (rc != 0) {
		return rc;
	}

	spi_flash_ll_get_buffer_data(hw, buffer, read_len);
	return 0;
}

static int read_data(const struct device *dev, uint8_t *buffer, uint32_t address, uint32_t length)
{
	int rc = 0;

	rc = set_read_options(dev);

	if (rc == -ENOTSUP) {
		LOG_ERR("configure host io mode failed - unsupported");
		return rc;
	}

	while (rc == 0 && length > 0) {
		uint32_t read_len = MIN(length, SPI_FLASH_HAL_MAX_READ_BYTES);

		rc = read_once(dev, buffer, address, read_len);

		address += read_len;
		length -= read_len;
		buffer += read_len;
	}

	return rc;
}

static int flash_esp32_read(const struct device *dev, off_t address, void *buffer, size_t length)
{
	const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev);
	const spi_flash_guard_funcs_t *guard = spi_flash_guard_get();
	uint32_t chip_size = cfg->chip->chip_size;

#if defined(CONFIG_SOC_ESP32S2) || defined(CONFIG_SOC_ESP32C3)
	WRITE_PERI_REG(PERIPHS_SPI_FLASH_CTRL, 0);
#endif

	if (length == 0) {
		return 0;
	}

	if (buffer == NULL || address > chip_size || address + length > chip_size) {
		return -EINVAL;
	}

	bool direct_read = points_to_dram(buffer);
	uint8_t *temp_buff = NULL;
	size_t read_chunk = MIN(MAX_READ_CHUNK, length);
	size_t temp_chunk = MAX_READ_CHUNK;
	int rc = 0;

	flash_esp32_sem_take(dev);

	if (!direct_read) {

		unsigned int retries = MAX_BUFF_ALLOC_RETRIES;

		while (temp_buff == NULL && retries--) {
			read_chunk = MIN(read_chunk, temp_chunk);
			temp_chunk >>= 1;
			read_chunk = (read_chunk + 3) & ~3;
			temp_buff = k_malloc(read_chunk);
		}

		LOG_INF("allocate temp buffer: %p (%d)", temp_buff, read_chunk);

		if (temp_buff == NULL) {
			rc = -ENOMEM;
			goto out;
		}
	}

	uint8_t *buff = (uint8_t *)buffer;

	do {
		guard->start();

		uint8_t *read_buff = (temp_buff) ? temp_buff : buffer;
		size_t read_len = MIN(read_chunk, length);

		rc = read_data(dev, read_buff, address, read_len);

		if (rc) {
			guard->end();
			break;
		}

		guard->end();

		if (temp_buff) {
			memcpy(buffer, temp_buff, read_len);
		}

		address += read_len;
		length -= read_len;
		buff += read_len;
		buffer = (void *)buff;
	} while (rc == 0 && length > 0);

	k_free(temp_buff);

out:
	flash_esp32_sem_give(dev);

	return rc;
}

static inline void set_write_options(const struct device *dev)
{
	spi_dev_t *hw = DEV_CFG(dev)->controller;

	spi_flash_ll_set_dummy(hw, 0);
	/* only single line flash write is currently supported */
	spi_flash_ll_set_addr_bitlen(hw, (1 + ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN));
}

static int read_status(const struct device *dev, uint32_t *status)
{
	const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev);
	uint32_t status_value = ESP_ROM_SPIFLASH_BUSY_FLAG;

	if (SPI1_EXTRA_DUMMIES == 0) {
		while (ESP_ROM_SPIFLASH_BUSY_FLAG ==
		       (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) {
			WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, 0);
			WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, HOST_FLASH_RDSR);

			int rc = flash_esp32_wait_cmd_done(cfg->controller);

			if (rc != 0) {
				return rc;
			}

			status_value = READ_PERI_REG(PERIPHS_SPI_FLASH_STATUS);
			status_value &= cfg->chip->status_mask;
		}
	} else {
		while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) {
			esp_rom_spiflash_read_user_cmd(&status_value, CMD_RDSR);
		}
	}
	*status = status_value;

	return 0;
}

static inline bool host_idle(spi_dev_t *hw)
{
#if defined(CONFIG_SOC_ESP32)
	bool idle = spi_flash_ll_host_idle(hw);

	idle &= spi_flash_ll_host_idle(&HOST_FLASH_CONTROLLER);
#elif defined(CONFIG_SOC_ESP32S2) || defined(CONFIG_SOC_ESP32C3)
	bool idle = spimem_flash_ll_host_idle((spi_mem_dev_t *)hw);

	idle &= spimem_flash_ll_host_idle(&HOST_FLASH_CONTROLLER);
#endif

	return idle;
}

static int wait_idle(const struct device *dev)
{
	const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev);
	uint32_t status;
	int64_t timeout = k_uptime_get() + SPI_TIMEOUT_MSEC;

	/* wait for spi control ready */
	while (!host_idle(cfg->controller)) {
		if (k_uptime_get() > timeout) {
			return -ETIMEDOUT;
		}
	}

	/* wait for flash status ready */
	if (read_status(dev, &status) != 0) {
		return -EINVAL;
	}
	return 0;
}

static int write_protect(const struct device *dev, bool write_protect)
{
	const struct flash_esp32_dev_config *const cfg = DEV_CFG(dev);

	wait_idle(dev);

	/* enable writing */
	spi_flash_ll_set_write_protect(cfg->controller, write_protect);

	int rc = flash_esp32_wait_cmd_done(cfg->controller);

	if (rc != 0) {
		return rc;
	}
#if !defined(CONFIG_SOC_ESP32C3)
	uint32_t flash_status = 0;

	/* make sure the flash is ready for writing */
	while (ESP_ROM_SPIFLASH_WRENABLE_FLAG != (flash_status & ESP_ROM_SPIFLASH_WRENABLE_FLAG)) {
		read_status(dev, &flash_status);
	}
#endif
	return 0;
}

static int program_page(const struct device *dev, uint32_t spi_addr,
			uint32_t *addr_source, int32_t byte_length)
{
	const uint32_t page_size =  DEV_CFG(dev)->chip->page_size;
	spi_dev_t *hw = DEV_CFG(dev)->controller;

	/* check 4byte alignment */
	if ((byte_length & 0x3) != 0) {
		return -EINVAL;
	}

	/* check if write in one page */
	if (page_size < ((spi_addr % page_size) + byte_length)) {
		return -EINVAL;
	}

	wait_idle(dev);

	uint32_t addr;
	uint32_t prog_len;

	while (byte_length > 0) {
		if (write_protect(dev, false) != 0) {
			return -EINVAL;
		}

		addr = spi_addr & ADDRESS_MASK_24BIT;

		if (byte_length >= ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM) {
			addr |= ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM << ESP_ROM_SPIFLASH_BYTES_LEN;
			prog_len = (uint32_t)ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM;
			spi_flash_ll_set_address(hw, addr);
			spi_flash_ll_program_page(hw, addr_source, prog_len);
			byte_length -= ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM;
			spi_addr += ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM;
		} else {
			addr |= byte_length << ESP_ROM_SPIFLASH_BYTES_LEN;
			prog_len = (uint32_t)byte_length;
			spi_flash_ll_set_address(hw, addr);
			spi_flash_ll_program_page(hw, addr_source, prog_len);
			byte_length = 0;
		}

		addr_source += (ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM/4);

		int rc = flash_esp32_wait_cmd_done(hw);

		if (rc != 0) {
			return rc;
		}

		wait_idle(dev);
	}

	return 0;
}

static int flash_esp32_write_inner(const struct device *dev,
			     uint32_t address,
			     const uint32_t *buffer,
			     size_t length)
{

	const uint32_t page_size =  DEV_CFG(dev)->chip->page_size;
	const uint32_t chip_size =  DEV_CFG(dev)->chip->chip_size;
	uint32_t prog_len, prog_num;

	set_write_options(dev);

	/* check program size */
	if ((address + length) > chip_size) {
		return -EINVAL;
	}

	prog_len = page_size - (address % page_size);
	if (length < prog_len) {
		if (program_page(dev, address, (uint32_t *)buffer, length) != 0) {
			return -EINVAL;
		}
	} else {
		if (program_page(dev, address, (uint32_t *)buffer, prog_len) != 0) {
			return -EINVAL;
		}

		/* whole page program */
		prog_num = (length - prog_len) / page_size;
		for (uint8_t i = 0; i < prog_num; ++i) {
			if (program_page(dev, address + prog_len,
					(uint32_t *)buffer + (prog_len >> 2),
					page_size) != 0) {
				return -EINVAL;
			}

			prog_len += page_size;
		}

		/* remain parts to program */
		if (program_page(dev, address + prog_len,
				(uint32_t *)buffer + (prog_len >> 2),
				length - prog_len) != 0) {
			return -EINVAL;
		}
	}

	return 0;
}

static int flash_esp32_write(const struct device *dev,
			     off_t address,
			     const void *buffer,
			     size_t length)
{
	const uint32_t chip_size =  DEV_CFG(dev)->chip->chip_size;
	const spi_flash_guard_funcs_t *guard = spi_flash_guard_get();
	int rc = 0;

	if (address + length > chip_size) {
		return -EINVAL;
	}

	if (length == 0) {
		return 0;
	}

	const uint8_t *srcc = (const uint8_t *) buffer;
	/*
	 * Large operations are split into (up to) 3 parts:
	 * - Left padding: 4 bytes up to the first 4-byte aligned destination offset.
	 * - Middle part
	 * - Right padding: 4 bytes from the last 4-byte aligned offset covered.
	 */
	size_t left_off = address & ~3U;
	size_t left_size = MIN(((address + 3) & ~3U) - address, length);
	size_t mid_off = left_size;
	size_t mid_size = (length - left_size) & ~3U;
	size_t right_off = left_size + mid_size;
	size_t right_size = length - mid_size - left_size;

	flash_esp32_sem_take(dev);

	if (left_size > 0) {
		uint32_t t = 0xffffffff;

		memcpy(((uint8_t *) &t) + (address - left_off), srcc, left_size);
		guard->start();
		rc = flash_esp32_write_inner(dev, left_off, &t, 4);
		guard->end();
		if (rc != 0) {
			goto out;
		}
	}
	if (mid_size > 0) {
		bool direct_write = esp_ptr_internal(srcc)
				&& esp_ptr_byte_accessible(srcc)
				&& ((uintptr_t) srcc + mid_off) % 4 == 0;

		while (mid_size > 0 && rc == 0) {
			uint32_t write_buf[8];
			uint32_t write_size = MIN(mid_size, MAX_WRITE_CHUNK);
			const uint8_t *write_src = srcc + mid_off;

			if (!direct_write) {
				write_size = MIN(write_size, sizeof(write_buf));
				memcpy(write_buf, write_src, write_size);
				write_src = (const uint8_t *)write_buf;
			}
			guard->start();
			rc = flash_esp32_write_inner(dev, address + mid_off,
					(const uint32_t *) write_src, write_size);
			guard->end();
			mid_size -= write_size;
			mid_off += write_size;
		}
		if (rc != 0) {
			goto out;
		}
	}

	if (right_size > 0) {
		uint32_t t = 0xffffffff;

		memcpy(&t, srcc + right_off, right_size);
		guard->start();
		rc = flash_esp32_write_inner(dev, address + right_off, &t, 4);
		guard->end();
	}

out:
	guard->start();
	flash_esp32_flush_cache(address, length);
	guard->end();
	flash_esp32_sem_give(dev);

	return rc;
}

static int erase_sector(const struct device *dev, uint32_t start_addr)
{
	spi_dev_t *hw = DEV_CFG(dev)->controller;
	int rc = write_protect(dev, false);

	if (rc == 0) {
		rc = wait_idle(dev);
	}

	if (rc == 0) {
		spi_flash_ll_set_addr_bitlen(hw, 24);
		spi_flash_ll_set_address(hw, start_addr & ADDRESS_MASK_24BIT);
		spi_flash_ll_erase_sector(hw);

		rc = flash_esp32_wait_cmd_done(hw);
		if (rc) {
			return rc;
		}

		rc = wait_idle(dev);
		if (rc) {
			LOG_ERR("waiting for host device idle state has failed");
		}
	}

	return rc;
}

static int flash_esp32_erase(const struct device *dev, off_t start, size_t len)
{
	uint32_t sector_size = DEV_CFG(dev)->chip->sector_size;
	uint32_t chip_size = DEV_CFG(dev)->chip->chip_size;
	const spi_flash_guard_funcs_t *guard = spi_flash_guard_get();
	int rc = 0;

	if (start % sector_size != 0) {
		return -EINVAL;
	}
	if (len % sector_size != 0) {
		return -EINVAL;
	}
	if (len + start > chip_size) {
		return -EINVAL;
	}

	flash_esp32_sem_take(dev);

	set_write_options(dev);

	while (len >= sector_size) {
		guard->start();

		rc = erase_sector(dev, start);
		if (rc) {
			guard->end();
			goto out;
		}

		start += sector_size;
		len -= sector_size;

		guard->end();
	}

out:
	guard->start();
	flash_esp32_flush_cache(start, len);
	guard->end();

	flash_esp32_sem_give(dev);

	return rc;
}

#if CONFIG_FLASH_PAGE_LAYOUT
static const struct flash_pages_layout flash_esp32_pages_layout = {
	.pages_count = DT_REG_SIZE(SOC_NV_FLASH_NODE) / FLASH_ERASE_BLK_SZ,
	.pages_size = DT_PROP(SOC_NV_FLASH_NODE, erase_block_size),
};

void flash_esp32_page_layout(const struct device *dev,
			     const struct flash_pages_layout **layout,
			     size_t *layout_size)
{
	*layout = &flash_esp32_pages_layout;
	*layout_size = 1;
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */

static const struct flash_parameters *
flash_esp32_get_parameters(const struct device *dev)
{
	ARG_UNUSED(dev);

	return &flash_esp32_parameters;
}

static int flash_esp32_init(const struct device *dev)
{
	struct flash_esp32_dev_data *const dev_data = DEV_DATA(dev);

#if defined(CONFIG_SOC_ESP32C3)
	spiflash_legacy_data_t *legacy_data = rom_spiflash_legacy_data;

	esp_flashchip_info.chip_size = legacy_data->chip.chip_size;
	esp_flashchip_info.sector_size = legacy_data->chip.sector_size;
	esp_flashchip_info.page_size = legacy_data->chip.page_size;
#endif

	k_sem_init(&dev_data->sem, 1, 1);

	return 0;
}

static const struct flash_driver_api flash_esp32_driver_api = {
	.read = flash_esp32_read,
	.write = flash_esp32_write,
	.erase = flash_esp32_erase,
	.get_parameters = flash_esp32_get_parameters,
#ifdef CONFIG_FLASH_PAGE_LAYOUT
	.page_layout = flash_esp32_page_layout,
#endif
};

static struct flash_esp32_dev_data flash_esp32_data;

static const struct flash_esp32_dev_config flash_esp32_config = {
	.controller = (spi_dev_t *) DT_INST_REG_ADDR(0),
	.chip = &esp_flashchip_info
};

DEVICE_DT_INST_DEFINE(0, flash_esp32_init,
		      NULL,
		      &flash_esp32_data, &flash_esp32_config,
		      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		      &flash_esp32_driver_api);
