/*
 * Copyright (c) 2020 Richard Osterloh
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "vcnl4040.h"
#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(vcnl4040, CONFIG_SENSOR_LOG_LEVEL);

static void vcnl4040_handle_cb(struct vcnl4040_data *data)
{
	const struct vcnl4040_config *config = data->dev->config;

	gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_DISABLE);

#if defined(CONFIG_VCNL4040_TRIGGER_OWN_THREAD)
	k_sem_give(&data->trig_sem);
#elif defined(CONFIG_VCNL4040_TRIGGER_GLOBAL_THREAD)
	k_work_submit(&data->work);
#endif
}

static void vcnl4040_gpio_callback(const struct device *dev,
				   struct gpio_callback *cb,
				   uint32_t pin_mask)
{
	struct vcnl4040_data *data =
		CONTAINER_OF(cb, struct vcnl4040_data, gpio_cb);
	const struct vcnl4040_config *config = data->dev->config;

	if ((pin_mask & BIT(config->int_gpio.pin)) == 0U) {
		return;
	}

	vcnl4040_handle_cb(data);
}

static int vcnl4040_handle_proxy_int(const struct device *dev)
{
	struct vcnl4040_data *data = dev->data;
	struct sensor_trigger proxy_trig = {
		.type = SENSOR_TRIG_THRESHOLD,
		.chan = SENSOR_CHAN_PROX,
	};

	if (data->proxy_handler) {
		data->proxy_handler(dev, &proxy_trig);
	}

	return 0;
}

static int vcnl4040_handle_als_int(const struct device *dev)
{
	struct vcnl4040_data *data = dev->data;
	struct sensor_trigger als_trig = {
		.type = SENSOR_TRIG_THRESHOLD,
		.chan = SENSOR_CHAN_LIGHT,
	};

	if (data->als_handler) {
		data->als_handler(dev, &als_trig);
	}

	return 0;
}

static void vcnl4040_handle_int(const struct device *dev)
{
	const struct vcnl4040_config *config = dev->config;
	struct vcnl4040_data *data = dev->data;
	uint16_t int_source;

	k_sem_take(&data->sem, K_FOREVER);

	if (vcnl4040_read(dev, VCNL4040_REG_INT_FLAG, &int_source)) {
		LOG_ERR("Could not read interrupt source");
		int_source = 0U;
	}

	k_sem_give(&data->sem);

	data->int_type = int_source >> 8;

	if (data->int_type == VCNL4040_PROXIMITY_AWAY ||
	    data->int_type == VCNL4040_PROXIMITY_CLOSE) {
		vcnl4040_handle_proxy_int(dev);
	} else if (data->int_type == VCNL4040_AMBIENT_HIGH ||
		   data->int_type == VCNL4040_AMBIENT_LOW) {
		vcnl4040_handle_als_int(dev);
	} else {
		LOG_ERR("Unknown interrupt source %d", data->int_type);
	}

	gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE);
}

#ifdef CONFIG_VCNL4040_TRIGGER_OWN_THREAD
static void vcnl4040_thread_main(struct vcnl4040_data *data)
{
	while (true) {
		k_sem_take(&data->trig_sem, K_FOREVER);
		vcnl4040_handle_int(data->dev);
	}
}
#endif

#ifdef CONFIG_VCNL4040_TRIGGER_GLOBAL_THREAD
static void vcnl4040_work_handler(struct k_work *work)
{
	struct vcnl4040_data *data =
		CONTAINER_OF(work, struct vcnl4040_data, work);

	vcnl4040_handle_int(data->dev);
}
#endif

int vcnl4040_attr_set(const struct device *dev,
		      enum sensor_channel chan,
		      enum sensor_attribute attr,
		      const struct sensor_value *val)
{
	struct vcnl4040_data *data = dev->data;
	int ret = 0;

	k_sem_take(&data->sem, K_FOREVER);

	if (chan == SENSOR_CHAN_PROX) {
		if (attr == SENSOR_ATTR_UPPER_THRESH) {
			if (vcnl4040_write(dev, VCNL4040_REG_PS_THDH,
					   (uint16_t)val->val1)) {
				ret = -EIO;
				goto exit;
			}

			ret = 0;
			goto exit;
		}
		if (attr == SENSOR_ATTR_LOWER_THRESH) {
			if (vcnl4040_write(dev, VCNL4040_REG_PS_THDL,
					   (uint16_t)val->val1)) {
				ret = -EIO;
				goto exit;
			}

			ret = 0;
			goto exit;
		}
	}
#ifdef CONFIG_VCNL4040_ENABLE_ALS
	if (chan == SENSOR_CHAN_LIGHT) {
		if (attr == SENSOR_ATTR_UPPER_THRESH) {
			if (vcnl4040_write(dev, VCNL4040_REG_ALS_THDH,
					   (uint16_t)val->val1)) {
				ret = -EIO;
				goto exit;
			}

			ret = 0;
			goto exit;
		}
		if (attr == SENSOR_ATTR_LOWER_THRESH) {
			if (vcnl4040_write(dev, VCNL4040_REG_ALS_THDL,
					   (uint16_t)val->val1)) {
				ret = -EIO;
				goto exit;
			}

			ret = 0;
			goto exit;
		}
	}
#endif
	ret = -ENOTSUP;
exit:
	k_sem_give(&data->sem);

	return ret;
}

int vcnl4040_trigger_set(const struct device *dev,
			 const struct sensor_trigger *trig,
			 sensor_trigger_handler_t handler)
{
	const struct vcnl4040_config *config = dev->config;
	struct vcnl4040_data *data = dev->data;
	uint16_t conf;
	int ret = 0;

	if (!config->int_gpio.port) {
		return -ENOTSUP;
	}

	k_sem_take(&data->sem, K_FOREVER);

	switch (trig->type) {
	case SENSOR_TRIG_THRESHOLD:
		if (trig->chan == SENSOR_CHAN_PROX) {
			if (vcnl4040_read(dev, VCNL4040_REG_PS_CONF, &conf)) {
				ret = -EIO;
				goto exit;
			}

			/* Set interrupt bits 1:0 of high register */
			conf |= config->proxy_type << 8;

			if (vcnl4040_write(dev, VCNL4040_REG_PS_CONF, conf)) {
				ret = -EIO;
				goto exit;
			}

			data->proxy_handler = handler;
		} else if (trig->chan == SENSOR_CHAN_LIGHT) {
#ifdef CONFIG_VCNL4040_ENABLE_ALS
			if (vcnl4040_read(dev, VCNL4040_REG_ALS_CONF, &conf)) {
				ret = -EIO;
				goto exit;
			}

			/* Set interrupt enable bit 1 */
			conf |= 1 << 1;

			if (vcnl4040_write(dev, VCNL4040_REG_ALS_CONF, conf)) {
				ret = -EIO;
				goto exit;
			}

			data->als_handler = handler;
#else
			ret = -ENOTSUP;
			goto exit;
#endif
		} else {
			ret = -ENOTSUP;
			goto exit;
		}
		break;
	default:
		LOG_ERR("Unsupported sensor trigger");
		ret = -ENOTSUP;
		goto exit;
	}
