/*
 * Copyright (c) 2020, Antmicro <www.antmicro.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT quicklogic_eos_s3_gpio

#include <errno.h>
#include <zephyr/drivers/gpio.h>
#include <soc.h>
#include <eoss3_hal_gpio.h>
#include <eoss3_hal_pads.h>
#include <eoss3_hal_pad_config.h>

#include "gpio_utils.h"

#define MAX_GPIOS		8U
#define GPIOS_MASK		(BIT(MAX_GPIOS) - 1)
#define DISABLED_GPIO_IRQ	0xFFU

struct gpio_eos_s3_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	/* Pin configuration to determine whether use primary
	 * or secondary pin for a target GPIO. Secondary pin is used
	 * when the proper bit is set to 1.
	 *
	 * bit_index : primary_pin_number / secondary_pin_number
	 *
	 * 0 : 6 / 24
	 * 1 : 9 / 26
	 * 2 : 11 / 28
	 * 3 : 14 / 30
	 * 4 : 18 / 31
	 * 5 : 21 / 36
	 * 6 : 22 / 38
	 * 7 : 23 / 45
	 */
	uint8_t pin_secondary_config;
};

struct gpio_eos_s3_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	/* port ISR callback routine address */
	sys_slist_t callbacks;
	/* array of interrupts mapped to the gpio number */
	uint8_t gpio_irqs[MAX_GPIOS];
};

/* Connection table to configure GPIOs with pads */
static const PadConfig pad_configs[] = {
	{.ucPin = PAD_6, .ucFunc = PAD6_FUNC_SEL_GPIO_0},
	{.ucPin = PAD_9, .ucFunc = PAD9_FUNC_SEL_GPIO_1},
	{.ucPin = PAD_11, .ucFunc = PAD11_FUNC_SEL_GPIO_2},
	{.ucPin = PAD_14, .ucFunc = PAD14_FUNC_SEL_GPIO_3},
	{.ucPin = PAD_18, .ucFunc = PAD18_FUNC_SEL_GPIO_4},
	{.ucPin = PAD_21, .ucFunc = PAD21_FUNC_SEL_GPIO_5},
	{.ucPin = PAD_22, .ucFunc = PAD22_FUNC_SEL_GPIO_6},
	{.ucPin = PAD_23, .ucFunc = PAD23_FUNC_SEL_GPIO_7},
	{.ucPin = PAD_24, .ucFunc = PAD24_FUNC_SEL_GPIO_0},
	{.ucPin = PAD_26, .ucFunc = PAD26_FUNC_SEL_GPIO_1},
	{.ucPin = PAD_28, .ucFunc = PAD28_FUNC_SEL_GPIO_2},
	{.ucPin = PAD_30, .ucFunc = PAD30_FUNC_SEL_GPIO_3},
	{.ucPin = PAD_31, .ucFunc = PAD31_FUNC_SEL_GPIO_4},
	{.ucPin = PAD_36, .ucFunc = PAD36_FUNC_SEL_GPIO_5},
	{.ucPin = PAD_38, .ucFunc = PAD38_FUNC_SEL_GPIO_6},
	{.ucPin = PAD_45, .ucFunc = PAD45_FUNC_SEL_GPIO_7},
};

static PadConfig gpio_eos_s3_pad_select(const struct device *dev,
					 uint8_t gpio_num)
{
	const struct gpio_eos_s3_config *config = dev->config;
	uint8_t is_secondary = (config->pin_secondary_config >> gpio_num) & 1;

	return pad_configs[(MAX_GPIOS * is_secondary) + gpio_num];
}

