/*
 * Copyright (c) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT microchip_xec_gpio_v2

#include <errno.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/dt-bindings/gpio/gpio.h>
#include <zephyr/dt-bindings/pinctrl/mchp-xec-pinctrl.h>
#include <soc.h>
#include <zephyr/irq.h>

#include <zephyr/drivers/gpio/gpio_utils.h>

#define XEC_GPIO_EDGE_DLY_COUNT		4

static const uint32_t valid_ctrl_masks[NUM_MCHP_GPIO_PORTS] = {
	(MCHP_GPIO_PORT_A_BITMAP),
	(MCHP_GPIO_PORT_B_BITMAP),
	(MCHP_GPIO_PORT_C_BITMAP),
	(MCHP_GPIO_PORT_D_BITMAP),
	(MCHP_GPIO_PORT_E_BITMAP),
	(MCHP_GPIO_PORT_F_BITMAP),
};

struct gpio_xec_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	/* port ISR callback routine address */
	sys_slist_t callbacks;
};

struct gpio_xec_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	uintptr_t pcr1_base;
	uintptr_t parin_addr;
	uintptr_t parout_addr;
	uint8_t girq_id;
	uint8_t port_num;
	uint32_t flags;
};

/* Each GPIO pin 32-bit control register located consecutively in memory */
static inline uintptr_t pin_ctrl_addr(const struct device *dev, gpio_pin_t pin)
{
	const struct gpio_xec_config *config = dev->config;

	return config->pcr1_base + ((uintptr_t)pin * 4u);
}

/* GPIO Parallel input is a single 32-bit register per bank of 32 pins */
static inline uintptr_t pin_parin_addr(const struct device *dev)
{
	const struct gpio_xec_config *config = dev->config;

	return config->parin_addr;
}

/* GPIO Parallel output is a single 32-bit register per bank of 32 pins */
static inline uintptr_t pin_parout_addr(const struct device *dev)
{
	const struct gpio_xec_config *config = dev->config;

	return config->parout_addr;
}

/*
 * Use Zephyr system API to implement
 * reg32(addr) = (reg32(addr) & ~mask) | (val & mask)
 */
static inline void xec_mask_write32(uintptr_t addr, uint32_t mask, uint32_t val)
{
	uint32_t r = (sys_read32(addr) & ~mask) | (val & mask);

	sys_write32(r, addr);
}

/*
 * NOTE: gpio_flags_t b[15:0] are defined in the dt-binding gpio header.
 * b[31:16] are defined in the driver gpio header.
 * Hardware only supports push-pull or open-drain.
 */
static int gpio_xec_validate_flags(gpio_flags_t flags)
{
	if ((flags & (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN))
	    == (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE)) {
		return -ENOTSUP;
	}

	if ((flags & (GPIO_INPUT | GPIO_OUTPUT))
	    == (GPIO_INPUT | GPIO_OUTPUT)) {
		return -ENOTSUP;
	}

	if ((flags & GPIO_OUTPUT_INIT_LOW) && (flags & GPIO_OUTPUT_INIT_HIGH)) {
		return -EINVAL;
	}

	return 0;
}

/*
 * Each GPIO pin has two 32-bit control registers. Control 1 configures pin
 * features except for drive strength and slew rate in Control 2.
 * A pin's input and output state can be read/written from either the Control 1
 * register or from corresponding bits in the GPIO parallel input/output registers.
 * The parallel input and output registers group 32 pins into each register.
 * The GPIO hardware restricts the pin output state to Control 1 or the parallel bit.
 * Both output bits reflect each other on read and writes but only one is writable
 * selected by the output control select bit in Control 1. In the configuration API
 * we use Control 1 to configure all pin features and output state. Before exiting,
 * we set the output select for parallel mode enabling writes to the parallel output bit.
 */
