/*
 * Copyright (c) 2022 ITE Corporation. All Rights Reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ite_it8xxx2_pinctrl_func

#include <zephyr/drivers/pinctrl.h>
#include <zephyr/logging/log.h>

#include <chip_chipregs.h>

LOG_MODULE_REGISTER(pinctrl_ite_it8xxx2, LOG_LEVEL_ERR);

#define GPIO_IT8XXX2_REG_BASE \
	((struct gpio_it8xxx2_regs *)DT_REG_ADDR(DT_NODELABEL(gpiogcr)))
#define GPIO_GROUP_MEMBERS  8

struct pinctrl_it8xxx2_gpio {
	/* gpio port control register (byte mapping to pin) */
	uint8_t *reg_gpcr;
	/* function 3 general control register */
	uintptr_t func3_gcr[GPIO_GROUP_MEMBERS];
	/* function 3 enable mask */
	uint8_t func3_en_mask[GPIO_GROUP_MEMBERS];
	/* function 3 external control register */
	uintptr_t func3_ext[GPIO_GROUP_MEMBERS];
	/* function 3 external mask */
	uint8_t func3_ext_mask[GPIO_GROUP_MEMBERS];
	/* function 4 general control register */
	uintptr_t func4_gcr[GPIO_GROUP_MEMBERS];
	/* function 4 enable mask */
	uint8_t func4_en_mask[GPIO_GROUP_MEMBERS];
	/* Input voltage selection */
	uintptr_t volt_sel[GPIO_GROUP_MEMBERS];
	/* Input voltage selection mask */
	uint8_t volt_sel_mask[GPIO_GROUP_MEMBERS];
};

struct pinctrl_it8xxx2_ksi_kso {
	/*
	 * KSI[7:0]/KSO[15:8]/KSO[7:0] port gpio control register
	 * (bit mapping to pin)
	 */
	uint8_t *reg_gctrl;
	/* KSI[7:0]/KSO[15:8]/KSO[7:0] port control register */
	uint8_t *reg_ctrl;
	/*
	 * KSO push-pull/open-drain bit of KSO[15:0] control register
	 * (this bit apply to all pins)
	 */
	int pp_od_mask;
	/*
	 * KSI/KSO pullup bit of KSI[7:0]/KSO[15:0] control register
	 * (this bit apply to all pins)
	 */
	int pullup_mask;
};

struct pinctrl_it8xxx2_config {
	bool gpio_group;
	union {
		struct pinctrl_it8xxx2_gpio gpio;
		struct pinctrl_it8xxx2_ksi_kso ksi_kso;
	};
};

static int pinctrl_it8xxx2_set(const pinctrl_soc_pin_t *pins)
{
	const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
	const struct pinctrl_it8xxx2_gpio *gpio = &(pinctrl_config->gpio);
	uint32_t pincfg = pins->pincfg;
	uint8_t pin = pins->pin;
	volatile uint8_t *reg_gpcr = (uint8_t *)gpio->reg_gpcr + pin;
	volatile uint8_t *reg_volt_sel = (uint8_t *)(gpio->volt_sel[pin]);

	/* Setting pull-up or pull-down. */
	switch (IT8XXX2_DT_PINCFG_PUPDR(pincfg)) {
	case IT8XXX2_PULL_PIN_DEFAULT:
		/* No pull-up or pull-down */
		*reg_gpcr &= ~(GPCR_PORT_PIN_MODE_PULLUP |
			       GPCR_PORT_PIN_MODE_PULLDOWN);
		break;
	case IT8XXX2_PULL_UP:
		*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_PULLUP) &
			     ~GPCR_PORT_PIN_MODE_PULLDOWN;
		break;
	case IT8XXX2_PULL_DOWN:
		*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_PULLDOWN) &
			     ~GPCR_PORT_PIN_MODE_PULLUP;
		break;
	default:
		LOG_ERR("This pull level is not supported.");
		return -EINVAL;
	}

	/*
	 * Since not all GPIOs support voltage selection, configure voltage
	 * selection register only if it is present.
	 */
	if (reg_volt_sel != NULL) {
		/* Setting voltage 3.3V or 1.8V. */
		switch (IT8XXX2_DT_PINCFG_VOLTAGE(pincfg)) {
		case IT8XXX2_VOLTAGE_3V3:
			/* Input voltage selection 3.3V. */
			*reg_volt_sel &= ~gpio->volt_sel_mask[pin];
			break;
		case IT8XXX2_VOLTAGE_1V8:
			__ASSERT(!(IT8XXX2_DT_PINCFG_PUPDR(pincfg)
				   == IT8XXX2_PULL_UP),
			"Don't enable internal pullup if 1.8V voltage is used");
			/* Input voltage selection 1.8V. */
			*reg_volt_sel |= gpio->volt_sel_mask[pin];
			break;
		default:
			LOG_ERR("The voltage selection is not supported");
			return -EINVAL;
		}
	}

	/* Setting tri-state mode. */
	if (IT8XXX2_DT_PINCFG_IMPEDANCE(pincfg)) {
		*reg_gpcr |= (GPCR_PORT_PIN_MODE_PULLUP |
			      GPCR_PORT_PIN_MODE_PULLDOWN);
	}

	return 0;
}

