/*
 * Copyright (c) 2016 Linaro Limited.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT arm_cmsdk_gpio

#include <zephyr/kernel.h>

#include <zephyr/device.h>
#include <errno.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/init.h>
#include <soc.h>
#include <zephyr/drivers/clock_control/arm_clock_control.h>
#include <zephyr/drivers/gpio/gpio_cmsdk_ahb.h>
#include <zephyr/irq.h>

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

/**
 * @brief GPIO driver for ARM CMSDK AHB GPIO
 */

typedef void (*gpio_config_func_t)(const struct device *port);

struct gpio_cmsdk_ahb_cfg {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	volatile struct gpio_cmsdk_ahb *port;
	gpio_config_func_t gpio_config_func;
	/* GPIO Clock control in Active State */
	struct arm_clock_control_t gpio_cc_as;
	/* GPIO Clock control in Sleep State */
	struct arm_clock_control_t gpio_cc_ss;
	/* GPIO Clock control in Deep Sleep State */
	struct arm_clock_control_t gpio_cc_dss;
};

struct gpio_cmsdk_ahb_dev_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	/* list of callbacks */
	sys_slist_t gpio_cb;
};

static int gpio_cmsdk_ahb_port_get_raw(const struct device *dev,
				       uint32_t *value)
{
	const struct gpio_cmsdk_ahb_cfg * const cfg = dev->config;

	*value = cfg->port->data;

	return 0;
}

static int gpio_cmsdk_ahb_port_set_masked_raw(const struct device *dev,
					      uint32_t mask,
					      uint32_t value)
{
	const struct gpio_cmsdk_ahb_cfg * const cfg = dev->config;

	cfg->port->dataout = (cfg->port->dataout & ~mask) | (mask & value);

	return 0;
}

static int gpio_cmsdk_ahb_port_set_bits_raw(const struct device *dev,
					    uint32_t mask)
{
	const struct gpio_cmsdk_ahb_cfg * const cfg = dev->config;

	cfg->port->dataout |= mask;

	return 0;
}

static int gpio_cmsdk_ahb_port_clear_bits_raw(const struct device *dev,
					      uint32_t mask)
{
	const struct gpio_cmsdk_ahb_cfg * const cfg = dev->config;

	cfg->port->dataout &= ~mask;

	return 0;
}

static int gpio_cmsdk_ahb_port_toggle_bits(const struct device *dev,
					   uint32_t mask)
{
	const struct gpio_cmsdk_ahb_cfg * const cfg = dev->config;

	cfg->port->dataout ^= mask;

	return 0;
}

static int cmsdk_ahb_gpio_config(const struct device *dev, uint32_t mask,
				 gpio_flags_t flags)
{
	const struct gpio_cmsdk_ahb_cfg * const cfg = dev->config;

	if (((flags & GPIO_INPUT) == 0) && ((flags & GPIO_OUTPUT) == 0)) {
		return -ENOTSUP;
	}

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

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

	/*
	 * Setup the pin direction
	 * Output Enable:
	 * 0 - Input
	 * 1 - Output
	 */
	if ((flags & GPIO_OUTPUT) != 0) {
		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
			gpio_cmsdk_ahb_port_set_bits_raw(dev, mask);
		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
			gpio_cmsdk_ahb_port_clear_bits_raw(dev, mask);
		}
		cfg->port->outenableset = mask;
	} else {
		cfg->port->outenableclr = mask;
	}

	cfg->port->altfuncclr = mask;

	return 0;
}

/**
 * @brief Configure pin or port
 *
 * @param dev Device struct
 * @param pin The pin number
 * @param flags Flags of pin or port
 *
 * @return 0 if successful, failed otherwise
 */
static int gpio_cmsdk_ahb_config(const struct device *dev,
				 gpio_pin_t pin,
				 gpio_flags_t flags)
{
	return cmsdk_ahb_gpio_config(dev, BIT(pin), flags);
}

static int gpio_cmsdk_ahb_pin_interrupt_configure(const struct device *dev,
						  gpio_pin_t pin,
						  enum gpio_int_mode mode,
						  enum gpio_int_trig trig)
{
	const struct gpio_cmsdk_ahb_cfg * const cfg = dev->config;

	if (trig == GPIO_INT_TRIG_BOTH) {
		return -ENOTSUP;
	}

	/* For now treat level interrupts as not supported, as we seem to only
	 * get a single 'edge' still interrupt rather than continuous
	 * interrupts until the cause is cleared */
	if (mode == GPIO_INT_MODE_LEVEL) {
		return -ENOTSUP;
	}

	if (mode == GPIO_INT_MODE_DISABLED) {
		cfg->port->intenclr = BIT(pin);
	} else {
		if (mode == GPIO_INT_MODE_EDGE) {
			cfg->port->inttypeset = BIT(pin);
		} else {
			/* LEVEL */
			cfg->port->inttypeclr = BIT(pin);
		}

		/* Level High or Edge Rising */
		if (trig == GPIO_INT_TRIG_HIGH) {
			cfg->port->intpolset = BIT(pin);
		} else {
			cfg->port->intpolclr = BIT(pin);
		}
		cfg->port->intclear = BIT(pin);
		cfg->port->intenset = BIT(pin);
	}

