/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * Copyright (c) 2024 Realtek Semiconductor Corporation, SIBG-SD7
 * Author: Lin Yu-Cheng <lin_yu_cheng@realtek.com>
 */

#define DT_DRV_COMPAT realtek_rts5912_gpio

#include <errno.h>
#include <zephyr/device.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/irq.h>
#include "zephyr/drivers/gpio/gpio_utils.h"
#include <zephyr/logging/log.h>
#include <zephyr/dt-bindings/gpio/realtek-gpio.h>

#include <reg/reg_gpio.h>

LOG_MODULE_REGISTER(gpio_rts5912, CONFIG_GPIO_LOG_LEVEL);

#define RTS5912_GPIOA_REG_BASE ((GPIO_Type *)(DT_REG_ADDR(DT_NODELABEL(gpioa))))

struct gpio_rts5912_config {
	struct gpio_driver_config common;
	volatile uint32_t *reg_base;
	uint8_t num_pins;
};

struct gpio_rts5912_data {
	struct gpio_driver_data common;
	sys_slist_t callbacks;
};

static int pin_is_valid(const struct gpio_rts5912_config *config, gpio_pin_t pin)
{
	if (pin >= config->num_pins) {
		return -EINVAL;
	}

	return 0;
}

static int pin_output_high(const struct device *port, gpio_pin_t pin)
{
	const struct gpio_rts5912_config *config = port->config;
	volatile uint32_t *gcr = &config->reg_base[pin];

	int err = pin_is_valid(config, pin);

	if (err) {
		return err;
	}

	if (*gcr & GPIO_GCR_OUTMD_Msk) {
		/* Switch I/O mode to input mode when configuration is open-drain with output high
		 */
		*gcr = (*gcr & ~GPIO_GCR_DIR_Msk) | GPIO_GCR_OUTCTRL_Msk;
	} else {
		*gcr |= GPIO_GCR_OUTCTRL_Msk | GPIO_GCR_DIR_Msk;
	}

	return 0;
}

static int pin_output_low(const struct device *port, gpio_pin_t pin)
{
	const struct gpio_rts5912_config *config = port->config;
	volatile uint32_t *gcr = &config->reg_base[pin];

	int err = pin_is_valid(config, pin);

	if (err) {
		return err;
	}

	*gcr = (*gcr & ~GPIO_GCR_OUTCTRL_Msk) | GPIO_GCR_DIR_Msk;

	return 0;
}

