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

#define DT_DRV_COMPAT sensirion_sht3xd

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

#include "sht3xd.h"

LOG_MODULE_REGISTER(SHT3XD, CONFIG_SENSOR_LOG_LEVEL);

#ifdef CONFIG_SHT3XD_SINGLE_SHOT_MODE
static const uint16_t measure_cmd[3] = {
	0x2400, 0x240B, 0x2416
};
#endif
#ifdef CONFIG_SHT3XD_PERIODIC_MODE
static const uint16_t measure_cmd[5][3] = {
	{ 0x202F, 0x2024, 0x2032 },
	{ 0x212D, 0x2126, 0x2130 },
	{ 0x222B, 0x2220, 0x2236 },
	{ 0x2329, 0x2322, 0x2334 },
	{ 0x272A, 0x2721, 0x2737 }
};
#endif

static const int measure_wait[3] = {
	4000, 6000, 15000
};

/*
 * CRC algorithm parameters were taken from the
 * "Checksum Calculation" section of the datasheet.
 */
static uint8_t sht3xd_compute_crc(uint16_t value)
{
	uint8_t buf[2];

	sys_put_be16(value, buf);
	return crc8(buf, 2, 0x31, 0xFF, false);
}

int sht3xd_write_command(const struct device *dev, uint16_t cmd)
{
	const struct sht3xd_config *config = dev->config;
	uint8_t tx_buf[2];

	sys_put_be16(cmd, tx_buf);
	return i2c_write_dt(&config->bus, tx_buf, sizeof(tx_buf));
}

int sht3xd_write_reg(const struct device *dev, uint16_t cmd, uint16_t val)
{
	const struct sht3xd_config *config = dev->config;
	uint8_t tx_buf[5];

	sys_put_be16(cmd, &tx_buf[0]);
	sys_put_be16(val, &tx_buf[2]);
	tx_buf[4] = sht3xd_compute_crc(val);

	return i2c_write_dt(&config->bus, tx_buf, sizeof(tx_buf));
}

static int sht3xd_sample_fetch(const struct device *dev,
			       enum sensor_channel chan)
{
	const struct sht3xd_config *config = dev->config;
	struct sht3xd_data *data = dev->data;
	uint8_t rx_buf[6];
	uint16_t t_sample, rh_sample;

	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);

#ifdef CONFIG_SHT3XD_SINGLE_SHOT_MODE
	/* start single shot measurement */
	if (sht3xd_write_command(dev,
				 measure_cmd[SHT3XD_REPEATABILITY_IDX])
	    < 0) {
		LOG_DBG("Failed to set single shot measurement mode!");
		return -EIO;
	}
	k_sleep(K_MSEC(measure_wait[SHT3XD_REPEATABILITY_IDX] / USEC_PER_MSEC));

	if (i2c_read_dt(&config->bus, rx_buf, sizeof(rx_buf)) < 0) {
		LOG_DBG("Failed to read data sample!");
		return -EIO;
	}
#endif
#ifdef CONFIG_SHT3XD_PERIODIC_MODE
	uint8_t tx_buf[2];

	sys_put_be16(SHT3XD_CMD_FETCH, tx_buf);

	if (i2c_write_read_dt(&config->bus, tx_buf, sizeof(tx_buf),
			      rx_buf, sizeof(rx_buf)) < 0) {
		LOG_DBG("Failed to read data sample!");
		return -EIO;
	}
#endif

	t_sample = sys_get_be16(&rx_buf[0]);
	if (sht3xd_compute_crc(t_sample) != rx_buf[2]) {
		LOG_DBG("Received invalid temperature CRC!");
		return -EIO;
	}

	rh_sample = sys_get_be16(&rx_buf[3]);
	if (sht3xd_compute_crc(rh_sample) != rx_buf[5]) {
		LOG_DBG("Received invalid relative humidity CRC!");
		return -EIO;
	}

	data->t_sample = t_sample;
	data->rh_sample = rh_sample;

	return 0;
}

