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

#define DT_DRV_COMPAT st_lis2dh


#include <zephyr/init.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/device.h>

LOG_MODULE_REGISTER(lis2dh, CONFIG_SENSOR_LOG_LEVEL);
#include "lis2dh.h"

#define ACCEL_SCALE(sensitivity)			\
	((SENSOR_G * (sensitivity) >> 14) / 100)

/*
 * Use values for low-power mode in DS "Mechanical (Sensor) characteristics",
 * multiplied by 100.
 */
static uint32_t lis2dh_reg_val_to_scale[] = {
	ACCEL_SCALE(1600),
	ACCEL_SCALE(3200),
	ACCEL_SCALE(6400),
	ACCEL_SCALE(19200),
};

static void lis2dh_convert(int16_t raw_val, uint32_t scale,
			   struct sensor_value *val)
{
	int32_t converted_val;

	/*
	 * maximum converted value we can get is: max(raw_val) * max(scale)
	 *	max(raw_val >> 4) = +/- 2^11
	 *	max(scale) = 114921
	 *	max(converted_val) = 235358208 which is less than 2^31
	 */
	converted_val = (raw_val >> 4) * scale;
	val->val1 = converted_val / 1000000;
	val->val2 = converted_val % 1000000;
}

static int lis2dh_sample_fetch_temp(const struct device *dev)
{
	int ret = -ENOTSUP;

#ifdef CONFIG_LIS2DH_MEASURE_TEMPERATURE
	struct lis2dh_data *lis2dh = dev->data;
	const struct lis2dh_config *cfg = dev->config;
	uint8_t raw[sizeof(uint16_t)];

	ret = lis2dh->hw_tf->read_data(dev, cfg->temperature.dout_addr, raw,
				       sizeof(raw));

	if (ret < 0) {
		LOG_WRN("Failed to fetch raw temperature sample");
		ret = -EIO;
	} else {
		/*
		 * The result contains a delta value for the
		 * temperature that must be added to the reference temperature set
		 * for your board to return an absolute temperature in Celsius.
		 *
		 * The data is left aligned.  Fixed point after first 8 bits.
		 */
		lis2dh->temperature.val1 = (int32_t)((int8_t)raw[1]);
		if (cfg->temperature.fractional_bits == 0) {
			lis2dh->temperature.val2 = 0;
		} else {
			lis2dh->temperature.val2 =
				(raw[0] >> (8 - cfg->temperature.fractional_bits));
			lis2dh->temperature.val2 = (lis2dh->temperature.val2 * 1000000);
			lis2dh->temperature.val2 >>= cfg->temperature.fractional_bits;
			if (lis2dh->temperature.val1 < 0) {
				lis2dh->temperature.val2 *= -1;
			}
		}
	}
#else
	LOG_WRN("Temperature measurement disabled");
#endif

	return ret;
}

static int lis2dh_channel_get(const struct device *dev,
			      enum sensor_channel chan,
			      struct sensor_value *val)
{
	struct lis2dh_data *lis2dh = dev->data;
	int ofs_start;
	int ofs_end;
	int i;

	switch (chan) {
	case SENSOR_CHAN_ACCEL_X:
		ofs_start = ofs_end = 0;
		break;
	case SENSOR_CHAN_ACCEL_Y:
		ofs_start = ofs_end = 1;
		break;
	case SENSOR_CHAN_ACCEL_Z:
		ofs_start = ofs_end = 2;
		break;
	case SENSOR_CHAN_ACCEL_XYZ:
		ofs_start = 0;
		ofs_end = 2;
		break;
#ifdef CONFIG_LIS2DH_MEASURE_TEMPERATURE
	case SENSOR_CHAN_DIE_TEMP:
		memcpy(val, &lis2dh->temperature, sizeof(*val));
		return 0;
#endif
	default:
		return -ENOTSUP;
	}

	for (i = ofs_start; i <= ofs_end; i++, val++) {
		lis2dh_convert(lis2dh->sample.xyz[i], lis2dh->scale, val);
	}

	return 0;
}

static int lis2dh_fetch_xyz(const struct device *dev,
			       enum sensor_channel chan)
{
	struct lis2dh_data *lis2dh = dev->data;
	int status = -ENODATA;
	size_t i;
	/*
	 * since status and all accel data register addresses are consecutive,
	 * a burst read can be used to read all the samples
	 */
	status = lis2dh->hw_tf->read_data(dev, LIS2DH_REG_STATUS,
					  lis2dh->sample.raw,
					  sizeof(lis2dh->sample.raw));
	if (status < 0) {
		LOG_WRN("Could not read accel axis data");
		return status;
	}

