/* lsm6ds0.c - Driver for LSM6DS0 accelerometer, gyroscope and
 * temperature sensor
 */

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

#include <sensor.h>
#include <kernel.h>
#include <device.h>
#include <init.h>
#include <misc/byteorder.h>
#include <misc/__assert.h>
#include <logging/log.h>

#include "lsm6ds0.h"

#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
LOG_MODULE_REGISTER(LSM6DS0);

static inline int lsm6ds0_reboot(struct device *dev)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;

	if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				LSM6DS0_REG_CTRL_REG8,
				LSM6DS0_MASK_CTRL_REG8_BOOT,
				1 << LSM6DS0_SHIFT_CTRL_REG8_BOOT) < 0) {
		return -EIO;
	}

	k_busy_wait(USEC_PER_MSEC * 50U);

	return 0;
}

static inline int lsm6ds0_accel_axis_ctrl(struct device *dev, int x_en,
					  int y_en, int z_en)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;
	u8_t state = (x_en << LSM6DS0_SHIFT_CTRL_REG5_XL_XEN_XL) |
			(y_en << LSM6DS0_SHIFT_CTRL_REG5_XL_YEN_XL) |
			(z_en << LSM6DS0_SHIFT_CTRL_REG5_XL_ZEN_XL);

	return i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				   LSM6DS0_REG_CTRL_REG5_XL,
				   LSM6DS0_MASK_CTRL_REG5_XL_XEN_XL |
				   LSM6DS0_MASK_CTRL_REG5_XL_YEN_XL |
				   LSM6DS0_MASK_CTRL_REG5_XL_ZEN_XL,
				   state);
}

static int lsm6ds0_accel_set_fs_raw(struct device *dev, u8_t fs)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;

	if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				LSM6DS0_REG_CTRL_REG6_XL,
				LSM6DS0_MASK_CTRL_REG6_XL_FS_XL,
				fs << LSM6DS0_SHIFT_CTRL_REG6_XL_FS_XL) < 0) {
		return -EIO;
	}

	return 0;
}

static int lsm6ds0_accel_set_odr_raw(struct device *dev, u8_t odr)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;

	if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				LSM6DS0_REG_CTRL_REG6_XL,
				LSM6DS0_MASK_CTRL_REG6_XL_ODR_XL,
				odr << LSM6DS0_SHIFT_CTRL_REG6_XL_ODR_XL) < 0) {
		return -EIO;
	}

	return 0;
}

static inline int lsm6ds0_gyro_axis_ctrl(struct device *dev, int x_en, int y_en,
					 int z_en)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;
	u8_t state = (x_en << LSM6DS0_SHIFT_CTRL_REG4_XEN_G) |
			(y_en << LSM6DS0_SHIFT_CTRL_REG4_YEN_G) |
			(z_en << LSM6DS0_SHIFT_CTRL_REG4_ZEN_G);

	return i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				   LSM6DS0_REG_CTRL_REG4,
				   LSM6DS0_MASK_CTRL_REG4_XEN_G |
				   LSM6DS0_MASK_CTRL_REG4_YEN_G |
				   LSM6DS0_MASK_CTRL_REG4_ZEN_G,
				   state);
}

static int lsm6ds0_gyro_set_fs_raw(struct device *dev, u8_t fs)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;

	if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				LSM6DS0_REG_CTRL_REG1_G,
				LSM6DS0_MASK_CTRL_REG1_G_FS_G,
				fs << LSM6DS0_SHIFT_CTRL_REG1_G_FS_G) < 0) {
		return -EIO;
	}

	return 0;
}

static int lsm6ds0_gyro_set_odr_raw(struct device *dev, u8_t odr)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;

	if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				LSM6DS0_REG_CTRL_REG1_G,
				LSM6DS0_MASK_CTRL_REG1_G_ODR_G,
				odr << LSM6DS0_SHIFT_CTRL_REG1_G_ODR_G) < 0) {
		return -EIO;
	}

	return 0;
}

static int lsm6ds0_sample_fetch_accel(struct device *dev)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;
	u8_t buf[6];

	if (i2c_burst_read(data->i2c_master, config->i2c_slave_addr,
			   LSM6DS0_REG_OUT_X_L_XL, buf, sizeof(buf)) < 0) {
		LOG_DBG("failed to read sample");
		return -EIO;
	}

#if defined(CONFIG_LSM6DS0_ACCEL_ENABLE_X_AXIS)
	data->accel_sample_x = (s16_t)((u16_t)(buf[0]) |
				((u16_t)(buf[1]) << 8));