exit:
	k_sem_give(&data->sem);

	return ret;
}

int vcnl4040_trigger_init(const struct device *dev)
{
	const struct vcnl4040_config *config = dev->config;
	struct vcnl4040_data *data = dev->data;

	data->dev = dev;

	/* dts doesn't have GPIO int pin set, so we dont support
	 * trigger mode for this instance
	 */
	if (!config->int_gpio.port) {
		return 0;
	}

	/* Get the GPIO device */
	if (!device_is_ready(config->int_gpio.port)) {
		LOG_ERR("%s: device %s is not ready", dev->name,
				config->int_gpio.port->name);
		return -ENODEV;
	}

#if defined(CONFIG_VCNL4040_TRIGGER_OWN_THREAD)
	k_sem_init(&data->trig_sem, 0, K_SEM_MAX_LIMIT);
	k_thread_create(&data->thread, data->thread_stack,
			CONFIG_VCNL4040_THREAD_STACK_SIZE,
			(k_thread_entry_t)vcnl4040_thread_main,
			data, NULL, NULL,
			K_PRIO_COOP(CONFIG_VCNL4040_THREAD_PRIORITY),
			0, K_NO_WAIT);
	k_thread_name_set(&data->thread, "VCNL4040 trigger");
#elif defined(CONFIG_VCNL4040_TRIGGER_GLOBAL_THREAD)
	data->work.handler = vcnl4040_work_handler;
#endif

	gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT);

	gpio_init_callback(&data->gpio_cb, vcnl4040_gpio_callback,
			   BIT(config->int_gpio.pin));

	if (gpio_add_callback(config->int_gpio.port, &data->gpio_cb) < 0) {
		LOG_DBG("Failed to set gpio callback!");
		return -EIO;
	}

	gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE);

	if (gpio_pin_get_dt(&config->int_gpio) > 0) {
		vcnl4040_handle_cb(data);
	}

	return 0;
}
