/*
 * Copyright (c) 2023 Analog Devices Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/sensor.h>
#include "adxl367.h"

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(ADXL367, CONFIG_SENSOR_LOG_LEVEL);

static void adxl367_thread_cb(const struct device *dev)
{
	const struct adxl367_dev_config *cfg = dev->config;
	struct adxl367_data *drv_data = dev->data;
	uint8_t status;
	int ret;

	/* Clear the status */
	ret = drv_data->hw_tf->read_reg(dev, ADXL367_STATUS, &status);
	if (ret != 0) {
		return;
	}

	if (drv_data->th_handler != NULL) {
		if (((FIELD_GET(ADXL367_STATUS_INACT, status)) != 0) ||
			(FIELD_GET(ADXL367_STATUS_ACT, status)) != 0) {
			drv_data->th_handler(dev, drv_data->th_trigger);
		}
	}

	if ((drv_data->drdy_handler != NULL) &&
		(FIELD_GET(ADXL367_STATUS_DATA_RDY, status) != 0)) {
		drv_data->drdy_handler(dev, drv_data->drdy_trigger);
	}

	ret = gpio_pin_interrupt_configure_dt(&cfg->interrupt,
					      GPIO_INT_EDGE_TO_ACTIVE);
	__ASSERT(ret == 0, "Interrupt configuration failed");
}

static void adxl367_gpio_callback(const struct device *dev,
				  struct gpio_callback *cb, uint32_t pins)
{
	struct adxl367_data *drv_data =
		CONTAINER_OF(cb, struct adxl367_data, gpio_cb);
	const struct adxl367_dev_config *cfg = drv_data->dev->config;

	gpio_pin_interrupt_configure_dt(&cfg->interrupt, GPIO_INT_DISABLE);

#if defined(CONFIG_ADXL367_TRIGGER_OWN_THREAD)
	k_sem_give(&drv_data->gpio_sem);
#elif defined(CONFIG_ADXL367_TRIGGER_GLOBAL_THREAD)
	k_work_submit(&drv_data->work);
#endif
}

#if defined(CONFIG_ADXL367_TRIGGER_OWN_THREAD)
static void adxl367_thread(struct adxl367_data *drv_data)
{
	while (true) {
		k_sem_take(&drv_data->gpio_sem, K_FOREVER);
		adxl367_thread_cb(drv_data->dev);
	}
}

#elif defined(CONFIG_ADXL367_TRIGGER_GLOBAL_THREAD)
static void adxl367_work_cb(struct k_work *work)
{
	struct adxl367_data *drv_data =
		CONTAINER_OF(work, struct adxl367_data, work);

	adxl367_thread_cb(drv_data->dev);
}
#endif

int adxl367_trigger_set(const struct device *dev,
			const struct sensor_trigger *trig,
			sensor_trigger_handler_t handler)
{
	const struct adxl367_dev_config *cfg = dev->config;
	struct adxl367_data *drv_data = dev->data;
	uint8_t int_mask, int_en, status;
	int ret;

	ret = gpio_pin_interrupt_configure_dt(&cfg->interrupt,
					      GPIO_INT_DISABLE);
	if (ret != 0) {
		return ret;
	}

	switch (trig->type) {
	case SENSOR_TRIG_THRESHOLD:
		drv_data->th_handler = handler;
		drv_data->th_trigger = trig;
		int_mask = ADXL367_ACT_INT | ADXL367_INACT_INT;
		break;
	case SENSOR_TRIG_DATA_READY:
		drv_data->drdy_handler = handler;
		drv_data->drdy_trigger = trig;
		int_mask = ADXL367_DATA_RDY;
		break;
	default:
		LOG_ERR("Unsupported sensor trigger");
		return -ENOTSUP;
	}

	if (handler != NULL) {
		int_en = int_mask;
	} else {
		int_en = 0U;
	}

	ret = drv_data->hw_tf->write_reg_mask(dev, ADXL367_INTMAP1_LOWER, int_mask, int_en);
	if (ret != 0) {
		return ret;
	}

	/* Clear status */
	ret = drv_data->hw_tf->read_reg(dev, ADXL367_STATUS, &status);
	if (ret != 0) {
		return ret;
	}

	ret = gpio_pin_interrupt_configure_dt(&cfg->interrupt,
					      GPIO_INT_EDGE_TO_ACTIVE);
	if (ret != 0) {
		return ret;
	}

	return 0;
}

int adxl367_init_interrupt(const struct device *dev)
{
	const struct adxl367_dev_config *cfg = dev->config;
	struct adxl367_data *drv_data = dev->data;
	int ret;

	if (!gpio_is_ready_dt(&cfg->interrupt)) {
		LOG_ERR("GPIO port %s not ready", cfg->interrupt.port->name);
		return -EINVAL;
	}

	ret = gpio_pin_configure_dt(&cfg->interrupt, GPIO_INPUT);
	if (ret != 0) {
		return ret;
	}

	gpio_init_callback(&drv_data->gpio_cb,
			   adxl367_gpio_callback,
			   BIT(cfg->interrupt.pin));

	ret = gpio_add_callback(cfg->interrupt.port, &drv_data->gpio_cb);
	if (ret != 0) {
		LOG_ERR("Failed to set gpio callback!");
		return ret;
	}

	drv_data->dev = dev;

#if defined(CONFIG_ADXL367_TRIGGER_OWN_THREAD)
	k_sem_init(&drv_data->gpio_sem, 0, K_SEM_MAX_LIMIT);

	k_thread_create(&drv_data->thread, drv_data->thread_stack,
			CONFIG_ADXL367_THREAD_STACK_SIZE,
			(k_thread_entry_t)adxl367_thread, drv_data,
			NULL, NULL, K_PRIO_COOP(CONFIG_ADXL367_THREAD_PRIORITY),
			0, K_NO_WAIT);
#elif defined(CONFIG_ADXL367_TRIGGER_GLOBAL_THREAD)
	drv_data->work.handler = adxl367_work_cb;
#endif

	return 0;
}