#endif
#if defined(CONFIG_LSM6DS0_ACCEL_ENABLE_Y_AXIS)
	data->accel_sample_y = (s16_t)((u16_t)(buf[2]) |
				((u16_t)(buf[3]) << 8));
#endif
#if defined(CONFIG_LSM6DS0_ACCEL_ENABLE_Z_AXIS)
	data->accel_sample_z = (s16_t)((u16_t)(buf[4]) |
				((u16_t)(buf[5]) << 8));
#endif

	return 0;
}

static int lsm6ds0_sample_fetch_gyro(struct device *dev)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;
	u8_t buf[6];

	if (i2c_burst_read(data->i2c_master, config->i2c_slave_addr,
			   LSM6DS0_REG_OUT_X_L_G, buf, sizeof(buf)) < 0) {
		LOG_DBG("failed to read sample");
		return -EIO;
	}

#if defined(CONFIG_LSM6DS0_GYRO_ENABLE_X_AXIS)
	data->gyro_sample_x = (s16_t)((u16_t)(buf[0]) |
				((u16_t)(buf[1]) << 8));
#endif
#if defined(CONFIG_LSM6DS0_GYRO_ENABLE_Y_AXIS)
	data->gyro_sample_y = (s16_t)((u16_t)(buf[2]) |
				((u16_t)(buf[3]) << 8));
#endif
#if defined(CONFIG_LSM6DS0_GYRO_ENABLE_Z_AXIS)
	data->gyro_sample_z = (s16_t)((u16_t)(buf[4]) |
				((u16_t)(buf[5]) << 8));
#endif

	return 0;
}

#if defined(CONFIG_LSM6DS0_ENABLE_TEMP)
static int lsm6ds0_sample_fetch_temp(struct device *dev)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;
	u8_t buf[2];

	if (i2c_burst_read(data->i2c_master, config->i2c_slave_addr,
			   LSM6DS0_REG_OUT_TEMP_L, buf, sizeof(buf)) < 0) {
		LOG_DBG("failed to read sample");
		return -EIO;
	}

	data->temp_sample = (s16_t)((u16_t)(buf[0]) |
				((u16_t)(buf[1]) << 8));

	return 0;
}
#endif

