/*
 * Copyright (c) 2023 Andreas Kilian
 * Copyright (c) 2024 Jeff Welder (Ellenby Technologies, Inc.)
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT vishay_veml7700

#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/byteorder.h>

#include <zephyr/drivers/sensor/veml7700.h>

LOG_MODULE_REGISTER(VEML7700, CONFIG_SENSOR_LOG_LEVEL);

/*
 * Bit mask to zero out all bits except 14 and 15.
 * Those two are used for the high and low threshold
 * interrupt flags in the ALS_INT register.
 */
#define VEML7700_ALS_INT_MASK (~BIT_MASK(14))

/*
 * 16-bit command register addresses
 */
#define VEML7700_CMDCODE_ALS_CONF 0x00
#define VEML7700_CMDCODE_ALS_WH	  0x01
#define VEML7700_CMDCODE_ALS_WL	  0x02
#define VEML7700_CMDCODE_PSM	  0x03
#define VEML7700_CMDCODE_ALS	  0x04
#define VEML7700_CMDCODE_WHITE	  0x05
#define VEML7700_CMDCODE_ALS_INT  0x06

/*
 * Devicetree psm-mode property value for "PSM disabled"
 */
#define VEML7700_PSM_DISABLED 0x00

/*
 * ALS integration time setting values.
 *
 * The enumerators of <tt>enum veml7700_als_it</tt> provide
 * indices into this array to get the related value for the
 * ALS_IT configuration bits.
 */
static const uint8_t veml7700_it_values[VEML7700_ALS_IT_ELEM_COUNT] = {
	0x0C, /* 25  - 0b1100 */
	0x08, /* 50  - 0b1000 */
	0x00, /* 100 - 0b0000 */
	0x01, /* 200 - 0b0001 */
	0x02, /* 400 - 0b0010 */
	0x03, /* 800 - 0b0011 */
};

/*
 * Resolution matrix for values to convert between data provided
 * by the sensor ("counts") and lux.
 *
 * These values depend on the current gain and integration time settings.
 * The enumerators of <tt>enum veml7700_als_gain</tt> and <tt>enum veml7700_als_it</tt>
 * are used for indices into this matrix.
 */
static const float veml7700_resolution[VEML7700_ALS_GAIN_ELEM_COUNT][VEML7700_ALS_IT_ELEM_COUNT] = {
	/* 25ms    50ms    100ms   200ms   400ms   800ms  Integration Time */
	{0.2304f, 0.1152f, 0.0576f, 0.0288f, 0.0144f, 0.0072f}, /* Gain 1 */
	{0.1152f, 0.0576f, 0.0288f, 0.0144f, 0.0072f, 0.0036f}, /* Gain 2 */
	{1.8432f, 0.9216f, 0.4608f, 0.2304f, 0.1152f, 0.0576f}, /* Gain 1/8 */
	{0.9216f, 0.4608f, 0.2304f, 0.1152f, 0.0576f, 0.0288f}, /* Gain 1/4 */
};

struct veml7700_config {
	struct i2c_dt_spec bus;
	uint8_t psm;
};

struct veml7700_data {
	uint8_t shut_down;
	enum veml7700_als_gain gain;
	enum veml7700_als_it it;
	enum veml7700_int_mode int_mode;
	uint16_t thresh_high;
	uint16_t thresh_low;
	uint16_t als_counts;
	uint32_t als_lux;
	uint16_t white_counts;
	uint32_t int_flags;
};

/**
 * @brief Waits for a specific amount of time which depends
 * on the current integration time setting.
 *
 * According to datasheet for a measurement to complete one has
 * to wait for at least the integration time. But tests showed
 * that a much longer wait time is needed. Simply adding 50 or
 * 100ms to the integration time is not enough so we doubled
 * the integration time to get our wait time.
 *
 * This function is only called if the sensor is used in "single shot"
 * measuring mode. In this mode the sensor measures on demand an
 * measurements take time depending on the configures integration time.
 * In continuous mode, activated by one of the power saving modes,
 * you can always use the last sample value and no waiting is required.
 *
 * For more information see the "Designing the VEML7700 Into an Application"
 * application notes about the power saving modes.
 */
static void veml7700_sleep_by_integration_time(const struct veml7700_data *data)
{
	switch (data->it) {
	case VEML7700_ALS_IT_25:
		k_msleep(50);
		break;
	case VEML7700_ALS_IT_50:
		k_msleep(100);
		break;
	case VEML7700_ALS_IT_100:
		k_msleep(200);
		break;
	case VEML7700_ALS_IT_200:
		k_msleep(400);
		break;
	case VEML7700_ALS_IT_400:
		k_msleep(800);
		break;
	case VEML7700_ALS_IT_800:
		k_msleep(1600);
		break;
	}
}

