/* ST Microelectronics LSM6DSO16IS 6-axis IMU sensor driver
 *
 * Copyright (c) 2023 STMicroelectronics
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Datasheet:
 * https://www.st.com/resource/en/datasheet/lsm6dso16is.pdf
 */

#define DT_DRV_COMPAT st_lsm6dso16is

#include <zephyr/drivers/sensor.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <string.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/logging/log.h>

#include "lsm6dso16is.h"

LOG_MODULE_REGISTER(LSM6DSO16IS, CONFIG_SENSOR_LOG_LEVEL);

static const uint16_t lsm6dso16is_odr_map[] = {0, 12, 26, 52, 104, 208, 416, 833,
					1667, 3333, 6667};

static int lsm6dso16is_freq_to_odr_val(uint16_t freq)
{
	size_t i;

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

	return -EINVAL;
}

static int lsm6dso16is_odr_to_freq_val(uint16_t odr)
{
	/* for valid index, return value from map */
	if (odr < ARRAY_SIZE(lsm6dso16is_odr_map)) {
		return lsm6dso16is_odr_map[odr & 0xF];
	}

	/* invalid index, return last entry */
	return lsm6dso16is_odr_map[ARRAY_SIZE(lsm6dso16is_odr_map) - 1];
}

static const uint16_t lsm6dso16is_accel_fs_map[] = {2, 16, 4, 8};

static int lsm6dso16is_accel_range_to_fs_val(int32_t range)
{
	size_t i;

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

	return -EINVAL;
}

static const uint16_t lsm6dso16is_gyro_fs_map[] = {250, 125, 500, 0, 1000, 0, 2000};
static const uint16_t lsm6dso16is_gyro_fs_sens[] = {2, 1, 4, 0, 8, 0, 16};

static int lsm6dso16is_gyro_range_to_fs_val(int32_t range)
{
	size_t i;

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

	return -EINVAL;
}

static inline int lsm6dso16is_reboot(const struct device *dev)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;

	if (lsm6dso16is_boot_set(ctx, 1) < 0) {
		return -EIO;
	}

	/* Wait sensor turn-on time as per datasheet */
	k_sleep(K_MSEC(35)); /* turn-on time in ms */

	return 0;
}

static int lsm6dso16is_accel_set_fs_raw(const struct device *dev, uint8_t fs)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	struct lsm6dso16is_data *data = dev->data;

	if (lsm6dso16is_xl_full_scale_set(ctx, fs) < 0) {
		return -EIO;
	}

	data->accel_fs = fs;

	return 0;
}

static int lsm6dso16is_accel_set_odr_raw(const struct device *dev, uint8_t odr)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	struct lsm6dso16is_data *data = dev->data;

	if (lsm6dso16is_xl_data_rate_set(ctx, odr) < 0) {
		return -EIO;
	}

	data->accel_freq = lsm6dso16is_odr_to_freq_val(odr);

	return 0;
}

static int lsm6dso16is_gyro_set_fs_raw(const struct device *dev, uint8_t fs)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;

	if (lsm6dso16is_gy_full_scale_set(ctx, fs) < 0) {
		return -EIO;
	}

	return 0;
}

static int lsm6dso16is_gyro_set_odr_raw(const struct device *dev, uint8_t odr)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;

	if (lsm6dso16is_gy_data_rate_set(ctx, odr) < 0) {
		return -EIO;
	}

	return 0;
}

static int lsm6dso16is_accel_odr_set(const struct device *dev, uint16_t freq)
{
	int odr;

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

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

	return 0;
}

static int lsm6dso16is_accel_range_set(const struct device *dev, int32_t range)
{
	int fs;
	struct lsm6dso16is_data *data = dev->data;

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

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

	data->acc_gain = lsm6dso16is_accel_fs_map[fs] * GAIN_UNIT_XL / 2;
	return 0;
}

