/*
 * Copyright (c) 2021 Teslabs Engineering S.L.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/pinctrl.h>

#include <gd32_gpio.h>
#include <gd32_rcu.h>

/** AFIO DT node */
#define AFIO_NODE DT_NODELABEL(afio)

/** GPIO mode: input floating (CTL bits) */
#define GPIO_MODE_INP_FLOAT 0x4U
/** GPIO mode: input with pull-up/down (CTL bits) */
#define GPIO_MODE_INP_PUPD 0x8U
/** GPIO mode: output push-pull (CTL bits) */
#define GPIO_MODE_ALT_PP 0x8U
/** GPIO mode: output open-drain (CTL bits) */
#define GPIO_MODE_ALT_OD 0xCU

/** Utility macro that expands to the GPIO port address if it exists */
#define GD32_PORT_ADDR_OR_NONE(nodelabel)				       \
	COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)),		       \
		   (DT_REG_ADDR(DT_NODELABEL(nodelabel)),), ())

/** Utility macro that expands to the GPIO RCU if it exists */
#define GD32_PORT_RCU_OR_NONE(nodelabel)				       \
	COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)),		       \
		   (DT_PROP(DT_NODELABEL(nodelabel), rcu_periph_clock),), ())

/** GD32 port addresses */
static const uint32_t gd32_port_addrs[] = {
	GD32_PORT_ADDR_OR_NONE(gpioa)
	GD32_PORT_ADDR_OR_NONE(gpiob)
	GD32_PORT_ADDR_OR_NONE(gpioc)
	GD32_PORT_ADDR_OR_NONE(gpiod)
	GD32_PORT_ADDR_OR_NONE(gpioe)
	GD32_PORT_ADDR_OR_NONE(gpiof)
	GD32_PORT_ADDR_OR_NONE(gpiog)
};

/** GD32 port RCUs */
static const uint32_t gd32_port_rcus[] = {
	GD32_PORT_RCU_OR_NONE(gpioa)
	GD32_PORT_RCU_OR_NONE(gpiob)
	GD32_PORT_RCU_OR_NONE(gpioc)
	GD32_PORT_RCU_OR_NONE(gpiod)
	GD32_PORT_RCU_OR_NONE(gpioe)
	GD32_PORT_RCU_OR_NONE(gpiof)
	GD32_PORT_RCU_OR_NONE(gpiog)
};

/**
 * @brief Initialize AFIO
 *
 * This function enables AFIO clock and configures the I/O compensation if
 * available and enabled in Devicetree.
 *
 * @retval 0 Always
 */
static int afio_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	rcu_periph_clock_enable(DT_PROP(AFIO_NODE, rcu_periph_clock));

#ifdef AFIO_CPSCTL
	if (DT_PROP(AFIO_NODE, enable_cps)) {
		gpio_compensation_config(GPIO_COMPENSATION_ENABLE);
		while (gpio_compensation_flag_get() == RESET)
			;
	}
#endif /* AFIO_CPSCTL */

	return 0;
}

SYS_INIT(afio_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

/**
 * @brief Helper function to configure the SPD register if available.
 *
 * @param port GPIO port address.
 * @param pin_bit GPIO pin, set as bit position.
 * @param speed GPIO speed.
 *
 * @return Value of the mode register (speed) that should be set later.
 */
static inline uint8_t configure_spd(uint32_t port, uint32_t pin_bit,
				    uint8_t speed)
{
	switch (speed) {
	case GD32_OSPEED_MAX:
#ifdef GPIOx_SPD
		GPIOx_SPD(port) |= pin_bit;
#endif /* GPIOx_SPD */
		return speed;
	default:
#ifdef GPIOx_SPD
		GPIOx_SPD(port) &= ~pin_bit;
#endif /* GPIOx_SPD */
		return speed + 1U;
	}
}

/**
 * @brief Configure a pin.
 *
 * @param pin The pin to configure.
 */
static void configure_pin(pinctrl_soc_pin_t pin)
{
	uint8_t port_idx, mode, pin_num;
	uint32_t rcu, port, pin_bit, reg_val;
	volatile uint32_t *reg;

	port_idx = GD32_PORT_GET(pin);
	__ASSERT_NO_MSG(port_idx < ARRAY_SIZE(gd32_port_addrs));

	rcu = gd32_port_rcus[port_idx];
	port = gd32_port_addrs[port_idx];
	pin_num = GD32_PIN_GET(pin);
	pin_bit = BIT(pin_num);
	mode = GD32_MODE_GET(pin);

	if (pin_num < 8U) {
		reg = &GPIO_CTL0(port);
	} else {
		reg = &GPIO_CTL1(port);
		pin_num -= 8U;
	}

	rcu_periph_clock_enable(rcu);

	reg_val = *reg;
	reg_val &= ~GPIO_MODE_MASK(pin_num);

	if (mode == GD32_MODE_ALTERNATE) {
		uint8_t mode;

		mode = configure_spd(port, pin_bit, GD32_OSPEED_GET(pin));

		if (GD32_OTYPE_GET(pin) == GD32_OTYPE_PP) {
			mode |= GPIO_MODE_ALT_PP;
		} else {
			mode |= GPIO_MODE_ALT_OD;
		}

		reg_val |= GPIO_MODE_SET(pin_num, mode);
	} else if (mode == GD32_MODE_GPIO_IN) {
		uint8_t pupd = GD32_PUPD_GET(pin);

		if (pupd == GD32_PUPD_NONE) {
			reg_val |= GPIO_MODE_SET(pin_num, GPIO_MODE_INP_FLOAT);
		} else {
			reg_val |= GPIO_MODE_SET(pin_num, GPIO_MODE_INP_PUPD);

			if (pupd == GD32_PUPD_PULLDOWN) {
				GPIO_BC(port) = pin_bit;
			} else if (pupd == GD32_PUPD_PULLUP) {
				GPIO_BOP(port) = pin_bit;
			}
		}
	}

	*reg = reg_val;
}

/**
 * @brief Configure remap.
 *
 * @param remap Remap bit field as encoded by #GD32_REMAP.
 */
static void configure_remap(uint16_t remap)
{
	uint8_t pos;
	uint32_t reg_val;
	volatile uint32_t *reg;

	/* not remappable */
	if (remap == GD32_NORMP) {
		return;
	}

	if (GD32_REMAP_REG_GET(remap) == 0U) {
		reg = &AFIO_PCF0;
	} else {
		reg = &AFIO_PCF1;
	}

	pos = GD32_REMAP_POS_GET(remap);

	reg_val = *reg;
	reg_val &= ~(GD32_REMAP_MSK_GET(remap) << pos);
	reg_val |= GD32_REMAP_VAL_GET(remap) << pos;
	*reg = reg_val;
}

int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
			   uintptr_t reg)
{
	ARG_UNUSED(reg);

	if (pin_cnt == 0U) {
		return -EINVAL;
	}

	/* same remap is encoded in all pins, so just pick the first */
	configure_remap(GD32_REMAP_GET(pins[0]));

	/* configure all pins */
	for (uint8_t i = 0U; i < pin_cnt; i++) {
		configure_pin(pins[i]);
	}

	return 0;
}
