/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <rom/ets_sys.h>
#include <soc/dport_reg.h>
#include <soc/gpio_reg.h>
#include <soc/soc.h>
#include <errno.h>
#include <device.h>
#include <gpio.h>
#include <kernel.h>
#include <misc/util.h>
#include <pinmux.h>

#include "gpio_utils.h"

struct gpio_esp32_data {
	struct device *pinmux;

	struct {
		struct {
			volatile u32_t *set_reg;
			volatile u32_t *clear_reg;
		} write;
		struct {
			volatile u32_t *reg;
		} read;
		struct {
			volatile u32_t *status_reg;
			volatile u32_t *ack_reg;
		} irq;
		int pin_offset;
	} port;

	u32_t cb_pins;
	sys_slist_t cb;
};

static int convert_int_type(int flags)
{
	/* Reference: "ESP32 Technical Reference Manual", "IO_MUX and
	 * GPIO matrix"; "GPIO_PINn_INT_TYPE".
	 */

	if (!(flags & GPIO_INT)) {
		return 0;	/* Disables interrupt for a pin. */
	}

	if ((flags & GPIO_INT_EDGE) == GPIO_INT_EDGE) {
		if ((flags & GPIO_INT_ACTIVE_LOW) == GPIO_INT_ACTIVE_LOW) {
			return 2;
		}

		if ((flags & GPIO_INT_DOUBLE_EDGE) == GPIO_INT_DOUBLE_EDGE) {
			return 3;
		}

		return 1;	/* Defaults to rising edge. */
	}

	if ((flags & GPIO_INT_LEVEL) == GPIO_INT_LEVEL) {
		if ((flags & GPIO_INT_ACTIVE_LOW) == GPIO_INT_ACTIVE_LOW) {
			return 4;
		}

		return 5;	/* Defaults to high level. */
	}

	/* Any other type of interrupt triggering is invalid. */
	return -EINVAL;
}

static inline u32_t *gpio_pin_reg(int pin)
{
	return (u32_t *)(GPIO_PIN0_REG + pin * 4);
}

static int config_interrupt(u32_t pin, int flags)
{
	volatile u32_t *reg = gpio_pin_reg(pin);
	int type = convert_int_type(flags);
	u32_t v;
	int key;

	if (type < 0) {
		return type;
	}

	key = irq_lock();

	v = *reg;
	v &= ~(GPIO_PIN_INT_ENA_M | GPIO_PIN_INT_TYPE_M);
	/* Bit 3 of INT_ENA will enable interrupts on CPU 0 */
	v |= (1<<2) << GPIO_PIN_INT_ENA_S;
	/* Interrupt triggering mode */
	v |= type << GPIO_PIN_INT_TYPE_S;
	*reg = v;

	irq_unlock(key);

	return 0;
}

static void config_polarity(u32_t pin, int flags)
{
	volatile u32_t *reg = (u32_t *)(GPIO_FUNC0_IN_SEL_CFG_REG + 4 * pin);

	if (flags & GPIO_POL_INV) {
		*reg |= BIT(GPIO_FUNC0_IN_INV_SEL_S);
	} else {
		*reg &= ~BIT(GPIO_FUNC0_IN_INV_SEL_S);
	}
}

static int gpio_esp32_config(struct device *dev, int access_op,
			     u32_t pin, int flags)
{
	struct gpio_esp32_data *data = dev->driver_data;
	u32_t func;
	int r;

	if (access_op != GPIO_ACCESS_BY_PIN) {
		return -ENOTSUP;
	}

	/* Query pinmux to validate pin number. */
	r = pinmux_pin_get(data->pinmux, pin, &func);
	if (r < 0) {
		return r;
	}

	pinmux_pin_set(data->pinmux, pin, PINMUX_FUNC_A);
	if (flags & GPIO_PUD_PULL_UP) {
		pinmux_pin_pullup(data->pinmux, pin, PINMUX_PULLUP_ENABLE);
	} else if (flags & GPIO_PUD_PULL_DOWN) {
		pinmux_pin_pullup(data->pinmux, pin, PINMUX_PULLUP_DISABLE);
	}

	if (flags & GPIO_DIR_OUT) {
		pinmux_pin_input_enable(data->pinmux, pin,
					PINMUX_OUTPUT_ENABLED);
	} else {
		pinmux_pin_input_enable(data->pinmux, pin,
					PINMUX_INPUT_ENABLED);
		config_polarity(pin, flags);
	}

	return config_interrupt(pin, flags);
}

static int gpio_esp32_write(struct device *dev, int access_op,
			    u32_t pin, u32_t value)
{
	struct gpio_esp32_data *data = dev->driver_data;
	u32_t v;

	if (access_op != GPIO_ACCESS_BY_PIN) {
		return -ENOTSUP;
	}

	v = BIT(pin - data->port.pin_offset);
	if (value) {
		*data->port.write.set_reg = v;
	} else {
		*data->port.write.clear_reg = v;
	}

	return 0;
}

static int gpio_esp32_read(struct device *dev, int access_op,
			   u32_t pin, u32_t *value)
{
	struct gpio_esp32_data *data = dev->driver_data;
	u32_t v;

	if (access_op != GPIO_ACCESS_BY_PIN) {
		return -ENOTSUP;
	}

	v = *data->port.read.reg;
	*value = !!(v & BIT(pin - data->port.pin_offset));

	return 0;
}