static int lsm6dso16is_accel_config(const struct device *dev,
				enum sensor_channel chan,
				enum sensor_attribute attr,
				const struct sensor_value *val)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	lsm6dso16is_hm_mode_t mode;

	switch (attr) {
	case SENSOR_ATTR_FULL_SCALE:
		return lsm6dso16is_accel_range_set(dev, sensor_ms2_to_g(val));
	case SENSOR_ATTR_SAMPLING_FREQUENCY:
		return lsm6dso16is_accel_odr_set(dev, val->val1);
	case SENSOR_ATTR_CONFIGURATION:
		switch (val->val1) {
		case 0: /* High Performance */
			mode = LSM6DSO16IS_HIGH_PERFOMANCE_MODE_ENABLED;
			break;
		case 1: /* Low Power */
			mode = LSM6DSO16IS_HIGH_PERFOMANCE_MODE_DISABLED;
			break;
		default:
			return -EIO;
		}

		return lsm6dso16is_xl_hm_mode_set(ctx, mode);
	default:
		LOG_DBG("Accel attribute not supported.");
		return -ENOTSUP;
	}

	return 0;
}

static int lsm6dso16is_gyro_odr_set(const struct device *dev, uint16_t freq)
{
	int odr;

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

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

	return 0;
}

static int lsm6dso16is_gyro_range_set(const struct device *dev, int32_t range)
{
	int fs;
	struct lsm6dso16is_data *data = dev->data;

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

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

	data->gyro_gain = (lsm6dso16is_gyro_fs_sens[fs] * GAIN_UNIT_G);
	return 0;
}

static int lsm6dso16is_gyro_config(const struct device *dev,
			       enum sensor_channel chan,
			       enum sensor_attribute attr,
			       const struct sensor_value *val)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	lsm6dso16is_hm_mode_t mode;

	switch (attr) {
	case SENSOR_ATTR_FULL_SCALE:
		return lsm6dso16is_gyro_range_set(dev, sensor_rad_to_degrees(val));
	case SENSOR_ATTR_SAMPLING_FREQUENCY:
		return lsm6dso16is_gyro_odr_set(dev, val->val1);
	case SENSOR_ATTR_CONFIGURATION:
		switch (val->val1) {
		case 0: /* High Performance */
			mode = LSM6DSO16IS_HIGH_PERFOMANCE_MODE_ENABLED;
			break;
		case 1: /* Low Power */
			mode = LSM6DSO16IS_HIGH_PERFOMANCE_MODE_DISABLED;
			break;
		default:
			return -EIO;
		}

		return lsm6dso16is_xl_hm_mode_set(ctx, mode);
	default:
		LOG_DBG("Gyro attribute not supported.");
		return -ENOTSUP;
	}

	return 0;
}

static int lsm6dso16is_attr_set(const struct device *dev,
			    enum sensor_channel chan,
			    enum sensor_attribute attr,
			    const struct sensor_value *val)
{
#if defined(CONFIG_LSM6DSO16IS_SENSORHUB)
	struct lsm6dso16is_data *data = dev->data;
#endif /* CONFIG_LSM6DSO16IS_SENSORHUB */

	switch (chan) {
	case SENSOR_CHAN_ACCEL_XYZ:
		return lsm6dso16is_accel_config(dev, chan, attr, val);
	case SENSOR_CHAN_GYRO_XYZ:
		return lsm6dso16is_gyro_config(dev, chan, attr, val);
#if defined(CONFIG_LSM6DSO16IS_SENSORHUB)
	case SENSOR_CHAN_MAGN_XYZ:
	case SENSOR_CHAN_PRESS:
	case SENSOR_CHAN_HUMIDITY:
		if (!data->shub_inited) {
			LOG_ERR("shub not inited.");
			return -ENOTSUP;
		}

		return lsm6dso16is_shub_config(dev, chan, attr, val);
#endif /* CONFIG_LSM6DSO16IS_SENSORHUB */
	default:
		LOG_WRN("attr_set() not supported on this channel.");
		return -ENOTSUP;
	}

	return 0;
}

static int lsm6dso16is_sample_fetch_accel(const struct device *dev)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	struct lsm6dso16is_data *data = dev->data;

	if (lsm6dso16is_acceleration_raw_get(ctx, data->acc) < 0) {
		LOG_DBG("Failed to read sample");
		return -EIO;
	}

	return 0;
}

