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

#include <device.h>
#include <i2c.h>
#include <kernel.h>
#include <sensor.h>
#include <misc/__assert.h>

#include "sht3xd.h"

/*
 * CRC algorithm parameters were taken from the
 * "Checksum Calculation" section of the datasheet.
 */
static u8_t sht3xd_compute_crc(u16_t value)
{
	u8_t buf[2] = {value >> 8, value & 0xFF};
	u8_t crc = 0xFF;
	u8_t polynom = 0x31;
	int i, j;

	for (i = 0; i < 2; ++i) {
		crc  = crc ^ buf[i];
		for (j = 0; j < 8; ++j) {
			if (crc & 0x80) {
				crc = (crc << 1) ^ polynom;
			} else {
				crc = crc << 1;
			}
		}
	}

	return crc;
}

int sht3xd_write_command(struct sht3xd_data *drv_data, u16_t cmd)
{
	u8_t tx_buf[2] = {cmd >> 8, cmd & 0xFF};

	return i2c_write(drv_data->i2c, tx_buf, sizeof(tx_buf),
			 SHT3XD_I2C_ADDRESS);
}

int sht3xd_write_reg(struct sht3xd_data *drv_data, u16_t cmd,
		     u16_t val)
{
	u8_t tx_buf[5];

	tx_buf[0] = cmd >> 8;
	tx_buf[1] = cmd & 0xFF;
	tx_buf[2] = val >> 8;
	tx_buf[3] = val & 0xFF;
	tx_buf[4] = sht3xd_compute_crc(val);

	return i2c_write(drv_data->i2c, tx_buf, sizeof(tx_buf),
			 SHT3XD_I2C_ADDRESS);
}

static int sht3xd_sample_fetch(struct device *dev, enum sensor_channel chan)
{
	struct sht3xd_data *drv_data = dev->driver_data;
	u8_t rx_buf[6];
	u16_t t_sample, rh_sample;

	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);

	u8_t tx_buf[2] = {
		SHT3XD_CMD_FETCH >> 8,
		SHT3XD_CMD_FETCH & 0xFF
	};

	struct i2c_msg msgs[2] = {
		{
			.buf = tx_buf,
			.len = sizeof(tx_buf),
			.flags = I2C_MSG_WRITE | I2C_MSG_RESTART,
		},
		{
			.buf = rx_buf,
			.len = sizeof(rx_buf),
			.flags = I2C_MSG_READ | I2C_MSG_STOP,
		},
	};

	if (i2c_transfer(drv_data->i2c, msgs, 2, SHT3XD_I2C_ADDRESS) < 0) {
		SYS_LOG_DBG("Failed to read data sample!");
		return -EIO;
	}

	t_sample = (rx_buf[0] << 8) | rx_buf[1];
	if (sht3xd_compute_crc(t_sample) != rx_buf[2]) {
		SYS_LOG_DBG("Received invalid temperature CRC!");
		return -EIO;
	}

	rh_sample = (rx_buf[3] << 8) | rx_buf[4];
	if (sht3xd_compute_crc(rh_sample) != rx_buf[5]) {
		SYS_LOG_DBG("Received invalid relative humidity CRC!");
		return -EIO;
	}

	drv_data->t_sample = t_sample;
	drv_data->rh_sample = rh_sample;

	return 0;
}

static int sht3xd_channel_get(struct device *dev,
			      enum sensor_channel chan,
			      struct sensor_value *val)
{
	struct sht3xd_data *drv_data = dev->driver_data;
	u64_t tmp;

	/*
	 * See datasheet "Conversion of Signal Output" section
	 * for more details on processing sample data.
	 */
	if (chan == SENSOR_CHAN_TEMP) {
		/* val = -45 + 175 * sample / (2^16 -1) */
		tmp = 175 * (u64_t)drv_data->t_sample;
		val->val1 = (s32_t)(tmp / 0xFFFF) - 45;
		val->val2 = (1000000 * (tmp % 0xFFFF)) / 0xFFFF;
	} else if (chan == SENSOR_CHAN_HUMIDITY) {
		/* val = 100000 * sample / (2^16 -1) */
		tmp = 100000 * (u64_t)drv_data->rh_sample;
		val->val1 = tmp / 0xFFFF;
		val->val2 = (1000000 * (tmp % 0xFFFF)) / 0xFFFF;
	} 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(struct device *dev)
{
	struct sht3xd_data *drv_data = dev->driver_data;

	drv_data->i2c = device_get_binding(CONFIG_SHT3XD_I2C_MASTER_DEV_NAME);
	if (drv_data->i2c == NULL) {
		SYS_LOG_DBG("Failed to get pointer to %s device!",
		    CONFIG_SHT3XD_I2C_MASTER_DEV_NAME);
		return -EINVAL;
	}

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

	k_busy_wait(SHT3XD_CLEAR_STATUS_WAIT_USEC);

	/* set periodic measurement mode */
	if (sht3xd_write_command(drv_data,
		sht3xd_measure_cmd[SHT3XD_MPS_IDX][SHT3XD_REPEATABILITY_IDX])
		< 0) {
		SYS_LOG_DBG("Failed to set measurement mode!");
		return -EIO;
	}

	k_busy_wait(sht3xd_measure_wait[SHT3XD_REPEATABILITY_IDX]);

#ifdef CONFIG_SHT3XD_TRIGGER
	if (sht3xd_init_interrupt(dev) < 0) {
		SYS_LOG_DBG("Failed to initialize interrupt");
		return -EIO;
	}
#endif

	dev->driver_api = &sht3xd_driver_api;

	return 0;
}

struct sht3xd_data sht3xd_driver;

DEVICE_INIT(sht3xd, CONFIG_SHT3XD_NAME, sht3xd_init, &sht3xd_driver,
	    NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY);