	for (i = 0; i < (3 * sizeof(int16_t)); i += sizeof(int16_t)) {
		int16_t *sample =
			(int16_t *)&lis2dh->sample.raw[1 + i];

		*sample = sys_le16_to_cpu(*sample);
	}

	if (lis2dh->sample.status & LIS2DH_STATUS_DRDY_MASK) {
		status = 0;
	}

	return status;
}

static int lis2dh_sample_fetch(const struct device *dev,
			       enum sensor_channel chan)
{
	int status = -ENODATA;

	if (chan == SENSOR_CHAN_ALL) {
		status = lis2dh_fetch_xyz(dev, chan);
#ifdef CONFIG_LIS2DH_MEASURE_TEMPERATURE
		if (status == 0) {
			status = lis2dh_sample_fetch_temp(dev);
		}
#endif
	} else if (chan == SENSOR_CHAN_ACCEL_XYZ) {
		status = lis2dh_fetch_xyz(dev, chan);
	} else if (chan == SENSOR_CHAN_DIE_TEMP) {
		status = lis2dh_sample_fetch_temp(dev);
	} else {
		__ASSERT(false, "Invalid sensor channel in fetch");
	}

	return status;
}

#ifdef CONFIG_LIS2DH_ODR_RUNTIME
/* 1620 & 5376 are low power only */
static const uint16_t lis2dh_odr_map[] = {0, 1, 10, 25, 50, 100, 200, 400, 1620,
				       1344, 5376};

static int lis2dh_freq_to_odr_val(uint16_t freq)
{
	size_t i;

	for (i = 0; i < ARRAY_SIZE(lis2dh_odr_map); i++) {
		if (freq == lis2dh_odr_map[i]) {
			return i;
		}
	}

	return -EINVAL;
}

static int lis2dh_acc_odr_set(const struct device *dev, uint16_t freq)
{
	int odr;
	int status;
	uint8_t value;
	struct lis2dh_data *data = dev->data;

	odr = lis2dh_freq_to_odr_val(freq);
	if (odr < 0) {
		return odr;
	}

	status = data->hw_tf->read_reg(dev, LIS2DH_REG_CTRL1, &value);
	if (status < 0) {
		return status;
	}

	/* some odr values cannot be set in certain power modes */
	if ((value & LIS2DH_LP_EN_BIT_MASK) == 0U && odr == LIS2DH_ODR_8) {
		return -ENOTSUP;
	}

	/* adjust odr index for LP enabled mode, see table above */
	if (((value & LIS2DH_LP_EN_BIT_MASK) == LIS2DH_LP_EN_BIT_MASK) &&
		(odr == LIS2DH_ODR_9 + 1)) {
		odr--;
	}

	return data->hw_tf->write_reg(dev, LIS2DH_REG_CTRL1,
				      (value & ~LIS2DH_ODR_MASK) |
				      LIS2DH_ODR_RATE(odr));
}
#endif

#ifdef CONFIG_LIS2DH_ACCEL_RANGE_RUNTIME

#define LIS2DH_RANGE_IDX_TO_VALUE(idx)		(1 << ((idx) + 1))
#define LIS2DH_NUM_RANGES			4

static int lis2dh_range_to_reg_val(uint16_t range)
{
	int i;

	for (i = 0; i < LIS2DH_NUM_RANGES; i++) {
		if (range == LIS2DH_RANGE_IDX_TO_VALUE(i)) {
			return i;
		}
	}

	return -EINVAL;
}

static int lis2dh_acc_range_set(const struct device *dev, int32_t range)
{
	struct lis2dh_data *lis2dh = dev->data;
	int fs;

	fs = lis2dh_range_to_reg_val(range);
	if (fs < 0) {
		return fs;
	}

	lis2dh->scale = lis2dh_reg_val_to_scale[fs];

	return lis2dh->hw_tf->update_reg(dev, LIS2DH_REG_CTRL4,
					 LIS2DH_FS_MASK,
					 (fs << LIS2DH_FS_SHIFT));
}
#endif