static int lsm6dso16is_sample_fetch_gyro(const struct device *dev)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	struct lsm6dso16is_data *data = dev->data;

	if (lsm6dso16is_angular_rate_raw_get(ctx, data->gyro) < 0) {
		LOG_DBG("Failed to read sample");
		return -EIO;
	}

	return 0;
}

#if defined(CONFIG_LSM6DSO16IS_ENABLE_TEMP)
static int lsm6dso16is_sample_fetch_temp(const struct device *dev)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	struct lsm6dso16is_data *data = dev->data;

	if (lsm6dso16is_temperature_raw_get(ctx, &data->temp_sample) < 0) {
		LOG_DBG("Failed to read sample");
		return -EIO;
	}

	return 0;
}
#endif

#if defined(CONFIG_LSM6DSO16IS_SENSORHUB)
static int lsm6dso16is_sample_fetch_shub(const struct device *dev)
{
	if (lsm6dso16is_shub_fetch_external_devs(dev) < 0) {
		LOG_DBG("failed to read ext shub devices");
		return -EIO;
	}

	return 0;
}
#endif /* CONFIG_LSM6DSO16IS_SENSORHUB */

static int lsm6dso16is_sample_fetch(const struct device *dev,
				enum sensor_channel chan)
{
#if defined(CONFIG_LSM6DSO16IS_SENSORHUB)
	struct lsm6dso16is_data *data = dev->data;
#endif /* CONFIG_LSM6DSO16IS_SENSORHUB */