static int gpio_xec_configure(const struct device *dev,
			      gpio_pin_t pin, gpio_flags_t flags)
{
	const struct gpio_xec_config *config = dev->config;
	uintptr_t pcr1_addr = 0u;
	uint32_t pcr1 = 0u, pcr1_new = 0u;
	uint32_t msk = (MCHP_GPIO_CTRL_PWRG_MASK
		| MCHP_GPIO_CTRL_BUFT_MASK | MCHP_GPIO_CTRL_DIR_MASK
		| MCHP_GPIO_CTRL_AOD_MASK | BIT(MCHP_GPIO_CTRL_POL_POS)
		| MCHP_GPIO_CTRL_MUX_MASK | MCHP_GPIO_CTRL_INPAD_DIS_MASK);

	if (!(valid_ctrl_masks[config->port_num] & BIT(pin))) {
		return -EINVAL;
	}

	int ret = gpio_xec_validate_flags(flags);

	if (ret) {
		return ret;
	}

	pcr1_addr = pin_ctrl_addr(dev, pin);
	pcr1 = sys_read32(pcr1_addr);

	if (flags == GPIO_DISCONNECTED) {
		pcr1 = (pcr1 & ~MCHP_GPIO_CTRL_PWRG_MASK) | MCHP_GPIO_CTRL_PWRG_OFF;
		sys_write32(pcr1, pcr1_addr);
		return 0;
	}

	/* final pin state will be powered */
	pcr1_new = MCHP_GPIO_CTRL_PWRG_VTR_IO;

	/* always enable input pad */
	if (pcr1 & BIT(MCHP_GPIO_CTRL_INPAD_DIS_POS)) {
		pcr1 &= ~BIT(MCHP_GPIO_CTRL_INPAD_DIS_POS);
		sys_write32(pcr1, pcr1_addr);
	}

	if (flags & GPIO_OUTPUT) {
		pcr1_new |= BIT(MCHP_GPIO_CTRL_DIR_POS);
		msk |= BIT(MCHP_GPIO_CTRL_OUTVAL_POS);
		if (flags & GPIO_OUTPUT_INIT_HIGH) {
			pcr1_new |= BIT(MCHP_GPIO_CTRL_OUTVAL_POS);
		} else if (flags & GPIO_OUTPUT_INIT_LOW) {
			pcr1_new &= ~BIT(MCHP_GPIO_CTRL_OUTVAL_POS);
		} else { /* copy current input state to output state */
			if ((pcr1 & MCHP_GPIO_CTRL_PWRG_MASK) == MCHP_GPIO_CTRL_PWRG_OFF) {
				pcr1 &= ~(MCHP_GPIO_CTRL_PWRG_MASK);
				pcr1 |= MCHP_GPIO_CTRL_PWRG_VTR_IO;
				sys_write32(pcr1, pcr1_addr);
			}
			pcr1 = sys_read32(pcr1_addr);
			if (pcr1 & BIT(MCHP_GPIO_CTRL_INPAD_VAL_POS)) {
				pcr1_new |= BIT(MCHP_GPIO_CTRL_OUTVAL_POS);
			} else {
				pcr1_new &= ~BIT(MCHP_GPIO_CTRL_OUTVAL_POS);
			}
		}
		if (flags & GPIO_LINE_OPEN_DRAIN) {
			pcr1_new |= BIT(MCHP_GPIO_CTRL_BUFT_POS);
		}
	}

	if (flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) {
		msk |= MCHP_GPIO_CTRL_PUD_MASK;
		/* both bits specifies repeater mode */
		if (flags & GPIO_PULL_UP) {
			pcr1_new |= MCHP_GPIO_CTRL_PUD_PU;
		}
		if (flags & GPIO_PULL_DOWN) {
			pcr1_new |= MCHP_GPIO_CTRL_PUD_PD;
		}
	}

	/*
	 * Problem, if pin was power gated off we can't read input.
	 * How to turn on pin to read input but not glitch it?
	 */
	pcr1 = (pcr1 & ~msk) | (pcr1_new & msk);
	sys_write32(pcr1, pcr1_addr); /* configuration. may generate a single edge */
	 /* Control output bit becomes read-only and parallel out register bit becomes r/w */
	sys_write32(pcr1 | BIT(MCHP_GPIO_CTRL_AOD_POS), pcr1_addr);

	return 0;
}

