/*
 * Copyright (c) 2020 arithmetics.io
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ti_fdc2x1x

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

#include <stdio.h>

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

static void fdc2x1x_thread_cb(const struct device *dev)
{
	struct fdc2x1x_data *drv_data = dev->data;
	uint16_t status;

#ifdef CONFIG_PM_DEVICE
	/* INTB asserts after exiting shutdown mode. Drop this interrupt */
	if (drv_data->pm_state == PM_DEVICE_STATE_OFF) {
		return;
	}
#endif

	/* Clear the status */
	if (fdc2x1x_get_status(dev, &status) < 0) {
		LOG_ERR("Unable to get status.");
		return;
	}

	k_mutex_lock(&drv_data->trigger_mutex, K_FOREVER);
	if ((drv_data->drdy_handler != NULL) && FDC2X1X_STATUS_DRDY(status)) {
		drv_data->drdy_handler(dev, &drv_data->drdy_trigger);
	}
	k_mutex_unlock(&drv_data->trigger_mutex);
}

static void fdc2x1x_gpio_callback(const struct device *dev,
				  struct gpio_callback *cb, uint32_t pins)
{
	struct fdc2x1x_data *drv_data =
		CONTAINER_OF(cb, struct fdc2x1x_data, gpio_cb);

#ifdef CONFIG_FDC2X1X_TRIGGER_OWN_THREAD
	k_sem_give(&drv_data->gpio_sem);
#elif CONFIG_FDC2X1X_TRIGGER_GLOBAL_THREAD
	k_work_submit(&drv_data->work);
#endif
}

#ifdef CONFIG_FDC2X1X_TRIGGER_OWN_THREAD
static void fdc2x1x_thread(struct fdc2x1x_data *drv_data)
{
	while (true) {
		k_sem_take(&drv_data->gpio_sem, K_FOREVER);
		fdc2x1x_thread_cb(drv_data->dev);
	}
}

#elif CONFIG_FDC2X1X_TRIGGER_GLOBAL_THREAD
static void fdc2x1x_work_cb(struct k_work *work)
{
	struct fdc2x1x_data *drv_data =
		CONTAINER_OF(work, struct fdc2x1x_data, work);

	fdc2x1x_thread_cb(drv_data->dev);
}
#endif

int fdc2x1x_trigger_set(const struct device *dev,
			const struct sensor_trigger *trig,
			sensor_trigger_handler_t handler)
{
	struct fdc2x1x_data *drv_data = dev->data;
	const struct fdc2x1x_config *cfg = dev->config;
	uint16_t status, int_mask, int_en;
	int ret;

	gpio_pin_interrupt_configure(cfg->intb_gpio, cfg->intb_pin,
				     GPIO_INT_DISABLE);

	switch (trig->type) {
	case SENSOR_TRIG_DATA_READY:
		k_mutex_lock(&drv_data->trigger_mutex, K_FOREVER);
		drv_data->drdy_handler = handler;
		drv_data->drdy_trigger = *trig;
		k_mutex_unlock(&drv_data->trigger_mutex);

		int_mask = FDC2X1X_ERROR_CONFIG_DRDY_2INT_MSK;
		break;
	default:
		LOG_ERR("Unsupported sensor trigger");
		ret = -ENOTSUP;
		goto out;
	}

	if (handler) {
		int_en = int_mask;
		drv_data->int_config |= int_mask;
	} else {
		int_en = 0U;
	}

	ret = fdc2x1x_reg_write_mask(dev,
				     FDC2X1X_ERROR_CONFIG, int_mask, int_en);

	/* Clear INTB pin by reading STATUS register */
	fdc2x1x_get_status(dev, &status);
out:
	gpio_pin_interrupt_configure(cfg->intb_gpio, cfg->intb_pin,
				     GPIO_INT_EDGE_TO_ACTIVE);

	return ret;
}

int fdc2x1x_init_interrupt(const struct device *dev)
{
	struct fdc2x1x_data *drv_data = dev->data;
	const struct fdc2x1x_config *cfg = dev->config;
	int ret;

	k_mutex_init(&drv_data->trigger_mutex);

	if (!device_is_ready(cfg->intb_gpio)) {
		LOG_ERR("%s: intb_gpio device not ready", cfg->intb_gpio->name);
		return -ENODEV;
	}

	ret = fdc2x1x_set_interrupt_pin(dev, true);
	if (ret) {
		return ret;
	}

	gpio_pin_configure(cfg->intb_gpio, cfg->intb_pin,
			   GPIO_INPUT | cfg->intb_flags);

	gpio_init_callback(&drv_data->gpio_cb,
			   fdc2x1x_gpio_callback,
			   BIT(cfg->intb_pin));

	if (gpio_add_callback(cfg->intb_gpio, &drv_data->gpio_cb) < 0) {
		LOG_ERR("Failed to set gpio callback!");
		return -EIO;
	}

	drv_data->dev = dev;

#ifdef CONFIG_FDC2X1X_TRIGGER_OWN_THREAD
	k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX);

	k_thread_create(&drv_data->thread, drv_data->thread_stack,
			CONFIG_FDC2X1X_THREAD_STACK_SIZE,
			(k_thread_entry_t)fdc2x1x_thread,
			drv_data, 0, NULL,
			K_PRIO_COOP(CONFIG_FDC2X1X_THREAD_PRIORITY),
			0, K_NO_WAIT);
#elif CONFIG_FDC2X1X_TRIGGER_GLOBAL_THREAD
	drv_data->work.handler = fdc2x1x_work_cb;
#endif

	return 0;
}