static int gpio_rts5912_configuration(const struct device *port, gpio_pin_t pin, gpio_flags_t flags)
{
	const struct gpio_rts5912_config *config = port->config;
	volatile uint32_t *gcr = &config->reg_base[pin];
	uint32_t cfg_val = *gcr;

	int err = pin_is_valid(config, pin);

	if (err) {
		return err;
	}

	if (flags & GPIO_INPUT) {
		cfg_val &= ~GPIO_GCR_DIR_Msk;
		cfg_val &= ~GPIO_GCR_OUTCTRL_Msk;
		/* enable input detect */
		cfg_val |= GPIO_GCR_INDETEN_Msk;
	}

	if (flags & GPIO_DISCONNECTED) {
		cfg_val &= ~GPIO_GCR_DIR_Msk;
		cfg_val &= ~GPIO_GCR_OUTCTRL_Msk;
		/* disable input detect */
		cfg_val &= ~GPIO_GCR_INDETEN_Msk;
	}

	if (flags & GPIO_OPEN_DRAIN) {
		cfg_val |= GPIO_GCR_OUTMD_Msk;
	} else {
		cfg_val &= ~GPIO_GCR_OUTMD_Msk;
	}

	switch (flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) {
	case GPIO_PULL_UP:
		cfg_val &= ~GPIO_GCR_PULLDWEN_Msk;
		cfg_val |= GPIO_GCR_PULLUPEN_Msk;
		break;
	case GPIO_PULL_DOWN:
		cfg_val &= ~GPIO_GCR_PULLUPEN_Msk;
		cfg_val |= GPIO_GCR_PULLDWEN_Msk;
		break;
	default:
		break;
	}

	switch (flags & RTS5912_GPIO_VOLTAGE_MASK) {
	case RTS5912_GPIO_VOLTAGE_1V8:
		cfg_val |= GPIO_GCR_INVOLMD_Msk;
		break;
	case RTS5912_GPIO_VOLTAGE_DEFAULT:
	case RTS5912_GPIO_VOLTAGE_3V3:
		cfg_val &= ~GPIO_GCR_INVOLMD_Msk;
		break;
	case RTS5912_GPIO_VOLTAGE_5V0:
		return -ENOTSUP;
	default:
		break;
	}

	if (flags & RTS5912_GPIO_OUTDRV) {
		cfg_val |= GPIO_GCR_OUTDRV_Msk;
	} else {
		cfg_val &= ~GPIO_GCR_OUTDRV_Msk;
	}

	if (flags & RTS5912_GPIO_SLEWRATE) {
		cfg_val |= GPIO_GCR_SLEWRATE_Msk;
	} else {
		cfg_val &= ~GPIO_GCR_SLEWRATE_Msk;
	}

	if (flags & RTS5912_GPIO_SCHEN) {
		cfg_val |= GPIO_GCR_SCHEN_Msk;
	} else {
		cfg_val &= ~GPIO_GCR_SCHEN_Msk;
	}

	cfg_val &= ~GPIO_GCR_MFCTRL_Msk;
	switch (flags & RTS5912_GPIO_MFCTRL_MASK) {
	case RTS5912_GPIO_MFCTRL_0:
		cfg_val |= (0U << GPIO_GCR_MFCTRL_Pos);
		break;
	case RTS5912_GPIO_MFCTRL_1:
		cfg_val |= (1U << GPIO_GCR_MFCTRL_Pos);
		break;
	case RTS5912_GPIO_MFCTRL_2:
		cfg_val |= (2U << GPIO_GCR_MFCTRL_Pos);
		break;
	case RTS5912_GPIO_MFCTRL_3:
		cfg_val |= (3U << GPIO_GCR_MFCTRL_Pos);
		break;
	default:
		return -EINVAL;
	}

	*gcr = cfg_val;

	if (flags & GPIO_OUTPUT) {
		if (flags & GPIO_OUTPUT_INIT_HIGH) {
			pin_output_high(port, pin);
		} else if (flags & GPIO_OUTPUT_INIT_LOW) {
			pin_output_low(port, pin);
		}
	}

	return 0;
}

