/*
 * Copyright (c) 2021 Bosch Sensortec GmbH
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT bosch_bmi270

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

#include "bmi270.h"
#include "bmi270_config_file.h"

LOG_MODULE_REGISTER(bmi270, CONFIG_SENSOR_LOG_LEVEL);

#define BMI270_WR_LEN                           256
#define BMI270_CONFIG_FILE_RETRIES              15
#define BMI270_CONFIG_FILE_POLL_PERIOD_US       10000
#define BMI270_INTER_WRITE_DELAY_US             1000

struct bmi270_config {
	union bmi270_bus bus;
	const struct bmi270_bus_io *bus_io;
};

static inline int bmi270_bus_check(const struct device *dev)
{
	const struct bmi270_config *cfg = dev->config;

	return cfg->bus_io->check(&cfg->bus);
}

static inline int bmi270_bus_init(const struct device *dev)
{
	const struct bmi270_config *cfg = dev->config;

	return cfg->bus_io->init(&cfg->bus);
}

static int bmi270_reg_read(const struct device *dev, uint8_t reg, uint8_t *data, uint16_t length)
{
	const struct bmi270_config *cfg = dev->config;

	return cfg->bus_io->read(&cfg->bus, reg, data, length);
}

static int bmi270_reg_write(const struct device *dev, uint8_t reg,
			    const uint8_t *data, uint16_t length)
{
	const struct bmi270_config *cfg = dev->config;

	return cfg->bus_io->write(&cfg->bus, reg, data, length);
}

static int bmi270_reg_write_with_delay(const struct device *dev,
				       uint8_t reg,
				       const uint8_t *data,
				       uint16_t length,
				       uint32_t delay_us)
{
	int ret = 0;

	ret = bmi270_reg_write(dev, reg, data, length);
	if (ret == 0) {
		k_usleep(delay_us);
	}
	return ret;
}

static void channel_accel_convert(struct sensor_value *val, int64_t raw_val,
				  uint8_t range)
{
	/* 16 bit accelerometer. 2^15 bits represent the range in G */
	/* Converting from G to m/s^2 */
	raw_val = (raw_val * SENSOR_G * (int64_t) range) / INT16_MAX;

	val->val1 = raw_val / 1000000LL;
	val->val2 = raw_val % 1000000LL;
}

static void channel_gyro_convert(struct sensor_value *val, int64_t raw_val,
				 uint16_t range)
{
	/* 16 bit gyroscope. 2^15 bits represent the range in degrees/s */
	/* Converting from degrees/s to radians/s */

	val->val1 = ((raw_val * (int64_t) range * SENSOR_PI)
		     / (180LL * INT16_MAX)) / 1000000LL;
	val->val2 = ((raw_val * (int64_t) range * SENSOR_PI)
		     / (180LL * INT16_MAX)) % 1000000LL;
}

static uint8_t acc_odr_to_reg(const struct sensor_value *val)
{
	double odr = sensor_value_to_double((struct sensor_value *) val);
	uint8_t reg = 0;

	if ((odr >= 0.78125) && (odr < 1.5625)) {
		reg = BMI270_ACC_ODR_25D32_HZ;
	} else if ((odr >= 1.5625) && (odr < 3.125)) {
		reg = BMI270_ACC_ODR_25D16_HZ;
	} else if ((odr >= 3.125) && (odr < 6.25)) {
		reg = BMI270_ACC_ODR_25D8_HZ;
	} else if ((odr >= 6.25) && (odr < 12.5)) {
		reg = BMI270_ACC_ODR_25D4_HZ;
	} else if ((odr >= 12.5) && (odr < 25.0)) {
		reg = BMI270_ACC_ODR_25D2_HZ;
	} else if ((odr >= 25.0) && (odr < 50.0)) {
		reg = BMI270_ACC_ODR_25_HZ;
	} else if ((odr >= 50.0) && (odr < 100.0)) {
		reg = BMI270_ACC_ODR_50_HZ;
	} else if ((odr >= 100.0) && (odr < 200.0)) {
		reg = BMI270_ACC_ODR_100_HZ;
	} else if ((odr >= 200.0) && (odr < 400.0)) {
		reg = BMI270_ACC_ODR_200_HZ;
	} else if ((odr >= 400.0) && (odr < 800.0)) {
		reg = BMI270_ACC_ODR_400_HZ;
	} else if ((odr >= 800.0) && (odr < 1600.0)) {
		reg = BMI270_ACC_ODR_800_HZ;
	} else if (odr >= 1600.0) {
		reg = BMI270_ACC_ODR_1600_HZ;
	}
	return reg;
}

