/*
 * Copyright (c) 2021, Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <sys/util.h>
#include <logging/log.h>

#include "mpu9250.h"

LOG_MODULE_DECLARE(MPU9250, CONFIG_SENSOR_LOG_LEVEL);


#define MPU9250_REG_INT_EN	0x38
#define MPU9250_DRDY_EN		BIT(0)


int mpu9250_trigger_set(const struct device *dev,
			const struct sensor_trigger *trig,
			sensor_trigger_handler_t handler)
{
	struct mpu9250_data *drv_data = dev->data;
	const struct mpu9250_config *cfg = dev->config;
	int ret;

	if (trig->type != SENSOR_TRIG_DATA_READY) {
		return -ENOTSUP;
	}

	ret = gpio_pin_interrupt_configure_dt(&cfg->int_pin, GPIO_INT_DISABLE);
	if (ret < 0) {
		LOG_ERR("Failed to disable gpio interrupt.");
		return ret;
	}

	drv_data->data_ready_handler = handler;
	if (handler == NULL) {
		return 0;
	}

	drv_data->data_ready_trigger = *trig;

	ret = gpio_pin_interrupt_configure_dt(&cfg->int_pin,
					      GPIO_INT_EDGE_TO_ACTIVE);
	if (ret < 0) {
		LOG_ERR("Failed to enable gpio interrupt.");
		return ret;
	}

	return 0;
}

static void mpu9250_gpio_callback(const struct device *dev,
				  struct gpio_callback *cb, uint32_t pins)
{
	struct mpu9250_data *drv_data =
		CONTAINER_OF(cb, struct mpu9250_data, gpio_cb);
	const struct mpu9250_config *cfg = drv_data->dev->config;
	int ret;

	ARG_UNUSED(pins);

	ret = gpio_pin_interrupt_configure_dt(&cfg->int_pin, GPIO_INT_DISABLE);
	if (ret < 0) {
		LOG_ERR("Disabling gpio interrupt failed with err: %d", ret);
		return;
	}

#if defined(CONFIG_MPU9250_TRIGGER_OWN_THREAD)
	k_sem_give(&drv_data->gpio_sem);
#elif defined(CONFIG_MPU9250_TRIGGER_GLOBAL_THREAD)
	k_work_submit(&drv_data->work);
#endif
}

static void mpu9250_thread_cb(const struct device *dev)
{
	struct mpu9250_data *drv_data = dev->data;
	const struct mpu9250_config *cfg = dev->config;
	int ret;

	if (drv_data->data_ready_handler != NULL) {
		drv_data->data_ready_handler(dev,
					     &drv_data->data_ready_trigger);
	}

	ret = gpio_pin_interrupt_configure_dt(&cfg->int_pin,
					      GPIO_INT_EDGE_TO_ACTIVE);
	if (ret < 0) {
		LOG_ERR("Enabling gpio interrupt failed with err: %d", ret);
	}

}

#ifdef CONFIG_MPU9250_TRIGGER_OWN_THREAD
static void mpu9250_thread(struct mpu9250_data *drv_data)
{
	while (1) {
		k_sem_take(&drv_data->gpio_sem, K_FOREVER);
		mpu9250_thread_cb(drv_data->dev);
	}
}
#endif

#ifdef CONFIG_MPU9250_TRIGGER_GLOBAL_THREAD
static void mpu9250_work_cb(struct k_work *work)
{
	struct mpu9250_data *drv_data =
		CONTAINER_OF(work, struct mpu9250_data, work);

	mpu9250_thread_cb(drv_data->dev);
}
#endif

int mpu9250_init_interrupt(const struct device *dev)
{
	struct mpu9250_data *drv_data = dev->data;
	const struct mpu9250_config *cfg = dev->config;
	int ret;

	/* setup data ready gpio interrupt */
	if (!device_is_ready(cfg->int_pin.port)) {
		LOG_ERR("Interrupt pin is not ready.");
		return -EIO;
	}

	drv_data->dev = dev;

	ret = gpio_pin_configure_dt(&cfg->int_pin, GPIO_INPUT);
	if (ret < 0) {
		LOG_ERR("Failed to configure interrupt pin.");
		return ret;
	}

	gpio_init_callback(&drv_data->gpio_cb,
			   mpu9250_gpio_callback,
			   BIT(cfg->int_pin.pin));

	ret = gpio_add_callback(cfg->int_pin.port, &drv_data->gpio_cb);
	if (ret < 0) {
		LOG_ERR("Failed to set gpio callback.");
		return ret;
	}

	/* enable data ready interrupt */
	ret = i2c_reg_write_byte_dt(&cfg->i2c, MPU9250_REG_INT_EN,
				    MPU9250_DRDY_EN);
	if (ret < 0) {
		LOG_ERR("Failed to enable data ready interrupt.");
		return ret;
	}

#if defined(CONFIG_MPU9250_TRIGGER_OWN_THREAD)
	ret = k_sem_init(&drv_data->gpio_sem, 0, K_SEM_MAX_LIMIT);
	if (ret < 0) {
		LOG_ERR("Failed to enable semaphore");
		return ret;
	}

	k_thread_create(&drv_data->thread, drv_data->thread_stack,
			CONFIG_MPU9250_THREAD_STACK_SIZE,
			(k_thread_entry_t)mpu9250_thread, drv_data,
			NULL, NULL, K_PRIO_COOP(CONFIG_MPU9250_THREAD_PRIORITY),
			0, K_NO_WAIT);
#elif defined(CONFIG_MPU9250_TRIGGER_GLOBAL_THREAD)
	drv_data->work.handler = mpu9250_work_cb;
#endif

	ret = gpio_pin_interrupt_configure_dt(&cfg->int_pin,
					      GPIO_INT_EDGE_TO_ACTIVE);
	if (ret < 0) {
		LOG_ERR("Failed to enable interrupt");
		return ret;
	}

	return 0;
}