static uint32_t veml7700_counts_to_lux(const struct veml7700_data *data,
				       uint16_t counts)
{
	return counts * veml7700_resolution[data->gain][data->it];
}

static uint16_t veml7700_lux_to_counts(const struct veml7700_data *data,
				       uint32_t lux)
{
	return lux / veml7700_resolution[data->gain][data->it];
}

static int veml7700_check_gain(const struct sensor_value *val)
{
	return val->val1 >= VEML7700_ALS_GAIN_1
	       && val->val1 <= VEML7700_ALS_GAIN_1_4;
}

static int veml7700_check_it(const struct sensor_value *val)
{
	return val->val1 >= VEML7700_ALS_IT_25
	       && val->val1 <= VEML7700_ALS_IT_800;
}

static int veml7700_check_int_mode(const struct sensor_value *val)
{
	return (val->val1 >= VEML7700_ALS_PERS_1
		&& val->val1 <= VEML7700_ALS_PERS_8)
	       || val->val1 == VEML7700_INT_DISABLED;
}

static uint16_t veml7700_build_als_conf_param(const struct veml7700_data *data)
{
	uint16_t param = 0;
	/* Bits 15:13 -> reserved */
	/* Bits 12:11 -> gain selection (ALS_GAIN) */
	param |= data->gain << 11;
	/* Bit 10 -> reserved */
	/* Bits 9:6 -> integration time (ALS_IT) */
	param |= veml7700_it_values[data->it] << 6;
	/* Bits 5:4 -> interrupt persistent protection (ALS_PERS) */
	if (data->int_mode != VEML7700_INT_DISABLED) {
		param |= data->int_mode << 4;
		/* Bit 1 -> interrupt enable (ALS_INT_EN) */
		param |= BIT(1);
	}
	/* Bits 3:2 -> reserved */
	/* Bit 0 -> shut down setting (ALS_SD) */
	if (data->shut_down) {
		param |= BIT(0);
	}
	return param;
}

static uint16_t veml7700_build_psm_param(const struct veml7700_config *conf)
{
	/* We can directly use the devicetree configuration value. */
	return conf->psm;
}

static int veml7700_write(const struct device *dev, uint8_t cmd, uint16_t data)
{
	const struct veml7700_config *conf = dev->config;
	uint8_t send_buf[3];

	send_buf[0] = cmd; /* byte 0: command code */
	sys_put_le16(data, &send_buf[1]); /* bytes 1,2: command arguments */

	return i2c_write_dt(&conf->bus, send_buf, ARRAY_SIZE(send_buf));
}

static int veml7700_read(const struct device *dev, uint8_t cmd, uint16_t *data)
{
	const struct veml7700_config *conf = dev->config;

	uint8_t recv_buf[2];
	int ret = i2c_write_read_dt(&conf->bus,
				    &cmd,
				    sizeof(cmd),
				    &recv_buf,
				    ARRAY_SIZE(recv_buf));
	if (ret < 0) {
		return ret;
	}

	*data = sys_get_le16(recv_buf);

	return 0;
}

static int veml7700_write_als_conf(const struct device *dev)
{
	const struct veml7700_data *data = dev->data;
	uint16_t param;

	param = veml7700_build_als_conf_param(data);
	LOG_DBG("Writing ALS configuration: 0x%04x", param);
	return veml7700_write(dev, VEML7700_CMDCODE_ALS_CONF, param);
}

static int veml7700_write_psm(const struct device *dev)
{
	const struct veml7700_config *conf = dev->config;
	uint16_t psm_param;

	psm_param = veml7700_build_psm_param(conf);
	LOG_DBG("Writing PSM configuration: 0x%04x", psm_param);
	return veml7700_write(dev, VEML7700_CMDCODE_PSM, psm_param);
}

static int veml7700_write_thresh_low(const struct device *dev)
{
	const struct veml7700_data *data = dev->data;

	LOG_DBG("Writing low threshold counts: %d", data->thresh_low);
	return veml7700_write(dev, VEML7700_CMDCODE_ALS_WL, data->thresh_low);
}

static int veml7700_write_thresh_high(const struct device *dev)
{
	const struct veml7700_data *data = dev->data;

	LOG_DBG("Writing high threshold counts: %d", data->thresh_high);
	return veml7700_write(dev, VEML7700_CMDCODE_ALS_WH, data->thresh_high);
}

static int veml7700_set_shutdown_flag(const struct device *dev, uint8_t new_val)
{
	struct veml7700_data *data = dev->data;
	uint8_t prev_sd;
	int ret;

	prev_sd = data->shut_down;
	data->shut_down = new_val;

	ret = veml7700_write_als_conf(dev);
	if (ret < 0) {
		data->shut_down = prev_sd;
	}
	return ret;
}