static int set_accel_odr_osr(const struct device *dev, const struct sensor_value *odr,
			     const struct sensor_value *osr)
{
	struct bmi270_data *data = dev->data;
	uint8_t acc_conf, odr_bits, pwr_ctrl, osr_bits;
	int ret = 0;

	if (odr || osr) {
		ret = bmi270_reg_read(dev, BMI270_REG_ACC_CONF, &acc_conf, 1);
		if (ret != 0) {
			return ret;
		}

		ret = bmi270_reg_read(dev, BMI270_REG_PWR_CTRL, &pwr_ctrl, 1);
		if (ret != 0) {
			return ret;
		}
	}

	if (odr) {
		odr_bits = acc_odr_to_reg(odr);
		acc_conf = BMI270_SET_BITS_POS_0(acc_conf, BMI270_ACC_ODR,
						 odr_bits);

		/* If odr_bits is 0, implies that the sampling frequency is 0Hz
		 * or invalid too.
		 */
		if (odr_bits) {
			pwr_ctrl |= BMI270_PWR_CTRL_ACC_EN;
		} else {
			pwr_ctrl &= ~BMI270_PWR_CTRL_ACC_EN;
		}

		/* If the Sampling frequency (odr) >= 100Hz, enter performance
		 * mode else, power optimized. This also has a consequence
		 * for the OSR
		 */
		if (odr_bits >= BMI270_ACC_ODR_100_HZ) {
			acc_conf = BMI270_SET_BITS(acc_conf, BMI270_ACC_FILT,
						   BMI270_ACC_FILT_PERF_OPT);
		} else {
			acc_conf = BMI270_SET_BITS(acc_conf, BMI270_ACC_FILT,
						   BMI270_ACC_FILT_PWR_OPT);
		}

		data->acc_odr = odr_bits;
	}

	if (osr) {
		if (data->acc_odr >= BMI270_ACC_ODR_100_HZ) {
			/* Performance mode */
			/* osr->val2 should be unused */
			switch (osr->val1) {
			case 4:
				osr_bits = BMI270_ACC_BWP_OSR4_AVG1;
				break;
			case 2:
				osr_bits = BMI270_ACC_BWP_OSR2_AVG2;
				break;
			case 1:
				osr_bits = BMI270_ACC_BWP_NORM_AVG4;
				break;
			default:
				osr_bits = BMI270_ACC_BWP_CIC_AVG8;
				break;
			}
		} else {
			/* Power optimized mode */
			/* osr->val2 should be unused */
			switch (osr->val1) {
			case 1:
				osr_bits = BMI270_ACC_BWP_OSR4_AVG1;
				break;
			case 2:
				osr_bits = BMI270_ACC_BWP_OSR2_AVG2;
				break;
			case 4:
				osr_bits = BMI270_ACC_BWP_NORM_AVG4;
				break;
			case 8:
				osr_bits = BMI270_ACC_BWP_CIC_AVG8;
				break;
			case 16:
				osr_bits = BMI270_ACC_BWP_RES_AVG16;
				break;
			case 32:
				osr_bits = BMI270_ACC_BWP_RES_AVG32;
				break;
			case 64:
				osr_bits = BMI270_ACC_BWP_RES_AVG64;
				break;
			case 128:
				osr_bits = BMI270_ACC_BWP_RES_AVG128;
				break;
			default:
				return -ENOTSUP;
			}
		}

		acc_conf = BMI270_SET_BITS(acc_conf, BMI270_ACC_BWP,
					   osr_bits);
	}

	if (odr || osr) {
		ret = bmi270_reg_write(dev, BMI270_REG_ACC_CONF, &acc_conf, 1);
		if (ret != 0) {
			return ret;
		}

		/* Assuming we have advance power save enabled */
		k_usleep(BMI270_TRANSC_DELAY_SUSPEND);

		pwr_ctrl &= BMI270_PWR_CTRL_MSK;
		ret = bmi270_reg_write_with_delay(dev, BMI270_REG_PWR_CTRL,
						  &pwr_ctrl, 1,
						  BMI270_INTER_WRITE_DELAY_US);
	}

	return ret;
}

