/*
 * Copyright (c) 2016, Texas Instruments Incorporated
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ti_cc32xx_gpio
#include <errno.h>

#include <device.h>
#include <drivers/gpio.h>
#include <init.h>
#include <kernel.h>
#include <sys/sys_io.h>

/* Driverlib includes */
#include <inc/hw_types.h>
#include <inc/hw_memmap.h>
#include <inc/hw_ints.h>
#include <inc/hw_gpio.h>
#include <driverlib/rom.h>
#include <driverlib/pin.h>
#undef __GPIO_H__  /* Zephyr and CC32XX SDK gpio.h conflict */
#include <driverlib/gpio.h>
#include <driverlib/rom_map.h>
#include <driverlib/interrupt.h>

#include "gpio_utils.h"

/* Reserved */
#define PIN_XX  0xFF

static const uint8_t pinTable[] = {
	/* 00     01      02      03      04      05      06      07  */
	PIN_50, PIN_55, PIN_57, PIN_58, PIN_59, PIN_60, PIN_61, PIN_62,
	/* 08     09      10      11      12      13      14      15  */
	PIN_63, PIN_64, PIN_01, PIN_02, PIN_03, PIN_04, PIN_05, PIN_06,
	/* 16     17      18      19      20      21      22      23  */
	PIN_07, PIN_08, PIN_XX, PIN_XX, PIN_XX, PIN_XX, PIN_15, PIN_16,
	/* 24     25      26      27      28      29      30      31  */
	PIN_17, PIN_21, PIN_29, PIN_30, PIN_18, PIN_20, PIN_53, PIN_45,
	/* 32 */
	PIN_52
};

struct gpio_cc32xx_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	/* base address of GPIO port */
	unsigned long port_base;
	/* GPIO port number */
	uint8_t port_num;
};

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

#define DEV_CFG(dev) \
	((const struct gpio_cc32xx_config *)(dev)->config)
#define DEV_DATA(dev) \
	((struct gpio_cc32xx_data *)(dev)->data)

static int gpio_cc32xx_port_set_bits_raw(const struct device *port,
					 uint32_t mask);
static int gpio_cc32xx_port_clear_bits_raw(const struct device *port,
					   uint32_t mask);

static inline int gpio_cc32xx_config(const struct device *port,
				     gpio_pin_t pin,
				     gpio_flags_t flags)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

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

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

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

	MAP_PinTypeGPIO(pinTable[gpio_config->port_num * 8 + pin],
		PIN_MODE_0, false);
	if (flags & GPIO_OUTPUT) {
		MAP_GPIODirModeSet(port_base, (1 << pin), GPIO_DIR_MODE_OUT);
		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
			gpio_cc32xx_port_set_bits_raw(port, BIT(pin));
		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
			gpio_cc32xx_port_clear_bits_raw(port, BIT(pin));
		}
	} else {
		MAP_GPIODirModeSet(port_base, (1 << pin), GPIO_DIR_MODE_IN);
	}

	return 0;
}

static int gpio_cc32xx_port_get_raw(const struct device *port,
				    uint32_t *value)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;
	unsigned char pin_packed = 0xFF;

	*value = MAP_GPIOPinRead(port_base, pin_packed);

	return 0;
}

static int gpio_cc32xx_port_set_masked_raw(const struct device *port,
					   uint32_t mask,
					   uint32_t value)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	MAP_GPIOPinWrite(port_base, (unsigned char)mask, (unsigned char)value);

	return 0;
}

static int gpio_cc32xx_port_set_bits_raw(const struct device *port,
					 uint32_t mask)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	MAP_GPIOPinWrite(port_base, (unsigned char)mask, (unsigned char)mask);

	return 0;
}

static int gpio_cc32xx_port_clear_bits_raw(const struct device *port,
					   uint32_t mask)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;

	MAP_GPIOPinWrite(port_base, (unsigned char)mask, (unsigned char)~mask);

	return 0;
}

static int gpio_cc32xx_port_toggle_bits(const struct device *port,
					uint32_t mask)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;
	long value;

	value = MAP_GPIOPinRead(port_base, mask);

	MAP_GPIOPinWrite(port_base, (unsigned char)mask,
		(unsigned char)~value);

	return 0;
}

static int gpio_cc32xx_pin_interrupt_configure(const struct device *port,
					       gpio_pin_t pin,
					       enum gpio_int_mode mode,
					       enum gpio_int_trig trig)
{
	const struct gpio_cc32xx_config *gpio_config = DEV_CFG(port);
	unsigned long port_base = gpio_config->port_base;
	unsigned long int_type;