static int gen_gpio_ctrl_icfg(enum gpio_int_mode mode, enum gpio_int_trig trig,
			      uint32_t *pin_ctr1)
{
	if (!pin_ctr1) {
		return -EINVAL;
	}

	if (mode == GPIO_INT_MODE_DISABLED) {
		*pin_ctr1 = MCHP_GPIO_CTRL_IDET_DISABLE;
	} else {
		if (mode == GPIO_INT_MODE_LEVEL) {
			if (trig == GPIO_INT_TRIG_HIGH) {
				*pin_ctr1 = MCHP_GPIO_CTRL_IDET_LVL_HI;
			} else {
				*pin_ctr1 = MCHP_GPIO_CTRL_IDET_LVL_LO;
			}
		} else {
			switch (trig) {
			case GPIO_INT_TRIG_LOW:
				*pin_ctr1 = MCHP_GPIO_CTRL_IDET_FEDGE;
				break;
			case GPIO_INT_TRIG_HIGH:
				*pin_ctr1 = MCHP_GPIO_CTRL_IDET_REDGE;
				break;
			case GPIO_INT_TRIG_BOTH:
				*pin_ctr1 = MCHP_GPIO_CTRL_IDET_BEDGE;
				break;
			default:
				return -EINVAL;
			}
		}
	}

	return 0;
}

static void gpio_xec_intr_en(gpio_pin_t pin, enum gpio_int_mode mode,
			     uint8_t girq_id)
{
	if (mode != GPIO_INT_MODE_DISABLED) {
		/* Enable interrupt to propagate via its GIRQ to the NVIC */
		mchp_soc_ecia_girq_src_en(girq_id, pin);
	}
}

static int gpio_xec_pin_interrupt_configure(const struct device *dev,
					    gpio_pin_t pin,
					    enum gpio_int_mode mode,
					    enum gpio_int_trig trig)
{
	const struct gpio_xec_config *config = dev->config;
	uintptr_t pcr1_addr = pin_ctrl_addr(dev, pin);
	uint32_t pcr1 = 0u;
	uint32_t pcr1_req = 0u;

	/* Validate pin number range in terms of current port */
	if ((valid_ctrl_masks[config->port_num] & BIT(pin)) == 0U) {
		return -EINVAL;
	}

	/* Check if GPIO port supports interrupts */
	if ((mode != GPIO_INT_MODE_DISABLED) &&
	    ((config->flags & GPIO_INT_ENABLE) == 0)) {
		return -ENOTSUP;
	}

	pcr1_req = MCHP_GPIO_CTRL_IDET_DISABLE;
	if (gen_gpio_ctrl_icfg(mode, trig, &pcr1_req)) {
		return -EINVAL;
	}

	/* Disable interrupt in the EC aggregator */
	mchp_soc_ecia_girq_src_dis(config->girq_id, pin);

	/* pin configuration matches requested detection mode? */
	pcr1 = sys_read32(pcr1_addr);
	/* HW detects interrupt on input. Make sure input pad disable is cleared */
	pcr1 &= ~BIT(MCHP_GPIO_CTRL_INPAD_DIS_POS);

	if ((pcr1 & MCHP_GPIO_CTRL_IDET_MASK) == pcr1_req) {
		gpio_xec_intr_en(pin, mode, config->girq_id);
		return 0;
	}

	pcr1 &= ~MCHP_GPIO_CTRL_IDET_MASK;

	if (mode == GPIO_INT_MODE_LEVEL) {
		if (trig == GPIO_INT_TRIG_HIGH) {
			pcr1 |= MCHP_GPIO_CTRL_IDET_LVL_HI;
		} else {
			pcr1 |= MCHP_GPIO_CTRL_IDET_LVL_LO;
		}
	} else if (mode == GPIO_INT_MODE_EDGE) {
		if (trig == GPIO_INT_TRIG_LOW) {
			pcr1 |= MCHP_GPIO_CTRL_IDET_FEDGE;
		} else if (trig == GPIO_INT_TRIG_HIGH) {
			pcr1 |= MCHP_GPIO_CTRL_IDET_REDGE;
		} else if (trig == GPIO_INT_TRIG_BOTH) {
			pcr1 |= MCHP_GPIO_CTRL_IDET_BEDGE;
		}
	} else {
		pcr1 |= MCHP_GPIO_CTRL_IDET_DISABLE;
	}