#ifdef CONFIG_GPIO_GET_CONFIG
static int gpio_rts5912_get_configuration(const struct device *port, gpio_pin_t pin,
					  gpio_flags_t *flags)
{
	const struct gpio_rts5912_config *config = port->config;
	volatile uint32_t *gcr = &config->reg_base[pin];
	gpio_flags_t cfg_flag = 0x0UL;

	int err = pin_is_valid(config, pin);

	if (err) {
		return err;
	}

	if (*gcr & GPIO_GCR_OUTCTRL_Msk) {
		cfg_flag |= GPIO_OUTPUT | GPIO_OUTPUT_INIT_HIGH;
	} else {
		if (*gcr & GPIO_GCR_DIR_Msk) {
			cfg_flag |= GPIO_OUTPUT | GPIO_OUTPUT_INIT_LOW;
		} else {
			cfg_flag |= GPIO_INPUT;
			if (*gcr & GPIO_GCR_INVOLMD_Msk) {
				cfg_flag |= RTS5912_GPIO_VOLTAGE_1V8;
			} else {
				cfg_flag |= RTS5912_GPIO_VOLTAGE_3V3;
			}
		}
	}

	if (*gcr & GPIO_GCR_OUTMD_Msk) {
		cfg_flag |= GPIO_OPEN_DRAIN;
	}

	if (*gcr & GPIO_GCR_PULLUPEN_Msk) {
		cfg_flag |= GPIO_PULL_UP;
	} else if (*gcr & GPIO_GCR_PULLDWEN_Msk) {
		cfg_flag |= GPIO_PULL_DOWN;
	}

	if (*gcr & GPIO_GCR_INDETEN_Msk) {
		cfg_flag |= RTS5912_GPIO_INDETEN;
	} else {
		cfg_flag &= ~RTS5912_GPIO_INDETEN;
	}

	if (*gcr & GPIO_GCR_OUTDRV_Msk) {
		cfg_flag |= RTS5912_GPIO_OUTDRV;
	} else {
		cfg_flag &= ~RTS5912_GPIO_OUTDRV;
	}

	if (*gcr & GPIO_GCR_SLEWRATE_Msk) {
		cfg_flag |= RTS5912_GPIO_SLEWRATE;
	} else {
		cfg_flag &= ~RTS5912_GPIO_SLEWRATE;
	}

	if (*gcr & GPIO_GCR_SCHEN_Msk) {
		cfg_flag |= RTS5912_GPIO_SCHEN;
	} else {
		cfg_flag &= ~RTS5912_GPIO_SCHEN;
	}

	switch ((*gcr & GPIO_GCR_MFCTRL_Msk) >> GPIO_GCR_MFCTRL_Pos) {
	case 0:
		cfg_flag |= RTS5912_GPIO_MFCTRL_0;
		break;
	case 1:
		cfg_flag |= RTS5912_GPIO_MFCTRL_1;
		break;
	case 2:
		cfg_flag |= RTS5912_GPIO_MFCTRL_2;
		break;
	case 3:
		cfg_flag |= RTS5912_GPIO_MFCTRL_3;
		break;
	default:
		cfg_flag |= RTS5912_GPIO_MFCTRL_0;
		break;
	}

	if (*gcr & GPIO_GCR_INTEN_Msk) {
		switch (*gcr & GPIO_GCR_INTCTRL_Msk) {
		case GPIO_GCR_INTCTRL_TRIG_EDGE_HIGH:
			cfg_flag |= GPIO_INT_EDGE_RISING;
			break;
		case GPIO_GCR_INTCTRL_TRIG_EDGE_LOW:
			cfg_flag |= GPIO_INT_EDGE_FALLING;
			break;
		case GPIO_GCR_INTCTRL_TRIG_EDGE_BOTH:
			cfg_flag |= GPIO_INT_EDGE_BOTH;
			break;
		case GPIO_GCR_INTCTRL_TRIG_LEVEL_LOW:
			cfg_flag |= GPIO_INT_LEVEL_LOW;
			break;
		case GPIO_GCR_INTCTRL_TRIG_LEVEL_HIGH:
			cfg_flag |= GPIO_INT_LEVEL_HIGH;
			break;
		default:
			cfg_flag |= GPIO_INT_LEVEL_LOW;
			break;
		}
	} else {
		cfg_flag |= GPIO_INT_DISABLE;
	}

	*flags = cfg_flag;

	return 0;
}
#endif

static int gpio_rts5912_port_get_raw(const struct device *port, gpio_port_value_t *value)
{
	const struct gpio_rts5912_config *config = port->config;
	gpio_port_value_t ret_val = 0;
	uint16_t mask = 0x1U;

	for (gpio_pin_t i = 0; i < config->num_pins; i++) {
		if (config->reg_base[i] & GPIO_GCR_PINSTS_Msk) {
			ret_val |= (gpio_port_value_t)mask;
		}
		mask <<= 1;
	}

	*value = ret_val;

	return 0;
}

static int gpio_rts5912_port_set_masked_raw(const struct device *port, gpio_port_pins_t mask,
					    gpio_port_value_t value)
{
	const struct gpio_rts5912_config *config = port->config;
	uint32_t pin;

	mask &= 0x0000FFFF;
	for (; mask; mask &= ~BIT(pin)) {
		pin = find_lsb_set(mask) - 1;
		if (pin >= config->num_pins) {
			break;
		}

		if (value & BIT(pin)) {
			pin_output_high(port, pin);
		} else {
			pin_output_low(port, pin);
		}
	}

	return 0;
}

static int gpio_rts5912_port_set_bits_raw(const struct device *port, gpio_port_pins_t pins)
{
	const struct gpio_rts5912_config *config = port->config;
	volatile uint32_t *gcr = config->reg_base;
	uint32_t pin = 0;

	pins &= 0x0000FFFF;
	gpio_port_pins_t sel_pin = 1;

	for (; pins;) {
		if (pins & sel_pin) {
			pin_output_high(port, pin);
		}
		pins &= ~sel_pin;
		sel_pin <<= 1;
		gcr++;
		pin++;
	}

	return 0;
}

