/* ST Microelectronics IIS2ICLX 2-axis accelerometer sensor driver
 *
 * Copyright (c) 2020 STMicroelectronics
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Datasheet:
 * https://www.st.com/resource/en/datasheet/iis2iclx.pdf
 */

#define DT_DRV_COMPAT st_iis2iclx

#include <kernel.h>
#include <drivers/sensor.h>
#include <drivers/gpio.h>
#include <logging/log.h>

#include "iis2iclx.h"

LOG_MODULE_DECLARE(IIS2ICLX, CONFIG_SENSOR_LOG_LEVEL);

#if defined(CONFIG_IIS2ICLX_ENABLE_TEMP)
/**
 * iis2iclx_enable_t_int - TEMP enable selected int pin to generate interrupt
 */
static int iis2iclx_enable_t_int(const struct device *dev, int enable)
{
	const struct iis2iclx_config *cfg = dev->config;
	iis2iclx_pin_int2_route_t int2_route;

	if (enable) {
		int16_t buf;

		/* dummy read: re-trigger interrupt */
		iis2iclx_temperature_raw_get((stmdev_ctx_t *)&cfg->ctx, &buf);
	}

	/* set interrupt (TEMP DRDY interrupt is only on INT2) */
	if (cfg->int_pin == 1)
		return -EIO;

	iis2iclx_read_reg((stmdev_ctx_t *)&cfg->ctx, IIS2ICLX_INT2_CTRL,
			  (uint8_t *)&int2_route.int2_ctrl, 1);
	int2_route.int2_ctrl.int2_drdy_temp = enable;
	return iis2iclx_write_reg((stmdev_ctx_t *)&cfg->ctx, IIS2ICLX_INT2_CTRL,
				  (uint8_t *)&int2_route.int2_ctrl, 1);
}
#endif

/**
 * iis2iclx_enable_xl_int - XL enable selected int pin to generate interrupt
 */
static int iis2iclx_enable_xl_int(const struct device *dev, int enable)
{
	const struct iis2iclx_config *cfg = dev->config;

	if (enable) {
		int16_t buf[3];

		/* dummy read: re-trigger interrupt */
		iis2iclx_acceleration_raw_get((stmdev_ctx_t *)&cfg->ctx, buf);
	}

	/* set interrupt */
	if (cfg->int_pin == 1) {
		iis2iclx_pin_int1_route_t int1_route;

		iis2iclx_read_reg((stmdev_ctx_t *)&cfg->ctx, IIS2ICLX_INT1_CTRL,
				    (uint8_t *)&int1_route.int1_ctrl, 1);

		int1_route.int1_ctrl.int1_drdy_xl = enable;
		return iis2iclx_write_reg((stmdev_ctx_t *)&cfg->ctx,
					  IIS2ICLX_INT1_CTRL,
					  (uint8_t *)&int1_route.int1_ctrl, 1);
	} else {
		iis2iclx_pin_int2_route_t int2_route;

		iis2iclx_read_reg((stmdev_ctx_t *)&cfg->ctx, IIS2ICLX_INT2_CTRL,
				    (uint8_t *)&int2_route.int2_ctrl, 1);
		int2_route.int2_ctrl.int2_drdy_xl = enable;
		return iis2iclx_write_reg((stmdev_ctx_t *)&cfg->ctx,
					  IIS2ICLX_INT2_CTRL,
					  (uint8_t *)&int2_route.int2_ctrl, 1);
	}
}

/**
 * iis2iclx_trigger_set - link external trigger to event data ready
 */
int iis2iclx_trigger_set(const struct device *dev,
			   const struct sensor_trigger *trig,
			   sensor_trigger_handler_t handler)
{
	const struct iis2iclx_config *cfg = dev->config;
	struct iis2iclx_data *iis2iclx = dev->data;

	if (!cfg->trig_enabled) {
		LOG_ERR("trigger_set op not supported");
		return -ENOTSUP;
	}

	if (trig->chan == SENSOR_CHAN_ACCEL_XYZ) {
		iis2iclx->handler_drdy_acc = handler;
		if (handler) {
			return iis2iclx_enable_xl_int(dev, IIS2ICLX_EN_BIT);
		} else {
			return iis2iclx_enable_xl_int(dev, IIS2ICLX_DIS_BIT);
		}
	}
#if defined(CONFIG_IIS2ICLX_ENABLE_TEMP)
	else if (trig->chan == SENSOR_CHAN_DIE_TEMP) {
		iis2iclx->handler_drdy_temp = handler;
		if (handler) {
			return iis2iclx_enable_t_int(dev, IIS2ICLX_EN_BIT);
		} else {
			return iis2iclx_enable_t_int(dev, IIS2ICLX_DIS_BIT);
		}
	}
#endif

	return -ENOTSUP;
}

/**
 * iis2iclx_handle_interrupt - handle the drdy event
 * read data and call handler if registered any
 */