	switch (chan) {
	case SENSOR_CHAN_ACCEL_XYZ:
		lsm6dso16is_sample_fetch_accel(dev);
		break;
	case SENSOR_CHAN_GYRO_XYZ:
		lsm6dso16is_sample_fetch_gyro(dev);
		break;
#if defined(CONFIG_LSM6DSO16IS_ENABLE_TEMP)
	case SENSOR_CHAN_DIE_TEMP:
		lsm6dso16is_sample_fetch_temp(dev);
		break;
#endif
	case SENSOR_CHAN_ALL:
		lsm6dso16is_sample_fetch_accel(dev);
		lsm6dso16is_sample_fetch_gyro(dev);
#if defined(CONFIG_LSM6DSO16IS_ENABLE_TEMP)
		lsm6dso16is_sample_fetch_temp(dev);
#endif
#if defined(CONFIG_LSM6DSO16IS_SENSORHUB)
		if (data->shub_inited) {
			lsm6dso16is_sample_fetch_shub(dev);
		}
#endif
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

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

	/* Sensitivity is exposed in ug/LSB */
	/* Convert to m/s^2 */
	dval = (int64_t)(raw_val) * sensitivity * SENSOR_G_DOUBLE;
	val->val1 = (int32_t)(dval / 1000000);
	val->val2 = (int32_t)(dval % 1000000);

}

static inline int lsm6dso16is_accel_get_channel(enum sensor_channel chan,
					    struct sensor_value *val,
					    struct lsm6dso16is_data *data,
					    uint32_t sensitivity)
{
	uint8_t i;

	switch (chan) {
	case SENSOR_CHAN_ACCEL_X:
		lsm6dso16is_accel_convert(val, data->acc[0], sensitivity);
		break;
	case SENSOR_CHAN_ACCEL_Y:
		lsm6dso16is_accel_convert(val, data->acc[1], sensitivity);
		break;
	case SENSOR_CHAN_ACCEL_Z:
		lsm6dso16is_accel_convert(val, data->acc[2], sensitivity);
		break;
	case SENSOR_CHAN_ACCEL_XYZ:
		for (i = 0; i < 3; i++) {
			lsm6dso16is_accel_convert(val++, data->acc[i], sensitivity);
		}
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static int lsm6dso16is_accel_channel_get(enum sensor_channel chan,
				     struct sensor_value *val,
				     struct lsm6dso16is_data *data)
{
	return lsm6dso16is_accel_get_channel(chan, val, data, data->acc_gain);
}

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

	/* Sensitivity is exposed in udps/LSB */
	/* Convert to rad/s */
	dval = (int64_t)(raw_val) * sensitivity * SENSOR_DEG2RAD_DOUBLE;
	val->val1 = (int32_t)(dval / 1000000);
	val->val2 = (int32_t)(dval % 1000000);
}

static inline int lsm6dso16is_gyro_get_channel(enum sensor_channel chan,
					   struct sensor_value *val,
					   struct lsm6dso16is_data *data,
					   uint32_t sensitivity)
{
	uint8_t i;

	switch (chan) {
	case SENSOR_CHAN_GYRO_X:
		lsm6dso16is_gyro_convert(val, data->gyro[0], sensitivity);
		break;
	case SENSOR_CHAN_GYRO_Y:
		lsm6dso16is_gyro_convert(val, data->gyro[1], sensitivity);
		break;
	case SENSOR_CHAN_GYRO_Z:
		lsm6dso16is_gyro_convert(val, data->gyro[2], sensitivity);
		break;
	case SENSOR_CHAN_GYRO_XYZ:
		for (i = 0; i < 3; i++) {
			lsm6dso16is_gyro_convert(val++, data->gyro[i], sensitivity);
		}
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static int lsm6dso16is_gyro_channel_get(enum sensor_channel chan,
				    struct sensor_value *val,
				    struct lsm6dso16is_data *data)
{
	return lsm6dso16is_gyro_get_channel(chan, val, data, data->gyro_gain);
}

#if defined(CONFIG_LSM6DSO16IS_ENABLE_TEMP)
static void lsm6dso16is_gyro_channel_get_temp(struct sensor_value *val,
					  struct lsm6dso16is_data *data)
{
	int32_t micro_c;

	/* convert units to micro Celsius. Raw temperature samples are
	 * expressed in 256 LSB/deg_C units. And LSB output is 0 at 25 C.
	 */
	micro_c = (data->temp_sample * 1000000) / 256;

	val->val1 = micro_c / 1000000 + 25;
	val->val2 = micro_c % 1000000;
}
#endif

#if defined(CONFIG_LSM6DSO16IS_SENSORHUB)
static inline void lsm6dso16is_magn_convert(struct sensor_value *val, int raw_val,
					uint16_t sensitivity)
{
	double dval;

	/* Sensitivity is exposed in mgauss/LSB */
	dval = (double)(raw_val * sensitivity);
	val->val1 = (int32_t)dval / 1000000;
	val->val2 = (int32_t)dval % 1000000;
}

static inline int lsm6dso16is_magn_get_channel(enum sensor_channel chan,
					   struct sensor_value *val,
					   struct lsm6dso16is_data *data)
{
	int16_t sample[3];
	int idx;

	idx = lsm6dso16is_shub_get_idx(data->dev, SENSOR_CHAN_MAGN_XYZ);
	if (idx < 0) {
		LOG_DBG("external magn not supported");
		return -ENOTSUP;
	}


	sample[0] = sys_le16_to_cpu((int16_t)(data->ext_data[idx][0] |
				    (data->ext_data[idx][1] << 8)));
	sample[1] = sys_le16_to_cpu((int16_t)(data->ext_data[idx][2] |
				    (data->ext_data[idx][3] << 8)));
	sample[2] = sys_le16_to_cpu((int16_t)(data->ext_data[idx][4] |
				    (data->ext_data[idx][5] << 8)));

	switch (chan) {
	case SENSOR_CHAN_MAGN_X:
		lsm6dso16is_magn_convert(val, sample[0], data->magn_gain);
		break;
	case SENSOR_CHAN_MAGN_Y:
		lsm6dso16is_magn_convert(val, sample[1], data->magn_gain);
		break;
	case SENSOR_CHAN_MAGN_Z:
		lsm6dso16is_magn_convert(val, sample[2], data->magn_gain);
		break;
	case SENSOR_CHAN_MAGN_XYZ:
		lsm6dso16is_magn_convert(val, sample[0], data->magn_gain);
		lsm6dso16is_magn_convert(val + 1, sample[1], data->magn_gain);
		lsm6dso16is_magn_convert(val + 2, sample[2], data->magn_gain);
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static inline void lsm6dso16is_hum_convert(struct sensor_value *val,
				       struct lsm6dso16is_data *data)
{
	float rh;
	int16_t raw_val;
	struct hts221_data *ht = &data->hts221;
	int idx;

	idx = lsm6dso16is_shub_get_idx(data->dev, SENSOR_CHAN_HUMIDITY);
	if (idx < 0) {
		LOG_DBG("external press/temp not supported");
		return;
	}

	raw_val = sys_le16_to_cpu((int16_t)(data->ext_data[idx][0] |
					  (data->ext_data[idx][1] << 8)));

	/* find relative humidty by linear interpolation */
	rh = (ht->y1 - ht->y0) * raw_val + ht->x1 * ht->y0 - ht->x0 * ht->y1;
	rh /= (ht->x1 - ht->x0);

	/* convert humidity to integer and fractional part */
	val->val1 = rh;
	val->val2 = rh * 1000000;
}

static inline void lsm6dso16is_press_convert(struct sensor_value *val,
					 struct lsm6dso16is_data *data)
{
	int32_t raw_val;
	int idx;

	idx = lsm6dso16is_shub_get_idx(data->dev, SENSOR_CHAN_PRESS);
	if (idx < 0) {
		LOG_DBG("external press/temp not supported");
		return;
	}

	raw_val = sys_le32_to_cpu((int32_t)(data->ext_data[idx][0] |
					  (data->ext_data[idx][1] << 8) |
					  (data->ext_data[idx][2] << 16)));

	/* Pressure sensitivity is 4096 LSB/hPa */
	/* Convert raw_val to val in kPa */
	val->val1 = (raw_val >> 12) / 10;
	val->val2 = (raw_val >> 12) % 10 * 100000 +
		(((int32_t)((raw_val) & 0x0FFF) * 100000L) >> 12);
}

static inline void lsm6dso16is_temp_convert(struct sensor_value *val,
					struct lsm6dso16is_data *data)
{
	int16_t raw_val;
	int idx;

	idx = lsm6dso16is_shub_get_idx(data->dev, SENSOR_CHAN_PRESS);
	if (idx < 0) {
		LOG_DBG("external press/temp not supported");
		return;
	}

	raw_val = sys_le16_to_cpu((int16_t)(data->ext_data[idx][3] |
					  (data->ext_data[idx][4] << 8)));

	/* Temperature sensitivity is 100 LSB/deg C */
	val->val1 = raw_val / 100;
	val->val2 = (int32_t)raw_val % 100 * (10000);
}
#endif

static int lsm6dso16is_channel_get(const struct device *dev,
			       enum sensor_channel chan,
			       struct sensor_value *val)
{
	struct lsm6dso16is_data *data = dev->data;

	switch (chan) {
	case SENSOR_CHAN_ACCEL_X:
	case SENSOR_CHAN_ACCEL_Y:
	case SENSOR_CHAN_ACCEL_Z:
	case SENSOR_CHAN_ACCEL_XYZ:
		lsm6dso16is_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:
		lsm6dso16is_gyro_channel_get(chan, val, data);
		break;
#if defined(CONFIG_LSM6DSO16IS_ENABLE_TEMP)
	case SENSOR_CHAN_DIE_TEMP:
		lsm6dso16is_gyro_channel_get_temp(val, data);
		break;
#endif
#if defined(CONFIG_LSM6DSO16IS_SENSORHUB)
	case SENSOR_CHAN_MAGN_X:
	case SENSOR_CHAN_MAGN_Y:
	case SENSOR_CHAN_MAGN_Z:
	case SENSOR_CHAN_MAGN_XYZ:
		if (!data->shub_inited) {
			LOG_ERR("attr_set() shub not inited.");
			return -ENOTSUP;
		}

		lsm6dso16is_magn_get_channel(chan, val, data);
		break;

	case SENSOR_CHAN_HUMIDITY:
		if (!data->shub_inited) {
			LOG_ERR("attr_set() shub not inited.");
			return -ENOTSUP;
		}

		lsm6dso16is_hum_convert(val, data);
		break;

	case SENSOR_CHAN_PRESS:
		if (!data->shub_inited) {
			LOG_ERR("attr_set() shub not inited.");
			return -ENOTSUP;
		}

		lsm6dso16is_press_convert(val, data);
		break;

	case SENSOR_CHAN_AMBIENT_TEMP:
		if (!data->shub_inited) {
			LOG_ERR("attr_set() shub not inited.");
			return -ENOTSUP;
		}

		lsm6dso16is_temp_convert(val, data);
		break;
#endif
	default:
		return -ENOTSUP;
	}

	return 0;
}

static const struct sensor_driver_api lsm6dso16is_driver_api = {
	.attr_set = lsm6dso16is_attr_set,
#if CONFIG_LSM6DSO16IS_TRIGGER
	.trigger_set = lsm6dso16is_trigger_set,
#endif
	.sample_fetch = lsm6dso16is_sample_fetch,
	.channel_get = lsm6dso16is_channel_get,
};

static int lsm6dso16is_init_chip(const struct device *dev)
{
	const struct lsm6dso16is_config *cfg = dev->config;
	stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
	struct lsm6dso16is_data *lsm6dso16is = dev->data;
	uint8_t chip_id;
	uint8_t odr, fs;

	/* All registers except 0x01 are different between banks, including the WHO_AM_I
	 * register and the register used for a SW reset.  If the lsm6dso16is wasn't on the user
	 * bank when it reset, then both the chip id check and the sw reset will fail unless we
	 * set the bank now.
	 */
	if (lsm6dso16is_mem_bank_set(ctx, LSM6DSO16IS_MAIN_MEM_BANK) < 0) {
		LOG_DBG("Failed to set user bank");
		return -EIO;
	}

	if (lsm6dso16is_device_id_get(ctx, &chip_id) < 0) {
		LOG_DBG("Failed reading chip id");
		return -EIO;
	}

	LOG_INF("chip id 0x%x", chip_id);

	if (chip_id != LSM6DSO16IS_ID) {
		LOG_DBG("Invalid chip id 0x%x", chip_id);
		return -EIO;
	}

	/* reset device */
	if (lsm6dso16is_software_reset(ctx) < 0) {
		return -EIO;
	}

	fs = cfg->accel_range;
	LOG_DBG("accel range is %d", fs);
	if (lsm6dso16is_accel_set_fs_raw(dev, fs) < 0) {
		LOG_ERR("failed to set accelerometer range %d", fs);
		return -EIO;
	}
	lsm6dso16is->acc_gain = lsm6dso16is_accel_fs_map[fs] * GAIN_UNIT_XL / 2;

	odr = cfg->accel_odr;
	LOG_DBG("accel odr is %d", odr);
	if (lsm6dso16is_accel_set_odr_raw(dev, odr) < 0) {
		LOG_ERR("failed to set accelerometer odr %d", odr);
		return -EIO;
	}

	fs = cfg->gyro_range;
	LOG_DBG("gyro range is %d", fs);
	if (lsm6dso16is_gyro_set_fs_raw(dev, fs) < 0) {
		LOG_ERR("failed to set gyroscope range %d", fs);
		return -EIO;
	}
	lsm6dso16is->gyro_gain = (lsm6dso16is_gyro_fs_sens[fs] * GAIN_UNIT_G);

	odr = cfg->gyro_odr;
	LOG_DBG("gyro odr is %d", odr);
	lsm6dso16is->gyro_freq = lsm6dso16is_odr_to_freq_val(odr);
	if (lsm6dso16is_gyro_set_odr_raw(dev, odr) < 0) {
		LOG_ERR("failed to set gyroscope odr %d", odr);
		return -EIO;
	}

	if (lsm6dso16is_block_data_update_set(ctx, 1) < 0) {
		LOG_DBG("failed to set BDU mode");
		return -EIO;
	}

	return 0;
}

static int lsm6dso16is_init(const struct device *dev)
{
#ifdef CONFIG_LSM6DSO16IS_TRIGGER
	const struct lsm6dso16is_config *cfg = dev->config;
#endif
	struct lsm6dso16is_data *data = dev->data;

	LOG_INF("Initialize device %s", dev->name);
	data->dev = dev;

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

#ifdef CONFIG_LSM6DSO16IS_TRIGGER
	if (cfg->trig_enabled) {
		if (lsm6dso16is_init_interrupt(dev) < 0) {
			LOG_ERR("Failed to initialize interrupt.");
			return -EIO;
		}
	}
#endif

#ifdef CONFIG_LSM6DSO16IS_SENSORHUB
	data->shub_inited = true;
	if (lsm6dso16is_shub_init(dev) < 0) {
		LOG_INF("shub: no external chips found");
		data->shub_inited = false;
	}
#endif

	return 0;
}

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

/*
 * Device creation macro, shared by LSM6DSO16IS_DEFINE_SPI() and
 * LSM6DSO16IS_DEFINE_I2C().
 */

#define LSM6DSO16IS_DEVICE_INIT(inst)					\
	SENSOR_DEVICE_DT_INST_DEFINE(inst,				\
			    lsm6dso16is_init,				\
			    NULL,					\
			    &lsm6dso16is_data_##inst,			\
			    &lsm6dso16is_config_##inst,			\
			    POST_KERNEL,				\
			    CONFIG_SENSOR_INIT_PRIORITY,		\
			    &lsm6dso16is_driver_api);

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

#ifdef CONFIG_LSM6DSO16IS_TRIGGER
#define LSM6DSO16IS_CFG_IRQ(inst)						\
	.trig_enabled = true,						\
	.gpio_drdy = GPIO_DT_SPEC_INST_GET(inst, irq_gpios),		\
	.drdy_pin = DT_INST_PROP(inst, drdy_pin)
#else
#define LSM6DSO16IS_CFG_IRQ(inst)
#endif /* CONFIG_LSM6DSO16IS_TRIGGER */

#define LSM6DSO16IS_SPI_OP  (SPI_WORD_SET(8) |				\
			 SPI_OP_MODE_MASTER |				\
			 SPI_MODE_CPOL |				\
			 SPI_MODE_CPHA)					\

#define LSM6DSO16IS_CONFIG_COMMON(inst)					\
	.accel_odr = DT_INST_PROP(inst, accel_odr),			\
	.accel_range = DT_INST_PROP(inst, accel_range),			\
	.gyro_odr = DT_INST_PROP(inst, gyro_odr),			\
	.gyro_range = DT_INST_PROP(inst, gyro_range),			\
	.drdy_pulsed = DT_INST_PROP(inst, drdy_pulsed),                 \
	COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, irq_gpios),		\
		(LSM6DSO16IS_CFG_IRQ(inst)), ())


#define LSM6DSO16IS_CONFIG_SPI(inst)						\
	{									\
		STMEMSC_CTX_SPI(&lsm6dso16is_config_##inst.stmemsc_cfg),	\
		.stmemsc_cfg = {						\
			.spi = SPI_DT_SPEC_INST_GET(inst,			\
					   LSM6DSO16IS_SPI_OP,			\
					   0),					\
		},								\
		LSM6DSO16IS_CONFIG_COMMON(inst)					\
	}

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

#define LSM6DSO16IS_CONFIG_I2C(inst)						\
	{									\
		STMEMSC_CTX_I2C(&lsm6dso16is_config_##inst.stmemsc_cfg),	\
		.stmemsc_cfg = {						\
			.i2c = I2C_DT_SPEC_INST_GET(inst),			\
		},								\
		LSM6DSO16IS_CONFIG_COMMON(inst)					\
	}

/*
 * Main instantiation macro. Use of COND_CODE_1() selects the right
 * bus-specific macro at preprocessor time.
 */

#define LSM6DSO16IS_DEFINE(inst)						\
	static struct lsm6dso16is_data lsm6dso16is_data_##inst;			\
	static const struct lsm6dso16is_config lsm6dso16is_config_##inst =	\
		COND_CODE_1(DT_INST_ON_BUS(inst, spi),			\
			(LSM6DSO16IS_CONFIG_SPI(inst)),			\
			(LSM6DSO16IS_CONFIG_I2C(inst)));			\
	LSM6DSO16IS_DEVICE_INIT(inst)

DT_INST_FOREACH_STATUS_OKAY(LSM6DSO16IS_DEFINE)