	sys_write32(pcr1, pcr1_addr);
	/* delay for HW to synchronize after it ungates its clock */
	for (int i = 0; i < XEC_GPIO_EDGE_DLY_COUNT; i++) {
		sys_read32(pcr1_addr);
	}

	mchp_soc_ecia_girq_src_clr(config->girq_id, pin);

	gpio_xec_intr_en(pin, mode, config->girq_id);

	return 0;
}

static int gpio_xec_port_set_masked_raw(const struct device *dev,
					uint32_t mask,
					uint32_t value)
{
	uintptr_t pout_addr = pin_parout_addr(dev);

	xec_mask_write32(pout_addr, mask, value);

	return 0;
}

static int gpio_xec_port_set_bits_raw(const struct device *dev, uint32_t mask)
{
	uintptr_t pout_addr = pin_parout_addr(dev);

	sys_write32(sys_read32(pout_addr) | mask, pout_addr);

	return 0;
}

static int gpio_xec_port_clear_bits_raw(const struct device *dev,
					uint32_t mask)
{
	uintptr_t pout_addr = pin_parout_addr(dev);

	sys_write32(sys_read32(pout_addr) & ~mask, pout_addr);

	return 0;
}

static int gpio_xec_port_toggle_bits(const struct device *dev, uint32_t mask)
{
	uintptr_t pout_addr = pin_parout_addr(dev);

	sys_write32(sys_read32(pout_addr) ^ mask, pout_addr);

	return 0;
}

static int gpio_xec_port_get_raw(const struct device *dev, uint32_t *value)
{
	uintptr_t pin_addr = pin_parin_addr(dev);

	*value = sys_read32(pin_addr);

	return 0;
}

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

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

	return 0;
}

#ifdef CONFIG_GPIO_GET_DIRECTION
static int gpio_xec_get_direction(const struct device *port, gpio_port_pins_t map,
				  gpio_port_pins_t *inputs, gpio_port_pins_t *outputs)
{
	if (!port) {
		return -EINVAL;
	}

	const struct gpio_xec_config *config = port->config;
	uint32_t valid_msk = valid_ctrl_masks[config->port_num];

	*inputs = 0u;
	*outputs = 0u;
	for (uint8_t pin = 0; pin < 32; pin++) {
		if (!map) {
			break;
		}
		if ((map & BIT(pin)) && (valid_msk & BIT(pin))) {
			uintptr_t pcr1_addr = pin_ctrl_addr(port, pin);
			uint32_t pcr1 = sys_read32(pcr1_addr);

			if (!((pcr1 & MCHP_GPIO_CTRL_PWRG_MASK) == MCHP_GPIO_CTRL_PWRG_OFF)) {
				if (outputs && (pcr1 & BIT(MCHP_GPIO_CTRL_DIR_POS))) {
					*outputs |= BIT(pin);
				} else if (inputs && !(pcr1 & BIT(MCHP_GPIO_CTRL_INPAD_DIS_POS))) {
					*inputs |= BIT(pin);
				}
			}

			map &= ~BIT(pin);
		}
	}

	return 0;
}
#endif

#ifdef CONFIG_GPIO_GET_CONFIG
int gpio_xec_get_config(const struct device *port, gpio_pin_t pin, gpio_flags_t *flags)
{
	if (!port || !flags) {
		return -EINVAL;
	}

	const struct gpio_xec_config *config = port->config;
	uint32_t valid_msk = valid_ctrl_masks[config->port_num];

	if (!(valid_msk & BIT(pin))) {
		return -EINVAL;
		/* Or should we set *flags = GPIO_DISCONNECTED and return success? */
	}

	uintptr_t pcr1_addr = pin_ctrl_addr(port, pin);
	uint32_t pcr1 = sys_read32(pcr1_addr);
	uint32_t pin_flags = 0u;

	if (pcr1 & BIT(MCHP_GPIO_CTRL_DIR_POS)) {
		pin_flags |= GPIO_OUTPUT;
		if (pcr1 & BIT(MCHP_GPIO_CTRL_OUTVAL_POS)) {
			pin_flags |= GPIO_OUTPUT_INIT_HIGH;
		} else {
			pin_flags |= GPIO_OUTPUT_INIT_LOW;
		}

		if (pcr1 & BIT(MCHP_GPIO_CTRL_BUFT_POS)) {
			pin_flags |= GPIO_OPEN_DRAIN;
		}
	} else if (!(pcr1 & BIT(MCHP_GPIO_CTRL_INPAD_DIS_POS))) {
		pin_flags |= GPIO_INPUT;
	}

	if (pin_flags) {
		*flags = pin_flags;
	} else {
		*flags = GPIO_DISCONNECTED;
	}

	return 0;
}
#endif