static int gpio_esp32_manage_callback(struct device *dev,
				      struct gpio_callback *callback,
				      bool set)
{
	struct gpio_esp32_data *data = dev->driver_data;

	_gpio_manage_callback(&data->cb, callback, set);

	return 0;
}

static int gpio_esp32_enable_callback(struct device *dev,
				      int access_op, u32_t pin)
{
	struct gpio_esp32_data *data = dev->driver_data;

	if (access_op == GPIO_ACCESS_BY_PIN) {
		data->cb_pins |= BIT(pin);

		return 0;
	}

	return -ENOTSUP;
}

static int gpio_esp32_disable_callback(struct device *dev,
				       int access_op, u32_t pin)
{
	struct gpio_esp32_data *data = dev->driver_data;

	if (access_op == GPIO_ACCESS_BY_PIN) {
		data->cb_pins &= ~BIT(pin);

		return 0;
	}

	return -ENOTSUP;
}

static void gpio_esp32_fire_callbacks(struct device *device)
{
	struct gpio_esp32_data *data = device->driver_data;
	u32_t values = *data->port.irq.status_reg;

	if (values & data->cb_pins) {
		_gpio_fire_callbacks(&data->cb, device, values);
	}

	*data->port.irq.ack_reg = values;
}

static void gpio_esp32_isr(void *param);

static int gpio_esp32_init(struct device *device)
{
	struct gpio_esp32_data *data = device->driver_data;
	static bool isr_connected;

	data->pinmux = device_get_binding(CONFIG_PINMUX_NAME);
	if (!data->pinmux) {
		return -ENOTSUP;
	}

	if (!isr_connected) {
		irq_disable(CONFIG_GPIO_ESP32_IRQ);

		IRQ_CONNECT(CONFIG_GPIO_ESP32_IRQ, 1, gpio_esp32_isr,
			    NULL, 0);

		intr_matrix_set(0, ETS_GPIO_INTR_SOURCE,
				CONFIG_GPIO_ESP32_IRQ);

		irq_enable(CONFIG_GPIO_ESP32_IRQ);

		isr_connected = true;
	}

	return 0;
}

static const struct gpio_driver_api gpio_esp32_driver = {
	.config = gpio_esp32_config,
	.write = gpio_esp32_write,
	.read = gpio_esp32_read,
	.manage_callback = gpio_esp32_manage_callback,
	.enable_callback = gpio_esp32_enable_callback,
	.disable_callback = gpio_esp32_disable_callback,
};

static struct gpio_esp32_data gpio_data_pins_0_to_31 = {
	.port = {
		.write = {
			.set_reg = (u32_t *)GPIO_OUT_W1TS_REG,
			.clear_reg = (u32_t *)GPIO_OUT_W1TC_REG,
		},
		.read = {
			.reg = (u32_t *)GPIO_IN_REG,
		},
		.irq = {
			.status_reg = (u32_t *)GPIO_STATUS_REG,
			.ack_reg = (u32_t *)GPIO_STATUS_W1TC_REG,
		},
		.pin_offset = 0,
	}
};
static struct gpio_esp32_data gpio_data_pins_32_to_63 = {
	.port = {
		.write = {
			.set_reg = (u32_t *)GPIO_OUT1_W1TS_REG,
			.clear_reg = (u32_t *)GPIO_OUT1_W1TC_REG,
		},
		.read = {
			.reg = (u32_t *)GPIO_IN1_REG,
		},
		.irq = {
			.status_reg = (u32_t *)GPIO_STATUS1_REG,
			.ack_reg = (u32_t *)GPIO_STATUS1_W1TC_REG,
		},
		.pin_offset = 32,
	}
};

#define GPIO_DEVICE_INIT(__name, __data_struct_name) \
	DEVICE_AND_API_INIT(gpio_esp32_ ## __data_struct_name, \
			    __name, \
			    gpio_esp32_init, \
			    &gpio_data_pins_ ## __data_struct_name, \
			    NULL, \
			    POST_KERNEL, \
			    CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
			    &gpio_esp32_driver)

/* GPIOs are divided in two groups for ESP32 because the callback
 * API works with 32-bit bitmasks to manage interrupt callbacks,
 * and the device has 40 GPIO pins.
 */
#if defined(CONFIG_GPIO_ESP32_0)
GPIO_DEVICE_INIT(CONFIG_GPIO_ESP32_0_NAME, 0_to_31);
#endif

#if defined(CONFIG_GPIO_ESP32_1)
GPIO_DEVICE_INIT(CONFIG_GPIO_ESP32_1_NAME, 32_to_63);
#endif

static void gpio_esp32_isr(void *param)
{
#if defined(CONFIG_GPIO_ESP32_0)
	gpio_esp32_fire_callbacks(DEVICE_GET(gpio_esp32_0_to_31));
#endif
#if defined(CONFIG_GPIO_ESP32_1)
	gpio_esp32_fire_callbacks(DEVICE_GET(gpio_esp32_32_to_63));
#endif

	ARG_UNUSED(param);
}