/* This function maps pad number to IRQ number */
static int gpio_eos_s3_get_irq_num(uint8_t pad)
{
	int gpio_irq_num;

	switch (pad) {
	case PAD_6:
		gpio_irq_num = 1;
		break;
	case PAD_9:
		gpio_irq_num = 3;
		break;
	case PAD_11:
		gpio_irq_num = 5;
		break;
	case PAD_14:
		gpio_irq_num = 5;
		break;
	case PAD_18:
		gpio_irq_num = 1;
		break;
	case PAD_21:
		gpio_irq_num = 2;
		break;
	case PAD_22:
		gpio_irq_num = 3;
		break;
	case PAD_23:
		gpio_irq_num = 7;
		break;
	case PAD_24:
		gpio_irq_num = 1;
		break;
	case PAD_26:
		gpio_irq_num = 4;
		break;
	case PAD_28:
		gpio_irq_num = 3;
		break;
	case PAD_30:
		gpio_irq_num = 5;
		break;
	case PAD_31:
		gpio_irq_num = 6;
		break;
	case PAD_36:
		gpio_irq_num = 1;
		break;
	case PAD_38:
		gpio_irq_num = 2;
		break;
	case PAD_45:
		gpio_irq_num = 5;
		break;
	default:
		return -EINVAL;
	}

	return gpio_irq_num;
}

static int gpio_eos_s3_configure(const struct device *dev,
				 gpio_pin_t gpio_num,
				 gpio_flags_t flags)
{
	uint32_t *io_mux = (uint32_t *)IO_MUX;
	GPIOCfgTypeDef gpio_cfg;
	PadConfig pad_config = gpio_eos_s3_pad_select(dev, gpio_num);

	if (flags & GPIO_SINGLE_ENDED) {
		return -ENOTSUP;
	}

	gpio_cfg.ucGpioNum = gpio_num;
	gpio_cfg.xPadConf = &pad_config;

	/* Configure PAD */
	if (flags & GPIO_PULL_UP) {
		gpio_cfg.xPadConf->ucPull = PAD_PULLUP;
	} else if (flags & GPIO_PULL_DOWN) {
		gpio_cfg.xPadConf->ucPull = PAD_PULLDOWN;
	} else {
		/* High impedance */
		gpio_cfg.xPadConf->ucPull = PAD_NOPULL;
	}

	if ((flags & GPIO_INPUT) != 0) {
		gpio_cfg.xPadConf->ucMode = PAD_MODE_INPUT_EN;
		gpio_cfg.xPadConf->ucSmtTrg = PAD_SMT_TRIG_EN;
	}

	if ((flags & GPIO_OUTPUT) != 0) {
		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
			MISC_CTRL->IO_OUTPUT |= (BIT(gpio_num) & GPIOS_MASK);
		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
			MISC_CTRL->IO_OUTPUT &= ~(BIT(gpio_num) & GPIOS_MASK);
		}
		gpio_cfg.xPadConf->ucMode = PAD_MODE_OUTPUT_EN;
	}

	if (flags == GPIO_DISCONNECTED) {
		gpio_cfg.xPadConf->ucMode = PAD_MODE_INPUT_EN;
		gpio_cfg.xPadConf->ucSmtTrg = PAD_SMT_TRIG_DIS;
	}

	/* Initial PAD configuration */
	HAL_PAD_Config(gpio_cfg.xPadConf);

	/* Override direction setup to support bidirectional config */
	if ((flags & GPIO_DIR_MASK) == (GPIO_INPUT | GPIO_OUTPUT)) {
		io_mux += gpio_cfg.xPadConf->ucPin;
		*io_mux &= ~PAD_OEN_DISABLE;
		*io_mux |= PAD_REN_ENABLE;
	}

	return 0;
}

static int gpio_eos_s3_port_get_raw(const struct device *dev,
				    uint32_t *value)
{
	ARG_UNUSED(dev);

	*value = (MISC_CTRL->IO_INPUT & GPIOS_MASK);

	return 0;
}

static int gpio_eos_s3_port_set_masked_raw(const struct device *dev,
					   uint32_t mask,
					   uint32_t value)
{
	ARG_UNUSED(dev);
	uint32_t target_value;
	uint32_t output_states = MISC_CTRL->IO_OUTPUT;

	target_value = ((output_states & ~mask) | (value & mask));
	MISC_CTRL->IO_OUTPUT = (target_value & GPIOS_MASK);

	return 0;
}

static int gpio_eos_s3_port_set_bits_raw(const struct device *dev,
					 uint32_t mask)
{
	ARG_UNUSED(dev);

	MISC_CTRL->IO_OUTPUT |= (mask & GPIOS_MASK);

	return 0;
}

