/*
 * 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
	enum pm_device_state state;

	/* INTB asserts after exiting shutdown mode. Drop this interrupt */
	(void)pm_device_state_get(dev, &state);
	if (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;
}
