/* ST Microelectronics IIS3DHHC accelerometer sensor
 *
 * Copyright (c) 2019 STMicroelectronics
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Datasheet:
 * https://www.st.com/resource/en/datasheet/iis3dhhc.pdf
 */

#define DT_DRV_COMPAT st_iis3dhhc

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

#include "iis3dhhc.h"

LOG_MODULE_DECLARE(IIS3DHHC, CONFIG_SENSOR_LOG_LEVEL);

/**
 * iis3dhhc_enable_int - enable selected int pin to generate interrupt
 */
static int iis3dhhc_enable_int(const struct device *dev, int enable)
{
	struct iis3dhhc_data *iis3dhhc = dev->data;

	/* set interrupt */
#ifdef CONFIG_IIS3DHHC_DRDY_INT1
	return iis3dhhc_drdy_on_int1_set(iis3dhhc->ctx, enable);
#else
	return iis3dhhc_drdy_on_int2_set(iis3dhhc->ctx, enable);
#endif
}

/**
 * iis3dhhc_trigger_set - link external trigger to event data ready
 */
int iis3dhhc_trigger_set(const struct device *dev,
			 const struct sensor_trigger *trig,
			 sensor_trigger_handler_t handler)
{
	struct iis3dhhc_data *iis3dhhc = dev->data;
	int16_t raw[3];

	if (trig->chan == SENSOR_CHAN_ACCEL_XYZ) {
		iis3dhhc->handler_drdy = handler;
		if (handler) {
			/* dummy read: re-trigger interrupt */
			iis3dhhc_acceleration_raw_get(iis3dhhc->ctx, raw);
			return iis3dhhc_enable_int(dev, PROPERTY_ENABLE);
		} else {
			return iis3dhhc_enable_int(dev, PROPERTY_DISABLE);
		}
	}

	return -ENOTSUP;
}

/**
 * iis3dhhc_handle_interrupt - handle the drdy event
 * read data and call handler if registered any
 */
static void iis3dhhc_handle_interrupt(const struct device *dev)
{
	struct iis3dhhc_data *iis3dhhc = dev->data;
	struct sensor_trigger drdy_trigger = {
		.type = SENSOR_TRIG_DATA_READY,
	};
	const struct iis3dhhc_config *cfg = dev->config;

	if (iis3dhhc->handler_drdy != NULL) {
		iis3dhhc->handler_drdy(dev, &drdy_trigger);
	}

	gpio_pin_interrupt_configure(iis3dhhc->gpio, cfg->int_pin,
				     GPIO_INT_EDGE_TO_ACTIVE);
}

static void iis3dhhc_gpio_callback(const struct device *dev,
				    struct gpio_callback *cb, uint32_t pins)
{
	struct iis3dhhc_data *iis3dhhc =
		CONTAINER_OF(cb, struct iis3dhhc_data, gpio_cb);
	const struct iis3dhhc_config *cfg = iis3dhhc->dev->config;

	ARG_UNUSED(pins);

	gpio_pin_interrupt_configure(iis3dhhc->gpio, cfg->int_pin,
				     GPIO_INT_DISABLE);

#if defined(CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD)
	k_sem_give(&iis3dhhc->gpio_sem);
#elif defined(CONFIG_IIS3DHHC_TRIGGER_GLOBAL_THREAD)
	k_work_submit(&iis3dhhc->work);
#endif /* CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD */
}

#ifdef CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD
static void iis3dhhc_thread(struct iis3dhhc_data *iis3dhhc)
{
	while (1) {
		k_sem_take(&iis3dhhc->gpio_sem, K_FOREVER);
		iis3dhhc_handle_interrupt(iis3dhhc->dev);
	}
}
#endif /* CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD */

#ifdef CONFIG_IIS3DHHC_TRIGGER_GLOBAL_THREAD
static void iis3dhhc_work_cb(struct k_work *work)
{
	struct iis3dhhc_data *iis3dhhc =
		CONTAINER_OF(work, struct iis3dhhc_data, work);

	iis3dhhc_handle_interrupt(iis3dhhc->dev);
}
#endif /* CONFIG_IIS3DHHC_TRIGGER_GLOBAL_THREAD */

int iis3dhhc_init_interrupt(const struct device *dev)
{
	struct iis3dhhc_data *iis3dhhc = dev->data;
	const struct iis3dhhc_config *cfg = dev->config;
	int ret;

	/* setup data ready gpio interrupt (INT1 or INT2) */
	iis3dhhc->gpio = device_get_binding(cfg->int_port);
	if (iis3dhhc->gpio == NULL) {
		LOG_DBG("Cannot get pointer to %s device", cfg->int_port);
		return -EINVAL;
	}
	iis3dhhc->dev = dev;

#if defined(CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD)
	k_sem_init(&iis3dhhc->gpio_sem, 0, UINT_MAX);

	k_thread_create(&iis3dhhc->thread, iis3dhhc->thread_stack,
		       CONFIG_IIS3DHHC_THREAD_STACK_SIZE,
		       (k_thread_entry_t)iis3dhhc_thread, iis3dhhc,
		       NULL, NULL, K_PRIO_COOP(CONFIG_IIS3DHHC_THREAD_PRIORITY),
		       0, K_NO_WAIT);
#elif defined(CONFIG_IIS3DHHC_TRIGGER_GLOBAL_THREAD)
	iis3dhhc->work.handler = iis3dhhc_work_cb;
#endif /* CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD */

	ret = gpio_pin_configure(iis3dhhc->gpio, cfg->int_pin,
				 GPIO_INPUT | cfg->int_flags);
	if (ret < 0) {
		LOG_DBG("Could not configure gpio");
		return ret;
	}

	gpio_init_callback(&iis3dhhc->gpio_cb,
			   iis3dhhc_gpio_callback,
			   BIT(cfg->int_pin));

	if (gpio_add_callback(iis3dhhc->gpio, &iis3dhhc->gpio_cb) < 0) {
		LOG_DBG("Could not set gpio callback");
		return -EIO;
	}

	/* enable interrupt on int1/int2 in pulse mode */
	if (iis3dhhc_drdy_notification_mode_set(iis3dhhc->ctx, IIS3DHHC_PULSED)) {
		return -EIO;
	}

	return gpio_pin_interrupt_configure(iis3dhhc->gpio, cfg->int_pin,
					    GPIO_INT_EDGE_TO_ACTIVE);
}