static int set_accel_range(const struct device *dev, const struct sensor_value *range)
{
	struct bmi270_data *data = dev->data;
	int ret = 0;
	uint8_t acc_range, reg;

	ret = bmi270_reg_read(dev, BMI270_REG_ACC_RANGE, &acc_range, 1);
	if (ret != 0) {
		return ret;
	}

	/* range->val2 is unused */
	switch (range->val1) {
	case 2:
		reg = BMI270_ACC_RANGE_2G;
		data->acc_range = 2;
		break;
	case 4:
		reg = BMI270_ACC_RANGE_4G;
		data->acc_range = 4;
		break;
	case 8:
		reg = BMI270_ACC_RANGE_8G;
		data->acc_range = 8;
		break;
	case 16:
		reg = BMI270_ACC_RANGE_16G;
		data->acc_range = 16;
		break;
	default:
		return -ENOTSUP;
	}

	acc_range = BMI270_SET_BITS_POS_0(acc_range, BMI270_ACC_RANGE,
					  reg);
	ret = bmi270_reg_write_with_delay(dev, BMI270_REG_ACC_RANGE, &acc_range,
					  1, BMI270_INTER_WRITE_DELAY_US);

	return ret;
}

static uint8_t gyr_odr_to_reg(const struct sensor_value *val)
{
	double odr = sensor_value_to_double((struct sensor_value *) val);
	uint8_t reg = 0;

	if ((odr >= 25.0) && (odr < 50.0)) {
		reg = BMI270_GYR_ODR_25_HZ;
	} else if ((odr >= 50.0) && (odr < 100.0)) {
		reg = BMI270_GYR_ODR_50_HZ;
	} else if ((odr >= 100.0) && (odr < 200.0)) {
		reg = BMI270_GYR_ODR_100_HZ;
	} else if ((odr >= 200.0) && (odr < 400.0)) {
		reg = BMI270_GYR_ODR_200_HZ;
	} else if ((odr >= 400.0) && (odr < 800.0)) {
		reg = BMI270_GYR_ODR_400_HZ;
	} else if ((odr >= 800.0) && (odr < 1600.0)) {
		reg = BMI270_GYR_ODR_800_HZ;
	} else if ((odr >= 1600.0) && (odr < 3200.0)) {
		reg = BMI270_GYR_ODR_1600_HZ;
	} else if (odr >= 3200.0) {
		reg = BMI270_GYR_ODR_3200_HZ;
	}

	return reg;
}

