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

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;
	uint32_t int_type = 0;
	uint32_t int_level = 0;
	uint32_t int_level_mask = BIT(pin) | BIT(pin + 16);

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

	cfg->regs->INTTYPE = (cfg->regs->INTTYPE & ~BIT(pin)) | (int_type << pin);
	cfg->regs->INTEN = (cfg->regs->INTEN & ~int_level_mask) | int_level;

	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 const struct gpio_driver_api 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)