static int veml7700_fetch_als(const struct device *dev)
{
	struct veml7700_data *data = dev->data;
	uint16_t counts;
	int ret;

	ret = veml7700_read(dev, VEML7700_CMDCODE_ALS, &counts);
	if (ret < 0) {
		return ret;
	}

	data->als_counts = counts;
	data->als_lux = veml7700_counts_to_lux(data, counts);
	LOG_DBG("Read ALS measurement: counts=%d, lux=%d", data->als_counts, data->als_lux);

	return 0;
}

static int veml7700_fetch_white(const struct device *dev)
{
	struct veml7700_data *data = dev->data;
	uint16_t counts;
	int ret;

	ret = veml7700_read(dev, VEML7700_CMDCODE_WHITE, &counts);
	if (ret < 0) {
		return ret;
	}

	data->white_counts = counts;
	LOG_DBG("Read White Light measurement: counts=%d", data->white_counts);

	return 0;
}

static int veml7700_fetch_int_flags(const struct device *dev)
{
	struct veml7700_data *data = dev->data;
	uint16_t int_flags = 0;
	int ret;

	ret = veml7700_read(dev, VEML7700_CMDCODE_ALS_INT, &int_flags);
	if (ret < 0) {
		return ret;
	}

	data->int_flags = int_flags & VEML7700_ALS_INT_MASK;
	LOG_DBG("Read int state: 0x%02x", data->int_flags);

	return 0;
}

static int veml7700_attr_set(const struct device *dev,
			     enum sensor_channel chan,
			     enum sensor_attribute attr,
			     const struct sensor_value *val)
{
	if (chan != SENSOR_CHAN_LIGHT) {
		return -ENOTSUP;
	}

	struct veml7700_data *data = dev->data;

	if (attr == SENSOR_ATTR_LOWER_THRESH) {
		data->thresh_low = veml7700_lux_to_counts(data, val->val1);
		return veml7700_write_thresh_low(dev);
	} else if (attr == SENSOR_ATTR_UPPER_THRESH) {
		data->thresh_high = veml7700_lux_to_counts(data, val->val1);
		return veml7700_write_thresh_high(dev);
	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_GAIN) {
		if (veml7700_check_gain(val)) {
			data->gain = (enum veml7700_als_gain)val->val1;
			return veml7700_write_als_conf(dev);
		} else {
			return -EINVAL;
		}
	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_ITIME) {
		if (veml7700_check_it(val)) {
			data->it = (enum veml7700_als_it)val->val1;
			return veml7700_write_als_conf(dev);
		} else {
			return -EINVAL;
		}
	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_INT_MODE) {
		if (veml7700_check_int_mode(val)) {
			data->int_mode = (enum veml7700_int_mode)val->val1;
			return veml7700_write_als_conf(dev);
		} else {
			return -EINVAL;
		}
	} else {
		return -ENOTSUP;
	}
}

static int veml7700_attr_get(const struct device *dev,
			     enum sensor_channel chan,
			     enum sensor_attribute attr,
			     struct sensor_value *val)
{
	if (chan != SENSOR_CHAN_LIGHT) {
		return -ENOTSUP;
	}

	struct veml7700_data *data = dev->data;

	if (attr == SENSOR_ATTR_LOWER_THRESH) {
		val->val1 = data->thresh_low;
	} else if (attr == SENSOR_ATTR_UPPER_THRESH) {
		val->val1 = data->thresh_high;
	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_GAIN) {
		val->val1 = data->gain;
	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_ITIME) {
		val->val1 = data->it;
	} else if ((enum sensor_attribute_veml7700)attr == SENSOR_ATTR_VEML7700_INT_MODE) {
		val->val1 = data->int_mode;
	} else {
		return -ENOTSUP;
	}

	val->val2 = 0;

	return 0;
}

static int veml7700_perform_single_measurement(const struct device *dev)
{
	struct veml7700_data *data = dev->data;
	int ret;

	/* Start sensor */
	ret = veml7700_set_shutdown_flag(dev, 0);
	if (ret < 0) {
		return ret;
	}

	/* Wait for sensor to finish it's startup sequence */
	k_msleep(5);
	/* Wait for measurement to complete */
	veml7700_sleep_by_integration_time(data);

	/* Shut down sensor */
	return veml7700_set_shutdown_flag(dev, 1);
}

static int veml7700_sample_fetch(const struct device *dev,
				 enum sensor_channel chan)
{
	const struct veml7700_config *conf = dev->config;
	struct veml7700_data *data;
	int ret;

	/* Start sensor for new measurement if power saving mode is disabled */
	if ((chan == SENSOR_CHAN_LIGHT || chan == SENSOR_CHAN_ALL)
	    && conf->psm == VEML7700_PSM_DISABLED) {
		ret = veml7700_perform_single_measurement(dev);
		if (ret < 0) {
			return ret;
		}
	}