static int pinctrl_gpio_it8xxx2_configure_pins(const pinctrl_soc_pin_t *pins)
{
	const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
	const struct pinctrl_it8xxx2_gpio *gpio = &(pinctrl_config->gpio);
	uint8_t pin = pins->pin;
	volatile uint8_t *reg_gpcr = (uint8_t *)gpio->reg_gpcr + pin;
	volatile uint8_t *reg_func3_gcr = (uint8_t *)(gpio->func3_gcr[pin]);
	volatile uint8_t *reg_func4_gcr = (uint8_t *)(gpio->func4_gcr[pin]);
	volatile uint8_t *reg_func3_ext = (uint8_t *)(gpio->func3_ext[pin]);

	/* Handle PIN configuration. */
	if (pinctrl_it8xxx2_set(pins)) {
		LOG_ERR("Pin configuration is invalid.");
		return -EINVAL;
	}

	/*
	 * If pincfg is input, we don't need to handle
	 * alternate function.
	 */
	if (IT8XXX2_DT_PINCFG_INPUT(pins->pincfg)) {
		*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) &
			     ~GPCR_PORT_PIN_MODE_OUTPUT;
		return 0;
	}

	/*
	 * Handle alternate function.
	 */
	/* Common settings for alternate function. */
	*reg_gpcr &= ~(GPCR_PORT_PIN_MODE_INPUT |
		       GPCR_PORT_PIN_MODE_OUTPUT);
	/* Ensure that func3-ext setting is in default state. */
	if (reg_func3_ext != NULL) {
		*reg_func3_ext &= ~gpio->func3_ext_mask[pin];
	}

	switch (pins->alt_func) {
	case IT8XXX2_ALT_FUNC_1:
		/* Func1: Alternate function has been set above. */
		break;
	case IT8XXX2_ALT_FUNC_2:
		/* Func2: WUI function: turn the pin into an input */
		*reg_gpcr |= GPCR_PORT_PIN_MODE_INPUT;
		break;
	case IT8XXX2_ALT_FUNC_3:
		/*
		 * Func3: In addition to the alternate setting above,
		 *        Func3 also need to set the general control.
		 */
		*reg_func3_gcr |= gpio->func3_en_mask[pin];

		/* Func3-external: Some pins require external setting. */
		if (reg_func3_ext != NULL) {
			*reg_func3_ext |= gpio->func3_ext_mask[pin];
		}
		break;
	case IT8XXX2_ALT_FUNC_4:
		/*
		 * Func4: In addition to the alternate setting above,
		 *        Func4 also need to set the general control.
		 */
		*reg_func4_gcr |= gpio->func4_en_mask[pin];
		break;
	case IT8XXX2_ALT_DEFAULT:
		*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) &
			     ~GPCR_PORT_PIN_MODE_OUTPUT;
		*reg_func3_gcr &= ~gpio->func3_en_mask[pin];
		*reg_func4_gcr &= ~gpio->func4_en_mask[pin];
		break;
	default:
		LOG_ERR("This function is not supported.");
		return -EINVAL;
	}

	return 0;
}