static int gpio_eos_s3_port_clear_bits_raw(const struct device *dev,
					   uint32_t mask)
{
	ARG_UNUSED(dev);

	MISC_CTRL->IO_OUTPUT &= ~(mask & GPIOS_MASK);

	return 0;
}

static int gpio_eos_s3_port_toggle_bits(const struct device *dev,
					uint32_t mask)
{
	ARG_UNUSED(dev);
	uint32_t target_value;
	uint32_t output_states = MISC_CTRL->IO_OUTPUT;

	target_value = output_states ^ mask;
	MISC_CTRL->IO_OUTPUT = (target_value & GPIOS_MASK);

	return 0;
}

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

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

static int gpio_eos_s3_pin_interrupt_configure(const struct device *dev,
					       gpio_pin_t gpio_num,
					       enum gpio_int_mode mode,
					       enum gpio_int_trig trig)
{
	struct gpio_eos_s3_data *data = dev->data;
	GPIOCfgTypeDef gpio_cfg;
	PadConfig pad_config = gpio_eos_s3_pad_select(dev, gpio_num);

	gpio_cfg.ucGpioNum = gpio_num;
	gpio_cfg.xPadConf = &pad_config;

	if (mode == GPIO_INT_MODE_DISABLED) {
		/* Get IRQ number which should be disabled */
		int irq_num = gpio_eos_s3_get_irq_num(pad_config.ucPin);

		if (irq_num < 0) {
			return -EINVAL;
		}

		/* Disable IRQ */
		INTR_CTRL->GPIO_INTR_EN_M4 &= ~BIT((uint32_t)irq_num);

		/* Mark corresponding IRQ number as disabled */
		data->gpio_irqs[irq_num] = DISABLED_GPIO_IRQ;

		/* Clear configuration */
		INTR_CTRL->GPIO_INTR_TYPE &= ~((uint32_t)(BIT(irq_num)));
		INTR_CTRL->GPIO_INTR_POL &= ~((uint32_t)(BIT(irq_num)));
	} else {
		/* Prepare configuration */
		if (mode == GPIO_INT_MODE_LEVEL) {
			gpio_cfg.intr_type = LEVEL_TRIGGERED;
			if (trig == GPIO_INT_TRIG_LOW) {
				gpio_cfg.pol_type = FALL_LOW;
			} else {
				gpio_cfg.pol_type = RISE_HIGH;
			}
		} else {
			gpio_cfg.intr_type = EDGE_TRIGGERED;
			switch (trig) {
			case GPIO_INT_TRIG_LOW:
				gpio_cfg.pol_type = FALL_LOW;
				break;
			case GPIO_INT_TRIG_HIGH:
				gpio_cfg.pol_type = RISE_HIGH;
				break;
			case GPIO_INT_TRIG_BOTH:
				return -ENOTSUP;
			}
		}

		/* Set IRQ configuration */
		int irq_num = HAL_GPIO_IntrCfg(&gpio_cfg);

		if (irq_num < 0) {
			return -EINVAL;
		}

		/* Set corresponding IRQ number as enabled */
		data->gpio_irqs[irq_num] = gpio_num;

		/* Clear pending GPIO interrupts */
		INTR_CTRL->GPIO_INTR |=  BIT((uint32_t)irq_num);

		/* Enable IRQ */
		INTR_CTRL->GPIO_INTR_EN_M4 |= BIT((uint32_t)irq_num);
	}

	return 0;
}

static void gpio_eos_s3_isr(const struct device *dev)
{
	struct gpio_eos_s3_data *data = dev->data;
	/* Level interrupts can be only checked from read-only GPIO_INTR_RAW,
	 * we need to add it to the intr_status.
	 */
	uint32_t intr_status = (INTR_CTRL->GPIO_INTR | INTR_CTRL->GPIO_INTR_RAW);

	/* Clear pending GPIO interrupts */
	INTR_CTRL->GPIO_INTR |= intr_status;

	/* Fire callbacks */
	for (int irq_num = 0; irq_num < MAX_GPIOS; irq_num++) {
		if (data->gpio_irqs[irq_num] != DISABLED_GPIO_IRQ) {
			gpio_fire_callbacks(&data->callbacks,
					    dev, BIT(data->gpio_irqs[irq_num]));
		}
	}
}

