/*
 * Copyright (c) 2022 Nuvoton Technology Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <assert.h>
#include <zephyr/drivers/pinctrl.h>
#include <soc.h>

/* Driver config */
struct npcx_pinctrl_config {
	/* Device base address used for pinctrl driver */
	uintptr_t base_scfg;
	uintptr_t base_glue;
};

static const struct npcx_pinctrl_config npcx_pinctrl_cfg = {
	.base_scfg = NPCX_SCFG_REG_ADDR,
	.base_glue = NPCX_GLUE_REG_ADDR,
};

/* PWM pinctrl config */
struct npcx_pwm_pinctrl_config {
	uintptr_t base;
	int channel;
};

#define NPCX_PWM_PINCTRL_CFG_INIT(node_id)			\
	{							\
		.base = DT_REG_ADDR(node_id),			\
		.channel = DT_PROP(node_id, pwm_channel),	\
	},

static const struct npcx_pwm_pinctrl_config pwm_pinctrl_cfg[] = {
	DT_FOREACH_STATUS_OKAY(nuvoton_npcx_pwm, NPCX_PWM_PINCTRL_CFG_INIT)
};

/* Pin-control local functions for peripheral devices */
static bool npcx_periph_pinmux_has_lock(int group)
{
#if defined(CONFIG_SOC_SERIES_NPCX7)
	if (group == 0x00 || (group >= 0x02 && group <= 0x04) || group == 0x06 ||
		group == 0x0b || group == 0x0f) {
		return true;
	}
#elif defined(CONFIG_SOC_SERIES_NPCX9)
	if (group == 0x00 || (group >= 0x02 && group <= 0x06) || group == 0x0b ||
		group == 0x0d || (group >= 0x0f && group <= 0x12)) {
		return true;
	}
#endif
	return false;
}

static void npcx_periph_pinmux_configure(const struct npcx_periph *alt, bool is_alternate,
	bool is_locked)
{
	const uintptr_t scfg_base = npcx_pinctrl_cfg.base_scfg;
	uint8_t alt_mask = BIT(alt->bit);

	/*
	 * is_alternate == 0 means select GPIO, otherwise Alternate Func.
	 * inverted == 0:
	 *    Set devalt bit to select Alternate Func.
	 * inverted == 1:
	 *    Clear devalt bit to select Alternate Func.
	 */
	if (is_alternate != alt->inverted) {
		NPCX_DEVALT(scfg_base, alt->group) |=  alt_mask;
	} else {
		NPCX_DEVALT(scfg_base, alt->group) &= ~alt_mask;
	}

	if (is_locked && npcx_periph_pinmux_has_lock(alt->group)) {
		NPCX_DEVALT_LK(scfg_base, alt->group) |= alt_mask;
	}
}

static void npcx_periph_pupd_configure(const struct npcx_periph *pupd,
	enum npcx_io_bias_type type)
{
	const uintptr_t scfg_base = npcx_pinctrl_cfg.base_scfg;

	if (type == NPCX_BIAS_TYPE_NONE) {
		NPCX_PUPD_EN(scfg_base, pupd->group) &= ~BIT(pupd->bit);
	} else {
		NPCX_PUPD_EN(scfg_base, pupd->group) |=  BIT(pupd->bit);
	}
}

static void npcx_periph_pwm_drive_mode_configure(const struct npcx_periph *periph,
	bool is_od)
{
	uintptr_t reg = 0;

	/* Find selected pwm module which enables open-drain prop. */
	for (int i = 0; i < ARRAY_SIZE(pwm_pinctrl_cfg); i++) {
		if (periph->group == pwm_pinctrl_cfg[i].channel) {
			reg = pwm_pinctrl_cfg[i].base;
			break;
		}
	}

	if (reg == 0) {
		return;
	}

	struct pwm_reg *const inst = (struct pwm_reg *)(reg);

	if (is_od) {
		inst->PWMCTLEX |= BIT(NPCX_PWMCTLEX_OD_OUT);
	} else {
		inst->PWMCTLEX &= ~BIT(NPCX_PWMCTLEX_OD_OUT);
	}
}

static void npcx_periph_configure(const pinctrl_soc_pin_t *pin, uintptr_t reg)
{
	if (pin->cfg.periph.type == NPCX_PINCTRL_TYPE_PERIPH_PINMUX) {
		/* Configure peripheral device's pinmux functionality */
		npcx_periph_pinmux_configure(&pin->cfg.periph,
					     !pin->flags.pinmux_gpio,
					     pin->flags.pinmux_lock);
	} else if (pin->cfg.periph.type == NPCX_PINCTRL_TYPE_PERIPH_PUPD) {
		/* Configure peripheral device's internal PU/PD */
		npcx_periph_pupd_configure(&pin->cfg.periph,
			pin->flags.io_bias_type);
	} else if (pin->cfg.periph.type == NPCX_PINCTRL_TYPE_PERIPH_DRIVE) {
		/* Configure peripheral device's drive mode. (Only PWM pads support it) */
		npcx_periph_pwm_drive_mode_configure(&pin->cfg.periph,
			pin->flags.io_drive_type == NPCX_DRIVE_TYPE_OPEN_DRAIN);
	}
}

static void npcx_psl_input_detection_configure(const pinctrl_soc_pin_t *pin)
{
	struct glue_reg *inst_glue = (struct glue_reg *)(npcx_pinctrl_cfg.base_glue);
	const uintptr_t scfg_base = npcx_pinctrl_cfg.base_scfg;
	const struct npcx_psl_input *psl_in = (const struct npcx_psl_input *)&pin->cfg.psl_in;

	/* Configure detection polarity of PSL input pads */
	if (pin->flags.psl_in_polarity == NPCX_PSL_IN_POL_HIGH) {
		NPCX_DEVALT(scfg_base, psl_in->pol_group) |=  BIT(psl_in->pol_bit);
	} else {
		NPCX_DEVALT(scfg_base, psl_in->pol_group) &= ~BIT(psl_in->pol_bit);
	}

	/* Configure detection mode of PSL input pads */
	if (pin->flags.psl_in_mode == NPCX_PSL_IN_MODE_EDGE) {
		inst_glue->PSL_CTS |= NPCX_PSL_CTS_MODE_BIT(psl_in->port);
	} else {
		inst_glue->PSL_CTS &= ~NPCX_PSL_CTS_MODE_BIT(psl_in->port);
	}
}

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

	/* Configure all peripheral devices' properties here. */
	for (uint8_t i = 0; i < pin_cnt; i++) {
		if (pins[i].flags.type == NPCX_PINCTRL_TYPE_PERIPH) {
			/* Configure peripheral device's pinmux functionality */
			npcx_periph_configure(&pins[i], reg);
		} else if (pins[i].flags.type == NPCX_PINCTRL_TYPE_PSL_IN) {
			/* Configure SPL input's detection mode */
			npcx_psl_input_detection_configure(&pins[i]);
		} else {
			return -ENOTSUP;
		}
	}

	return 0;
}
