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

#define DT_DRV_COMPAT st_iis2dlpc

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

#include "iis2dlpc.h"

LOG_MODULE_DECLARE(IIS2DLPC, CONFIG_SENSOR_LOG_LEVEL);

/**
 * iis2dlpc_enable_int - enable selected int pin to generate interrupt
 */
static int iis2dlpc_enable_int(const struct device *dev,
			       enum sensor_trigger_type type, int enable)
{
	const struct iis2dlpc_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	iis2dlpc_reg_t int_route;

	switch (type) {
	case SENSOR_TRIG_DATA_READY:
		if (cfg->drdy_int == 1) {
			/* set interrupt for pin INT1 */
			iis2dlpc_pin_int1_route_get(ctx,
					&int_route.ctrl4_int1_pad_ctrl);
			int_route.ctrl4_int1_pad_ctrl.int1_drdy = enable;

			return iis2dlpc_pin_int1_route_set(ctx,
					&int_route.ctrl4_int1_pad_ctrl);
		} else {
			/* set interrupt for pin INT2 */
			iis2dlpc_pin_int2_route_get(ctx,
					&int_route.ctrl5_int2_pad_ctrl);
			int_route.ctrl5_int2_pad_ctrl.int2_drdy = enable;

			return iis2dlpc_pin_int2_route_set(ctx,
					&int_route.ctrl5_int2_pad_ctrl);
		}
		break;
#ifdef CONFIG_IIS2DLPC_TAP
	case SENSOR_TRIG_TAP:
		/* set interrupt for pin INT1 */
		iis2dlpc_pin_int1_route_get(ctx,
				&int_route.ctrl4_int1_pad_ctrl);
		int_route.ctrl4_int1_pad_ctrl.int1_single_tap = enable;

		return iis2dlpc_pin_int1_route_set(ctx,
				&int_route.ctrl4_int1_pad_ctrl);
	case SENSOR_TRIG_DOUBLE_TAP:
		/* set interrupt for pin INT1 */
		iis2dlpc_pin_int1_route_get(ctx,
				&int_route.ctrl4_int1_pad_ctrl);
		int_route.ctrl4_int1_pad_ctrl.int1_tap = enable;

		return iis2dlpc_pin_int1_route_set(ctx,
				&int_route.ctrl4_int1_pad_ctrl);
#endif /* CONFIG_IIS2DLPC_TAP */
	default:
		LOG_ERR("Unsupported trigger interrupt route %d", type);
		return -ENOTSUP;
	}
}

/**
 * iis2dlpc_trigger_set - link external trigger to event data ready
 */
int iis2dlpc_trigger_set(const struct device *dev,
			  const struct sensor_trigger *trig,
			  sensor_trigger_handler_t handler)
{
	const struct iis2dlpc_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	struct iis2dlpc_data *iis2dlpc = dev->data;
	int16_t raw[3];
	int state = (handler != NULL) ? PROPERTY_ENABLE : PROPERTY_DISABLE;

	switch (trig->type) {
	case SENSOR_TRIG_DATA_READY:
		iis2dlpc->drdy_handler = handler;
		if (state) {
			/* dummy read: re-trigger interrupt */
			iis2dlpc_acceleration_raw_get(ctx, raw);
		}
		return iis2dlpc_enable_int(dev, SENSOR_TRIG_DATA_READY, state);
#ifdef CONFIG_IIS2DLPC_TAP
	case SENSOR_TRIG_TAP:
		iis2dlpc->tap_handler = handler;
		return iis2dlpc_enable_int(dev, SENSOR_TRIG_TAP, state);
	case SENSOR_TRIG_DOUBLE_TAP:
		iis2dlpc->double_tap_handler = handler;
		return iis2dlpc_enable_int(dev, SENSOR_TRIG_DOUBLE_TAP, state);
#endif /* CONFIG_IIS2DLPC_TAP */
	default:
		LOG_ERR("Unsupported sensor trigger");
		return -ENOTSUP;
	}
}

static int iis2dlpc_handle_drdy_int(const struct device *dev)
{
	struct iis2dlpc_data *data = dev->data;

	struct sensor_trigger drdy_trig = {
		.type = SENSOR_TRIG_DATA_READY,
		.chan = SENSOR_CHAN_ALL,
	};

	if (data->drdy_handler) {
		data->drdy_handler(dev, &drdy_trig);
	}

	return 0;
}

#ifdef CONFIG_IIS2DLPC_TAP
static int iis2dlpc_handle_single_tap_int(const struct device *dev)
{
	struct iis2dlpc_data *data = dev->data;
	sensor_trigger_handler_t handler = data->tap_handler;

	struct sensor_trigger tap_trig = {
		.type = SENSOR_TRIG_TAP,
		.chan = SENSOR_CHAN_ALL,
	};

	if (handler) {
		handler(dev, &tap_trig);
	}

	return 0;
}