static int set_gyro_odr_osr(const struct device *dev, const struct sensor_value *odr,
			    const struct sensor_value *osr)
{
	struct bmi270_data *data = dev->data;
	uint8_t gyr_conf, odr_bits, pwr_ctrl, osr_bits;
	int ret = 0;

	if (odr || osr) {
		ret = bmi270_reg_read(dev, BMI270_REG_GYR_CONF, &gyr_conf, 1);
		if (ret != 0) {
			return ret;
		}

		ret = bmi270_reg_read(dev, BMI270_REG_PWR_CTRL, &pwr_ctrl, 1);
		if (ret != 0) {
			return ret;
		}
	}

	if (odr) {
		odr_bits = gyr_odr_to_reg(odr);
		gyr_conf = BMI270_SET_BITS_POS_0(gyr_conf, BMI270_GYR_ODR,
						 odr_bits);

		/* If odr_bits is 0, implies that the sampling frequency is
		 * 0Hz or invalid too.
		 */
		if (odr_bits) {
			pwr_ctrl |= BMI270_PWR_CTRL_GYR_EN;
		} else {
			pwr_ctrl &= ~BMI270_PWR_CTRL_GYR_EN;
		}

		/* If the Sampling frequency (odr) >= 100Hz, enter performance
		 * mode else, power optimized. This also has a consequence for
		 * the OSR
		 */
		if (odr_bits >= BMI270_GYR_ODR_100_HZ) {
			gyr_conf = BMI270_SET_BITS(gyr_conf,
						   BMI270_GYR_FILT,
						   BMI270_GYR_FILT_PERF_OPT);
			gyr_conf = BMI270_SET_BITS(gyr_conf,
						   BMI270_GYR_FILT_NOISE,
						   BMI270_GYR_FILT_NOISE_PERF);
		} else {
			gyr_conf = BMI270_SET_BITS(gyr_conf,
						   BMI270_GYR_FILT,
						   BMI270_GYR_FILT_PWR_OPT);
			gyr_conf = BMI270_SET_BITS(gyr_conf,
						   BMI270_GYR_FILT_NOISE,
						   BMI270_GYR_FILT_NOISE_PWR);
		}

		data->gyr_odr = odr_bits;
	}

	if (osr) {
		/* osr->val2 should be unused */
		switch (osr->val1) {
		case 4:
			osr_bits = BMI270_GYR_BWP_OSR4;
			break;
		case 2:
			osr_bits = BMI270_GYR_BWP_OSR2;
			break;
		default:
			osr_bits = BMI270_GYR_BWP_NORM;
			break;
		}

		gyr_conf = BMI270_SET_BITS(gyr_conf, BMI270_GYR_BWP,
					   osr_bits);
	}

	if (odr || osr) {
		ret = bmi270_reg_write(dev, BMI270_REG_GYR_CONF, &gyr_conf, 1);
		if (ret != 0) {
			return ret;
		}

		/* Assuming we have advance power save enabled */
		k_usleep(BMI270_TRANSC_DELAY_SUSPEND);

		pwr_ctrl &= BMI270_PWR_CTRL_MSK;
		ret = bmi270_reg_write_with_delay(dev, BMI270_REG_PWR_CTRL,
						  &pwr_ctrl, 1,
						  BMI270_INTER_WRITE_DELAY_US);
	}

	return ret;
}

static int set_gyro_range(const struct device *dev, const struct sensor_value *range)
{
	struct bmi270_data *data = dev->data;
	int ret = 0;
	uint8_t gyr_range, reg;

	ret = bmi270_reg_read(dev, BMI270_REG_GYR_RANGE, &gyr_range, 1);
	if (ret != 0) {
		return ret;
	}

	/* range->val2 is unused */
	switch (range->val1) {
	case 125:
		reg = BMI270_GYR_RANGE_125DPS;
		data->gyr_range = 125;
		break;
	case 250:
		reg = BMI270_GYR_RANGE_250DPS;
		data->gyr_range = 250;
		break;
	case 500:
		reg = BMI270_GYR_RANGE_500DPS;
		data->gyr_range = 500;
		break;
	case 1000:
		reg = BMI270_GYR_RANGE_1000DPS;
		data->gyr_range = 1000;
		break;
	case 2000:
		reg = BMI270_GYR_RANGE_2000DPS;
		data->gyr_range = 2000;
		break;
	default:
		return -ENOTSUP;
	}

	gyr_range = BMI270_SET_BITS_POS_0(gyr_range, BMI270_GYR_RANGE, reg);
	ret = bmi270_reg_write_with_delay(dev, BMI270_REG_GYR_RANGE, &gyr_range,
					  1, BMI270_INTER_WRITE_DELAY_US);

	return ret;
}

