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

/* Include esp-idf headers first to avoid redefining BIT() macro */
#include <hal/gpio_ll.h>
#include <hal/rtc_io_hal.h>

#include <soc.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/pinctrl/pinctrl_esp32_common.h>

#ifdef CONFIG_SOC_SERIES_ESP32C2
#define out	out.val
#define in	in.val
#define out_w1ts out_w1ts.val
#define out_w1tc out_w1tc.val
#elif CONFIG_SOC_SERIES_ESP32C3
/* gpio structs in esp32c3 series are different from xtensa ones */
#define out out.data
#define in in.data
#define out_w1ts out_w1ts.val
#define out_w1tc out_w1tc.val
#elif CONFIG_SOC_SERIES_ESP32C6
/* gpio structs in esp32c6 are also different */
#define out out.out_data_orig
#define in in.in_data_next
#define out_w1ts out_w1ts.val
#define out_w1tc out_w1tc.val
#endif

#ifndef SOC_GPIO_SUPPORT_RTC_INDEPENDENT
#define SOC_GPIO_SUPPORT_RTC_INDEPENDENT 0
#endif

#define ESP32_INVALID_PORT_ADDR          0UL

#define ESP32_GPIO_PORT_ADDR(nodelabel)				\
	COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)),	\
		(DT_REG_ADDR(DT_NODELABEL(nodelabel)),),	\
		(ESP32_INVALID_PORT_ADDR))

/**
 * @brief Array containing each GPIO port address.
 *
 * Entries will be an invalid address if the port is not enabled.
 */
static const uint32_t esp32_gpio_ports_addrs[] = {
	ESP32_GPIO_PORT_ADDR(gpio0)
	ESP32_GPIO_PORT_ADDR(gpio1)
};

/** Number of GPIO ports. */
static const size_t esp32_gpio_ports_cnt = ARRAY_SIZE(esp32_gpio_ports_addrs);

static inline bool rtc_gpio_is_valid_gpio(uint32_t gpio_num)
{
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
	return (gpio_num < SOC_GPIO_PIN_COUNT && rtc_io_num_map[gpio_num] >= 0);
#else
	return false;
#endif
}

static inline bool esp32_pin_is_valid(uint32_t pin)
{
	return ((BIT(pin) & SOC_GPIO_VALID_GPIO_MASK) != 0);
}

static inline bool esp32_pin_is_output_capable(uint32_t pin)
{
	return ((BIT(pin) & SOC_GPIO_VALID_OUTPUT_GPIO_MASK) != 0);
}

static int esp32_pin_apply_config(uint32_t pin, uint32_t flags)
{
	gpio_dev_t *const gpio_base = (gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio0));
	uint32_t io_pin = (uint32_t) pin + ((ESP32_PORT_IDX(pin) == 1 && pin < 32) ? 32 : 0);
	int ret = 0;

	if (!esp32_pin_is_valid(io_pin)) {
		return -EINVAL;
	}

#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
	if (rtc_gpio_is_valid_gpio(io_pin)) {
		rtcio_hal_function_select(rtc_io_num_map[io_pin], RTCIO_FUNC_DIGITAL);
	}
#endif

	if (io_pin >= GPIO_NUM_MAX) {
		ret = -EINVAL;
		goto end;
	}

	/* Set pin function as GPIO */
	gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[io_pin], PIN_FUNC_GPIO);

	if (flags & ESP32_PULL_UP_FLAG) {
		if (!rtc_gpio_is_valid_gpio(io_pin) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
			gpio_ll_pulldown_dis(&GPIO, io_pin);
			gpio_ll_pullup_en(&GPIO, io_pin);
		} else {
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
			int rtcio_num = rtc_io_num_map[io_pin];

			rtcio_hal_pulldown_disable(rtc_io_num_map[io_pin]);

			if (rtc_io_desc[rtcio_num].pullup) {
				rtcio_hal_pullup_enable(rtc_io_num_map[io_pin]);
			} else {
				ret = -ENOTSUP;
				goto end;
			}
#endif
		}
	} else if (flags & ESP32_PULL_DOWN_FLAG) {
		if (!rtc_gpio_is_valid_gpio(io_pin) || SOC_GPIO_SUPPORT_RTC_INDEPENDENT) {
			gpio_ll_pullup_dis(&GPIO, io_pin);
			gpio_ll_pulldown_en(&GPIO, io_pin);
		} else {
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
			int rtcio_num = rtc_io_num_map[io_pin];

			rtcio_hal_pulldown_enable(rtc_io_num_map[io_pin]);

			if (rtc_io_desc[rtcio_num].pullup) {
				rtcio_hal_pullup_disable(rtc_io_num_map[io_pin]);
			} else {
				ret = -ENOTSUP;
				goto end;
			}
#endif
		}
	}

	if (flags & ESP32_DIR_OUT_FLAG) {
		if (!esp32_pin_is_output_capable(pin)) {
			ret = -EINVAL;
			goto end;
		}

		if (flags & ESP32_OPEN_DRAIN_FLAG) {
			gpio_ll_od_enable(gpio_base, io_pin);
		} else {
			gpio_ll_od_disable(gpio_base, io_pin);
		}

		/* Set output pin initial value */
		if (flags & ESP32_PIN_OUT_HIGH_FLAG) {
			gpio_ll_set_level(gpio_base, io_pin, 1);
		} else if (flags & ESP32_PIN_OUT_LOW_FLAG) {
			gpio_ll_set_level(gpio_base, io_pin, 0);
		}

		gpio_ll_output_enable(&GPIO, io_pin);
		esp_rom_gpio_matrix_out(io_pin, SIG_GPIO_OUT_IDX, false, false);
	} else {
		if (!(flags & ESP32_PIN_OUT_EN_FLAG)) {
			gpio_ll_output_disable(&GPIO, io_pin);
		}
	}

	if (flags & ESP32_DIR_INP_FLAG) {
		gpio_ll_input_enable(&GPIO, io_pin);
	} else {
		if (!(flags & ESP32_PIN_IN_EN_FLAG)) {
			gpio_ll_input_disable(&GPIO, io_pin);
		}
	}

