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

#define DT_DRV_COMPAT st_hts221

#include <zephyr/device.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#include <zephyr/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;
}