static int lsm6ds0_sample_fetch(struct device *dev, enum sensor_channel chan)
{
	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL ||
			chan == SENSOR_CHAN_ACCEL_XYZ ||
#if defined(CONFIG_LSM6DS0_ENABLE_TEMP)
			chan == SENSOR_CHAN_DIE_TEMP ||
#endif
			chan == SENSOR_CHAN_GYRO_XYZ);

	switch (chan) {
	case SENSOR_CHAN_ACCEL_XYZ:
		lsm6ds0_sample_fetch_accel(dev);
		break;
	case SENSOR_CHAN_GYRO_XYZ:
		lsm6ds0_sample_fetch_gyro(dev);
		break;
#if defined(CONFIG_LSM6DS0_ENABLE_TEMP)
	case SENSOR_CHAN_DIE_TEMP:
		lsm6ds0_sample_fetch_temp(dev);
		break;
#endif
	case SENSOR_CHAN_ALL:
		lsm6ds0_sample_fetch_accel(dev);
		lsm6ds0_sample_fetch_gyro(dev);
#if defined(CONFIG_LSM6DS0_ENABLE_TEMP)
		lsm6ds0_sample_fetch_temp(dev);
#endif
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static inline void lsm6ds0_accel_convert(struct sensor_value *val, int raw_val,
					 float scale)
{
	double dval;

	dval = (double)(raw_val) * scale / 32767.0;
	val->val1 = (s32_t)dval;
	val->val2 = ((s32_t)(dval * 1000000)) % 1000000;
}

static inline int lsm6ds0_accel_get_channel(enum sensor_channel chan,
					    struct sensor_value *val,
					    struct lsm6ds0_data *data,
					    float scale)
{
	switch (chan) {
#if defined(CONFIG_LSM6DS0_ACCEL_ENABLE_X_AXIS)
	case SENSOR_CHAN_ACCEL_X:
		lsm6ds0_accel_convert(val, data->accel_sample_x, scale);
		break;
#endif
#if defined(CONFIG_LSM6DS0_ACCEL_ENABLE_Y_AXIS)
	case SENSOR_CHAN_ACCEL_Y:
		lsm6ds0_accel_convert(val, data->accel_sample_y, scale);
		break;
#endif
#if defined(CONFIG_LSM6DS0_ACCEL_ENABLE_Z_AXIS)
	case SENSOR_CHAN_ACCEL_Z:
		lsm6ds0_accel_convert(val, data->accel_sample_z, scale);
		break;
#endif
	case SENSOR_CHAN_ACCEL_XYZ:
#if defined(CONFIG_LSM6DS0_ACCEL_ENABLE_X_AXIS)
		lsm6ds0_accel_convert(val, data->accel_sample_x, scale);
#endif
#if defined(CONFIG_LSM6DS0_ACCEL_ENABLE_Y_AXIS)
		lsm6ds0_accel_convert(val + 1, data->accel_sample_y, scale);
#endif
#if defined(CONFIG_LSM6DS0_ACCEL_ENABLE_Z_AXIS)
		lsm6ds0_accel_convert(val + 2, data->accel_sample_z, scale);
#endif
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static int lsm6ds0_accel_channel_get(enum sensor_channel chan,
				     struct sensor_value *val,
				     struct lsm6ds0_data *data)
{
	return lsm6ds0_accel_get_channel(chan, val, data,
					LSM6DS0_DEFAULT_ACCEL_FULLSCALE_FACTOR);
}

static inline void lsm6ds0_gyro_convert(struct sensor_value *val, int raw_val,
					float numerator)
{
	double dval;

	dval = (double)(raw_val) * numerator / 1000.0 * SENSOR_DEG2RAD_DOUBLE;
	val->val1 = (s32_t)dval;
	val->val2 = ((s32_t)(dval * 1000000)) % 1000000;
}

static inline int lsm6ds0_gyro_get_channel(enum sensor_channel chan,
					   struct sensor_value *val,
					   struct lsm6ds0_data *data,
					   float numerator)
{
	switch (chan) {
#if defined(CONFIG_LSM6DS0_GYRO_ENABLE_X_AXIS)
	case SENSOR_CHAN_GYRO_X:
		lsm6ds0_gyro_convert(val, data->gyro_sample_x, numerator);
		break;
#endif
#if defined(CONFIG_LSM6DS0_GYRO_ENABLE_Y_AXIS)
	case SENSOR_CHAN_GYRO_Y:
		lsm6ds0_gyro_convert(val, data->gyro_sample_y, numerator);
		break;
#endif
#if defined(CONFIG_LSM6DS0_GYRO_ENABLE_Z_AXIS)
	case SENSOR_CHAN_GYRO_Z:
		lsm6ds0_gyro_convert(val, data->gyro_sample_z, numerator);
		break;
#endif
	case SENSOR_CHAN_GYRO_XYZ:
#if defined(CONFIG_LSM6DS0_GYRO_ENABLE_X_AXIS)
		lsm6ds0_gyro_convert(val, data->gyro_sample_x, numerator);
#endif
#if defined(CONFIG_LSM6DS0_GYRO_ENABLE_Y_AXIS)
		lsm6ds0_gyro_convert(val + 1, data->gyro_sample_y, numerator);
#endif
#if defined(CONFIG_LSM6DS0_GYRO_ENABLE_Z_AXIS)
		lsm6ds0_gyro_convert(val + 2, data->gyro_sample_z, numerator);
#endif
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static int lsm6ds0_gyro_channel_get(enum sensor_channel chan,
				    struct sensor_value *val,
				    struct lsm6ds0_data *data)
{
	return lsm6ds0_gyro_get_channel(chan, val, data,
					LSM6DS0_DEFAULT_GYRO_FULLSCALE_FACTOR);
}

#if defined(CONFIG_LSM6DS0_ENABLE_TEMP)
static void lsm6ds0_gyro_channel_get_temp(struct sensor_value *val,
					  struct lsm6ds0_data *data)
{
	/* val = temp_sample / 16 + 25 */
	val->val1 = data->temp_sample / 16 + 25;
	val->val2 = (data->temp_sample % 16) * (1000000 / 16);
}
#endif

static int lsm6ds0_channel_get(struct device *dev,
			       enum sensor_channel chan,
			       struct sensor_value *val)
{
	struct lsm6ds0_data *data = dev->driver_data;

	switch (chan) {
	case SENSOR_CHAN_ACCEL_X:
	case SENSOR_CHAN_ACCEL_Y:
	case SENSOR_CHAN_ACCEL_Z:
	case SENSOR_CHAN_ACCEL_XYZ:
		lsm6ds0_accel_channel_get(chan, val, data);
		break;
	case SENSOR_CHAN_GYRO_X:
	case SENSOR_CHAN_GYRO_Y:
	case SENSOR_CHAN_GYRO_Z:
	case SENSOR_CHAN_GYRO_XYZ:
		lsm6ds0_gyro_channel_get(chan, val, data);
		break;
#if defined(CONFIG_LSM6DS0_ENABLE_TEMP)
	case SENSOR_CHAN_DIE_TEMP:
		lsm6ds0_gyro_channel_get_temp(val, data);
		break;
#endif
	default:
		return -ENOTSUP;
	}

	return 0;
}

static const struct sensor_driver_api lsm6ds0_api_funcs = {
	.sample_fetch = lsm6ds0_sample_fetch,
	.channel_get = lsm6ds0_channel_get,
};

static int lsm6ds0_init_chip(struct device *dev)
{
	struct lsm6ds0_data *data = dev->driver_data;
	const struct lsm6ds0_config *config = dev->config->config_info;
	u8_t chip_id;

	if (lsm6ds0_reboot(dev) < 0) {
		LOG_DBG("failed to reboot device");
		return -EIO;
	}

	if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr,
			      LSM6DS0_REG_WHO_AM_I, &chip_id) < 0) {
		LOG_DBG("failed reading chip id");
		return -EIO;
	}
	if (chip_id != LSM6DS0_VAL_WHO_AM_I) {
		LOG_DBG("invalid chip id 0x%x", chip_id);
		return -EIO;
	}
	LOG_DBG("chip id 0x%x", chip_id);

	if (lsm6ds0_accel_axis_ctrl(dev, LSM6DS0_ACCEL_ENABLE_X_AXIS,
				    LSM6DS0_ACCEL_ENABLE_Y_AXIS,
				    LSM6DS0_ACCEL_ENABLE_Z_AXIS) < 0) {
		LOG_DBG("failed to set accelerometer axis");
		return -EIO;
	}

	if (lsm6ds0_accel_set_fs_raw(dev, LSM6DS0_DEFAULT_ACCEL_FULLSCALE)
				     < 0) {
		LOG_DBG("failed to set accelerometer full-scale");
		return -EIO;
	}

	if (lsm6ds0_accel_set_odr_raw(dev, LSM6DS0_DEFAULT_ACCEL_SAMPLING_RATE)
				      < 0) {
		LOG_DBG("failed to set accelerometer sampling rate");
		return -EIO;
	}

	if (lsm6ds0_gyro_axis_ctrl(dev, LSM6DS0_GYRO_ENABLE_X_AXIS,
				   LSM6DS0_GYRO_ENABLE_Y_AXIS,
				   LSM6DS0_GYRO_ENABLE_Z_AXIS) < 0) {
		LOG_DBG("failed to set gyroscope axis");
		return -EIO;
	}

	if (lsm6ds0_gyro_set_fs_raw(dev, LSM6DS0_DEFAULT_GYRO_FULLSCALE)
				    < 0) {
		LOG_DBG("failed to set gyroscope full-scale");
		return -EIO;
	}

	if (lsm6ds0_gyro_set_odr_raw(dev, LSM6DS0_DEFAULT_GYRO_SAMPLING_RATE)
				     < 0) {
		LOG_DBG("failed to set gyroscope sampling rate");
		return -EIO;
	}

	if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
				LSM6DS0_REG_CTRL_REG8,
				LSM6DS0_MASK_CTRL_REG8_BDU |
				LSM6DS0_MASK_CTRL_REG8_BLE |
				LSM6DS0_MASK_CTRL_REG8_IF_ADD_INC,
				(1 << LSM6DS0_SHIFT_CTRL_REG8_BDU) |
				(0 << LSM6DS0_SHIFT_CTRL_REG8_BLE) |
				(1 << LSM6DS0_SHIFT_CTRL_REG8_IF_ADD_INC))
				< 0) {
		LOG_DBG("failed to set BDU, BLE and burst");
		return -EIO;
	}

	return 0;
}

static int lsm6ds0_init(struct device *dev)
{
	const struct lsm6ds0_config * const config = dev->config->config_info;
	struct lsm6ds0_data *data = dev->driver_data;

	data->i2c_master = device_get_binding(config->i2c_master_dev_name);
	if (!data->i2c_master) {
		LOG_DBG("i2c master not found: %s",
			    config->i2c_master_dev_name);
		return -EINVAL;
	}

	if (lsm6ds0_init_chip(dev) < 0) {
		LOG_DBG("failed to initialize chip");
		return -EIO;
	}

	return 0;
}

static const struct lsm6ds0_config lsm6ds0_config = {
	.i2c_master_dev_name = DT_ST_LSM6DS0_0_BUS_NAME,
	.i2c_slave_addr = DT_ST_LSM6DS0_0_BASE_ADDRESS,
};

static struct lsm6ds0_data lsm6ds0_data;

DEVICE_AND_API_INIT(lsm6ds0, DT_ST_LSM6DS0_0_LABEL, lsm6ds0_init,
		    &lsm6ds0_data, &lsm6ds0_config, POST_KERNEL,
		    CONFIG_SENSOR_INIT_PRIORITY, &lsm6ds0_api_funcs);