static int sht3xd_channel_get(const struct device *dev,
			      enum sensor_channel chan,
			      struct sensor_value *val)
{
	const struct sht3xd_data *data = dev->data;
	uint64_t tmp;

	/*
	 * See datasheet "Conversion of Signal Output" section
	 * for more details on processing sample data.
	 */
	if (chan == SENSOR_CHAN_AMBIENT_TEMP) {
		/* val = -45 + 175 * sample / (2^16 -1) */
		tmp = (uint64_t)data->t_sample * 175U;
		val->val1 = (int32_t)(tmp / 0xFFFF) - 45;
		val->val2 = ((tmp % 0xFFFF) * 1000000U) / 0xFFFF;
	} else if (chan == SENSOR_CHAN_HUMIDITY) {
		/* val = 100 * sample / (2^16 -1) */
		uint32_t tmp2 = (uint32_t)data->rh_sample * 100U;
		val->val1 = tmp2 / 0xFFFF;
		/* x * 100000 / 65536 == x * 15625 / 1024 */
		val->val2 = (tmp2 % 0xFFFF) * 15625U / 1024;
	} else {
		return -ENOTSUP;
	}

	return 0;
}

static const struct sensor_driver_api sht3xd_driver_api = {
#ifdef CONFIG_SHT3XD_TRIGGER
	.attr_set = sht3xd_attr_set,
	.trigger_set = sht3xd_trigger_set,
#endif
	.sample_fetch = sht3xd_sample_fetch,
	.channel_get = sht3xd_channel_get,
};

static int sht3xd_init(const struct device *dev)
{
	const struct sht3xd_config *cfg = dev->config;

	if (!device_is_ready(cfg->bus.bus)) {
		LOG_ERR("I2C bus %s is not ready!", cfg->bus.bus->name);
		return -EINVAL;
	}

	/* clear status register */
	if (sht3xd_write_command(dev, SHT3XD_CMD_CLEAR_STATUS) < 0) {
		LOG_DBG("Failed to clear status register!");
		return -EIO;
	}

	k_busy_wait(SHT3XD_CLEAR_STATUS_WAIT_USEC);

#ifdef CONFIG_SHT3XD_PERIODIC_MODE
	/* set periodic measurement mode */
	if (sht3xd_write_command(dev,
				 measure_cmd[SHT3XD_MPS_IDX][SHT3XD_REPEATABILITY_IDX])
	    < 0) {
		LOG_DBG("Failed to set measurement mode!");
		return -EIO;
	}

	k_busy_wait(measure_wait[SHT3XD_REPEATABILITY_IDX]);
#endif
#ifdef CONFIG_SHT3XD_TRIGGER
	struct sht3xd_data *data = dev->data;

	data->dev = dev;
	if (sht3xd_init_interrupt(dev) < 0) {
		LOG_DBG("Failed to initialize interrupt");
		return -EIO;
	}
#endif

	return 0;
}

#ifdef CONFIG_SHT3XD_TRIGGER
#define SHT3XD_TRIGGER_INIT(inst)						\
	.alert_gpio_name = DT_INST_GPIO_LABEL(inst, alert_gpios),		\
	.alert_pin = DT_INST_GPIO_PIN(inst, alert_gpios),			\
	.alert_flags = DT_INST_GPIO_FLAGS(inst, alert_gpios),
#else
#define SHT3XD_TRIGGER_INIT(inst)
#endif

#define SHT3XD_DEFINE(inst)							\
	struct sht3xd_data sht3xd0_data_##inst;					\
	static const struct sht3xd_config sht3xd0_cfg_##inst = {		\
		.bus = I2C_DT_SPEC_INST_GET(inst),				\
		SHT3XD_TRIGGER_INIT(inst)					\
	};									\
	DEVICE_DT_INST_DEFINE(inst, sht3xd_init, NULL,				\
		&sht3xd0_data_##inst, &sht3xd0_cfg_##inst,			\
		POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,			\
		&sht3xd_driver_api);

DT_INST_FOREACH_STATUS_OKAY(SHT3XD_DEFINE)
