/*
 * Copyright (c) 2016-2021 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT st_hts221

#include <device.h>
#include <sys/__assert.h>
#include <sys/util.h>
#include <kernel.h>
#include <logging/log.h>

#include "hts221.h"

LOG_MODULE_DECLARE(HTS221, CONFIG_SENSOR_LOG_LEVEL);

static inline void setup_drdy(const struct device *dev,
			      bool enable)
{
	const struct hts221_config *cfg = dev->config;
	unsigned int flags = enable
		? GPIO_INT_EDGE_TO_ACTIVE
		: GPIO_INT_DISABLE;

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

static inline void handle_drdy(const struct device *dev)
{
	struct hts221_data *data = dev->data;

	setup_drdy(dev, false);

#if defined(CONFIG_HTS221_TRIGGER_OWN_THREAD)
	k_sem_give(&data->drdy_sem);
#elif defined(CONFIG_HTS221_TRIGGER_GLOBAL_THREAD)
	k_work_submit(&data->work);
#endif
}

static void process_drdy(const struct device *dev)
{
	struct hts221_data *data = dev->data;

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

	if (data->data_ready_handler != NULL) {
		setup_drdy(dev, true);
	}
}

int hts221_trigger_set(const struct device *dev,
		       const struct sensor_trigger *trig,
		       sensor_trigger_handler_t handler)
{
	struct hts221_data *data = dev->data;
	const struct hts221_config *cfg = dev->config;

	__ASSERT_NO_MSG(trig->type == SENSOR_TRIG_DATA_READY);

	setup_drdy(dev, false);

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

	data->data_ready_trigger = *trig;

	setup_drdy(dev, true);

	/* If DRDY is active we probably won't get the rising edge, so
	 * invoke the callback manually.
	 */
	if (gpio_pin_get_dt(&cfg->gpio_drdy) > 0) {
		handle_drdy(dev);
	}

	return 0;
}

static void hts221_drdy_callback(const struct device *dev,
				 struct gpio_callback *cb, uint32_t pins)
{
	struct hts221_data *data =
		CONTAINER_OF(cb, struct hts221_data, drdy_cb);

	ARG_UNUSED(pins);

	handle_drdy(data->dev);
}

#ifdef CONFIG_HTS221_TRIGGER_OWN_THREAD
static void hts221_thread(struct hts221_data *data)
{
	while (1) {
		k_sem_take(&data->drdy_sem, K_FOREVER);
		process_drdy(data->dev);
	}
}
#endif

#ifdef CONFIG_HTS221_TRIGGER_GLOBAL_THREAD
static void hts221_work_cb(struct k_work *work)
{
	struct hts221_data *data =
		CONTAINER_OF(work, struct hts221_data, work);

	process_drdy(data->dev);
}
#endif

int hts221_init_interrupt(const struct device *dev)
{
	struct hts221_data *data = dev->data;
	const struct hts221_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	int status;

	if (cfg->gpio_drdy.port == NULL) {
		LOG_DBG("gpio_drdy not defined in DT");
		return 0;
	}

	if (!device_is_ready(cfg->gpio_drdy.port)) {
		LOG_ERR("device %s is not ready", cfg->gpio_drdy.port->name);
		return -ENODEV;
	}

	data->dev = dev;

	/* setup data ready gpio interrupt */
	status = gpio_pin_configure_dt(&cfg->gpio_drdy, GPIO_INPUT);
	if (status < 0) {
		LOG_ERR("Could not configure %s.%02u",
			cfg->gpio_drdy.port->name, cfg->gpio_drdy.pin);
		return status;
	}

	gpio_init_callback(&data->drdy_cb,
			   hts221_drdy_callback,
			   BIT(cfg->gpio_drdy.pin));

	status = gpio_add_callback(cfg->gpio_drdy.port, &data->drdy_cb);
	if (status < 0) {
		LOG_ERR("Could not set gpio callback.");
		return status;
	}

	/* enable data-ready interrupt */
	status = hts221_drdy_on_int_set(ctx, 1);
	if (status < 0) {
		LOG_ERR("Could not enable data-ready interrupt.");
		return status;
	}

#if defined(CONFIG_HTS221_TRIGGER_OWN_THREAD)
	k_sem_init(&data->drdy_sem, 0, K_SEM_MAX_LIMIT);

	k_thread_create(&data->thread, data->thread_stack,
			CONFIG_HTS221_THREAD_STACK_SIZE,
			(k_thread_entry_t)hts221_thread, data,
			NULL, NULL, K_PRIO_COOP(CONFIG_HTS221_THREAD_PRIORITY),
			0, K_NO_WAIT);
#elif defined(CONFIG_HTS221_TRIGGER_GLOBAL_THREAD)
	data->work.handler = hts221_work_cb;
#endif

	setup_drdy(dev, true);

	return 0;
}