static int gpio_rts5912_port_clear_bits_raw(const struct device *port, gpio_port_pins_t pins)
{
	const struct gpio_rts5912_config *config = port->config;
	volatile uint32_t *gcr = config->reg_base;
	uint32_t pin = 0;

	pins &= 0x0000FFFF;
	gpio_port_pins_t sel_pin = 1;

	for (; pins;) {
		if (pins & sel_pin) {
			pin_output_low(port, pin);
		}
		pins &= ~sel_pin;
		sel_pin <<= 1;
		gcr++;
		pin++;
	}

	return 0;
}

static int gpio_rts5912_port_toggle_bits(const struct device *port, gpio_port_pins_t pins)
{
	const struct gpio_rts5912_config *config = port->config;
	volatile uint32_t *gcr = config->reg_base;
	uint32_t pin = 0;

	pins &= 0x0000FFFF;
	gpio_port_pins_t sel_pin = 0x1UL;

	for (; pins;) {
		if (pins & sel_pin) {
			if (*gcr & GPIO_GCR_OUTCTRL_Msk) {
				pin_output_low(port, pin);
			} else {
				pin_output_high(port, pin);
			}
		}

		pins &= ~sel_pin;
		sel_pin <<= 1;
		gcr++;
		pin++;
	}

	return 0;
}

int gpio_rts5912_get_pin_num(const struct gpio_dt_spec *gpio)
{
	const struct device *dev = gpio->port;
	const struct gpio_rts5912_config *config = dev->config;
	uint32_t gcr = (uint32_t)config->reg_base;

	return (gcr - (uint32_t)(RTS5912_GPIOA_REG_BASE)) / 4 + gpio->pin;
}

volatile uint32_t *gpio_rts5912_get_port_address(const struct gpio_dt_spec *gpio)
{
	const struct device *dev = gpio->port;
	const struct gpio_rts5912_config *config = dev->config;
	volatile uint32_t *gcr = config->reg_base;

	return gcr;
}

gpio_pin_t gpio_rts5912_get_intr_pin(volatile uint32_t *reg_base)
{
	gpio_pin_t pin = 0U;

	for (; pin < 16; pin++) {
		if (reg_base[pin] & GPIO_GCR_INTSTS_Msk) {
			break;
		}
	}

	return pin;
}

static void gpio_rts5912_isr(const void *arg)
{
	const struct device *port = arg;
	const struct gpio_rts5912_config *config = port->config;
	struct gpio_rts5912_data *data = port->data;
	volatile uint32_t *gcr = config->reg_base;
	unsigned int key = irq_lock();
	gpio_pin_t pin = gpio_rts5912_get_intr_pin(gcr);

	if (gcr[pin] & GPIO_GCR_INTSTS_Msk) {
		gcr[pin] |= GPIO_GCR_INTSTS_Msk;

		gpio_fire_callbacks(&data->callbacks, port, BIT(pin));
	}
	irq_unlock(key);
}

static int gpio_rts5912_intr_config(const struct device *port, gpio_pin_t pin,
				    enum gpio_int_mode mode, enum gpio_int_trig trig)
{
	const struct gpio_rts5912_config *config = port->config;
	volatile uint32_t *gcr = &config->reg_base[pin];
	uint32_t cfg_val = *gcr;
	uint32_t pin_index =
		DT_IRQ_BY_IDX(DT_NODELABEL(gpioa), 0, irq) +
		((uint32_t)(&config->reg_base[pin]) - (uint32_t)(RTS5912_GPIOA_REG_BASE)) / 4;

	int err = pin_is_valid(config, pin);

	if (err) {
		return err;
	}

