/*
 * Copyright (c) 2022 Schlumberger
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT infineon_xmc4xxx_gpio

#include <errno.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/dt-bindings/gpio/infineon-xmc4xxx-gpio.h>
#include <xmc_gpio.h>

#include "gpio_utils.h"

struct gpio_xmc4xxx_config {
	/* gpio_driver_config needs to be first, required by Zephyr */
	struct gpio_driver_config common;
	XMC_GPIO_PORT_t *port;
};

struct gpio_xmc4xxx_data {
	/* gpio_driver_data needs to be first, required by Zephyr */
	struct gpio_driver_data common;
};

static int gpio_xmc4xxx_convert_flags(XMC_GPIO_CONFIG_t *pin_config, gpio_flags_t flags)
{
	bool is_input  = flags & GPIO_INPUT;
	bool is_output = flags & GPIO_OUTPUT;
	int ds;

	/* GPIO_DISCONNECTED */
	if (!is_input && !is_output) {
		return -ENOTSUP;
	}

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

	if (is_input) {
		pin_config->mode = XMC_GPIO_MODE_INPUT_TRISTATE;
		if (flags & GPIO_PULL_DOWN) {
			pin_config->mode = XMC_GPIO_MODE_INPUT_PULL_DOWN;
		}
		if (flags & GPIO_PULL_UP) {
			pin_config->mode = XMC_GPIO_MODE_INPUT_PULL_UP;
		}
	}

	ds = XMC4XXX_GPIO_GET_DS(flags);
	if ((!is_output && ds) || ds > XMC4XXX_GPIO_DS_WEAK) {
		return -EINVAL;
	}

	if (is_output) {
		pin_config->mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL;
		if (flags & GPIO_OPEN_DRAIN) {
			pin_config->mode = XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN;
		}
		if (flags & GPIO_OUTPUT_INIT_LOW) {
			pin_config->output_level = XMC_GPIO_OUTPUT_LEVEL_LOW;
		}
		if (flags & GPIO_OUTPUT_INIT_HIGH) {
			pin_config->output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH;
		}
		/* Strong medium edge is default */
		pin_config->output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_MEDIUM_EDGE;
		if (ds > 0) {
			pin_config->output_strength = ds - 1;
		}
	}

	return 0;
}

static int gpio_xmc4xxx_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
{
	const struct gpio_xmc4xxx_config *config = dev->config;
	XMC_GPIO_PORT_t *port = config->port;
	XMC_GPIO_CONFIG_t pin_config = {0};
	gpio_port_pins_t pin_mask = config->common.port_pin_mask;
	int ret;

	if ((BIT(pin) & pin_mask) == 0) {
		return -EINVAL;
	}

	ret = gpio_xmc4xxx_convert_flags(&pin_config, flags);
	if (ret) {
		return ret;
	}

	XMC_GPIO_Init(port, pin, &pin_config);
	return 0;
}

static int gpio_xmc4xxx_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);

	/* TODO: interrupt controller */
	return -ENOTSUP;
}

static int gpio_xmc4xxx_get_raw(const struct device *dev, gpio_port_value_t *value)
{
	const struct gpio_xmc4xxx_config *config = dev->config;
	XMC_GPIO_PORT_t *port = config->port;
	gpio_port_pins_t pin_mask = config->common.port_pin_mask;

	*value = port->IN & pin_mask;
	return 0;
}

static int gpio_xmc4xxx_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
				       gpio_port_value_t value)
{
	const struct gpio_xmc4xxx_config *config = dev->config;
	XMC_GPIO_PORT_t *port = config->port;
	gpio_port_pins_t pin_mask = config->common.port_pin_mask;

	mask &= pin_mask;

	/* OMR - output modification register. Upper 16 bits is used to clear pins */
	port->OMR = (value & mask) | (~value & mask) << 16;
	return 0;
}

static int gpio_xmc4xxx_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
{
	const struct gpio_xmc4xxx_config *config = dev->config;
	XMC_GPIO_PORT_t *port = config->port;
	gpio_port_pins_t pin_mask = config->common.port_pin_mask;

	port->OMR = pins & pin_mask;
	return 0;
}

static int gpio_xmc4xxx_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
{
	const struct gpio_xmc4xxx_config *config = dev->config;
	XMC_GPIO_PORT_t *port = config->port;

	port->OMR = pins << 16;
	return 0;
}

static int gpio_xmc4xxx_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
{
	const struct gpio_xmc4xxx_config *config = dev->config;
	XMC_GPIO_PORT_t *port = config->port;
	gpio_port_pins_t pin_mask = config->common.port_pin_mask;

	pins &= pin_mask;
	port->OMR = pins | pins << 16;
	return 0;
}

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

static const struct gpio_driver_api gpio_xmc4xxx_driver_api = {
	.pin_configure = gpio_xmc4xxx_pin_configure,
	.port_get_raw = gpio_xmc4xxx_get_raw,
	.port_set_masked_raw = gpio_xmc4xxx_set_masked_raw,
	.port_set_bits_raw = gpio_xmc4xxx_set_bits_raw,
	.port_clear_bits_raw = gpio_xmc4xxx_clear_bits_raw,
	.port_toggle_bits = gpio_xmc4xxx_toggle_bits,
	.pin_interrupt_configure = gpio_xmc4xxx_pin_interrupt_configure,
};

#define GPIO_XMC4XXX_INIT(index)                                                                   \
	static struct gpio_xmc4xxx_data xmc4xxx_data_##index;                                      \
                                                                                                   \
	static const struct gpio_xmc4xxx_config xmc4xxx_config_##index = {                         \
		.port = (XMC_GPIO_PORT_t *)DT_INST_REG_ADDR(index),                                \
		.common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(index)}};              \
                                                                                                   \
	DEVICE_DT_INST_DEFINE(index, gpio_xmc4xxx_init, NULL, &xmc4xxx_data_##index,               \
			      &xmc4xxx_config_##index, POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY,     \
			      &gpio_xmc4xxx_driver_api);

DT_INST_FOREACH_STATUS_OKAY(GPIO_XMC4XXX_INIT)