static void gpio_gpio_xec_port_isr(const struct device *dev)
{
	const struct gpio_xec_config *config = dev->config;
	struct gpio_xec_data *data = dev->data;
	uint32_t girq_result;

	/*
	 * Figure out which interrupts have been triggered from the EC
	 * aggregator result register
	 */
	girq_result = mchp_soc_ecia_girq_result(config->girq_id);

	/* Clear source register in aggregator before firing callbacks */
	mchp_soc_ecia_girq_src_clr_bitmap(config->girq_id, girq_result);

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

/* GPIO driver official API table */
static const struct gpio_driver_api gpio_xec_driver_api = {
	.pin_configure = gpio_xec_configure,
	.port_get_raw = gpio_xec_port_get_raw,
	.port_set_masked_raw = gpio_xec_port_set_masked_raw,
	.port_set_bits_raw = gpio_xec_port_set_bits_raw,
	.port_clear_bits_raw = gpio_xec_port_clear_bits_raw,
	.port_toggle_bits = gpio_xec_port_toggle_bits,
	.pin_interrupt_configure = gpio_xec_pin_interrupt_configure,
	.manage_callback = gpio_xec_manage_callback,
#ifdef CONFIG_GPIO_GET_DIRECTION
	.port_get_direction = gpio_xec_get_direction,
#endif
#ifdef CONFIG_GPIO_GET_CONFIG
	.pin_get_config = gpio_xec_get_config,
#endif
};

#define XEC_GPIO_PORT_FLAGS(n)						\
	((DT_INST_IRQ_HAS_CELL(n, irq)) ? GPIO_INT_ENABLE : 0)

#define XEC_GPIO_PORT(n)						\
	static int gpio_xec_port_init_##n(const struct device *dev)	\
	{								\
		if (!(DT_INST_IRQ_HAS_CELL(n, irq))) {			\
			return 0;					\
		}							\
									\
		const struct gpio_xec_config *config = dev->config;	\
									\
		mchp_soc_ecia_girq_aggr_en(config->girq_id, 1);		\
									\
		IRQ_CONNECT(DT_INST_IRQN(n),				\
			    DT_INST_IRQ(n, priority),			\
			    gpio_gpio_xec_port_isr,			\
			    DEVICE_DT_INST_GET(n), 0U);			\
									\
		irq_enable(DT_INST_IRQN(n));				\
									\
		return 0;						\
	}								\
									\
	static struct gpio_xec_data gpio_xec_port_data_##n;		\
									\
	static const struct gpio_xec_config xec_gpio_config_##n = {	\
		.common = {						\
			.port_pin_mask =				\
				GPIO_PORT_PIN_MASK_FROM_DT_INST(n),	\
		},							\
		.pcr1_base = (uintptr_t)DT_INST_REG_ADDR_BY_IDX(n, 0),	\
		.parin_addr = (uintptr_t)DT_INST_REG_ADDR_BY_IDX(n, 1),	\
		.parout_addr = (uintptr_t)DT_INST_REG_ADDR_BY_IDX(n, 2),\
		.port_num = DT_INST_PROP(n, port_id),			\
		.girq_id = DT_INST_PROP_OR(n, girq_id, 0),		\
		.flags = XEC_GPIO_PORT_FLAGS(n),			\
	};								\
									\
	DEVICE_DT_INST_DEFINE(n, gpio_xec_port_init_##n, NULL,		\
		&gpio_xec_port_data_##n, &xec_gpio_config_##n,		\
		PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,			\
		&gpio_xec_driver_api);

DT_INST_FOREACH_STATUS_OKAY(XEC_GPIO_PORT)
