/*
 * Copyright (c) 2022 ITE Corporation. All Rights Reserved
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ite_it8xxx2_wuc

#include <device.h>
#include <drivers/interrupt_controller/wuc_ite_it8xxx2.h>
#include <dt-bindings/interrupt-controller/it8xxx2-wuc.h>
#include <kernel.h>
#include <soc.h>
#include <soc_common.h>
#include <stdlib.h>

#include <logging/log.h>
LOG_MODULE_REGISTER(wuc_ite_it8xxx2, CONFIG_INTC_LOG_LEVEL);

/* Driver config */
struct it8xxx2_wuc_cfg {
	/* WUC wakeup edge mode register */
	uint8_t *reg_wuemr;
	/* WUC wakeup edge sense register */
	uint8_t *reg_wuesr;
	/* WUC wakeup enable register */
	uint8_t *reg_wuenr;
	/* WUC wakeup both edge mode register */
	uint8_t *reg_wubemr;
};

void it8xxx2_wuc_enable(const struct device *dev, uint8_t mask)
{
	const struct it8xxx2_wuc_cfg *config = dev->config;
	volatile uint8_t *reg_wuenr = config->reg_wuenr;

	/*
	 * WUC group only 1, 3, and 4 have enable/disable register,
	 * others are always enabled.
	 */
	if (reg_wuenr == IT8XXX2_WUC_UNUSED_REG) {
		return;
	}

	/* Enable wakeup interrupt of the pin */
	*reg_wuenr |= mask;
}

void it8xxx2_wuc_disable(const struct device *dev, uint8_t mask)
{
	const struct it8xxx2_wuc_cfg *config = dev->config;
	volatile uint8_t *reg_wuenr = config->reg_wuenr;

	/*
	 * WUC group only 1, 3, and 4 have enable/disable register,
	 * others are always enabled.
	 */
	if (reg_wuenr == IT8XXX2_WUC_UNUSED_REG) {
		return;
	}

	/* Disable wakeup interrupt of the pin */
	*reg_wuenr &= ~mask;
}

void it8xxx2_wuc_clear_status(const struct device *dev, uint8_t mask)
{
	const struct it8xxx2_wuc_cfg *config = dev->config;
	volatile uint8_t *reg_wuesr = config->reg_wuesr;

	if (reg_wuesr == IT8XXX2_WUC_UNUSED_REG) {
		return;
	}

	/* W/C wakeup interrupt status of the pin */
	*reg_wuesr = mask;
}

void it8xxx2_wuc_set_polarity(const struct device *dev, uint8_t mask, uint32_t flags)
{
	const struct it8xxx2_wuc_cfg *config = dev->config;
	volatile uint8_t *reg_wuemr = config->reg_wuemr;
	volatile uint8_t *reg_wubemr = config->reg_wubemr;

	if (reg_wuemr == IT8XXX2_WUC_UNUSED_REG) {
		return;
	}

	/* Set wakeup interrupt edge trigger mode of the pin */
	if ((flags & WUC_TYPE_EDGE_BOTH) == WUC_TYPE_EDGE_RISING) {
		*reg_wubemr &= ~mask;
		*reg_wuemr &= ~mask;
	} else if ((flags & WUC_TYPE_EDGE_BOTH) == WUC_TYPE_EDGE_FALLING) {
		*reg_wubemr &= ~mask;
		*reg_wuemr |= mask;
	} else {
		/* Both edge trigger mode */
		*reg_wubemr |= mask;
	}
}

static int it8xxx2_wuc_init(const struct device *dev)
{
	return 0;
}

#define IT8XXX2_WUC_INIT(inst)						       \
									       \
	static const struct it8xxx2_wuc_cfg it8xxx2_wuc_cfg_##inst = {	       \
		.reg_wuemr = (uint8_t *) DT_INST_REG_ADDR_BY_IDX(inst, 0),     \
		.reg_wuesr = (uint8_t *) DT_INST_REG_ADDR_BY_IDX(inst, 1),     \
		.reg_wuenr = (uint8_t *) DT_INST_REG_ADDR_BY_IDX(inst, 2),     \
		.reg_wubemr = (uint8_t *) DT_INST_REG_ADDR_BY_IDX(inst, 3),    \
	};								       \
									       \
	DEVICE_DT_INST_DEFINE(inst,					       \
			      &it8xxx2_wuc_init,			       \
			      NULL,					       \
			      NULL,					       \
			      &it8xxx2_wuc_cfg_##inst,			       \
			      PRE_KERNEL_1,				       \
			      CONFIG_KERNEL_INIT_PRIORITY_OBJECTS,	       \
			      NULL);

DT_INST_FOREACH_STATUS_OKAY(IT8XXX2_WUC_INIT)