static void iis2iclx_handle_interrupt(const struct device *dev)
{
	struct iis2iclx_data *iis2iclx = dev->data;
	struct sensor_trigger drdy_trigger = {
		.type = SENSOR_TRIG_DATA_READY,
	};
	const struct iis2iclx_config *cfg = dev->config;
	iis2iclx_status_reg_t status;

	while (1) {
		if (iis2iclx_status_reg_get((stmdev_ctx_t *)&cfg->ctx,
					    &status) < 0) {
			LOG_DBG("failed reading status reg");
			return;
		}

		if (status.xlda == 0
#if defined(CONFIG_IIS2ICLX_ENABLE_TEMP)
					&& status.tda == 0
#endif
					) {
			break;
		}

		if ((status.xlda) && (iis2iclx->handler_drdy_acc != NULL)) {
			iis2iclx->handler_drdy_acc(dev, &drdy_trigger);
		}

#if defined(CONFIG_IIS2ICLX_ENABLE_TEMP)
		if ((status.tda) && (iis2iclx->handler_drdy_temp != NULL)) {
			iis2iclx->handler_drdy_temp(dev, &drdy_trigger);
		}
#endif
	}

	gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy,
					GPIO_INT_EDGE_TO_ACTIVE);
}

static void iis2iclx_gpio_callback(const struct device *dev,
				     struct gpio_callback *cb, uint32_t pins)
{
	struct iis2iclx_data *iis2iclx =
		CONTAINER_OF(cb, struct iis2iclx_data, gpio_cb);
	const struct iis2iclx_config *cfg = iis2iclx->dev->config;

	ARG_UNUSED(pins);

	gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy, GPIO_INT_DISABLE);

#if defined(CONFIG_IIS2ICLX_TRIGGER_OWN_THREAD)
	k_sem_give(&iis2iclx->gpio_sem);
#elif defined(CONFIG_IIS2ICLX_TRIGGER_GLOBAL_THREAD)
	k_work_submit(&iis2iclx->work);
#endif /* CONFIG_IIS2ICLX_TRIGGER_OWN_THREAD */
}

#ifdef CONFIG_IIS2ICLX_TRIGGER_OWN_THREAD
static void iis2iclx_thread(struct iis2iclx_data *iis2iclx)
{
	while (1) {
		k_sem_take(&iis2iclx->gpio_sem, K_FOREVER);
		iis2iclx_handle_interrupt(iis2iclx->dev);
	}
}
#endif /* CONFIG_IIS2ICLX_TRIGGER_OWN_THREAD */

#ifdef CONFIG_IIS2ICLX_TRIGGER_GLOBAL_THREAD
static void iis2iclx_work_cb(struct k_work *work)
{
	struct iis2iclx_data *iis2iclx =
		CONTAINER_OF(work, struct iis2iclx_data, work);

	iis2iclx_handle_interrupt(iis2iclx->dev);
}
#endif /* CONFIG_IIS2ICLX_TRIGGER_GLOBAL_THREAD */

int iis2iclx_init_interrupt(const struct device *dev)
{
	struct iis2iclx_data *iis2iclx = dev->data;
	const struct iis2iclx_config *cfg = dev->config;
	int ret;

	/* setup data ready gpio interrupt (INT1 or INT2) */
	if (!device_is_ready(cfg->gpio_drdy.port)) {
		LOG_ERR("Cannot get pointer to drdy_gpio device");
		return -EINVAL;
	}

#if defined(CONFIG_IIS2ICLX_TRIGGER_OWN_THREAD)
	k_sem_init(&iis2iclx->gpio_sem, 0, K_SEM_MAX_LIMIT);

	k_thread_create(&iis2iclx->thread, iis2iclx->thread_stack,
			CONFIG_IIS2ICLX_THREAD_STACK_SIZE,
			(k_thread_entry_t)iis2iclx_thread,
			iis2iclx, NULL, NULL,
			K_PRIO_COOP(CONFIG_IIS2ICLX_THREAD_PRIORITY),
			0, K_NO_WAIT);
#elif defined(CONFIG_IIS2ICLX_TRIGGER_GLOBAL_THREAD)
	iis2iclx->work.handler = iis2iclx_work_cb;
#endif /* CONFIG_IIS2ICLX_TRIGGER_OWN_THREAD */

	ret = gpio_pin_configure_dt(&cfg->gpio_drdy, GPIO_INPUT);
	if (ret < 0) {
		LOG_ERR("Could not configure gpio");
		return ret;
	}

	gpio_init_callback(&iis2iclx->gpio_cb,
			   iis2iclx_gpio_callback,
			   BIT(cfg->gpio_drdy.pin));

	if (gpio_add_callback(cfg->gpio_drdy.port, &iis2iclx->gpio_cb) < 0) {
		LOG_ERR("Could not set gpio callback");
		return -EIO;
	}

	/* enable interrupt on int1/int2 in pulse mode */
	if (iis2iclx_int_notification_set((stmdev_ctx_t *)&cfg->ctx,
					    IIS2ICLX_ALL_INT_PULSED) < 0) {
		LOG_ERR("Could not set pulse mode");
		return -EIO;
	}

	if (gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy,
					    GPIO_INT_EDGE_TO_ACTIVE) < 0) {
		LOG_ERR("Could not configure interrupt");
		return -EIO;
	}

	return 0;
}
