/* ST Microelectronics IIS2DH 3-axis accelerometer driver
 *
 * Copyright (c) 2020 STMicroelectronics
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Datasheet:
 * https://www.st.com/resource/en/datasheet/iis2dh.pdf
 */

#define DT_DRV_COMPAT st_iis2dh

#include <init.h>
#include <sys/__assert.h>
#include <sys/byteorder.h>
#include <logging/log.h>
#include <drivers/sensor.h>

#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
#include <drivers/spi.h>
#elif DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
#include <drivers/i2c.h>
#endif

#include "iis2dh.h"

LOG_MODULE_REGISTER(IIS2DH, CONFIG_SENSOR_LOG_LEVEL);

/* gains in uG/LSB */
static const uint32_t iis2dh_gain[3][4] = {
	{
		/* HR mode */
		980/16,		/* 2G */
		1950/16,	/* 4G */
		3910/16,	/* 8G */
		11720/16,	/* 16G */
	},
	{
		/* NM mode */
		3910/64,	/* 2G */
		7810/64,	/* 4G */
		15630/64,	/* 8G */
		46950/64,	/* 16G */
	},
	{
		/* LP mode */
		15630/256,	/* 2G */
		31250/256,	/* 4G */
		62500/256,	/* 8G */
		188680/256,	/* 16G */
	},
};

static int iis2dh_set_fs_raw(struct iis2dh_data *iis2dh, uint8_t fs)
{
	int err;

	err = iis2dh_full_scale_set(iis2dh->ctx, fs);

	if (!err) {
		/* save internally gain for optimization */
		iis2dh->gain = iis2dh_gain[IIS2DH_HR_12bit][fs];
	}

	return err;
}

#if (CONFIG_IIS2DH_RANGE == 0)
/**
 * iis2dh_set_range - set full scale range for acc
 * @dev: Pointer to instance of struct device (I2C or SPI)
 * @range: Full scale range (2, 4, 8 and 16 G)
 */
static int iis2dh_set_range(const struct device *dev, uint16_t range)
{
	int err;
	struct iis2dh_data *iis2dh = dev->data;
	uint8_t fs = IIS2DH_FS_TO_REG(range);

	err = iis2dh_set_fs_raw(iis2dh, fs);

	return err;
}
#endif

#if (CONFIG_IIS2DH_ODR == 0)
/**
 * iis2dh_set_odr - set new sampling frequency
 * @dev: Pointer to instance of struct device (I2C or SPI)
 * @odr: Output data rate
 */
static int iis2dh_set_odr(const struct device *dev, uint16_t odr)
{
	struct iis2dh_data *iis2dh = dev->data;
	const struct iis2dh_device_config *cfg = dev->config;
	iis2dh_odr_t val;

	val = IIS2DH_ODR_TO_REG_HR(cfg->pm, odr);

	return iis2dh_data_rate_set(iis2dh->ctx, val);
}
#endif

static inline void iis2dh_convert(struct sensor_value *val, int raw_val,
				  uint32_t gain)
{
	int64_t dval;

	/* Gain is in ug/LSB */
	/* Convert to m/s^2 */
	dval = ((int64_t)raw_val * gain * SENSOR_G) / 1000000LL;
	val->val1 = dval / 1000000LL;
	val->val2 = dval % 1000000LL;
}

static inline void iis2dh_channel_get_acc(const struct device *dev,
					  enum sensor_channel chan,
					  struct sensor_value *val)
{
	int i;
	uint8_t ofs_start, ofs_stop;
	struct iis2dh_data *iis2dh = dev->data;
	struct sensor_value *pval = val;

	switch (chan) {
	case SENSOR_CHAN_ACCEL_X:
		ofs_start = ofs_stop = 0U;
		break;
	case SENSOR_CHAN_ACCEL_Y:
		ofs_start = ofs_stop = 1U;
		break;
	case SENSOR_CHAN_ACCEL_Z:
		ofs_start = ofs_stop = 2U;
		break;
	default:
		ofs_start = 0U; ofs_stop = 2U;
		break;
	}

	for (i = ofs_start; i <= ofs_stop ; i++) {
		iis2dh_convert(pval++, iis2dh->acc[i], iis2dh->gain);
	}
}

static int iis2dh_channel_get(const struct device *dev,
			      enum sensor_channel chan,
			      struct sensor_value *val)
{
	switch (chan) {
	case SENSOR_CHAN_ACCEL_X:
	case SENSOR_CHAN_ACCEL_Y:
	case SENSOR_CHAN_ACCEL_Z:
	case SENSOR_CHAN_ACCEL_XYZ:
		iis2dh_channel_get_acc(dev, chan, val);
		return 0;
	default:
		LOG_DBG("Channel not supported");
		break;
	}

	return -ENOTSUP;
}