static int lis2dh_acc_config(const struct device *dev,
			     enum sensor_channel chan,
			     enum sensor_attribute attr,
			     const struct sensor_value *val)
{
	switch (attr) {
#ifdef CONFIG_LIS2DH_ACCEL_RANGE_RUNTIME
	case SENSOR_ATTR_FULL_SCALE:
		return lis2dh_acc_range_set(dev, sensor_ms2_to_g(val));
#endif
#ifdef CONFIG_LIS2DH_ODR_RUNTIME
	case SENSOR_ATTR_SAMPLING_FREQUENCY:
		return lis2dh_acc_odr_set(dev, val->val1);
#endif
#if defined(CONFIG_LIS2DH_TRIGGER)
	case SENSOR_ATTR_SLOPE_TH:
	case SENSOR_ATTR_SLOPE_DUR:
		return lis2dh_acc_slope_config(dev, attr, val);
#endif
#ifdef CONFIG_LIS2DH_ACCEL_HP_FILTERS
	case SENSOR_ATTR_CONFIGURATION:
		return lis2dh_acc_hp_filter_set(dev, val->val1);
#endif
	default:
		LOG_DBG("Accel attribute not supported.");
		return -ENOTSUP;
	}

	return 0;
}

static int lis2dh_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 lis2dh_acc_config(dev, chan, attr, val);
	default:
		LOG_WRN("attr_set() not supported on this channel.");
		return -ENOTSUP;
	}

	return 0;
}

static const struct sensor_driver_api lis2dh_driver_api = {
	.attr_set = lis2dh_attr_set,
#if CONFIG_LIS2DH_TRIGGER
	.trigger_set = lis2dh_trigger_set,
#endif
	.sample_fetch = lis2dh_sample_fetch,
	.channel_get = lis2dh_channel_get,
};

int lis2dh_init(const struct device *dev)
{
	struct lis2dh_data *lis2dh = dev->data;
	const struct lis2dh_config *cfg = dev->config;
	int status;
	uint8_t id;
	uint8_t raw[6];

	status = cfg->bus_init(dev);
	if (status < 0) {
		return status;
	}

	status = lis2dh->hw_tf->read_reg(dev, LIS2DH_REG_WAI, &id);
	if (status < 0) {
		LOG_ERR("Failed to read chip id.");
		return status;
	}

	if (id != LIS2DH_CHIP_ID) {
		LOG_ERR("Invalid chip ID: %02x\n", id);
		return -EINVAL;
	}

	/* Fix LSM303AGR_ACCEL device scale values */
	if (cfg->hw.is_lsm303agr_dev) {
		lis2dh_reg_val_to_scale[0] = ACCEL_SCALE(1563);
		lis2dh_reg_val_to_scale[1] = ACCEL_SCALE(3126);
		lis2dh_reg_val_to_scale[2] = ACCEL_SCALE(6252);
		lis2dh_reg_val_to_scale[3] = ACCEL_SCALE(18758);
	}

	if (cfg->hw.disc_pull_up) {
		status = lis2dh->hw_tf->update_reg(dev, LIS2DH_REG_CTRL0,
						   LIS2DH_SDO_PU_DISC_MASK,
						   LIS2DH_SDO_PU_DISC_MASK);
		if (status < 0) {
			LOG_ERR("Failed to disconnect SDO/SA0 pull-up.");
			return status;
		}
	}

	/* Initialize control register ctrl1 to ctrl 6 to default boot values
	 * to avoid warm start/reset issues as the accelerometer has no reset
	 * pin. Register values are retained if power is not removed.
	 * Default values see LIS2DH documentation page 30, chapter 6.
	 */
	(void)memset(raw, 0, sizeof(raw));
	raw[0] = LIS2DH_ACCEL_EN_BITS;

	status = lis2dh->hw_tf->write_data(dev, LIS2DH_REG_CTRL1, raw,
					   sizeof(raw));

	if (status < 0) {
		LOG_ERR("Failed to reset ctrl registers.");
		return status;
	}

	/* set full scale range and store it for later conversion */
	lis2dh->scale = lis2dh_reg_val_to_scale[LIS2DH_FS_IDX];
#ifdef CONFIG_LIS2DH_BLOCK_DATA_UPDATE
	status = lis2dh->hw_tf->write_reg(dev, LIS2DH_REG_CTRL4,
					  LIS2DH_FS_BITS | LIS2DH_HR_BIT | LIS2DH_CTRL4_BDU_BIT);
#else
	status = lis2dh->hw_tf->write_reg(dev, LIS2DH_REG_CTRL4, LIS2DH_FS_BITS | LIS2DH_HR_BIT);
#endif

	if (status < 0) {
		LOG_ERR("Failed to set full scale ctrl register.");
		return status;
	}

#ifdef CONFIG_LIS2DH_MEASURE_TEMPERATURE
	status = lis2dh->hw_tf->update_reg(dev, cfg->temperature.cfg_addr,
					   cfg->temperature.enable_mask,
					   cfg->temperature.enable_mask);

	if (status < 0) {
		LOG_ERR("Failed to enable temperature measurement");
		return status;
	}
#endif

#ifdef CONFIG_LIS2DH_TRIGGER
	if (cfg->gpio_drdy.port != NULL || cfg->gpio_int.port != NULL) {
		status = lis2dh_init_interrupt(dev);
		if (status < 0) {
			LOG_ERR("Failed to initialize interrupts.");
			return status;
		}
	}
#endif

	LOG_INF("fs=%d, odr=0x%x lp_en=0x%x scale=%d", 1 << (LIS2DH_FS_IDX + 1), LIS2DH_ODR_IDX,
		(uint8_t)LIS2DH_LP_EN_BIT, lis2dh->scale);

	/* enable accel measurements and set power mode and data rate */
	return lis2dh->hw_tf->write_reg(dev, LIS2DH_REG_CTRL1,
					LIS2DH_ACCEL_EN_BITS | LIS2DH_LP_EN_BIT |
					LIS2DH_ODR_BITS);
}