static int pinctrl_kscan_it8xxx2_set(const pinctrl_soc_pin_t *pins)
{
	const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
	const struct pinctrl_it8xxx2_ksi_kso *ksi_kso = &(pinctrl_config->ksi_kso);
	volatile uint8_t *reg_ctrl = ksi_kso->reg_ctrl;
	uint8_t pullup_mask = ksi_kso->pullup_mask;
	uint8_t pp_od_mask = ksi_kso->pp_od_mask;
	uint32_t pincfg = pins->pincfg;

	/*
	 * Enable or disable internal pull-up (this bit apply to all pins):
	 * If KSI[7:0]/KSO[15:0] is in KBS mode , setting 1 enables the internal
	 * pull-up (KSO[17:16] setting internal pull-up by GPIO port GPCR register).
	 * If KSI[7:0]/KSO[15:0] is in GPIO mode, then this bit is always disabled.
	 */
	switch (IT8XXX2_DT_PINCFG_PULLUP(pincfg)) {
	case IT8XXX2_PULL_PIN_DEFAULT:
		/* Disable internal pulll-up */
		*reg_ctrl &= ~pullup_mask;
		break;
	case IT8XXX2_PULL_UP:
		*reg_ctrl |= pullup_mask;
		break;
	default:
		LOG_ERR("This pull level is not supported.");
		return -EINVAL;
	}

	/*
	 * Set push-pull or open-drain mode (this bit apply to all pins):
	 * KSI[7:0] doesn't support push-pull and open-drain settings in kbs mode.
	 * If KSO[17:0] is in KBS mode, setting 1 selects open-drain mode,
	 * setting 0 selects push-pull mode.
	 * If KSO[15:0] is in GPIO mode, then this bit is always disabled.
	 */
	if (pp_od_mask != NO_FUNC) {
		switch (IT8XXX2_DT_PINCFG_PP_OD(pincfg)) {
		case IT8XXX2_PUSH_PULL:
			*reg_ctrl &= ~pp_od_mask;
			break;
		case IT8XXX2_OPEN_DRAIN:
			*reg_ctrl |= pp_od_mask;
			break;
		default:
			LOG_ERR("This pull mode is not supported.");
			return -EINVAL;
		}
	}

	return 0;
}

static int pinctrl_kscan_it8xxx2_configure_pins(const pinctrl_soc_pin_t *pins)
{
	const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
	const struct pinctrl_it8xxx2_ksi_kso *ksi_kso = &(pinctrl_config->ksi_kso);

	/* Set a pin of KSI[7:0]/KSO[15:0] to pullup, push-pull/open-drain */
	if (pinctrl_kscan_it8xxx2_set(pins)) {
		return -EINVAL;
	}

#ifdef CONFIG_SOC_IT8XXX2_REG_SET_V1
	uint8_t pin_mask = BIT(pins->pin);
	volatile uint8_t *reg_gctrl = ksi_kso->reg_gctrl;

	switch (pins->alt_func) {
	case IT8XXX2_ALT_FUNC_1:
		/* Set a pin of KSI[7:0]/KSO[15:0] to kbs mode */
		*reg_gctrl &= ~pin_mask;
		break;
	case IT8XXX2_ALT_DEFAULT:
		/* Set a pin of KSI[7:0]/KSO[15:0] to gpio mode */
		*reg_gctrl |= pin_mask;
		break;
#elif CONFIG_SOC_IT8XXX2_REG_SET_V2
	uint8_t pin = pins->pin;
	volatile uint8_t *reg_gctrl = ksi_kso->reg_gctrl + pin;

	switch (pins->alt_func) {
	case IT8XXX2_ALT_FUNC_1:
		/* Set a pin of KSI[7:0]/KSO[15:0] to kbs mode */
		*reg_gctrl &= ~(GPCR_PORT_PIN_MODE_INPUT |
				GPCR_PORT_PIN_MODE_OUTPUT);
		break;
	case IT8XXX2_ALT_DEFAULT:
		/* Set a pin of KSI[7:0]/KSO[15:0] to gpio mode */
		*reg_gctrl = (*reg_gctrl | GPCR_PORT_PIN_MODE_INPUT) &
			      ~GPCR_PORT_PIN_MODE_OUTPUT;
		break;
#endif
	default:
		LOG_ERR("Alternate function not supported");
		return -ENOTSUP;
	}

	return 0;
}

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

	for (uint8_t i = 0U; i < pin_cnt; i++) {
		pinctrl_config = pins[i].pinctrls->config;

		if (pinctrl_config->gpio_group) {
			status = pinctrl_gpio_it8xxx2_configure_pins(&pins[i]);
		} else {
			status = pinctrl_kscan_it8xxx2_configure_pins(&pins[i]);
		}

		if (status < 0) {
			LOG_ERR("%s pin%d configuration is invalid.",
				pins[i].pinctrls->name, pins[i].pin);
			return status;
		}
	}

	return 0;
}