static int8_t write_config_file(const struct device *dev)
{
	int8_t ret = 0;
	uint16_t index = 0;
	uint8_t addr_array[2] = { 0 };

	/* Disable loading of the configuration */
	for (index = 0; index < sizeof(bmi270_config_file);
	     index += BMI270_WR_LEN) {
		/* Store 0 to 3 bits of address in first byte */
		addr_array[0] = (uint8_t)((index / 2) & 0x0F);

		/* Store 4 to 11 bits of address in the second byte */
		addr_array[1] = (uint8_t)((index / 2) >> 4);

		ret = bmi270_reg_write_with_delay(dev, BMI270_REG_INIT_ADDR_0,
						  addr_array, 2,
						  BMI270_INTER_WRITE_DELAY_US);

		if (ret == 0) {
			ret = bmi270_reg_write_with_delay(dev,
						BMI270_REG_INIT_DATA,
						(bmi270_config_file + index),
						BMI270_WR_LEN,
						BMI270_INTER_WRITE_DELAY_US);
		}
	}

	return ret;
}

static int bmi270_sample_fetch(const struct device *dev, enum sensor_channel chan)
{
	struct bmi270_data *data = dev->data;
	uint8_t buf[12];
	int ret;

	if (chan != SENSOR_CHAN_ALL) {
		return -ENOTSUP;
	}

	ret = bmi270_reg_read(dev, BMI270_REG_ACC_X_LSB, buf, 12);
	if (ret == 0) {
		data->ax = (int16_t)sys_get_le16(&buf[0]);
		data->ay = (int16_t)sys_get_le16(&buf[2]);
		data->az = (int16_t)sys_get_le16(&buf[4]);
		data->gx = (int16_t)sys_get_le16(&buf[6]);
		data->gy = (int16_t)sys_get_le16(&buf[8]);
		data->gz = (int16_t)sys_get_le16(&buf[10]);
	} else {
		data->ax = 0;
		data->ay = 0;
		data->az = 0;
		data->gx = 0;
		data->gy = 0;
		data->gz = 0;
	}

	return ret;
}

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

	if (chan == SENSOR_CHAN_ACCEL_X) {
		channel_accel_convert(val, data->ax, data->acc_range);
	} else if (chan == SENSOR_CHAN_ACCEL_Y) {
		channel_accel_convert(val, data->ay, data->acc_range);
	} else if (chan == SENSOR_CHAN_ACCEL_Z) {
		channel_accel_convert(val, data->az, data->acc_range);
	} else if (chan == SENSOR_CHAN_ACCEL_XYZ) {
		channel_accel_convert(&val[0], data->ax,
				      data->acc_range);
		channel_accel_convert(&val[1], data->ay,
				      data->acc_range);
		channel_accel_convert(&val[2], data->az,
				      data->acc_range);
	} else if (chan == SENSOR_CHAN_GYRO_X) {
		channel_gyro_convert(val, data->gx, data->gyr_range);
	} else if (chan == SENSOR_CHAN_GYRO_Y) {
		channel_gyro_convert(val, data->gy, data->gyr_range);
	} else if (chan == SENSOR_CHAN_GYRO_Z) {
		channel_gyro_convert(val, data->gz, data->gyr_range);
	} else if (chan == SENSOR_CHAN_GYRO_XYZ) {
		channel_gyro_convert(&val[0], data->gx,
				     data->gyr_range);
		channel_gyro_convert(&val[1], data->gy,
				     data->gyr_range);
		channel_gyro_convert(&val[2], data->gz,
				     data->gyr_range);
	} else {
		return -ENOTSUP;
	}

	return 0;
}