	__ASSERT(pin < 8, "Invalid pin number - only 8 pins per port");

	/*
	 * disable interrupt prior to changing int type helps
	 * prevent spurious interrupts observed when switching
	 * to level-based
	 */
	MAP_GPIOIntDisable(port_base, (1 << pin));

	if (mode != GPIO_INT_MODE_DISABLED) {
		if (mode == GPIO_INT_MODE_EDGE) {
			if (trig == GPIO_INT_TRIG_BOTH) {
				int_type = GPIO_BOTH_EDGES;
			} else if (trig == GPIO_INT_TRIG_HIGH) {
				int_type = GPIO_RISING_EDGE;
			} else {
				int_type = GPIO_FALLING_EDGE;
			}
		} else { /* GPIO_INT_MODE_LEVEL */
			if (trig == GPIO_INT_TRIG_HIGH) {
				int_type = GPIO_HIGH_LEVEL;
			} else {
				int_type = GPIO_LOW_LEVEL;
			}
		}

		MAP_GPIOIntTypeSet(port_base, (1 << pin), int_type);
		MAP_GPIOIntClear(port_base, (1 << pin));
		MAP_GPIOIntEnable(port_base, (1 << pin));
	}

	return 0;
}

static int gpio_cc32xx_manage_callback(const struct device *dev,
				       struct gpio_callback *callback,
				       bool set)
{
	struct gpio_cc32xx_data *data = DEV_DATA(dev);

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

static void gpio_cc32xx_port_isr(const struct device *dev)
{
	const struct gpio_cc32xx_config *config = DEV_CFG(dev);
	struct gpio_cc32xx_data *data = DEV_DATA(dev);
	uint32_t int_status;

	/* See which interrupts triggered: */
	int_status = (uint32_t)MAP_GPIOIntStatus(config->port_base, 1);

	/* Clear GPIO Interrupt */
	MAP_GPIOIntClear(config->port_base, int_status);

	/* Call the registered callbacks */
	gpio_fire_callbacks(&data->callbacks, dev, int_status);
}

static const struct gpio_driver_api api_funcs = {
	.pin_configure = gpio_cc32xx_config,
	.port_get_raw = gpio_cc32xx_port_get_raw,
	.port_set_masked_raw = gpio_cc32xx_port_set_masked_raw,
	.port_set_bits_raw = gpio_cc32xx_port_set_bits_raw,
	.port_clear_bits_raw = gpio_cc32xx_port_clear_bits_raw,
	.port_toggle_bits = gpio_cc32xx_port_toggle_bits,
	.pin_interrupt_configure = gpio_cc32xx_pin_interrupt_configure,
	.manage_callback = gpio_cc32xx_manage_callback,
};

#define GPIO_CC32XX_INIT_FUNC(n)					     \
	static int gpio_cc32xx_a##n##_init(const struct device *dev)		     \
	{								     \
		ARG_UNUSED(dev);					     \
									     \
		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority),	     \
			gpio_cc32xx_port_isr, DEVICE_DT_INST_GET(n),         \
			0);						     \
									     \
		MAP_IntPendClear(DT_INST_IRQN(n) + 16);			     \
		irq_enable(DT_INST_IRQN(n));				     \
									     \
		return 0;						     \
	}

#define GPIO_CC32XX_DEVICE_INIT(n)					     \
	DEVICE_DT_INST_DEFINE(n, &gpio_cc32xx_a##n##_init,		     \
			NULL, &gpio_cc32xx_a##n##_data,			     \
			&gpio_cc32xx_a##n##_config,			     \
			POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,     \
			&api_funcs)

#define GPIO_CC32XX_INIT(n)						     \
	static const struct gpio_cc32xx_config gpio_cc32xx_a##n##_config = { \
		.common = {						     \
			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \
		},							     \
		.port_base = DT_INST_REG_ADDR(n),			     \
		.port_num = n						     \
	};								     \
									     \
	static struct gpio_cc32xx_data gpio_cc32xx_a##n##_data;		     \
									     \
	GPIO_CC32XX_INIT_FUNC(n)					     \
									     \
	GPIO_CC32XX_DEVICE_INIT(n);

DT_INST_FOREACH_STATUS_OKAY(GPIO_CC32XX_INIT)
