/*
 * Copyright (c) 2021 Synopsys
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT snps_creg_gpio

#include <errno.h>

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/util.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(creg_gpio, CONFIG_GPIO_LOG_LEVEL);

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

/** Runtime driver data */
struct creg_gpio_drv_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	uint32_t pin_val;
	uint32_t base_addr;
};

/** Configuration data */
struct creg_gpio_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	uint32_t ngpios;
	uint8_t bit_per_gpio;
	uint8_t off_val;
	uint8_t on_val;
};

static int port_get(const struct device *dev,
		    gpio_port_value_t *value)
{
	const struct creg_gpio_config *cfg = dev->config;
	struct creg_gpio_drv_data *drv_data = dev->data;
	uint32_t in = sys_read32(drv_data->base_addr);
	uint32_t tmp = 0;
	uint32_t val = 0;

	for (uint8_t i = 0; i < cfg->ngpios; i++) {
		tmp = (in & cfg->on_val << i * cfg->bit_per_gpio) ? 1 : 0;
		val |= tmp << i;
	}
	*value = drv_data->pin_val = val;

	return 0;
}

static int port_write(const struct device *dev,
		      gpio_port_pins_t mask,
		      gpio_port_value_t value,
		      gpio_port_value_t toggle)
{
	const struct creg_gpio_config *cfg = dev->config;
	struct creg_gpio_drv_data *drv_data = dev->data;
	uint32_t *pin_val = &drv_data->pin_val;
	uint32_t out = 0;
	uint32_t tmp = 0;

	*pin_val = ((*pin_val & ~mask) | (value & mask)) ^ toggle;

	for (uint8_t i = 0; i < cfg->ngpios; i++) {
		tmp = (*pin_val & 1 << i) ? cfg->on_val : cfg->off_val;
		out |= tmp << i * cfg->bit_per_gpio;
	}
	sys_write32(out, drv_data->base_addr);

	return 0;
}

static int port_set_masked(const struct device *dev,
			   gpio_port_pins_t mask,
			   gpio_port_value_t value)
{
	return port_write(dev, mask, value, 0);
}

static int port_set_bits(const struct device *dev,
			 gpio_port_pins_t pins)
{
	return port_write(dev, pins, pins, 0);
}

static int port_clear_bits(const struct device *dev,
			   gpio_port_pins_t pins)
{
	return port_write(dev, pins, 0, 0);
}

static int port_toggle_bits(const struct device *dev,
			    gpio_port_pins_t pins)
{
	return port_write(dev, 0, 0, pins);
}

static int pin_interrupt_configure(const struct device *dev,
				   gpio_pin_t pin,
				   enum gpio_int_mode mode,
				   enum gpio_int_trig trig)
{
	return -ENOTSUP;
}

static int pin_config(const struct device *dev,
		       gpio_pin_t pin,
		       gpio_flags_t flags)
{
	const struct creg_gpio_config *cfg = dev->config;
	uint32_t io_flags;
	bool pin_is_output;

	/* Check for invalid pin number */
	if (pin >= cfg->ngpios) {
		return -EINVAL;
	}

	/* Does not support disconnected pin, and
	 * not supporting both input/output at same time.
	 */
	io_flags = flags & (GPIO_INPUT | GPIO_OUTPUT);
	if ((io_flags == GPIO_DISCONNECTED)
	    || (io_flags == (GPIO_INPUT | GPIO_OUTPUT))) {
		return -ENOTSUP;
	}

	/* No open-drain support */
	if ((flags & GPIO_SINGLE_ENDED) != 0U) {
		return -ENOTSUP;
	}

	/* Does not support pull-up/pull-down */
	if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0U) {
		return -ENOTSUP;
	}

	pin_is_output = (flags & GPIO_OUTPUT) != 0U;
	if (pin_is_output) {
		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) {
			return port_set_bits(dev, BIT(pin));
		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) {
			return port_clear_bits(dev, BIT(pin));
		}
	}

	return -ENOTSUP;
}

/**
 * @brief Initialization function of creg_gpio
 *
 * @param dev Device struct
 * @return 0 if successful, failed otherwise.
 */
static int creg_gpio_init(const struct device *dev)
{
	return 0;
}

static const struct gpio_driver_api api_table = {
	.pin_configure = pin_config,
	.port_get_raw = port_get,
	.port_set_masked_raw = port_set_masked,
	.port_set_bits_raw = port_set_bits,
	.port_clear_bits_raw = port_clear_bits,
	.port_toggle_bits = port_toggle_bits,
	.pin_interrupt_configure = pin_interrupt_configure,
};

static const struct creg_gpio_config creg_gpio_cfg = {
	.common = {
		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(0),
	},
	.ngpios = DT_INST_PROP(0, ngpios),
	.bit_per_gpio = DT_INST_PROP(0, bit_per_gpio),
	.off_val = DT_INST_PROP(0, off_val),
	.on_val = DT_INST_PROP(0, on_val),
};

static struct creg_gpio_drv_data creg_gpio_drvdata = {
	.base_addr = DT_INST_REG_ADDR(0),
};

DEVICE_DT_INST_DEFINE(0, creg_gpio_init, NULL,
		      &creg_gpio_drvdata, &creg_gpio_cfg,
		      POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY,
		      &api_table);
