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

#include <errno.h>

#include <gpio.h>
#include <soc.h>
#include <misc/util.h>

#include "qm_ss_gpio.h"
#include "qm_ss_isr.h"
#include "ss_clk.h"
#include "gpio_utils.h"

struct ss_gpio_qmsi_config {
	qm_ss_gpio_t gpio;
	u8_t num_pins;
};

struct ss_gpio_qmsi_runtime {
	sys_slist_t callbacks;
	u32_t pin_callbacks;
#ifdef CONFIG_GPIO_QMSI_API_REENTRANCY
	struct k_sem sem;
#endif /* CONFIG_GPIO_QMSI_API_REENTRANCY */
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
	u32_t device_power_state;
	qm_ss_gpio_context_t gpio_ctx;
#endif
};

#ifdef CONFIG_GPIO_QMSI_API_REENTRANCY
#define RP_GET(dev) (&((struct ss_gpio_qmsi_runtime *)(dev->driver_data))->sem)
#else
#define RP_GET(context) (NULL)
#endif /* CONFIG_GPIO_QMSI_API_REENTRANCY */

#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
static void ss_gpio_qmsi_set_power_state(struct device *dev,
					 u32_t power_state)
{
	struct ss_gpio_qmsi_runtime *context = dev->driver_data;

	context->device_power_state = power_state;
}

static u32_t ss_gpio_qmsi_get_power_state(struct device *dev)
{
	struct ss_gpio_qmsi_runtime *context = dev->driver_data;

	return context->device_power_state;
}

static int ss_gpio_suspend_device(struct device *dev)
{
	const struct ss_gpio_qmsi_config *gpio_config =
		dev->config->config_info;
	struct ss_gpio_qmsi_runtime *drv_data = dev->driver_data;

	qm_ss_gpio_save_context(gpio_config->gpio, &drv_data->gpio_ctx);

	ss_gpio_qmsi_set_power_state(dev, DEVICE_PM_SUSPEND_STATE);

	return 0;
}

static int ss_gpio_resume_device_from_suspend(struct device *dev)
{
	const struct ss_gpio_qmsi_config *gpio_config =
		dev->config->config_info;
	struct ss_gpio_qmsi_runtime *drv_data = dev->driver_data;

	qm_ss_gpio_restore_context(gpio_config->gpio, &drv_data->gpio_ctx);

	ss_gpio_qmsi_set_power_state(dev, DEVICE_PM_ACTIVE_STATE);

	return 0;
}

