/*
 * Copyright (c) 2021 Nuvoton Technology Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nuvoton_nct38xx_gpio_alert

#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/gpio/gpio_nct38xx.h>
#include <zephyr/drivers/mfd/nct38xx.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/util_macro.h>

#include "gpio_nct38xx.h"

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(gpio_ntc38xx, CONFIG_GPIO_LOG_LEVEL);

struct nct38xx_mfd {
	/* Lock for NCT38xx register access */
	struct k_sem *lock;
	/* I2C device used for register access */
	const struct i2c_dt_spec *i2c_dev;
};

/* Driver config */
struct nct38xx_alert_config {
	/* Alert GPIO pin */
	const struct gpio_dt_spec irq_gpio;
	/* NCT38XX devices which share the same alert pin */
	const struct device **nct38xx_dev;
	/* Number of NCT38XX devices on the alert pin */
	uint32_t nct38xx_num;
};

/* Driver data */
struct nct38xx_alert_data {
	/* Alert handler device */
	const struct device *alert_dev;
	/* Alert pin callback */
	struct gpio_callback gpio_cb;
	/* Alert worker */
	struct k_work alert_worker;
	/* Lock for NCT38xx register access */
	struct nct38xx_mfd *mfd;
};

static void nct38xx_alert_callback(const struct device *dev, struct gpio_callback *cb,
				   uint32_t pins)
{
	ARG_UNUSED(pins);
	struct nct38xx_alert_data *data = CONTAINER_OF(cb, struct nct38xx_alert_data, gpio_cb);

	k_work_submit(&data->alert_worker);
}

static bool nct38xx_alert_is_active(struct nct38xx_mfd *mfd)
{
	int ret;
	uint16_t alert, mask;

	k_sem_take(mfd->lock, K_FOREVER);

	/* Clear alert */
	ret = i2c_burst_read_dt(mfd->i2c_dev, NCT38XX_REG_ALERT, (uint8_t *)&alert,
				sizeof(alert));
	if (ret < 0) {
		goto release_lock;
	}
	ret = i2c_burst_read_dt(mfd->i2c_dev, NCT38XX_REG_ALERT_MASK,
				(uint8_t *)&mask, sizeof(mask));
	if (ret < 0) {
		goto release_lock;
	}

	alert &= mask;
	if (alert) {
		ret = i2c_burst_write_dt(mfd->i2c_dev, NCT38XX_REG_ALERT,
						(uint8_t *)&alert, sizeof(alert));
	}

release_lock:
	k_sem_give(mfd->lock);

	if (ret < 0) {
		LOG_ERR("i2c access failed");
		return false;
	}

	if (alert & BIT(NCT38XX_REG_ALERT_VENDOR_DEFINDED_ALERT)) {
		return true;
	}

	return false;
}

static void nct38xx_alert_worker(struct k_work *work)
{
	struct nct38xx_alert_data *const data =
		CONTAINER_OF(work, struct nct38xx_alert_data, alert_worker);
	const struct nct38xx_alert_config *const config = data->alert_dev->config;

	do {
		/* NCT38XX device handler */
		for (int i = 0; i < config->nct38xx_num; i++) {
			struct nct38xx_mfd *mfd = &data->mfd[i];

			if (nct38xx_alert_is_active(mfd)) {
				nct38xx_gpio_alert_handler(config->nct38xx_dev[i]);
			}
		}
		/* While the interrupt signal is still active; we have more work to do. */
	} while (gpio_pin_get_dt(&config->irq_gpio));
}

static int nct38xx_alert_init(const struct device *dev)
{
	const struct nct38xx_alert_config *const config = dev->config;
	struct nct38xx_alert_data *const data = dev->data;
	int ret;

	/* Check NCT38XX devices are all ready. */
	for (int i = 0; i < config->nct38xx_num; i++) {
		if (!device_is_ready(config->nct38xx_dev[i])) {
			LOG_ERR("%s device not ready", config->nct38xx_dev[i]->name);
			return -ENODEV;
		}

		data->mfd[i].lock = mfd_nct38xx_get_lock_reference(config->nct38xx_dev[i]);
		data->mfd[i].i2c_dev = mfd_nct38xx_get_i2c_dt_spec(config->nct38xx_dev[i]);
	}

	/* Set the alert pin for handling the interrupt */
	k_work_init(&data->alert_worker, nct38xx_alert_worker);

	if (!gpio_is_ready_dt(&config->irq_gpio)) {
		LOG_ERR("%s device not ready", config->irq_gpio.port->name);
		return -ENODEV;
	}

	gpio_pin_configure_dt(&config->irq_gpio, GPIO_INPUT);

	gpio_init_callback(&data->gpio_cb, nct38xx_alert_callback, BIT(config->irq_gpio.pin));

	ret = gpio_add_callback(config->irq_gpio.port, &data->gpio_cb);
	if (ret < 0) {
		return ret;
	}

	gpio_pin_interrupt_configure_dt(&config->irq_gpio, GPIO_INT_EDGE_TO_ACTIVE);

	return 0;
}

/* NCT38XX alert driver must be initialized after NCT38XX GPIO driver */
BUILD_ASSERT(CONFIG_GPIO_NCT38XX_ALERT_INIT_PRIORITY > CONFIG_GPIO_NCT38XX_INIT_PRIORITY);

#define NCT38XX_DEV_AND_COMMA(node_id, prop, idx)                                                  \
	DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)),

#define NCT38XX_ALERT_DEVICE_INSTANCE(inst)                                                        \
	const struct device *nct38xx_dev_##inst[] = {                                              \
		DT_INST_FOREACH_PROP_ELEM(inst, nct38xx_dev, NCT38XX_DEV_AND_COMMA)};              \
	static struct nct38xx_mfd nct38xx_mfd_##inst[DT_INST_PROP_LEN(inst, nct38xx_dev)];         \
	static const struct nct38xx_alert_config nct38xx_alert_cfg_##inst = {                      \
		.irq_gpio = GPIO_DT_SPEC_INST_GET(inst, irq_gpios),                                \
		.nct38xx_dev = &nct38xx_dev_##inst[0],                                             \
		.nct38xx_num = DT_INST_PROP_LEN(inst, nct38xx_dev),                                \
	};                                                                                         \
	static struct nct38xx_alert_data nct38xx_alert_data_##inst = {                             \
		.alert_dev = DEVICE_DT_INST_GET(inst),                                             \
		.mfd = nct38xx_mfd_##inst,                                                         \
	};                                                                                         \
	DEVICE_DT_INST_DEFINE(inst, nct38xx_alert_init, NULL, &nct38xx_alert_data_##inst,          \
			      &nct38xx_alert_cfg_##inst, POST_KERNEL,                              \
			      CONFIG_GPIO_NCT38XX_ALERT_INIT_PRIORITY, NULL);

DT_INST_FOREACH_STATUS_OKAY(NCT38XX_ALERT_DEVICE_INSTANCE)
