/*
 * Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT neorv32_gpio

#include <device.h>
#include <drivers/gpio.h>
#include <drivers/syscon.h>
#include <sys/sys_io.h>
#include <logging/log.h>
LOG_MODULE_REGISTER(gpio_neorv32, CONFIG_GPIO_LOG_LEVEL);

#include "gpio_utils.h"

/* Maximum number of GPIOs supported */
#define MAX_GPIOS 32

struct neorv32_gpio_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	const struct device *syscon;
	mm_reg_t input;
	mm_reg_t output;
};

struct neorv32_gpio_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	/* Shadow register for output */
	uint32_t output;
};

static inline uint32_t neorv32_gpio_read(const struct device *dev)
{
	const struct neorv32_gpio_config *config = dev->config;

	return sys_read32(config->input);
}

static inline void neorv32_gpio_write(const struct device *dev, uint32_t val)
{
	const struct neorv32_gpio_config *config = dev->config;

	sys_write32(val, config->output);
}

static int neorv32_gpio_pin_configure(const struct device *dev, gpio_pin_t pin,
				      gpio_flags_t flags)
{
	const struct neorv32_gpio_config *config = dev->config;
	struct neorv32_gpio_data *data = dev->data;
	unsigned int key;

	if (!(BIT(pin) & config->common.port_pin_mask)) {
		return -EINVAL;
	}

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

	if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) {
		return -ENOTSUP;
	}

	if ((flags & GPIO_OUTPUT) != 0) {
		key = irq_lock();

		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
			data->output |= BIT(pin);
		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
			data->output &= ~BIT(pin);
		}

		neorv32_gpio_write(dev, data->output);
		irq_unlock(key);
	}

	return 0;
}

static int neorv32_gpio_port_get_raw(const struct device *dev,
				      gpio_port_value_t *value)
{
	*value = neorv32_gpio_read(dev);
	return 0;
}

static int neorv32_gpio_port_set_masked_raw(const struct device *dev,
					     gpio_port_pins_t mask,
					     gpio_port_value_t value)
{
	struct neorv32_gpio_data *data = dev->data;
	unsigned int key;

	key = irq_lock();
	data->output = (data->output & ~mask) | (mask & value);
	neorv32_gpio_write(dev, data->output);
	irq_unlock(key);

	return 0;
}

static int neorv32_gpio_port_set_bits_raw(const struct device *dev,
					   gpio_port_pins_t pins)
{
	struct neorv32_gpio_data *data = dev->data;
	unsigned int key;

	key = irq_lock();
	data->output |= pins;
	neorv32_gpio_write(dev, data->output);
	irq_unlock(key);

	return 0;
}

static int neorv32_gpio_port_clear_bits_raw(const struct device *dev,
					     gpio_port_pins_t pins)
{
	struct neorv32_gpio_data *data = dev->data;
	unsigned int key;

	key = irq_lock();
	data->output &= ~pins;
	neorv32_gpio_write(dev, data->output);
	irq_unlock(key);

	return 0;
}

static int neorv32_gpio_port_toggle_bits(const struct device *dev,
					  gpio_port_pins_t pins)
{
	struct neorv32_gpio_data *data = dev->data;
	unsigned int key;

	key = irq_lock();
	data->output ^= pins;
	neorv32_gpio_write(dev, data->output);
	irq_unlock(key);

	return 0;
}

static int neorv32_gpio_pin_interrupt_configure(const struct device *dev,
						 gpio_pin_t pin,
						 enum gpio_int_mode mode,
						 enum gpio_int_trig trig)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(pin);
	ARG_UNUSED(mode);
	ARG_UNUSED(trig);

	return -ENOTSUP;
}

static int neorv32_gpio_manage_callback(const struct device *dev,
					struct gpio_callback *cb,
					bool set)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(cb);
	ARG_UNUSED(set);

	return -ENOTSUP;
}

static uint32_t neorv32_gpio_get_pending_int(const struct device *dev)
{
	return 0;
}

static int neorv32_gpio_init(const struct device *dev)
{
	const struct neorv32_gpio_config *config = dev->config;
	struct neorv32_gpio_data *data = dev->data;
	uint32_t features;
	int err;

	if (!device_is_ready(config->syscon)) {
		LOG_ERR("syscon device not ready");
		return -EINVAL;
	}

	err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_FEATURES, &features);
	if (err < 0) {
		LOG_ERR("failed to determine implemented features (err %d)", err);
		return -EIO;
	}

	if ((features & NEORV32_SYSINFO_FEATURES_IO_GPIO) == 0) {
		LOG_ERR("neorv32 gpio not supported");
		return -ENODEV;
	}

	neorv32_gpio_write(dev, data->output);

	return 0;
}

static const struct gpio_driver_api neorv32_gpio_driver_api = {
	.pin_configure = neorv32_gpio_pin_configure,
	.port_get_raw = neorv32_gpio_port_get_raw,
	.port_set_masked_raw = neorv32_gpio_port_set_masked_raw,
	.port_set_bits_raw = neorv32_gpio_port_set_bits_raw,
	.port_clear_bits_raw = neorv32_gpio_port_clear_bits_raw,
	.port_toggle_bits = neorv32_gpio_port_toggle_bits,
	.pin_interrupt_configure = neorv32_gpio_pin_interrupt_configure,
	.manage_callback = neorv32_gpio_manage_callback,
	.get_pending_int = neorv32_gpio_get_pending_int,
};

#define NEORV32_GPIO_INIT(n)						\
	static struct neorv32_gpio_data neorv32_gpio_##n##_data = {	\
		.output = 0,						\
	};								\
									\
	static const struct neorv32_gpio_config neorv32_gpio_##n##_config = { \
		.common = {						\
			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n) \
		},							\
		.syscon = DEVICE_DT_GET(DT_INST_PHANDLE(n, syscon)),	\
		.input = DT_INST_REG_ADDR_BY_NAME(n, input),		\
		.output = DT_INST_REG_ADDR_BY_NAME(n, output),		\
	};								\
									\
	DEVICE_DT_INST_DEFINE(n,					\
			&neorv32_gpio_init,				\
			NULL,						\
			&neorv32_gpio_##n##_data,			\
			&neorv32_gpio_##n##_config,			\
			PRE_KERNEL_2,					\
			CONFIG_GPIO_INIT_PRIORITY,			\
			&neorv32_gpio_driver_api);

DT_INST_FOREACH_STATUS_OKAY(NEORV32_GPIO_INIT)