static int iis2dlpc_handle_double_tap_int(const struct device *dev)
{
	struct iis2dlpc_data *data = dev->data;
	sensor_trigger_handler_t handler = data->double_tap_handler;

	struct sensor_trigger tap_trig = {
		.type = SENSOR_TRIG_DOUBLE_TAP,
		.chan = SENSOR_CHAN_ALL,
	};

	if (handler) {
		handler(dev, &tap_trig);
	}

	return 0;
}
#endif /* CONFIG_IIS2DLPC_TAP */

/**
 * iis2dlpc_handle_interrupt - handle the drdy event
 * read data and call handler if registered any
 */
static void iis2dlpc_handle_interrupt(const struct device *dev)
{
	const struct iis2dlpc_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	iis2dlpc_all_sources_t sources;

	iis2dlpc_all_sources_get(ctx, &sources);

	if (sources.status_dup.drdy) {
		iis2dlpc_handle_drdy_int(dev);
	}
#ifdef CONFIG_IIS2DLPC_TAP
	if (sources.status_dup.single_tap) {
		iis2dlpc_handle_single_tap_int(dev);
	}
	if (sources.status_dup.double_tap) {
		iis2dlpc_handle_double_tap_int(dev);
	}
#endif /* CONFIG_IIS2DLPC_TAP */

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

static void iis2dlpc_gpio_callback(const struct device *dev,
				    struct gpio_callback *cb, uint32_t pins)
{
	struct iis2dlpc_data *iis2dlpc =
		CONTAINER_OF(cb, struct iis2dlpc_data, gpio_cb);
	const struct iis2dlpc_config *cfg = iis2dlpc->dev->config;

	ARG_UNUSED(pins);

	gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy, GPIO_INT_DISABLE);

#if defined(CONFIG_IIS2DLPC_TRIGGER_OWN_THREAD)
	k_sem_give(&iis2dlpc->gpio_sem);
#elif defined(CONFIG_IIS2DLPC_TRIGGER_GLOBAL_THREAD)
	k_work_submit(&iis2dlpc->work);
#endif /* CONFIG_IIS2DLPC_TRIGGER_OWN_THREAD */
}

#ifdef CONFIG_IIS2DLPC_TRIGGER_OWN_THREAD
static void iis2dlpc_thread(struct iis2dlpc_data *iis2dlpc)
{
	while (1) {
		k_sem_take(&iis2dlpc->gpio_sem, K_FOREVER);
		iis2dlpc_handle_interrupt(iis2dlpc->dev);
	}
}
#endif /* CONFIG_IIS2DLPC_TRIGGER_OWN_THREAD */

#ifdef CONFIG_IIS2DLPC_TRIGGER_GLOBAL_THREAD
static void iis2dlpc_work_cb(struct k_work *work)
{
	struct iis2dlpc_data *iis2dlpc =
		CONTAINER_OF(work, struct iis2dlpc_data, work);

	iis2dlpc_handle_interrupt(iis2dlpc->dev);
}
#endif /* CONFIG_IIS2DLPC_TRIGGER_GLOBAL_THREAD */

int iis2dlpc_init_interrupt(const struct device *dev)
{
	struct iis2dlpc_data *iis2dlpc = dev->data;
	const struct iis2dlpc_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	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_IIS2DLPC_TRIGGER_OWN_THREAD)
	k_sem_init(&iis2dlpc->gpio_sem, 0, K_SEM_MAX_LIMIT);

	k_thread_create(&iis2dlpc->thread, iis2dlpc->thread_stack,
		       CONFIG_IIS2DLPC_THREAD_STACK_SIZE,
		       (k_thread_entry_t)iis2dlpc_thread, iis2dlpc,
		       NULL, NULL, K_PRIO_COOP(CONFIG_IIS2DLPC_THREAD_PRIORITY),
		       0, K_NO_WAIT);
#elif defined(CONFIG_IIS2DLPC_TRIGGER_GLOBAL_THREAD)
	iis2dlpc->work.handler = iis2dlpc_work_cb;
#endif /* CONFIG_IIS2DLPC_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(&iis2dlpc->gpio_cb,
			   iis2dlpc_gpio_callback,
			   BIT(cfg->gpio_drdy.pin));

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

	/* enable interrupt on int1/int2 in pulse mode */
	if (iis2dlpc_int_notification_set(ctx, IIS2DLPC_INT_PULSED)) {
		LOG_ERR("Could not set pulse mode");
		return -EIO;
	}

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