	switch (mode) {
	case GPIO_INT_MODE_DISABLED:
		cfg_val &= ~GPIO_GCR_INTEN_Msk;
		irq_disable(pin_index);
		*gcr = cfg_val;
		return 0;
	case GPIO_INT_MODE_LEVEL:
		switch (trig) {
		case GPIO_INT_TRIG_LOW:
			cfg_val &= ~GPIO_GCR_INTCTRL_Msk;
			cfg_val |= GPIO_GCR_INTCTRL_TRIG_LEVEL_LOW;
			break;
		case GPIO_INT_TRIG_HIGH:
			cfg_val &= ~GPIO_GCR_INTCTRL_Msk;
			cfg_val |= GPIO_GCR_INTCTRL_TRIG_LEVEL_HIGH;
			break;
		default:
			return -EINVAL;
		}
		break;
	case GPIO_INT_MODE_EDGE:
		switch (trig) {
		case GPIO_INT_TRIG_LOW:
			cfg_val &= ~GPIO_GCR_INTCTRL_Msk;
			cfg_val |= GPIO_GCR_INTCTRL_TRIG_EDGE_LOW;
			break;
		case GPIO_INT_TRIG_HIGH:
			cfg_val &= ~GPIO_GCR_INTCTRL_Msk;
			cfg_val |= GPIO_GCR_INTCTRL_TRIG_EDGE_HIGH;
			break;
		case GPIO_INT_TRIG_BOTH:
			cfg_val &= ~GPIO_GCR_INTCTRL_Msk;
			cfg_val |= GPIO_GCR_INTCTRL_TRIG_EDGE_BOTH;
			break;
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}

	/* enable interrupt */
	cfg_val |= GPIO_GCR_INTEN_Msk;
	/* set value to GPIO register */
	*gcr = cfg_val;

	irq_enable(pin_index);

	return 0;
}

static int gpio_rts5912_manage_cb(const struct device *port, struct gpio_callback *cb, bool set)
{
	struct gpio_rts5912_data *data = port->data;

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

static DEVICE_API(gpio, gpio_rts5912_driver_api) = {
	.pin_configure = gpio_rts5912_configuration,
#ifdef CONFIG_GPIO_GET_CONFIG
	.pin_get_config = gpio_rts5912_get_configuration,
#endif
	.port_get_raw = gpio_rts5912_port_get_raw,
	.port_set_masked_raw = gpio_rts5912_port_set_masked_raw,
	.port_set_bits_raw = gpio_rts5912_port_set_bits_raw,
	.port_clear_bits_raw = gpio_rts5912_port_clear_bits_raw,
	.port_toggle_bits = gpio_rts5912_port_toggle_bits,
	.pin_interrupt_configure = gpio_rts5912_intr_config,
	.manage_callback = gpio_rts5912_manage_cb,
};

#ifdef CONFIG_GEN_ISR_TABLES
#define RTS5912_GPIO_DTNAMIC_IRQ(id)                                                               \
	for (int i = 0; i < 16 && (DT_INST_IRQ_BY_IDX(id, 0, irq) + i) < 132; i++) {               \
		irq_connect_dynamic((DT_INST_IRQ_BY_IDX(id, 0, irq) + i),                          \
				    DT_INST_IRQ(id, priority), gpio_rts5912_isr,                   \
				    DEVICE_DT_INST_GET(id), 0U);                                   \
	}
#else
#define RTS5912_GPIO_DTNAMIC_IRQ(id)                                                               \
	IRQ_CONNECT(DT_INST_IRQN(id), DT_INST_IRQ(id, priority), gpio_rts5912_isr,                 \
		    DEVICE_DT_INST_GET(id), 0U);
#endif

#define GPIO_RTS5912_INIT(id)                                                                      \
	static int gpio_rts5912_init_##id(const struct device *dev)                                \
	{                                                                                          \
		if (!(DT_INST_IRQ_HAS_CELL(id, irq))) {                                            \
			return 0;                                                                  \
		}                                                                                  \
                                                                                                   \
		RTS5912_GPIO_DTNAMIC_IRQ(id)                                                       \
                                                                                                   \
		return 0;                                                                          \
	}                                                                                          \
                                                                                                   \
	static struct gpio_rts5912_data gpio_rts5912_data_##id;                                    \
                                                                                                   \
	static const struct gpio_rts5912_config gpio_rts5912_config_##id = {                       \
		.common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(id)},                  \
		.reg_base = (volatile uint32_t *)DT_INST_REG_ADDR(id),                             \
		.num_pins = DT_INST_PROP(id, ngpios),                                              \
	};                                                                                         \
	DEVICE_DT_INST_DEFINE(id, gpio_rts5912_init_##id, NULL, &gpio_rts5912_data_##id,           \
			      &gpio_rts5912_config_##id, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,  \
			      &gpio_rts5912_driver_api);

DT_INST_FOREACH_STATUS_OKAY(GPIO_RTS5912_INIT)
