/* 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;
	union axis3bit16_t buf;

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

	iis2dh->acc[0] = sys_le16_to_cpu(buf.i16bit[0]);
	iis2dh->acc[1] = sys_le16_to_cpu(buf.i16bit[1]);
	iis2dh->acc[2] = sys_le16_to_cpu(buf.i16bit[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_AND_API_INIT(iis2dh, DT_INST_LABEL(0), iis2dh_init,
	     &iis2dh_data, &iis2dh_cfg, POST_KERNEL,
	     CONFIG_SENSOR_INIT_PRIORITY, &iis2dh_driver_api);
