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

#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/gd32.h>
#include <zephyr/drivers/pinctrl.h>

#include <gd32_gpio.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 clock id if it exists */
#define GD32_PORT_CLOCK_ID_OR_NONE(nodelabel)				       \
	COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)),		       \
		   (DT_CLOCKS_CELL(DT_NODELABEL(nodelabel), id),), ())

/** 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 clock identifiers */
static const uint16_t gd32_port_clkids[] = {
	GD32_PORT_CLOCK_ID_OR_NONE(gpioa)
	GD32_PORT_CLOCK_ID_OR_NONE(gpiob)
	GD32_PORT_CLOCK_ID_OR_NONE(gpioc)
	GD32_PORT_CLOCK_ID_OR_NONE(gpiod)
	GD32_PORT_CLOCK_ID_OR_NONE(gpioe)
	GD32_PORT_CLOCK_ID_OR_NONE(gpiof)
	GD32_PORT_CLOCK_ID_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(void)
{
	uint16_t clkid = DT_CLOCKS_CELL(AFIO_NODE, id);


	(void)clock_control_on(GD32_CLOCK_CONTROLLER,
			       (clock_control_subsys_t)&clkid);

#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 port, pin_bit, reg_val;
	volatile uint32_t *reg;
	uint16_t clkid;

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

	clkid = gd32_port_clkids[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;
	}

	(void)clock_control_on(GD32_CLOCK_CONTROLLER,
			       (clock_control_subsys_t)&clkid);

	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;
}
