/*
 * 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 <zephyr/drivers/gpio/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)