static int bmi270_attr_set(const struct device *dev, enum sensor_channel chan,
			   enum sensor_attribute attr, const struct sensor_value *val)
{
	int ret = -ENOTSUP;

	if ((chan == SENSOR_CHAN_ACCEL_X) || (chan == SENSOR_CHAN_ACCEL_Y)
	    || (chan == SENSOR_CHAN_ACCEL_Z)
	    || (chan == SENSOR_CHAN_ACCEL_XYZ)) {
		switch (attr) {
		case SENSOR_ATTR_SAMPLING_FREQUENCY:
			ret = set_accel_odr_osr(dev, val, NULL);
			break;
		case SENSOR_ATTR_OVERSAMPLING:
			ret = set_accel_odr_osr(dev, NULL, val);
			break;
		case SENSOR_ATTR_FULL_SCALE:
			ret = set_accel_range(dev, val);
			break;
		default:
			ret = -ENOTSUP;
		}
	} else if ((chan == SENSOR_CHAN_GYRO_X) || (chan == SENSOR_CHAN_GYRO_Y)
		   || (chan == SENSOR_CHAN_GYRO_Z)
		   || (chan == SENSOR_CHAN_GYRO_XYZ)) {
		switch (attr) {
		case SENSOR_ATTR_SAMPLING_FREQUENCY:
			ret = set_gyro_odr_osr(dev, val, NULL);
			break;
		case SENSOR_ATTR_OVERSAMPLING:
			ret = set_gyro_odr_osr(dev, NULL, val);
			break;
		case SENSOR_ATTR_FULL_SCALE:
			ret = set_gyro_range(dev, val);
			break;
		default:
			ret = -ENOTSUP;
		}

	} else {
		ret = -ENOTSUP;
	}

	return ret;
}

