/*
 * Copyright (c) 2018 Linaro Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <device.h>
#include <gpio.h>
#include <i2c.h>
#include <kernel.h>
#include <misc/byteorder.h>
#include <misc/util.h>
#include <sensor.h>
#include <misc/__assert.h>
#include <logging/log.h>

#include "ccs811.h"

#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
LOG_MODULE_REGISTER(CCS811);

static int ccs811_sample_fetch(struct device *dev, enum sensor_channel chan)
{
	struct ccs811_data *drv_data = dev->driver_data;
	int tries = 11;
	u16_t buf[4];
	u8_t status;

	/* Check data ready flag for the measurement interval of 1 seconds */
	while (tries-- > 0) {
		if (i2c_reg_read_byte(drv_data->i2c, DT_AMS_CCS811_0_BASE_ADDRESS,
				      CCS811_REG_STATUS, &status) < 0) {
			LOG_ERR("Failed to read Status register");
			return -EIO;
		}

		if ((status & CCS811_STATUS_DATA_READY) || tries == 0) {
			break;
		}

		k_sleep(100);
	}

	if (!(status & CCS811_STATUS_DATA_READY)) {
		LOG_ERR("Sensor data not available");
		return -EIO;
	}

	if (i2c_burst_read(drv_data->i2c, DT_AMS_CCS811_0_BASE_ADDRESS,
			   CCS811_REG_ALG_RESULT_DATA, (u8_t *)buf, 8) < 0) {
		LOG_ERR("Failed to read conversion data.");
		return -EIO;
	}

	drv_data->co2 = sys_be16_to_cpu(buf[0]);
	drv_data->voc = sys_be16_to_cpu(buf[1]);
	drv_data->status = buf[2] & 0xff;
	drv_data->error = buf[2] >> 8;
	drv_data->resistance = sys_be16_to_cpu(buf[3]);

	return 0;
}

static int ccs811_channel_get(struct device *dev,
			       enum sensor_channel chan,
			       struct sensor_value *val)
{
	struct ccs811_data *drv_data = dev->driver_data;
	u32_t uval;

	switch (chan) {
	case SENSOR_CHAN_CO2:
		val->val1 = drv_data->co2;
		val->val2 = 0;

		break;
	case SENSOR_CHAN_VOC:
		val->val1 = drv_data->voc;
		val->val2 = 0;

		break;
	case SENSOR_CHAN_VOLTAGE:
		/*
		 * Raw ADC readings are contained in least significant 10 bits
		 */
		uval = (drv_data->resistance & CCS811_VOLTAGE_MASK)
					* CCS811_VOLTAGE_SCALE;
		val->val1 = uval / 1000000;
		val->val2 = uval % 1000000;

		break;
	case SENSOR_CHAN_CURRENT:
		/*
		 * Current readings are contained in most
		 * significant 6 bits in microAmps
		 */
		uval = drv_data->resistance >> 10;
		val->val1 = uval / 1000000;
		val->val2 = uval % 1000000;

		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static const struct sensor_driver_api ccs811_driver_api = {
	.sample_fetch = ccs811_sample_fetch,
	.channel_get = ccs811_channel_get,
};

static int switch_to_app_mode(struct device *i2c)
{
	u8_t status, buf;

	LOG_DBG("Switching to Application mode...");

	if (i2c_reg_read_byte(i2c, DT_AMS_CCS811_0_BASE_ADDRESS,
			      CCS811_REG_STATUS, &status) < 0) {
		LOG_ERR("Failed to read Status register");
		return -EIO;
	}

	/* Check for the application firmware */
	if (!(status & CCS811_STATUS_APP_VALID)) {
		LOG_ERR("No Application firmware loaded");
		return -EINVAL;
	}

	buf = CCS811_REG_APP_START;
	/* Set the device to application mode */
	if (i2c_write(i2c, &buf, 1, DT_AMS_CCS811_0_BASE_ADDRESS) < 0) {
		LOG_ERR("Failed to set Application mode");
		return -EIO;
	}

	if (i2c_reg_read_byte(i2c, DT_AMS_CCS811_0_BASE_ADDRESS,
			      CCS811_REG_STATUS, &status) < 0) {
		LOG_ERR("Failed to read Status register");
		return -EIO;
	}

	/* Check for application mode */
	if (!(status & CCS811_STATUS_FW_MODE)) {
		LOG_ERR("Failed to start Application firmware");
		return -EINVAL;
	}

	LOG_DBG("CCS811 Application firmware started!");

	return 0;
}

int ccs811_init(struct device *dev)
{
	struct ccs811_data *drv_data = dev->driver_data;
	int ret;
	u8_t hw_id, status;

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

#if defined(CONFIG_CCS811_GPIO_WAKEUP) || defined(CONFIG_CCS811_GPIO_RESET)
	drv_data->gpio = device_get_binding(CONFIG_CCS811_GPIO_DEV_NAME);
	if (drv_data->gpio == NULL) {
		LOG_ERR("Failed to get pointer to %s device!",
			    CONFIG_CCS811_GPIO_DEV_NAME);
		return -EINVAL;
	}
#endif

#ifdef CONFIG_CCS811_GPIO_RESET
	gpio_pin_configure(drv_data->gpio, CONFIG_CCS811_GPIO_RESET_PIN_NUM,
			   GPIO_DIR_OUT);
	gpio_pin_write(drv_data->gpio, CONFIG_CCS811_GPIO_RESET_PIN_NUM, 1);

	k_sleep(1);
#endif

	/*
	 * Wakeup pin should be pulled low before initiating any I2C transfer.
	 * If it has been tied to GND by default, skip this part.
	 */
#ifdef CONFIG_CCS811_GPIO_WAKEUP
	gpio_pin_configure(drv_data->gpio, CONFIG_CCS811_GPIO_WAKEUP_PIN_NUM,
			   GPIO_DIR_OUT);
	gpio_pin_write(drv_data->gpio, CONFIG_CCS811_GPIO_WAKEUP_PIN_NUM, 0);

	k_sleep(1);
#endif

	/* Switch device to application mode */
	ret = switch_to_app_mode(drv_data->i2c);
	if (ret) {
		return ret;
	}

	/* Check Hardware ID */
	if (i2c_reg_read_byte(drv_data->i2c, DT_AMS_CCS811_0_BASE_ADDRESS,
			      CCS811_REG_HW_ID, &hw_id) < 0) {
		LOG_ERR("Failed to read Hardware ID register");
		return -EIO;
	}

	if (hw_id != CCS881_HW_ID) {
		LOG_ERR("Hardware ID mismatch!");
		return -EINVAL;
	}

	/* Set Measurement mode for 1 second */
	if (i2c_reg_write_byte(drv_data->i2c, DT_AMS_CCS811_0_BASE_ADDRESS,
			       CCS811_REG_MEAS_MODE,
			       CCS811_MODE_IAQ_1SEC) < 0) {
		LOG_ERR("Failed to set Measurement mode");
		return -EIO;
	}

	/* Check for error */
	if (i2c_reg_read_byte(drv_data->i2c, DT_AMS_CCS811_0_BASE_ADDRESS,
			      CCS811_REG_STATUS, &status) < 0) {
		LOG_ERR("Failed to read Status register");
		return -EIO;
	}

	if (status & CCS811_STATUS_ERROR) {
		LOG_ERR("Error occurred during sensor configuration");
		return -EINVAL;
	}

	return 0;
}

static struct ccs811_data ccs811_driver;

DEVICE_AND_API_INIT(ccs811, DT_AMS_CCS811_0_LABEL, ccs811_init, &ccs811_driver,
		    NULL, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
		    &ccs811_driver_api);