/*
* Implements the driver control management functionality
* the *context may include IN data or/and OUT data
*/
static int ss_gpio_qmsi_device_ctrl(struct device *port, u32_t ctrl_command,
				    void *context, device_pm_cb cb, void *arg)
{
	int ret = 0;

	if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
		if (*((u32_t *)context) == DEVICE_PM_SUSPEND_STATE) {
			ret = ss_gpio_suspend_device(port);
		} else if (*((u32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
			ret = ss_gpio_resume_device_from_suspend(port);
		}
	} else if (ctrl_command == DEVICE_PM_GET_POWER_STATE) {
		*((u32_t *)context) = ss_gpio_qmsi_get_power_state(port);
	}
	if (cb) {
		cb(port, ret, context, arg);
	}

	return ret;
}
#else
#define ss_gpio_qmsi_set_power_state(...)
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */

static int ss_gpio_qmsi_init(struct device *dev);

#ifdef CONFIG_GPIO_QMSI_SS_0
static const struct ss_gpio_qmsi_config ss_gpio_0_config = {
	.gpio = QM_SS_GPIO_0,
	.num_pins = QM_SS_GPIO_NUM_PINS,
};

static struct ss_gpio_qmsi_runtime ss_gpio_0_runtime;

DEVICE_DEFINE(ss_gpio_0, DT_GPIO_QMSI_SS_0_NAME, &ss_gpio_qmsi_init,
	    ss_gpio_qmsi_device_ctrl, &ss_gpio_0_runtime, &ss_gpio_0_config,
	    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);

#endif /* CONFIG_GPIO_QMSI_SS_0 */

#ifdef CONFIG_GPIO_QMSI_SS_1
static const struct ss_gpio_qmsi_config ss_gpio_1_config = {
	.gpio = QM_SS_GPIO_1,
	.num_pins = QM_SS_GPIO_NUM_PINS,
};

static struct ss_gpio_qmsi_runtime gpio_1_runtime;

DEVICE_DEFINE(ss_gpio_1, DT_GPIO_QMSI_SS_1_NAME, &ss_gpio_qmsi_init,
	    ss_gpio_qmsi_device_ctrl, &gpio_1_runtime, &ss_gpio_1_config,
	    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);

#endif /* CONFIG_GPIO_QMSI_SS_1 */

static void ss_gpio_qmsi_callback(void *data, uint32_t status)
{
	struct device *port = data;
	struct ss_gpio_qmsi_runtime *context = port->driver_data;
	const u32_t enabled_mask = context->pin_callbacks & status;

	if (enabled_mask) {
		_gpio_fire_callbacks(&context->callbacks, port, enabled_mask);
	}
}

static void ss_qmsi_write_bit(u32_t *target, u8_t bit, u8_t value)
{
	if (value) {
		sys_set_bit((uintptr_t) target, bit);
	} else {
		sys_clear_bit((uintptr_t) target, bit);
	}
}

static inline void ss_qmsi_pin_config(struct device *port, u8_t pin,
				      int flags)
{
	const struct ss_gpio_qmsi_config *gpio_config =
		port->config->config_info;
	qm_ss_gpio_t gpio = gpio_config->gpio;
	u32_t controller;

	qm_ss_gpio_port_config_t cfg = { 0 };

	switch (gpio) {
#ifdef CONFIG_GPIO_QMSI_SS_0
	case QM_SS_GPIO_0:
		controller = QM_SS_GPIO_0_BASE;
		break;
#endif /* CONFIG_GPIO_QMSI_SS_0 */
#ifdef CONFIG_GPIO_QMSI_SS_1
	case QM_SS_GPIO_1:
		controller = QM_SS_GPIO_1_BASE;
		break;
#endif /* CONFIG_GPIO_QMSI_SS_1 */
	default:
		return;
	}

	cfg.direction = __builtin_arc_lr(controller + QM_SS_GPIO_SWPORTA_DDR);
	cfg.int_en = __builtin_arc_lr(controller + QM_SS_GPIO_INTEN);
	cfg.int_type = __builtin_arc_lr(controller + QM_SS_GPIO_INTTYPE_LEVEL);
	cfg.int_polarity =
	    __builtin_arc_lr(controller + QM_SS_GPIO_INT_POLARITY);
	cfg.int_debounce = __builtin_arc_lr(controller + QM_SS_GPIO_DEBOUNCE);
	cfg.callback = ss_gpio_qmsi_callback;
	cfg.callback_data = port;

	ss_qmsi_write_bit((u32_t *)&cfg.direction, pin, (flags & GPIO_DIR_MASK));

	if (flags & GPIO_INT) {
		ss_qmsi_write_bit((u32_t *)&cfg.int_type, pin, (flags & GPIO_INT_EDGE));
		ss_qmsi_write_bit((u32_t *)&cfg.int_polarity, pin,
			       (flags & GPIO_INT_ACTIVE_HIGH));
		ss_qmsi_write_bit((u32_t *)&cfg.int_debounce, pin,
			       (flags & GPIO_INT_DEBOUNCE));
		ss_qmsi_write_bit((u32_t *)&cfg.int_en, pin, 1);
	} else {
		ss_qmsi_write_bit((u32_t *)&cfg.int_en, pin, 0);
	}

	if (IS_ENABLED(CONFIG_GPIO_QMSI_API_REENTRANCY)) {
		k_sem_take(RP_GET(port), K_FOREVER);
	}

	qm_ss_gpio_set_config(gpio, &cfg);

	if (IS_ENABLED(CONFIG_GPIO_QMSI_API_REENTRANCY)) {
		k_sem_give(RP_GET(port));
	}
}

static inline void ss_qmsi_port_config(struct device *port, int flags)
{
	const struct ss_gpio_qmsi_config *gpio_config =
		port->config->config_info;
	u8_t num_pins = gpio_config->num_pins;
	int i;

	for (i = 0; i < num_pins; i++) {
		ss_qmsi_pin_config(port, i, flags);
	}
}

static inline int ss_gpio_qmsi_config(struct device *port, int access_op,
				      u32_t pin, int flags)
{
	/* check for an invalid pin configuration */
	if ((flags & GPIO_INT) && (flags & GPIO_DIR_OUT)) {
		return -EINVAL;
	}

	if (access_op == GPIO_ACCESS_BY_PIN) {
		ss_qmsi_pin_config(port, pin, flags);
	} else {
		ss_qmsi_port_config(port, flags);
	}
	return 0;
}

static inline int ss_gpio_qmsi_write(struct device *port, int access_op,
				     u32_t pin, u32_t value)
{
	const struct ss_gpio_qmsi_config *gpio_config =
		port->config->config_info;
	qm_ss_gpio_t gpio = gpio_config->gpio;

	if (IS_ENABLED(CONFIG_GPIO_QMSI_API_REENTRANCY)) {
		k_sem_take(RP_GET(port), K_FOREVER);
	}

	if (access_op == GPIO_ACCESS_BY_PIN) {
		if (value) {
			qm_ss_gpio_set_pin(gpio, pin);
		} else {
			qm_ss_gpio_clear_pin(gpio, pin);
		}
	} else {
		qm_ss_gpio_write_port(gpio, value);
	}

	if (IS_ENABLED(CONFIG_GPIO_QMSI_API_REENTRANCY)) {
		k_sem_give(RP_GET(port));
	}

	return 0;
}

static inline int ss_gpio_qmsi_read(struct device *port, int access_op,
				    u32_t pin, u32_t *value)
{
	const struct ss_gpio_qmsi_config *gpio_config =
		port->config->config_info;
	qm_ss_gpio_t gpio = gpio_config->gpio;
	qm_ss_gpio_state_t state;

	if (access_op == GPIO_ACCESS_BY_PIN) {
		qm_ss_gpio_read_pin(gpio, pin, &state);
		*value = state;
	} else {
		qm_ss_gpio_read_port(gpio, (uint32_t *)value);
	}

	return 0;
}

static inline int ss_gpio_qmsi_manage_callback(struct device *port,
					       struct gpio_callback *callback,
					       bool set)
{
	struct ss_gpio_qmsi_runtime *context = port->driver_data;

	return _gpio_manage_callback(&context->callbacks, callback, set);
}

static inline int ss_gpio_qmsi_enable_callback(struct device *port,
					       int access_op, u32_t pin)
{
	struct ss_gpio_qmsi_runtime *context = port->driver_data;

	if (IS_ENABLED(CONFIG_GPIO_QMSI_API_REENTRANCY)) {
		k_sem_take(RP_GET(port), K_FOREVER);
	}

	if (access_op == GPIO_ACCESS_BY_PIN) {
		context->pin_callbacks |= BIT(pin);
	} else {
		context->pin_callbacks = 0xffffffff;
	}

	if (IS_ENABLED(CONFIG_GPIO_QMSI_API_REENTRANCY)) {
		k_sem_give(RP_GET(port));
	}

	return 0;
}

static inline int ss_gpio_qmsi_disable_callback(struct device *port,
						int access_op, u32_t pin)
{
	struct ss_gpio_qmsi_runtime *context = port->driver_data;

	if (IS_ENABLED(CONFIG_GPIO_QMSI_API_REENTRANCY)) {
		k_sem_take(RP_GET(port), K_FOREVER);
	}

	if (access_op == GPIO_ACCESS_BY_PIN) {
		context->pin_callbacks &= ~BIT(pin);
	} else {
		context->pin_callbacks = 0U;
	}

	if (IS_ENABLED(CONFIG_GPIO_QMSI_API_REENTRANCY)) {
		k_sem_give(RP_GET(port));
	}

	return 0;
}

static const struct gpio_driver_api api_funcs = {
	.config = ss_gpio_qmsi_config,
	.write = ss_gpio_qmsi_write,
	.read = ss_gpio_qmsi_read,
	.manage_callback = ss_gpio_qmsi_manage_callback,
	.enable_callback = ss_gpio_qmsi_enable_callback,
	.disable_callback = ss_gpio_qmsi_disable_callback,
};

void ss_gpio_isr(void *arg)
{
	struct device *port = arg;
	const struct ss_gpio_qmsi_config *gpio_config =
		port->config->config_info;

	if (gpio_config->gpio == QM_SS_GPIO_0) {
		qm_ss_gpio_0_isr(NULL);
	} else {
		qm_ss_gpio_1_isr(NULL);
	}
}

static int ss_gpio_qmsi_init(struct device *port)
{
	const struct ss_gpio_qmsi_config *gpio_config =
		port->config->config_info;
	u32_t *scss_intmask = NULL;

	if (IS_ENABLED(CONFIG_GPIO_QMSI_API_REENTRANCY)) {
		k_sem_init(RP_GET(port), 1, UINT_MAX);
	}

	switch (gpio_config->gpio) {
#ifdef CONFIG_GPIO_QMSI_SS_0
	case QM_SS_GPIO_0:
		IRQ_CONNECT(DT_GPIO_QMSI_SS_0_IRQ,
			    DT_GPIO_QMSI_SS_0_IRQ_PRI, ss_gpio_isr,
			    DEVICE_GET(ss_gpio_0), 0);
		irq_enable(IRQ_GPIO0_INTR);

		ss_clk_gpio_enable(QM_SS_GPIO_0);

		scss_intmask =
			(u32_t *)&QM_INTERRUPT_ROUTER->ss_gpio_0_int_mask;
		*scss_intmask &= ~BIT(8);
		break;
#endif /* CONFIG_GPIO_QMSI_SS_0 */
#ifdef CONFIG_GPIO_QMSI_SS_1
	case QM_SS_GPIO_1:
		IRQ_CONNECT(DT_GPIO_QMSI_SS_1_IRQ,
			    DT_GPIO_QMSI_SS_1_IRQ_PRI, ss_gpio_isr,
			    DEVICE_GET(ss_gpio_1), 0);
		irq_enable(IRQ_GPIO1_INTR);

		ss_clk_gpio_enable(QM_SS_GPIO_1);

		scss_intmask =
			(u32_t *)&QM_INTERRUPT_ROUTER->ss_gpio_1_int_mask;
		*scss_intmask &= ~BIT(8);
		break;
#endif /* CONFIG_GPIO_QMSI_SS_1 */
	default:
		return -EIO;
	}

	ss_gpio_qmsi_set_power_state(port, DEVICE_PM_ACTIVE_STATE);

	port->driver_api = &api_funcs;
	return 0;
}