	if (chan == SENSOR_CHAN_LIGHT) {
		return veml7700_fetch_als(dev);
	} else if ((enum sensor_channel_veml7700)chan == SENSOR_CHAN_VEML7700_INTERRUPT) {
		data = dev->data;
		if (data->int_mode != VEML7700_INT_DISABLED) {
			return veml7700_fetch_int_flags(dev);
		} else {
			return -ENOTSUP;
		}
	} else if ((enum sensor_channel_veml7700)chan == SENSOR_CHAN_VEML7700_WHITE_RAW_COUNTS) {
		return veml7700_fetch_white(dev);
	} else if (chan == SENSOR_CHAN_ALL) {
		data = dev->data;
		if (data->int_mode != VEML7700_INT_DISABLED) {
			ret = veml7700_fetch_int_flags(dev);
			if (ret < 0) {
				return ret;
			}
		}
		ret = veml7700_fetch_white(dev);
		if (ret < 0) {
			return ret;
		}
		return veml7700_fetch_als(dev);
	} else {
		return -ENOTSUP;
	}
}

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

	if (chan == SENSOR_CHAN_LIGHT) {
		val->val1 = data->als_lux;
	} else if ((enum sensor_channel_veml7700)chan == SENSOR_CHAN_VEML7700_RAW_COUNTS) {
		val->val1 = data->als_counts;
	} else if ((enum sensor_channel_veml7700)chan == SENSOR_CHAN_VEML7700_WHITE_RAW_COUNTS) {
		val->val1 = data->white_counts;
	} else if ((enum sensor_channel_veml7700)chan == SENSOR_CHAN_VEML7700_INTERRUPT) {
		val->val1 = data->int_flags;
	} else {
		return -ENOTSUP;
	}

	val->val2 = 0;

	return 0;
}

#ifdef CONFIG_PM_DEVICE

static int veml7700_pm_action(const struct device *dev,
			      enum pm_device_action action)
{
	const struct veml7700_config *conf = dev->config;

	if (conf->psm != VEML7700_PSM_DISABLED) {
		switch (action) {
		case PM_DEVICE_ACTION_SUSPEND:
			return veml7700_set_shutdown_flag(dev, 1);

		case PM_DEVICE_ACTION_RESUME:
			return veml7700_set_shutdown_flag(dev, 0);

		default:
			return -ENOTSUP;
		}
	}

	return 0;
}

#endif /* CONFIG_PM_DEVICE */

static int veml7700_init(const struct device *dev)
{
	const struct veml7700_config *conf = dev->config;
	struct veml7700_data *data = dev->data;
	int ret;

	if (!i2c_is_ready_dt(&conf->bus)) {
		LOG_ERR("Device not ready");
		return -ENODEV;
	}

	/* Initialize power saving mode */
	ret = veml7700_write_psm(dev);
	if (ret < 0) {
		return ret;
	}

	/* Set initial data values */
	data->thresh_low = 0;
	data->thresh_high = 0xFFFF;
	data->gain = VEML7700_ALS_GAIN_1_4;
	data->it = VEML7700_ALS_IT_100;
	data->int_mode = VEML7700_INT_DISABLED;
	data->als_counts = 0;
	data->als_lux = 0;
	data->white_counts = 0;
	data->shut_down = (conf->psm != VEML7700_PSM_DISABLED) ? 0 : 1;

	/* Initialize sensor configuration */
	ret = veml7700_write_thresh_low(dev);
	if (ret < 0) {
		return ret;
	}

	ret = veml7700_write_thresh_high(dev);
	if (ret < 0) {
		return ret;
	}

	ret = veml7700_write_als_conf(dev);
	if (ret < 0) {
		return ret;
	}

	return 0;
}

static const struct sensor_driver_api veml7700_api = {
	.sample_fetch = veml7700_sample_fetch,
	.channel_get = veml7700_channel_get,
	.attr_set = veml7700_attr_set,
	.attr_get = veml7700_attr_get
};

#define VEML7700_INIT(n)                                                    \
	static struct veml7700_data veml7700_data_##n;                      \
									    \
	static const struct veml7700_config veml7700_config_##n = {         \
		.bus = I2C_DT_SPEC_INST_GET(n),                             \
		.psm = DT_INST_PROP(n, psm_mode)                            \
	};                                                                  \
                                                                            \
	PM_DEVICE_DT_INST_DEFINE(n, veml7700_pm_action);                    \
                                                                            \
	SENSOR_DEVICE_DT_INST_DEFINE(n,                                     \
				     veml7700_init,                         \
				     PM_DEVICE_DT_INST_GET(n),              \
				     &veml7700_data_##n,                    \
				     &veml7700_config_##n,                  \
				     POST_KERNEL,                           \
				     CONFIG_SENSOR_INIT_PRIORITY,           \
				     &veml7700_api);

DT_INST_FOREACH_STATUS_OKAY(VEML7700_INIT)
