/*
 * Copyright (c) 2022 SEAL AG
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nuvoton_numicro_gpio

#include <errno.h>
#include <stdint.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/irq.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/gpio/gpio_utils.h>
#include <zephyr/dt-bindings/gpio/numicro-gpio.h>
#include <NuMicro.h>

#define MODE_PIN_SHIFT(pin)	((pin) * 2)
#define MODE_MASK(pin)		(3 << MODE_PIN_SHIFT(pin))
#define DINOFF_PIN_SHIFT(pin)	((pin) + 16)
#define DINOFF_MASK(pin)	(1 << DINOFF_PIN_SHIFT(pin))
#define PUSEL_PIN_SHIFT(pin)	((pin) * 2)
#define PUSEL_MASK(pin)		(3 << PUSEL_PIN_SHIFT(pin))

#define PORT_PIN_MASK		0xFFFF

struct gpio_numicro_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	GPIO_T *regs;
};

struct gpio_numicro_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	/* port ISR callback routine address */
	sys_slist_t callbacks;
#ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
	/*
	 * backup of the INTEN register.
	 * The higher half is RHIEN for whether rising trigger is enabled, and
	 * the lower half is FLIEN for whether falling trigger is enabled.
	 */
	uint32_t interrupt_en_reg_bak;
#endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */
};

static int gpio_numicro_configure(const struct device *dev,
			       gpio_pin_t pin, gpio_flags_t flags)
{
	const struct gpio_numicro_config *cfg = dev->config;
	GPIO_T * const regs = cfg->regs;

	uint32_t mode;
	uint32_t debounce_enable = 0;
	uint32_t schmitt_enable = 0;
	uint32_t disable_input_path = 0;
	uint32_t bias = GPIO_PUSEL_DISABLE;

	/* Pin mode */
	if ((flags & GPIO_OUTPUT) != 0) {
		/* Output */

		if ((flags & GPIO_SINGLE_ENDED) != 0) {
			if ((flags & GPIO_LINE_OPEN_DRAIN) != 0) {
				mode = GPIO_MODE_OPEN_DRAIN;
			} else {
				/* Output can't be open source */
				return -ENOTSUP;
			}
		} else {
			mode = GPIO_MODE_OUTPUT;
		}
	} else if ((flags & GPIO_INPUT) != 0) {
		/* Input */

		mode = GPIO_MODE_INPUT;

		if ((flags & NUMICRO_GPIO_INPUT_DEBOUNCE) != 0) {
			debounce_enable = 1;
		}

		if ((flags & NUMICRO_GPIO_INPUT_SCHMITT) != 0) {
			schmitt_enable = 1;
		}
	} else {
		/* Deactivated: Analog */

		mode = GPIO_MODE_INPUT;
		disable_input_path = 1;
	}

	/* Bias */
	if ((flags & GPIO_OUTPUT) != 0 || (flags & GPIO_INPUT) != 0) {
		if ((flags & GPIO_PULL_UP) != 0) {
			bias = GPIO_PUSEL_PULL_UP;
		} else if ((flags & GPIO_PULL_DOWN) != 0) {
			bias = GPIO_PUSEL_PULL_DOWN;
		}
	}

	regs->MODE = (regs->MODE & ~MODE_MASK(pin)) |
		     (mode << MODE_PIN_SHIFT(pin));
	regs->DBEN = (regs->DBEN & ~BIT(pin)) | (debounce_enable << pin);
	regs->SMTEN = (regs->SMTEN & ~BIT(pin)) | (schmitt_enable << pin);
	regs->DINOFF = (regs->DINOFF & ~DINOFF_MASK(pin)) |
		       (disable_input_path << DINOFF_PIN_SHIFT(pin));
	regs->PUSEL = (regs->PUSEL & ~PUSEL_MASK(pin)) |
		      (bias << PUSEL_PIN_SHIFT(pin));

	return 0;
}

static int gpio_numicro_port_get_raw(const struct device *dev, uint32_t *value)
{
	const struct gpio_numicro_config *cfg = dev->config;

	*value = cfg->regs->PIN & PORT_PIN_MASK;

	return 0;
}

static int gpio_numicro_port_set_masked_raw(const struct device *dev,
					 uint32_t mask,
					 uint32_t value)
{
	const struct gpio_numicro_config *cfg = dev->config;

	cfg->regs->DATMSK = ~mask;
	cfg->regs->DOUT = value;

	return 0;
}

static int gpio_numicro_port_set_bits_raw(const struct device *dev,
				       uint32_t mask)
{
	const struct gpio_numicro_config *cfg = dev->config;

	cfg->regs->DATMSK = ~mask;
	cfg->regs->DOUT = PORT_PIN_MASK;

	return 0;
}