	return 0;
}

static void gpio_cmsdk_ahb_isr(const struct device *dev)
{
	const struct gpio_cmsdk_ahb_cfg * const cfg = dev->config;
	struct gpio_cmsdk_ahb_dev_data *data = dev->data;
	uint32_t int_stat;

	int_stat = cfg->port->intstatus;

	/* clear the port interrupts */
	cfg->port->intclear = int_stat;

	gpio_fire_callbacks(&data->gpio_cb, dev, int_stat);

}

static int gpio_cmsdk_ahb_manage_callback(const struct device *dev,
					  struct gpio_callback *callback,
					  bool set)
{
	struct gpio_cmsdk_ahb_dev_data *data = dev->data;

	return gpio_manage_callback(&data->gpio_cb, callback, set);
}

static const struct gpio_driver_api gpio_cmsdk_ahb_drv_api_funcs = {
	.pin_configure = gpio_cmsdk_ahb_config,
	.port_get_raw = gpio_cmsdk_ahb_port_get_raw,
	.port_set_masked_raw = gpio_cmsdk_ahb_port_set_masked_raw,
	.port_set_bits_raw = gpio_cmsdk_ahb_port_set_bits_raw,
	.port_clear_bits_raw = gpio_cmsdk_ahb_port_clear_bits_raw,
	.port_toggle_bits = gpio_cmsdk_ahb_port_toggle_bits,
	.pin_interrupt_configure = gpio_cmsdk_ahb_pin_interrupt_configure,
	.manage_callback = gpio_cmsdk_ahb_manage_callback,
};

/**
 * @brief Initialization function of GPIO
 *
 * @param dev Device struct
 * @return 0 if successful, failed otherwise.
 */
static int gpio_cmsdk_ahb_init(const struct device *dev)
{
	const struct gpio_cmsdk_ahb_cfg * const cfg = dev->config;

#ifdef CONFIG_CLOCK_CONTROL
	/* Enable clock for subsystem */
	const struct device *const clk = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0));

	if (!device_is_ready(clk)) {
		return -ENODEV;
	}

#ifdef CONFIG_SOC_SERIES_BEETLE
	clock_control_on(clk, (clock_control_subsys_t *) &cfg->gpio_cc_as);
	clock_control_off(clk, (clock_control_subsys_t *) &cfg->gpio_cc_ss);
	clock_control_off(clk, (clock_control_subsys_t *) &cfg->gpio_cc_dss);
#endif /* CONFIG_SOC_SERIES_BEETLE */
#endif /* CONFIG_CLOCK_CONTROL */

	cfg->gpio_config_func(dev);

	return 0;
}

#define CMSDK_AHB_GPIO_DEVICE(n)						\
	static void gpio_cmsdk_port_##n##_config_func(const struct device *dev); \
										\
	static const struct gpio_cmsdk_ahb_cfg gpio_cmsdk_port_##n##_config = {	\
		.common = {							\
			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n),	\
		},								\
		.port = ((volatile struct gpio_cmsdk_ahb *)DT_INST_REG_ADDR(n)),\
		.gpio_config_func = gpio_cmsdk_port_##n##_config_func,		\
		.gpio_cc_as = {.bus = CMSDK_AHB, .state = SOC_ACTIVE,		\
			       .device = DT_INST_REG_ADDR(n),},			\
		.gpio_cc_ss = {.bus = CMSDK_AHB, .state = SOC_SLEEP,		\
			       .device = DT_INST_REG_ADDR(n),},			\
		.gpio_cc_dss = {.bus = CMSDK_AHB, .state = SOC_DEEPSLEEP,	\
				.device = DT_INST_REG_ADDR(n),},		\
	};									\
										\
	static struct gpio_cmsdk_ahb_dev_data gpio_cmsdk_port_##n##_data;	\
										\
	DEVICE_DT_INST_DEFINE(n,						\
			    gpio_cmsdk_ahb_init,				\
			    NULL,						\
			    &gpio_cmsdk_port_##n##_data,			\
			    &gpio_cmsdk_port_## n ##_config,			\
			    PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,	\
			    &gpio_cmsdk_ahb_drv_api_funcs);			\
										\
	static void gpio_cmsdk_port_##n##_config_func(const struct device *dev)	\
	{									\
		IRQ_CONNECT(DT_INST_IRQN(n),					\
			    DT_INST_IRQ(n, priority),				\
			    gpio_cmsdk_ahb_isr,					\
			    DEVICE_DT_INST_GET(n), 0);				\
										\
		irq_enable(DT_INST_IRQN(n));					\
	}

DT_INST_FOREACH_STATUS_OKAY(CMSDK_AHB_GPIO_DEVICE)
