/*
 * Copyright (c) 2020, Laird Connectivity
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT honeywell_sm351lt

#include "sm351lt.h"

#include <zephyr/init.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/logging/log.h>
#include <stdio.h>
#include <zephyr/sys/util.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/sensor.h>
#include <string.h>

LOG_MODULE_REGISTER(SM351LT, CONFIG_SENSOR_LOG_LEVEL);

#if CONFIG_SM351LT_TRIGGER
static int sm351lt_trigger_set(const struct device *dev,
			       const struct sensor_trigger *trig,
			       sensor_trigger_handler_t handler)
{
	const struct sm351lt_config *const config = dev->config;
	struct sm351lt_data *data = dev->data;
	int ret = -ENOTSUP;

	if (trig->chan == SENSOR_CHAN_PROX) {
		data->changed_handler = handler;
		ret = gpio_pin_interrupt_configure(data->bus, config->gpio_pin,
						   (handler ? data->trigger_type
							    : GPIO_INT_DISABLE));

		if (ret < 0) {
			return ret;
		}

		if (handler) {
			ret = gpio_add_callback(data->bus, &data->gpio_cb);
		} else {
			ret = gpio_remove_callback(data->bus, &data->gpio_cb);
		}
	}

	return ret;
}

static void sm351lt_gpio_callback(const struct device *dev,
				  struct gpio_callback *cb, uint32_t pins)
{
	struct sm351lt_data *data =
		CONTAINER_OF(cb, struct sm351lt_data, gpio_cb);

#if defined(CONFIG_SM351LT_TRIGGER_OWN_THREAD)
	k_sem_give(&data->gpio_sem);
#elif defined(CONFIG_SM351LT_TRIGGER_GLOBAL_THREAD)
	k_work_submit(&data->work);
#endif
}

static void sm351lt_thread_cb(const struct device *dev)
{
	struct sm351lt_data *data = dev->data;

	struct sensor_trigger mag_trigger = {
		.type = SENSOR_TRIG_NEAR_FAR,
		.chan = SENSOR_CHAN_PROX,
	};

	if (likely(data->changed_handler != NULL)) {
		data->changed_handler(dev, &mag_trigger);
	}

	return;
}

#if defined(CONFIG_SM351LT_TRIGGER_OWN_THREAD)
static void sm351lt_thread(void *arg1, void *unused2, void *unused3)
{
	struct sm351lt_data *data = arg1;

	ARG_UNUSED(unused2);
	ARG_UNUSED(unused3);

	while (1) {
		k_sem_take(&data->gpio_sem, K_FOREVER);
		sm351lt_thread_cb(data->dev);
	}
}
#endif

#if defined(CONFIG_SM351LT_TRIGGER_GLOBAL_THREAD)
static void sm351lt_work_cb(struct k_work *work)
{
	struct sm351lt_data *data =
		CONTAINER_OF(work, struct sm351lt_data, work);

	sm351lt_thread_cb(data->dev);
}
#endif
#endif

static int sm351lt_sample_fetch(const struct device *dev,
				enum sensor_channel chan)
{
	const struct sm351lt_config *config = dev->config;
	struct sm351lt_data *data = dev->data;

	if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_PROX) {
		return -ENOTSUP;
	}

	data->sample_status = gpio_pin_get(data->bus, config->gpio_pin);

	return 0;
}

static int sm351lt_channel_get(const struct device *dev,
			       enum sensor_channel chan,
			       struct sensor_value *val)
{
	struct sm351lt_data *data = dev->data;

	if (chan == SENSOR_CHAN_PROX) {
		val->val1 = data->sample_status;
		val->val2 = 0;
	} else {
		return -ENOTSUP;
	}

	return 0;
}

#if CONFIG_SM351LT_TRIGGER
static int sm351lt_attr_set(const struct device *dev,
			    enum sensor_channel chan,
			    enum sensor_attribute attr,
			    const struct sensor_value *val)
{
	struct sm351lt_data *data = dev->data;

	if (chan == SENSOR_CHAN_PROX) {
		if (attr == SENSOR_ATTR_SM351LT_TRIGGER_TYPE) {
			/* Interrupt triggering type */
			data->trigger_type = val->val1;
		} else {
			return -ENOTSUP;
		}
	} else {
		return -ENOTSUP;
	}

	return 0;
}