#ifdef CONFIG_GPIO_GET_DIRECTION
static int gpio_eos_s3_port_get_direction(const struct device *port, gpio_port_pins_t map,
					  gpio_port_pins_t *inputs, gpio_port_pins_t *outputs)
{
	uint32_t pin;
	PadConfig pad_config;
	gpio_port_pins_t ip = 0;
	gpio_port_pins_t op = 0;
	const struct gpio_eos_s3_config *config = dev->config;

	map &= config->common.port_pin_mask;

	if (inputs != NULL) {
		for (pin = find_lsb_set(pins) - 1; pins;
		     pins &= ~BIT(pin), pin = find_lsb_set(pins) - 1) {
			pad_config = gpio_eos_s3_pad_select(port, pin);
			ip |= (pad_config.ucMode == PAD_MODE_INPUT_EN &&
			       pad_config.ucSmtTrg == PAD_SMT_TRIG_EN) *
			      BIT(pin);
		}

		*inputs = ip;
	}

	if (outputs != NULL) {
		for (pin = find_lsb_set(pins) - 1; pins;
		     pins &= ~BIT(pin), pin = find_lsb_set(pins) - 1) {
			pad_config = gpio_eos_s3_pad_select(port, pin);
			op |= (pad_config.ucMode == PAD_MODE_OUTPUT_EN) * BIT(pin);
		}

		*outputs = op;
	}

	return 0;
}
#endif /* CONFIG_GPIO_GET_DIRECTION */

static const struct gpio_driver_api gpio_eos_s3_driver_api = {
	.pin_configure = gpio_eos_s3_configure,
	.port_get_raw = gpio_eos_s3_port_get_raw,
	.port_set_masked_raw = gpio_eos_s3_port_set_masked_raw,
	.port_set_bits_raw = gpio_eos_s3_port_set_bits_raw,
	.port_clear_bits_raw = gpio_eos_s3_port_clear_bits_raw,
	.port_toggle_bits = gpio_eos_s3_port_toggle_bits,
	.pin_interrupt_configure = gpio_eos_s3_pin_interrupt_configure,
	.manage_callback = gpio_eos_s3_manage_callback,
#ifdef CONFIG_GPIO_GET_DIRECTION
	.port_get_direction = gpio_eos_s3_port_get_direction,
#endif /* CONFIG_GPIO_GET_DIRECTION */
};

static int gpio_eos_s3_init(const struct device *dev)
{
	ARG_UNUSED(dev);
	IRQ_CONNECT(DT_INST_IRQN(0),
		    DT_INST_IRQ(0, priority),
		    gpio_eos_s3_isr,
		    DEVICE_DT_INST_GET(0),
		    0);

	irq_enable(DT_INST_IRQN(0));

	return 0;
}

const struct gpio_eos_s3_config gpio_eos_s3_config = {
	.common = {
		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(0),
	},
	.pin_secondary_config = DT_INST_PROP(0, pin_secondary_config),
};

static struct gpio_eos_s3_data gpio_eos_s3_data = {
	.gpio_irqs = {
		DISABLED_GPIO_IRQ,
		DISABLED_GPIO_IRQ,
		DISABLED_GPIO_IRQ,
		DISABLED_GPIO_IRQ,
		DISABLED_GPIO_IRQ,
		DISABLED_GPIO_IRQ,
		DISABLED_GPIO_IRQ,
		DISABLED_GPIO_IRQ
	},
};

DEVICE_DT_INST_DEFINE(0,
		    gpio_eos_s3_init,
		    NULL,
		    &gpio_eos_s3_data,
		    &gpio_eos_s3_config,
		    PRE_KERNEL_1,
		    CONFIG_GPIO_INIT_PRIORITY,
		    &gpio_eos_s3_driver_api);