#ifdef CONFIG_PM_DEVICE
static int lis2dh_pm_action(const struct device *dev,
			    enum pm_device_action action)
{
	int status;
	struct lis2dh_data *lis2dh = dev->data;

	switch (action) {
	case PM_DEVICE_ACTION_RESUME:
		/* Resume previous mode. */
		status = lis2dh->hw_tf->write_reg(dev, LIS2DH_REG_CTRL1,
						  lis2dh->reg_ctrl1_active_val);
		if (status < 0) {
			LOG_ERR("failed to write reg_crtl1");
			return status;
		}
		break;
	case PM_DEVICE_ACTION_SUSPEND:
		/* Store current mode, suspend. */
		status = lis2dh->hw_tf->read_reg(dev, LIS2DH_REG_CTRL1,
						 &lis2dh->reg_ctrl1_active_val);
		if (status < 0) {
			LOG_ERR("failed to read reg_crtl1");
			return status;
		}
		status = lis2dh->hw_tf->write_reg(dev, LIS2DH_REG_CTRL1,
						  LIS2DH_SUSPEND);
		if (status < 0) {
			LOG_ERR("failed to write reg_crtl1");
			return status;
		}
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}
#endif /* CONFIG_PM_DEVICE */

#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
#warning "LIS2DH driver enabled without any devices"
#endif

/*
 * Device creation macro, shared by LIS2DH_DEFINE_SPI() and
 * LIS2DH_DEFINE_I2C().
 */

#define LIS2DH_DEVICE_INIT(inst)					\
	PM_DEVICE_DT_INST_DEFINE(inst, lis2dh_pm_action);		\
	SENSOR_DEVICE_DT_INST_DEFINE(inst,				\
			    lis2dh_init,				\
			    PM_DEVICE_DT_INST_GET(inst),		\
			    &lis2dh_data_##inst,			\
			    &lis2dh_config_##inst,			\
			    POST_KERNEL,				\
			    CONFIG_SENSOR_INIT_PRIORITY,		\
			    &lis2dh_driver_api);

#define IS_LSM303AGR_DEV(inst) \
	DT_NODE_HAS_COMPAT(DT_DRV_INST(inst), st_lsm303agr_accel)

#define DISC_PULL_UP(inst) \
	DT_INST_PROP(inst, disconnect_sdo_sa0_pull_up)

#define ANYM_ON_INT1(inst) \
	DT_INST_PROP(inst, anym_on_int1)

#define ANYM_LATCH(inst) \
	!DT_INST_PROP(inst, anym_no_latch)

#define ANYM_MODE(inst) \
	DT_INST_PROP(inst, anym_mode)

#ifdef CONFIG_LIS2DH_TRIGGER
#define GPIO_DT_SPEC_INST_GET_BY_IDX_COND(id, prop, idx)		\
	COND_CODE_1(DT_INST_PROP_HAS_IDX(id, prop, idx),		\
		    (GPIO_DT_SPEC_INST_GET_BY_IDX(id, prop, idx)),	\
		    ({.port = NULL, .pin = 0, .dt_flags = 0}))

#define LIS2DH_CFG_INT(inst)				\
	.gpio_drdy =							\
	    COND_CODE_1(ANYM_ON_INT1(inst),		\
		({.port = NULL, .pin = 0, .dt_flags = 0}),                  \
		(GPIO_DT_SPEC_INST_GET_BY_IDX_COND(inst, irq_gpios, 0))),	\
	.gpio_int =								\
	    COND_CODE_1(ANYM_ON_INT1(inst),		\
		(GPIO_DT_SPEC_INST_GET_BY_IDX_COND(inst, irq_gpios, 0)),	\
		(GPIO_DT_SPEC_INST_GET_BY_IDX_COND(inst, irq_gpios, 1))),
#else
#define LIS2DH_CFG_INT(inst)
#endif /* CONFIG_LIS2DH_TRIGGER */

#ifdef CONFIG_LIS2DH_MEASURE_TEMPERATURE
/* The first 8 bits are the integer portion of the temperature.
 * The result is left justified.  The remainder of the bits are
 * the fractional part.
 *
 * LIS2DH has 8 total bits.
 * LIS2DH12/LIS3DH have 10 bits unless they are in lower power mode.
 * compat(lis2dh) cannot be used here because it is the base part.
 */
#define FRACTIONAL_BITS(inst)	\
	(DT_NODE_HAS_COMPAT(DT_DRV_INST(inst), st_lis2dh12) ||				\
	 DT_NODE_HAS_COMPAT(DT_DRV_INST(inst), st_lis3dh)) ?				\
		      (IS_ENABLED(CONFIG_LIS2DH_OPER_MODE_LOW_POWER) ? 0 : 2) : \
		      0

#define LIS2DH_CFG_TEMPERATURE(inst)	\
	.temperature = { .cfg_addr = 0x1F,	\
			 .enable_mask = 0xC0,		\
			 .dout_addr = 0x0C,			\
			 .fractional_bits = FRACTIONAL_BITS(inst) },
#else
#define LIS2DH_CFG_TEMPERATURE(inst)
#endif /* CONFIG_LIS2DH_MEASURE_TEMPERATURE */

#define LIS2DH_CONFIG_SPI(inst)						\
	{								\
		.bus_init = lis2dh_spi_init,				\
		.bus_cfg = { .spi = SPI_DT_SPEC_INST_GET(inst,		\
					SPI_WORD_SET(8) |		\
					SPI_OP_MODE_MASTER |		\
					SPI_MODE_CPOL |			\
					SPI_MODE_CPHA,			\
					0) },				\
		.hw = { .is_lsm303agr_dev = IS_LSM303AGR_DEV(inst),	\
			.disc_pull_up = DISC_PULL_UP(inst),		\
			.anym_on_int1 = ANYM_ON_INT1(inst),		\
			.anym_latch = ANYM_LATCH(inst),			\
			.anym_mode = ANYM_MODE(inst), },		\
		LIS2DH_CFG_TEMPERATURE(inst)				\
		LIS2DH_CFG_INT(inst)					\
	}

#define LIS2DH_DEFINE_SPI(inst)						\
	static struct lis2dh_data lis2dh_data_##inst;			\
	static const struct lis2dh_config lis2dh_config_##inst =	\
		LIS2DH_CONFIG_SPI(inst);				\
	LIS2DH_DEVICE_INIT(inst)

/*
 * Instantiation macros used when a device is on an I2C bus.
 */

#define LIS2DH_CONFIG_I2C(inst)						\
	{								\
		.bus_init = lis2dh_i2c_init,				\
		.bus_cfg = { .i2c = I2C_DT_SPEC_INST_GET(inst), },	\
		.hw = { .is_lsm303agr_dev = IS_LSM303AGR_DEV(inst),	\
			.disc_pull_up = DISC_PULL_UP(inst),		\
			.anym_on_int1 = ANYM_ON_INT1(inst),		\
			.anym_latch = ANYM_LATCH(inst),			\
			.anym_mode = ANYM_MODE(inst), },		\
		LIS2DH_CFG_TEMPERATURE(inst)				\
		LIS2DH_CFG_INT(inst)					\
	}

#define LIS2DH_DEFINE_I2C(inst)						\
	static struct lis2dh_data lis2dh_data_##inst;			\
	static const struct lis2dh_config lis2dh_config_##inst =	\
		LIS2DH_CONFIG_I2C(inst);				\
	LIS2DH_DEVICE_INIT(inst)
/*
 * Main instantiation macro. Use of COND_CODE_1() selects the right
 * bus-specific macro at preprocessor time.
 */

#define LIS2DH_DEFINE(inst)						\
	COND_CODE_1(DT_INST_ON_BUS(inst, spi),				\
		    (LIS2DH_DEFINE_SPI(inst)),				\
		    (LIS2DH_DEFINE_I2C(inst)))

DT_INST_FOREACH_STATUS_OKAY(LIS2DH_DEFINE)