static int bmi270_init(const struct device *dev)
{
	int ret;
	struct bmi270_data *data = dev->data;
	uint8_t chip_id;
	uint8_t soft_reset_cmd;
	uint8_t init_ctrl;
	uint8_t msg;
	uint8_t tries;
	uint8_t adv_pwr_save;

	ret = bmi270_bus_check(dev);
	if (ret < 0) {
		LOG_ERR("Could not initialize bus");
		return ret;
	}

	data->acc_odr = BMI270_ACC_ODR_100_HZ;
	data->acc_range = 8;
	data->gyr_odr = BMI270_GYR_ODR_200_HZ;
	data->gyr_range = 2000;

	k_usleep(BMI270_POWER_ON_TIME);

	ret = bmi270_bus_init(dev);
	if (ret != 0) {
		LOG_ERR("Could not initiate bus communication");
		return ret;
	}

	ret = bmi270_reg_read(dev, BMI270_REG_CHIP_ID, &chip_id, 1);
	if (ret != 0) {
		return ret;
	}

	if (chip_id != BMI270_CHIP_ID) {
		LOG_ERR("Unexpected chip id (%x). Expected (%x)",
			chip_id, BMI270_CHIP_ID);
		return -EIO;
	}

	soft_reset_cmd = BMI270_CMD_SOFT_RESET;
	ret = bmi270_reg_write(dev, BMI270_REG_CMD, &soft_reset_cmd, 1);
	if (ret != 0) {
		return ret;
	}

	k_usleep(BMI270_SOFT_RESET_TIME);

	ret = bmi270_reg_read(dev, BMI270_REG_PWR_CONF, &adv_pwr_save, 1);
	if (ret != 0) {
		return ret;
	}

	adv_pwr_save = BMI270_SET_BITS_POS_0(adv_pwr_save,
					     BMI270_PWR_CONF_ADV_PWR_SAVE,
					     BMI270_PWR_CONF_ADV_PWR_SAVE_DIS);
	ret = bmi270_reg_write_with_delay(dev, BMI270_REG_PWR_CONF,
					  &adv_pwr_save, 1,
					  BMI270_INTER_WRITE_DELAY_US);
	if (ret != 0) {
		return ret;
	}

	init_ctrl = BMI270_PREPARE_CONFIG_LOAD;
	ret = bmi270_reg_write(dev, BMI270_REG_INIT_CTRL, &init_ctrl, 1);
	if (ret != 0) {
		return ret;
	}

	ret = write_config_file(dev);

	if (ret != 0) {
		return ret;
	}

	init_ctrl = BMI270_COMPLETE_CONFIG_LOAD;
	ret = bmi270_reg_write(dev, BMI270_REG_INIT_CTRL, &init_ctrl, 1);
	if (ret != 0) {
		return ret;
	}

	/* Timeout after BMI270_CONFIG_FILE_RETRIES x
	 * BMI270_CONFIG_FILE_POLL_PERIOD_US microseconds.
	 * If tries is BMI270_CONFIG_FILE_RETRIES by the end of the loop,
	 * report an error
	 */
	for (tries = 0; tries <= BMI270_CONFIG_FILE_RETRIES; tries++) {
		ret = bmi270_reg_read(dev, BMI270_REG_INTERNAL_STATUS, &msg, 1);
		if (ret != 0) {
			return ret;
		}

		msg &= BMI270_INST_MESSAGE_MSK;
		if (msg == BMI270_INST_MESSAGE_INIT_OK) {
			break;
		}

		k_usleep(BMI270_CONFIG_FILE_POLL_PERIOD_US);
	}

	if (tries == BMI270_CONFIG_FILE_RETRIES) {
		return -EIO;
	}

	adv_pwr_save = BMI270_SET_BITS_POS_0(adv_pwr_save,
					     BMI270_PWR_CONF_ADV_PWR_SAVE,
					     BMI270_PWR_CONF_ADV_PWR_SAVE_EN);
	ret = bmi270_reg_write_with_delay(dev, BMI270_REG_PWR_CONF,
					  &adv_pwr_save, 1,
					  BMI270_INTER_WRITE_DELAY_US);

	return ret;
}

static const struct sensor_driver_api bmi270_driver_api = {
	.sample_fetch = bmi270_sample_fetch,
	.channel_get = bmi270_channel_get,
	.attr_set = bmi270_attr_set
};

/* Initializes a struct bmi270_config for an instance on a SPI bus. */
#define BMI270_CONFIG_SPI(inst)				\
	{						\
		.bus.spi = SPI_DT_SPEC_INST_GET(	\
			inst, BMI270_SPI_OPERATION, 0),	\
		.bus_io = &bmi270_bus_io_spi,		\
	}

/* Initializes a struct bmi270_config for an instance on an I2C bus. */
#define BMI270_CONFIG_I2C(inst)			       \
	{					       \
		.bus.i2c = I2C_DT_SPEC_INST_GET(inst), \
		.bus_io = &bmi270_bus_io_i2c,	       \
	}


#define BMI270_CREATE_INST(inst)					\
									\
	static struct bmi270_data bmi270_drv_##inst;			\
									\
	static const struct bmi270_config bmi270_config_##inst =	\
		COND_CODE_1(DT_INST_ON_BUS(inst, spi),			\
			    (BMI270_CONFIG_SPI(inst)),			\
			    (BMI270_CONFIG_I2C(inst)));			\
									\
	SENSOR_DEVICE_DT_INST_DEFINE(inst,				\
			      bmi270_init,				\
			      NULL,					\
			      &bmi270_drv_##inst,			\
			      &bmi270_config_##inst,			\
			      POST_KERNEL,				\
			      CONFIG_SENSOR_INIT_PRIORITY,		\
			      &bmi270_driver_api);

DT_INST_FOREACH_STATUS_OKAY(BMI270_CREATE_INST)