static int pinctrl_it8xxx2_init(const struct device *dev)
{
	struct gpio_it8xxx2_regs *const gpio_base = GPIO_IT8XXX2_REG_BASE;

	/*
	 * The default value of LPCRSTEN is bit2:1 = 10b(GPD2) in GCR.
	 * If LPC reset is enabled on GPB7, we have to clear bit2:1
	 * to 00b.
	 */
	gpio_base->GPIO_GCR &= ~IT8XXX2_GPIO_LPCRSTEN;

#ifdef CONFIG_SOC_IT8XXX2_REG_SET_V2
	/*
	 * Swap the default I2C2 SMCLK2/SMDAT2 pins from GPC7/GPD0 to GPF6/GPF7,
	 * and I2C3 SMCLK3/SMDAT3 pins from GPB2/GPB5 to GPH1/GPH2,
	 * and I2C5 SMCLK5/SMDAT5 pins from GPE1/GPE2 to GPA4/GPA5,
	 */
	gpio_base->GPIO_GCR7 &= ~(IT8XXX2_GPIO_SMB2PS |
				  IT8XXX2_GPIO_SMB3PS |
				  IT8XXX2_GPIO_SMB5PS);
#endif
	return 0;
}

#define INIT_UNION_CONFIG(inst)                                                        \
	COND_CODE_1(DT_INST_PROP(inst, gpio_group),                                    \
		(.gpio = {                                                             \
			 .reg_gpcr = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0),      \
			 .func3_gcr = DT_INST_PROP(inst, func3_gcr),                   \
			 .func3_en_mask = DT_INST_PROP(inst, func3_en_mask),           \
			 .func3_ext = DT_INST_PROP_OR(inst, func3_ext, {0}),           \
			 .func3_ext_mask = DT_INST_PROP_OR(inst, func3_ext_mask, {0}), \
			 .func4_gcr = DT_INST_PROP(inst, func4_gcr),                   \
			 .func4_en_mask = DT_INST_PROP(inst, func4_en_mask),           \
			 .volt_sel = DT_INST_PROP(inst, volt_sel),                     \
			 .volt_sel_mask = DT_INST_PROP(inst, volt_sel_mask),           \
		}),                                                                    \
		(.ksi_kso = {                                                          \
			 .reg_gctrl = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0),     \
			 .reg_ctrl = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 1),      \
			 .pp_od_mask = (uint8_t)DT_INST_PROP(inst, pp_od_mask),        \
			 .pullup_mask = (uint8_t)DT_INST_PROP(inst, pullup_mask),      \
		})                                                                     \
	)

#define PINCTRL_ITE_INIT(inst)                                                     \
	static const struct pinctrl_it8xxx2_config pinctrl_it8xxx2_cfg_##inst = {  \
		.gpio_group = DT_INST_PROP(inst, gpio_group),                      \
		{                                                                  \
			INIT_UNION_CONFIG(inst)                                    \
		}                                                                  \
	};                                                                         \
										   \
	DEVICE_DT_INST_DEFINE(inst, &pinctrl_it8xxx2_init,                         \
			      NULL,                                                \
			      NULL,                                                \
			      &pinctrl_it8xxx2_cfg_##inst,                         \
			      PRE_KERNEL_1,                                        \
			      CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,                 \
			      NULL);
DT_INST_FOREACH_STATUS_OKAY(PINCTRL_ITE_INIT)
