/*
 * Copyright (c) 2022 ITE Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ite_it8xxx2_gpiokscan

#include <errno.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/gpio/gpio_utils.h>
#include <zephyr/dt-bindings/gpio/ite-it8xxx2-gpio.h>
#include <zephyr/sys/util.h>
#include <zephyr/types.h>

struct gpio_kscan_cfg {
	/* The gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	/* KSI[7:0]/KSO[15:8]/KSO[7:0] port gpio output enable register (bit mapping to pin) */
	volatile uint8_t *reg_ksi_kso_goen;
	/* KSI[7:0]/KSO[15:8]/KSO[7:0] port gpio control register (bit mapping to pin) */
	volatile uint8_t *reg_ksi_kso_gctrl;
	/* KSI[7:0]/KSO[15:8]/KSO[7:0] port gpio data register (bit mapping to pin) */
	volatile uint8_t *reg_ksi_kso_gdat;
	/* KSI[7:0]/KSO[15:8]/KSO[7:0] port gpio data mirror register (bit mapping to pin) */
	volatile uint8_t *reg_ksi_kso_gdmr;
	/* KSI[7:0]/KSO[15:8]/KSO[7:0] port gpio open drain register (bit mapping to pin) */
	volatile uint8_t *reg_ksi_kso_gpod;
};

struct gpio_kscan_data {
	/* The gpio_driver_data needs to be first */
	struct gpio_driver_data common;
};

static int gpio_kscan_it8xxx2_configure(const struct device *dev,
					gpio_pin_t pin,
					gpio_flags_t flags)
{
	const struct gpio_kscan_cfg *const config = dev->config;
	volatile uint8_t *reg_ksi_kso_gctrl = config->reg_ksi_kso_gctrl;
	volatile uint8_t *reg_ksi_kso_goen = config->reg_ksi_kso_goen;
	volatile uint8_t *reg_ksi_kso_gdat = config->reg_ksi_kso_gdat;
	volatile uint8_t *reg_ksi_kso_gpod = config->reg_ksi_kso_gpod;
	uint8_t mask = BIT(pin);

	/* KSI[7:0]/KSO[15:8]/KSO[7:0] pins don't support open source, 1.8V and 5.0V mode */
	if ((((flags & GPIO_SINGLE_ENDED) != 0) && ((flags & GPIO_LINE_OPEN_DRAIN) == 0)) ||
	     ((flags & IT8XXX2_GPIO_VOLTAGE_MASK) == IT8XXX2_GPIO_VOLTAGE_1P8) ||
	     ((flags & IT8XXX2_GPIO_VOLTAGE_MASK) == IT8XXX2_GPIO_VOLTAGE_5P0)) {
		return -ENOTSUP;
	}

	/* Set GPIO mode */
	*reg_ksi_kso_gctrl |= mask;

	if (flags & GPIO_OUTPUT) {
		/*
		 * Select open drain first, so that we don't glitch the signal
		 * when changing the line to an output.
		 */
		if (flags & GPIO_OPEN_DRAIN) {
			/* Set open-drain and enable internal pullup */
			*reg_ksi_kso_gpod |= mask;
		} else {
			/* Set push-pull and disable internal pullup */
			*reg_ksi_kso_gpod &= ~mask;
		}

		/* Set level before change to output */
		if (flags & GPIO_OUTPUT_INIT_HIGH) {
			*reg_ksi_kso_gdat |= mask;
		} else if (flags & GPIO_OUTPUT_INIT_LOW) {
			*reg_ksi_kso_gdat &= ~mask;
		}

		/* Set output mode */
		*reg_ksi_kso_goen |= mask;
	} else {
		/* Set input mode */
		*reg_ksi_kso_goen  &= ~mask;

		if (flags & GPIO_PULL_UP) {
			/* Enable internal pullup */
			*reg_ksi_kso_gpod |= mask;
		} else {
			/* No internal pullup and pulldown */
			*reg_ksi_kso_gpod &= ~mask;
		}
	}

	return 0;
}

#ifdef CONFIG_GPIO_GET_CONFIG
static int gpio_kscan_it8xxx2_get_config(const struct device *dev,
					 gpio_pin_t pin,
					 gpio_flags_t *out_flags)
{
	const struct gpio_kscan_cfg *const config = dev->config;
	volatile uint8_t *reg_ksi_kso_goen = config->reg_ksi_kso_goen;
	volatile uint8_t *reg_ksi_kso_gdat = config->reg_ksi_kso_gdat;
	volatile uint8_t *reg_ksi_kso_gpod = config->reg_ksi_kso_gpod;
	uint8_t mask = BIT(pin);
	gpio_flags_t flags = 0;

	/* KSI[7:0]/KSO[15:8]/KSO[7:0] pins only support 3.3V */
	flags |= IT8XXX2_GPIO_VOLTAGE_3P3;

	/* Input or output */
	if (*reg_ksi_kso_goen & mask) {
		flags |= GPIO_OUTPUT;

		/* Open-drain or push-pull */
		if (*reg_ksi_kso_gpod & mask) {
			flags |= GPIO_OPEN_DRAIN;
		}

		/* High or low */
		if (*reg_ksi_kso_gdat & mask) {
			flags |= GPIO_OUTPUT_HIGH;
		} else {
			flags |= GPIO_OUTPUT_LOW;
		}
	} else {
		flags |= GPIO_INPUT;

		/* pullup or no pull */
		if (*reg_ksi_kso_gpod & mask) {
			flags |= GPIO_PULL_UP;
		}
	}

	*out_flags = flags;

	return 0;
}
#endif