static int iis2dh_config(const struct device *dev, enum sensor_channel chan,
			 enum sensor_attribute attr,
			 const struct sensor_value *val)
{
	switch (attr) {
#if (CONFIG_IIS2DH_RANGE == 0)
	case SENSOR_ATTR_FULL_SCALE:
		return iis2dh_set_range(dev, sensor_ms2_to_g(val));
#endif
#if (CONFIG_IIS2DH_ODR == 0)
	case SENSOR_ATTR_SAMPLING_FREQUENCY:
		return iis2dh_set_odr(dev, val->val1);
#endif
	default:
		LOG_DBG("Acc attribute not supported");
		break;
	}

	return -ENOTSUP;
}

static int iis2dh_attr_set(const struct device *dev, enum sensor_channel chan,
			   enum sensor_attribute attr,
			   const struct sensor_value *val)
{
	switch (chan) {
	case SENSOR_CHAN_ACCEL_X:
	case SENSOR_CHAN_ACCEL_Y:
	case SENSOR_CHAN_ACCEL_Z:
	case SENSOR_CHAN_ACCEL_XYZ:
		return iis2dh_config(dev, chan, attr, val);
	default:
		LOG_DBG("Attr not supported on %d channel", chan);
		break;
	}

	return -ENOTSUP;
}

static int iis2dh_sample_fetch(const struct device *dev,
			       enum sensor_channel chan)
{
	struct iis2dh_data *iis2dh = dev->data;
	int16_t buf[3];

	/* fetch raw data sample */
	if (iis2dh_acceleration_raw_get(iis2dh->ctx, buf) < 0) {
		LOG_DBG("Failed to fetch raw data sample");
		return -EIO;
	}

	iis2dh->acc[0] = sys_le16_to_cpu(buf[0]);
	iis2dh->acc[1] = sys_le16_to_cpu(buf[1]);
	iis2dh->acc[2] = sys_le16_to_cpu(buf[2]);

	return 0;
}

static const struct sensor_driver_api iis2dh_driver_api = {
	.attr_set = iis2dh_attr_set,
#if CONFIG_IIS2DH_TRIGGER
	.trigger_set = iis2dh_trigger_set,
#endif /* CONFIG_IIS2DH_TRIGGER */
	.sample_fetch = iis2dh_sample_fetch,
	.channel_get = iis2dh_channel_get,
};

static int iis2dh_init_interface(const struct device *dev)
{
	struct iis2dh_data *iis2dh = dev->data;
	const struct iis2dh_device_config *cfg = dev->config;

	iis2dh->bus = device_get_binding(cfg->bus_name);
	if (!iis2dh->bus) {
		LOG_DBG("master bus not found: %s", cfg->bus_name);
		return -EINVAL;
	}

#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
	iis2dh_spi_init(dev);
#elif DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
	iis2dh_i2c_init(dev);
#else
#error "BUS MACRO NOT DEFINED IN DTS"
#endif

	return 0;
}

static int iis2dh_init(const struct device *dev)
{
	struct iis2dh_data *iis2dh = dev->data;
	const struct iis2dh_device_config *cfg = dev->config;
	uint8_t wai;

	if (iis2dh_init_interface(dev)) {
		return -EINVAL;
	}

	/* check chip ID */
	if (iis2dh_device_id_get(iis2dh->ctx, &wai) < 0) {
		return -EIO;
	}

	if (wai != IIS2DH_ID) {
		LOG_ERR("Invalid chip ID: %02x", wai);
		return -EINVAL;
	}

	if (iis2dh_block_data_update_set(iis2dh->ctx, PROPERTY_ENABLE) < 0) {
		return -EIO;
	}

	if (iis2dh_operating_mode_set(iis2dh->ctx, cfg->pm)) {
		return -EIO;
	}

#if (CONFIG_IIS2DH_ODR != 0)
	/* set default odr and full scale for acc */
	if (iis2dh_data_rate_set(iis2dh->ctx, CONFIG_IIS2DH_ODR) < 0) {
		return -EIO;
	}
#endif

#if (CONFIG_IIS2DH_RANGE != 0)
	iis2dh_set_fs_raw(iis2dh, CONFIG_IIS2DH_RANGE);
#endif

#ifdef CONFIG_IIS2DH_TRIGGER
	if (iis2dh_init_interrupt(dev) < 0) {
		LOG_ERR("Failed to initialize interrupts");
		return -EIO;
	}
#endif /* CONFIG_IIS2DH_TRIGGER */

	return 0;
}

const struct iis2dh_device_config iis2dh_cfg = {
	.bus_name = DT_INST_BUS_LABEL(0),
	.pm = CONFIG_IIS2DH_POWER_MODE,
#ifdef CONFIG_IIS2DH_TRIGGER
	.int_gpio_port = DT_INST_GPIO_LABEL(0, drdy_gpios),
	.int_gpio_pin = DT_INST_GPIO_PIN(0, drdy_gpios),
	.int_gpio_flags = DT_INST_GPIO_FLAGS(0, drdy_gpios),
#endif /* CONFIG_IIS2DH_TRIGGER */
};

struct iis2dh_data iis2dh_data;

DEVICE_DT_INST_DEFINE(0, iis2dh_init, NULL,
	     &iis2dh_data, &iis2dh_cfg, POST_KERNEL,
	     CONFIG_SENSOR_INIT_PRIORITY, &iis2dh_driver_api);
