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

/* Include esp-idf headers first to avoid redefining BIT() macro */
#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_HIGH) == GPIO_INT_ACTIVE_HIGH) {
			return 1;
		}

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

		return 2;	/* Defaults to falling edge. */
	}

	if ((flags & GPIO_INT_LEVEL) == GPIO_INT_LEVEL) {
		if ((flags & GPIO_INT_ACTIVE_HIGH) == GPIO_INT_ACTIVE_HIGH) {
			return 5;
		}

		return 4;	/* Defaults to low 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,
};

#if defined(CONFIG_GPIO_ESP32_0)
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,
	}
};
#endif

#if defined(CONFIG_GPIO_ESP32_1)
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,
	}
};
#endif

#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);
}