end:
	return ret;
}

static int esp32_pin_configure(const uint32_t pin_mux, const uint32_t pin_cfg)
{
	uint32_t port_addr;
	uint32_t pin_num = ESP32_PIN_NUM(pin_mux);
	uint32_t sig_in = ESP32_PIN_SIGI(pin_mux);
	uint32_t sig_out = ESP32_PIN_SIGO(pin_mux);
	uint32_t flags = 0;

	if (ESP32_PORT_IDX(pin_num) >= esp32_gpio_ports_cnt) {
		return -EINVAL;
	}

	port_addr = esp32_gpio_ports_addrs[ESP32_PORT_IDX(pin_num)];

	if (port_addr == ESP32_INVALID_PORT_ADDR) {
		return -EINVAL;
	}

	switch (ESP32_PIN_BIAS(pin_cfg)) {
	case ESP32_PULL_UP:
		flags |= ESP32_PULL_UP_FLAG;
		break;
	case ESP32_PULL_DOWN:
		flags |= ESP32_PULL_DOWN_FLAG;
		break;
	default:
		break;
	}

	switch (ESP32_PIN_DRV(pin_cfg)) {
	case ESP32_PUSH_PULL:
		flags |= ESP32_PUSH_PULL_FLAG;
		break;
	case ESP32_OPEN_DRAIN:
		flags |= ESP32_OPEN_DRAIN_FLAG;
		break;
	default:
		break;
	}

	if (sig_in == ESP_SIG_INVAL && sig_out == ESP_SIG_INVAL) {
		return -ENOTSUP;
	}

	if (sig_in != ESP_SIG_INVAL) {
		flags |= ESP32_DIR_INP_FLAG;
	}

	if (sig_out != ESP_SIG_INVAL) {
		flags |= ESP32_DIR_OUT_FLAG;
	}

	switch (ESP32_PIN_MODE_OUT(pin_cfg)) {
	case ESP32_PIN_OUT_HIGH:
		flags |= ESP32_PIN_OUT_HIGH_FLAG;
		break;
	case ESP32_PIN_OUT_LOW:
		flags |= ESP32_PIN_OUT_LOW_FLAG;
		break;
	default:
		break;
	}

	switch (ESP32_PIN_EN_DIR(pin_cfg)) {
	case ESP32_PIN_OUT_EN:
		flags |= ESP32_PIN_OUT_EN_FLAG;
		break;
	case ESP32_PIN_IN_EN:
		flags |= ESP32_PIN_IN_EN_FLAG;
		break;
	default:
		break;
	}

	if (flags & ESP32_PIN_OUT_HIGH_FLAG) {
		if (ESP32_PORT_IDX(pin_num) == 0) {
			gpio_dev_t *const gpio_dev =
				(gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio0));
			gpio_dev->out_w1ts = BIT(pin_num);
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio1))
		} else {
			gpio_dev_t *const gpio_dev =
				(gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio1));
			gpio_dev->out1_w1ts.data = BIT(pin_num - 32);
#endif
		}
	}

	if (flags & ESP32_PIN_OUT_LOW_FLAG) {
		if (ESP32_PORT_IDX(pin_num) == 0) {
			gpio_dev_t *const gpio_dev =
				(gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio0));
			gpio_dev->out_w1tc = BIT(pin_num);
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio1))
		} else {
			gpio_dev_t *const gpio_dev =
				(gpio_dev_t *)DT_REG_ADDR(DT_NODELABEL(gpio1));
			gpio_dev->out1_w1tc.data = BIT(pin_num - 32);
#endif
		}
	}

	esp32_pin_apply_config(pin_num, flags);

	if (flags & ESP32_DIR_OUT_FLAG) {
		esp_rom_gpio_matrix_out(pin_num, sig_out, 0, 0);
	}

	if (flags & ESP32_DIR_INP_FLAG) {
		esp_rom_gpio_matrix_in(pin_num, sig_in, 0);
	}

	return 0;
}

int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
			   uintptr_t reg)
{
	uint32_t pin_mux, pin_cfg;
	int ret = 0;

	ARG_UNUSED(reg);

	for (uint8_t i = 0U; i < pin_cnt; i++) {
		pin_mux = pins[i].pinmux;
		pin_cfg = pins[i].pincfg;

		ret = esp32_pin_configure(pin_mux, pin_cfg);
		if (ret < 0) {
			return ret;
		}
	}

	return 0;
}