static int gpio_numicro_port_clear_bits_raw(const struct device *dev,
					 uint32_t mask)
{
	const struct gpio_numicro_config *cfg = dev->config;

	cfg->regs->DATMSK = ~mask;
	cfg->regs->DOUT = 0;

	return 0;
}

static int gpio_numicro_port_toggle_bits(const struct device *dev, uint32_t mask)
{
	const struct gpio_numicro_config *cfg = dev->config;

	cfg->regs->DATMSK = 0;
	cfg->regs->DOUT ^= mask;

	return 0;
}

static int gpio_numicro_pin_interrupt_configure(const struct device *dev,
					     gpio_pin_t pin, enum gpio_int_mode mode,
					     enum gpio_int_trig trig)
{
	const struct gpio_numicro_config *cfg = dev->config;
#ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
	struct gpio_numicro_data *data = dev->data;
#endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */
	uint32_t int_type = 0;
	uint32_t int_level = 0;
	uint32_t int_level_mask = BIT(pin) | BIT(pin + 16);

#ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
	if (mode == GPIO_INT_MODE_DISABLE_ONLY) {
		cfg->regs->INTEN &= ~(BIT(pin) | BIT(pin + 16));
		return 0;
	} else if (mode == GPIO_INT_MODE_ENABLE_ONLY) {
		cfg->regs->INTEN |= data->interrupt_en_reg_bak & (BIT(pin) | BIT(pin + 16));
		return 0;
	}
#endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */

	if (mode != GPIO_INT_MODE_DISABLED) {
		int_type = (mode == GPIO_INT_MODE_LEVEL) ? 1 : 0;

		switch (trig) {
		case GPIO_INT_TRIG_LOW:
			int_level = BIT(pin);
			break;
		case GPIO_INT_TRIG_HIGH:
			int_level = BIT(pin + 16);
			break;
		case GPIO_INT_TRIG_BOTH:
			int_level = BIT(pin) | BIT(pin + 16);
			break;
		default:
			return -EINVAL;
		}
	}

	cfg->regs->INTTYPE = (cfg->regs->INTTYPE & ~BIT(pin)) | (int_type << pin);
	cfg->regs->INTEN = (cfg->regs->INTEN & ~int_level_mask) | int_level;
#ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
	data->interrupt_en_reg_bak = cfg->regs->INTEN;
#endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */

	return 0;
}

static int gpio_numicro_manage_callback(const struct device *dev,
					struct gpio_callback *callback,
					bool set)
{
	struct gpio_numicro_data *data = dev->data;

	return gpio_manage_callback(&data->callbacks, callback, set);
}

static void gpio_numicro_isr(const struct device *dev)
{
	const struct gpio_numicro_config *cfg = dev->config;
	struct gpio_numicro_data *data = dev->data;
	uint32_t int_status;

	int_status = cfg->regs->INTSRC;

	/* Clear the port interrupts */
	cfg->regs->INTSRC = int_status;

	gpio_fire_callbacks(&data->callbacks, dev, int_status);
}

static DEVICE_API(gpio, gpio_numicro_driver_api) = {
	.pin_configure = gpio_numicro_configure,
	.port_get_raw = gpio_numicro_port_get_raw,
	.port_set_masked_raw = gpio_numicro_port_set_masked_raw,
	.port_set_bits_raw = gpio_numicro_port_set_bits_raw,
	.port_clear_bits_raw = gpio_numicro_port_clear_bits_raw,
	.port_toggle_bits = gpio_numicro_port_toggle_bits,
	.pin_interrupt_configure = gpio_numicro_pin_interrupt_configure,
	.manage_callback = gpio_numicro_manage_callback,
};

#define GPIO_NUMICRO_INIT(n)						\
	static int gpio_numicro_port##n##_init(const struct device *dev)\
	{								\
		IRQ_CONNECT(DT_INST_IRQN(n),				\
			    DT_INST_IRQ(n, priority),			\
			    gpio_numicro_isr,				\
			    DEVICE_DT_INST_GET(n), 0);			\
		irq_enable(DT_INST_IRQN(n));				\
		return 0;						\
	}								\
									\
	static struct gpio_numicro_data gpio_numicro_port##n##_data;	\
									\
	static const struct gpio_numicro_config gpio_numicro_port##n##_config = {\
		.common = {						\
			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n),\
		},							\
		.regs = (GPIO_T *)DT_INST_REG_ADDR(n),			\
	};								\
									\
	DEVICE_DT_INST_DEFINE(n,					\
			      gpio_numicro_port##n##_init,		\
			      NULL,					\
			      &gpio_numicro_port##n##_data,		\
			      &gpio_numicro_port##n##_config,		\
			      PRE_KERNEL_1,				\
			      CONFIG_GPIO_INIT_PRIORITY,		\
			      &gpio_numicro_driver_api);

DT_INST_FOREACH_STATUS_OKAY(GPIO_NUMICRO_INIT)