static int sm351lt_attr_get(const struct device *dev,
			    enum sensor_channel chan,
			    enum sensor_attribute attr,
			    struct sensor_value *val)
{
	struct sm351lt_data *data = dev->data;

	if (chan == SENSOR_CHAN_PROX) {
		if (attr == SENSOR_ATTR_SM351LT_TRIGGER_TYPE) {
			/* Interrupt triggering type */
			val->val1 = data->trigger_type;
			val->val2 = 0;
		} else {
			return -ENOTSUP;
		}
	} else {
		return -ENOTSUP;
	}

	return 0;
}
#endif

static const struct sensor_driver_api sm351lt_api_funcs = {
	.sample_fetch = sm351lt_sample_fetch,
	.channel_get = sm351lt_channel_get,
#if CONFIG_SM351LT_TRIGGER
	.attr_set = sm351lt_attr_set,
	.attr_get = sm351lt_attr_get,
	.trigger_set = sm351lt_trigger_set,
#endif
};

static int sm351lt_init(const struct device *dev)
{
	const struct sm351lt_config *const config = dev->config;
	struct sm351lt_data *data = dev->data;
	uint32_t ret;

	data->bus = device_get_binding(config->bus_name);
	if (!data->bus) {
		LOG_ERR("gpio bus not found: %s", config->bus_name);
		return -ENODEV;
	}

	ret = gpio_pin_configure(data->bus, config->gpio_pin,
				 (config->gpio_flags | GPIO_INPUT));
	if (ret) {
		LOG_ERR("failed to configure gpio: %d", ret);
		return ret;
	}

#if defined(CONFIG_SM351LT_TRIGGER)
#if defined(CONFIG_SM351LT_TRIGGER_OWN_THREAD)
	data->dev = dev;

	k_sem_init(&data->gpio_sem, 0, K_SEM_MAX_LIMIT);

	k_thread_create(&data->thread, data->thread_stack,
			CONFIG_SM351LT_THREAD_STACK_SIZE,
			(k_thread_entry_t)sm351lt_thread, data, NULL,
			NULL, K_PRIO_COOP(CONFIG_SM351LT_THREAD_PRIORITY),
			0, K_NO_WAIT);

#if defined(CONFIG_THREAD_NAME) && defined(CONFIG_THREAD_MAX_NAME_LEN)
	/* Sets up thread name as the device name */
	k_thread_name_set(&data->thread, dev->name);
#endif

#elif defined(CONFIG_SM351LT_TRIGGER_GLOBAL_THREAD)
	data->work.handler = sm351lt_work_cb;
#endif

	data->trigger_type = GPIO_INT_DISABLE;

	ret = gpio_pin_interrupt_configure(data->bus, config->gpio_pin,
					   GPIO_INT_DISABLE);
	if (ret) {
		LOG_ERR("failed to configure gpio interrupt: %d", ret);
		return ret;
	}

	/* Setup callback struct but do not add it yet */
	gpio_init_callback(&data->gpio_cb, sm351lt_gpio_callback,
			   BIT(config->gpio_pin));
#endif

	return 0;
}

/* Instantiation macros for each individual device. */
#define SM351LT_DEFINE(inst)					     \
	static struct sm351lt_data sm351lt_data_##inst;		     \
	static const struct sm351lt_config sm351lt_config_##inst = { \
		.bus_name =   DT_INST_GPIO_LABEL(inst, gpios),	     \
		.gpio_pin =   DT_INST_GPIO_PIN(inst, gpios),	     \
		.gpio_flags = DT_INST_GPIO_FLAGS(inst, gpios),	     \
	};							     \
								     \
	DEVICE_DT_INST_DEFINE(inst,				     \
			    sm351lt_init,			     \
			    NULL,				     \
			    &sm351lt_data_##inst,		     \
			    &sm351lt_config_##inst,		     \
			    POST_KERNEL,			     \
			    CONFIG_SENSOR_INIT_PRIORITY,	     \
			    &sm351lt_api_funcs);


/* Main instantiation macro for every configured device in DTS. */
DT_INST_FOREACH_STATUS_OKAY(SM351LT_DEFINE)