static int gpio_kscan_it8xxx2_port_get_raw(const struct device *dev,
					   gpio_port_value_t *value)
{
	const struct gpio_kscan_cfg *const config = dev->config;
	volatile uint8_t *reg_ksi_kso_gdmr = config->reg_ksi_kso_gdmr;

	/* Get physical level from all pins of the port */
	*value = *reg_ksi_kso_gdmr;

	return 0;
}

static int gpio_kscan_it8xxx2_port_set_masked_raw(const struct device *dev,
						  gpio_port_pins_t mask,
						  gpio_port_value_t value)
{
	const struct gpio_kscan_cfg *const config = dev->config;
	volatile uint8_t *reg_ksi_kso_gdat = config->reg_ksi_kso_gdat;
	uint8_t out = *reg_ksi_kso_gdat;

	/* Set high/low level to mask pins of the port */
	*reg_ksi_kso_gdat = ((out & ~mask) | (value & mask));

	return 0;
}

static int gpio_kscan_it8xxx2_port_set_bits_raw(const struct device *dev,
						gpio_port_pins_t pins)
{
	const struct gpio_kscan_cfg *const config = dev->config;
	volatile uint8_t *reg_ksi_kso_gdat = config->reg_ksi_kso_gdat;

	/* Set high level to pins of the port */
	*reg_ksi_kso_gdat |= pins;

	return 0;
}

static int gpio_kscan_it8xxx2_port_clear_bits_raw(const struct device *dev,
						  gpio_port_pins_t pins)
{
	const struct gpio_kscan_cfg *const config = dev->config;
	volatile uint8_t *reg_ksi_kso_gdat = config->reg_ksi_kso_gdat;

	/* Set low level to pins of the port */
	*reg_ksi_kso_gdat &= ~pins;

	return 0;
}

static int gpio_kscan_it8xxx2_port_toggle_bits(const struct device *dev,
					       gpio_port_pins_t pins)
{
	const struct gpio_kscan_cfg *const config = dev->config;
	volatile uint8_t *reg_ksi_kso_gdat = config->reg_ksi_kso_gdat;

	/* Toggle output level to pins of the port */
	*reg_ksi_kso_gdat ^= pins;

	return 0;
}

static int gpio_kscan_it8xxx2_init(const struct device *dev)
{
	return 0;
}

static const struct gpio_driver_api gpio_kscan_it8xxx2_driver_api = {
	.pin_configure = gpio_kscan_it8xxx2_configure,
#ifdef CONFIG_GPIO_GET_CONFIG
	.pin_get_config = gpio_kscan_it8xxx2_get_config,
#endif
	.port_get_raw = gpio_kscan_it8xxx2_port_get_raw,
	.port_set_masked_raw = gpio_kscan_it8xxx2_port_set_masked_raw,
	.port_set_bits_raw = gpio_kscan_it8xxx2_port_set_bits_raw,
	.port_clear_bits_raw = gpio_kscan_it8xxx2_port_clear_bits_raw,
	.port_toggle_bits = gpio_kscan_it8xxx2_port_toggle_bits,
};

#define GPIO_KSCAN_IT8XXX2_INIT(inst)                                          \
static const struct gpio_kscan_cfg gpio_kscan_it8xxx2_cfg_##inst = {           \
	.common = {                                                            \
		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_NGPIOS(               \
				 DT_INST_PROP(inst, ngpios))                   \
	},                                                                     \
	.reg_ksi_kso_goen = (uint8_t *)DT_INST_REG_ADDR_BY_NAME(inst, goen),   \
	.reg_ksi_kso_gctrl = (uint8_t *)DT_INST_REG_ADDR_BY_NAME(inst, gctrl), \
	.reg_ksi_kso_gdat = (uint8_t *)DT_INST_REG_ADDR_BY_NAME(inst, gdat),   \
	.reg_ksi_kso_gdmr = (uint8_t *)DT_INST_REG_ADDR_BY_NAME(inst, gdmr),   \
	.reg_ksi_kso_gpod = (uint8_t *)DT_INST_REG_ADDR_BY_NAME(inst, gpod),   \
};                                                                             \
									       \
static struct gpio_kscan_data gpio_kscan_it8xxx2_data_##inst;                  \
									       \
DEVICE_DT_INST_DEFINE(inst,                                                    \
		      gpio_kscan_it8xxx2_init,                                 \
		      NULL,                                                    \
		      &gpio_kscan_it8xxx2_data_##inst,                         \
		      &gpio_kscan_it8xxx2_cfg_##inst,                          \
		      PRE_KERNEL_1,                                            \
		      CONFIG_GPIO_INIT_PRIORITY,                               \
		      &gpio_kscan_it8xxx2_driver_api);

DT_INST_FOREACH_STATUS_OKAY(GPIO_KSCAN_IT8XXX2_INIT)
