From 1a1c407c6828aea3e940032ce991fee03b5a3961 Mon Sep 17 00:00:00 2001
From: Dominik Chat <dominik.chat@nordicsemi.no>
Date: Thu, 18 Aug 2022 14:22:10 +0200
Subject: [PATCH 1/3] sensor: dts: Add SPI capability to bmi270 driver

Added SPI bus support for BMI270 gyroscope driver.

Signed-off-by: Dominik Chat <dominik.chat@nordicsemi.no>
---
 drivers/sensor/bmi270/CMakeLists.txt      |   3 +
 drivers/sensor/bmi270/Kconfig             |  20 ++-
 drivers/sensor/bmi270/bmi270.c            | 179 ++++++++++++++--------
 drivers/sensor/bmi270/bmi270.h            |  39 ++++-
 drivers/sensor/bmi270/bmi270_i2c.c        |  42 +++++
 drivers/sensor/bmi270/bmi270_spi.c        | 101 ++++++++++++
 dts/bindings/sensor/bosch,bmi270-i2c.yaml |   7 +-
 dts/bindings/sensor/bosch,bmi270-spi.yaml |   6 +
 dts/bindings/sensor/bosch,bmi270.yaml     |   9 ++
 9 files changed, 335 insertions(+), 71 deletions(-)
 create mode 100644 drivers/sensor/bmi270/bmi270_i2c.c
 create mode 100644 drivers/sensor/bmi270/bmi270_spi.c
 create mode 100644 dts/bindings/sensor/bosch,bmi270-spi.yaml
 create mode 100644 dts/bindings/sensor/bosch,bmi270.yaml

diff --git a/drivers/sensor/bmi270/CMakeLists.txt b/drivers/sensor/bmi270/CMakeLists.txt
index 29d278355c2..5f9b4bb2a60 100644
--- a/drivers/sensor/bmi270/CMakeLists.txt
+++ b/drivers/sensor/bmi270/CMakeLists.txt
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2021 Bosch Sensortec GmbH
+# Copyright (c) 2022 Nordic Semiconductor ASA
 #
 # SPDX-License-Identifier: Apache-2.0
 #
@@ -7,3 +8,5 @@
 zephyr_library()
 
 zephyr_library_sources(bmi270.c)
+zephyr_library_sources_ifdef(CONFIG_BMI270_BUS_I2C bmi270_i2c.c)
+zephyr_library_sources_ifdef(CONFIG_BMI270_BUS_SPI bmi270_spi.c)
diff --git a/drivers/sensor/bmi270/Kconfig b/drivers/sensor/bmi270/Kconfig
index 90bbe131b8b..f8cd1ba2840 100644
--- a/drivers/sensor/bmi270/Kconfig
+++ b/drivers/sensor/bmi270/Kconfig
@@ -1,12 +1,28 @@
 # BMI270 6 Axis IMU configuration
 
 # Copyright (c) 2021 Bosch Sensortec GmbH
+# Copyright (c) 2022 Nordic Semiconductor ASA
 # SPDX-License-Identifier: Apache-2.0
 
-config BMI270
+menuconfig BMI270
 	bool "BMI270 Inertial measurement unit"
 	default y
 	depends on DT_HAS_BOSCH_BMI270_ENABLED
-	select I2C
+	select I2C if $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI270),i2c)
+	select SPI if $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI270),spi)
 	help
 	  Enable driver for BMI270 I2C-based imu sensor
+
+if BMI270
+
+config BMI270_BUS_I2C
+	bool
+	default y
+	depends on $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI270),i2c)
+
+config BMI270_BUS_SPI
+	bool
+	default y
+	depends on $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI270),spi)
+
+endif # BMI270
diff --git a/drivers/sensor/bmi270/bmi270.c b/drivers/sensor/bmi270/bmi270.c
index 940168e4184..45077557923 100644
--- a/drivers/sensor/bmi270/bmi270.c
+++ b/drivers/sensor/bmi270/bmi270.c
@@ -1,12 +1,12 @@
 /*
  * 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/i2c.h>
 #include <zephyr/drivers/sensor.h>
 #include <zephyr/init.h>
 #include <zephyr/sys/__assert.h>
@@ -23,26 +23,49 @@ LOG_MODULE_REGISTER(bmi270, CONFIG_SENSOR_LOG_LEVEL);
 #define BMI270_CONFIG_FILE_POLL_PERIOD_US       10000
 #define BMI270_INTER_WRITE_DELAY_US             1000
 
-static int reg_read(const struct device *dev, uint8_t reg, uint8_t *data, uint16_t length)
+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_dev_config *cfg = dev->config;
+	const struct bmi270_config *cfg = dev->config;
 
-	return i2c_burst_read_dt(&cfg->i2c, reg, data, length);
+	return cfg->bus_io->init(&cfg->bus);
 }
 
-static int reg_write(const struct device *dev, uint8_t reg, const uint8_t *data, uint16_t length)
+static int bmi270_reg_read(const struct device *dev, uint8_t reg, uint8_t *data, uint16_t length)
 {
-	const struct bmi270_dev_config *cfg = dev->config;
+	const struct bmi270_config *cfg = dev->config;
 
-	return i2c_burst_write_dt(&cfg->i2c, reg, data, length);
+	return cfg->bus_io->read(&cfg->bus, reg, data, length);
 }
 
-static int reg_write_with_delay(const struct device *dev, uint8_t reg, const uint8_t *data,
-				uint16_t length, uint32_t delay_us)
+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 = reg_write(dev, reg, data, length);
+	ret = bmi270_reg_write(dev, reg, data, length);
 	if (ret == 0) {
 		k_usleep(delay_us);
 	}
@@ -125,12 +148,12 @@ static int set_accel_odr_osr(const struct device *dev, const struct sensor_value
 	int ret = 0;
 
 	if (odr || osr) {
-		ret = reg_read(dev, BMI270_REG_ACC_CONF, &acc_conf, 1);
+		ret = bmi270_reg_read(dev, BMI270_REG_ACC_CONF, &acc_conf, 1);
 		if (ret != 0) {
 			return ret;
 		}
 
-		ret = reg_read(dev, BMI270_REG_PWR_CTRL, &pwr_ctrl, 1);
+		ret = bmi270_reg_read(dev, BMI270_REG_PWR_CTRL, &pwr_ctrl, 1);
 		if (ret != 0) {
 			return ret;
 		}
@@ -221,7 +244,7 @@ static int set_accel_odr_osr(const struct device *dev, const struct sensor_value
 	}
 
 	if (odr || osr) {
-		ret = reg_write(dev, BMI270_REG_ACC_CONF, &acc_conf, 1);
+		ret = bmi270_reg_write(dev, BMI270_REG_ACC_CONF, &acc_conf, 1);
 		if (ret != 0) {
 			return ret;
 		}
@@ -230,8 +253,9 @@ static int set_accel_odr_osr(const struct device *dev, const struct sensor_value
 		k_usleep(BMI270_TRANSC_DELAY_SUSPEND);
 
 		pwr_ctrl &= BMI270_PWR_CTRL_MSK;
-		ret = reg_write_with_delay(dev, BMI270_REG_PWR_CTRL, &pwr_ctrl, 1,
-			BMI270_INTER_WRITE_DELAY_US);
+		ret = bmi270_reg_write_with_delay(dev, BMI270_REG_PWR_CTRL,
+						  &pwr_ctrl, 1,
+						  BMI270_INTER_WRITE_DELAY_US);
 	}
 
 	return ret;
@@ -243,7 +267,7 @@ static int set_accel_range(const struct device *dev, const struct sensor_value *
 	int ret = 0;
 	uint8_t acc_range, reg;
 
-	ret = reg_read(dev, BMI270_REG_ACC_RANGE, &acc_range, 1);
+	ret = bmi270_reg_read(dev, BMI270_REG_ACC_RANGE, &acc_range, 1);
 	if (ret != 0) {
 		return ret;
 	}
@@ -272,8 +296,8 @@ static int set_accel_range(const struct device *dev, const struct sensor_value *
 
 	acc_range = BMI270_SET_BITS_POS_0(acc_range, BMI270_ACC_RANGE,
 					  reg);
-	ret = reg_write_with_delay(dev, BMI270_REG_ACC_RANGE, &acc_range, 1,
-				   BMI270_INTER_WRITE_DELAY_US);
+	ret = bmi270_reg_write_with_delay(dev, BMI270_REG_ACC_RANGE, &acc_range,
+					  1, BMI270_INTER_WRITE_DELAY_US);
 
 	return ret;
 }
@@ -312,12 +336,12 @@ static int set_gyro_odr_osr(const struct device *dev, const struct sensor_value
 	int ret = 0;
 
 	if (odr || osr) {
-		ret = reg_read(dev, BMI270_REG_GYR_CONF, &gyr_conf, 1);
+		ret = bmi270_reg_read(dev, BMI270_REG_GYR_CONF, &gyr_conf, 1);
 		if (ret != 0) {
 			return ret;
 		}
 
-		ret = reg_read(dev, BMI270_REG_PWR_CTRL, &pwr_ctrl, 1);
+		ret = bmi270_reg_read(dev, BMI270_REG_PWR_CTRL, &pwr_ctrl, 1);
 		if (ret != 0) {
 			return ret;
 		}
@@ -379,7 +403,7 @@ static int set_gyro_odr_osr(const struct device *dev, const struct sensor_value
 	}
 
 	if (odr || osr) {
-		ret = reg_write(dev, BMI270_REG_GYR_CONF, &gyr_conf, 1);
+		ret = bmi270_reg_write(dev, BMI270_REG_GYR_CONF, &gyr_conf, 1);
 		if (ret != 0) {
 			return ret;
 		}
@@ -388,8 +412,9 @@ static int set_gyro_odr_osr(const struct device *dev, const struct sensor_value
 		k_usleep(BMI270_TRANSC_DELAY_SUSPEND);
 
 		pwr_ctrl &= BMI270_PWR_CTRL_MSK;
-		ret = reg_write_with_delay(dev, BMI270_REG_PWR_CTRL, &pwr_ctrl, 1,
-			BMI270_INTER_WRITE_DELAY_US);
+		ret = bmi270_reg_write_with_delay(dev, BMI270_REG_PWR_CTRL,
+						  &pwr_ctrl, 1,
+						  BMI270_INTER_WRITE_DELAY_US);
 	}
 
 	return ret;
@@ -401,7 +426,7 @@ static int set_gyro_range(const struct device *dev, const struct sensor_value *r
 	int ret = 0;
 	uint8_t gyr_range, reg;
 
-	ret = reg_read(dev, BMI270_REG_GYR_RANGE, &gyr_range, 1);
+	ret = bmi270_reg_read(dev, BMI270_REG_GYR_RANGE, &gyr_range, 1);
 	if (ret != 0) {
 		return ret;
 	}
@@ -433,8 +458,8 @@ static int set_gyro_range(const struct device *dev, const struct sensor_value *r
 	}
 
 	gyr_range = BMI270_SET_BITS_POS_0(gyr_range, BMI270_GYR_RANGE, reg);
-	ret = reg_write_with_delay(dev, BMI270_REG_GYR_RANGE, &gyr_range, 1,
-		BMI270_INTER_WRITE_DELAY_US);
+	ret = bmi270_reg_write_with_delay(dev, BMI270_REG_GYR_RANGE, &gyr_range,
+					  1, BMI270_INTER_WRITE_DELAY_US);
 
 	return ret;
 }
@@ -454,13 +479,16 @@ static int8_t write_config_file(const struct device *dev)
 		/* Store 4 to 11 bits of address in the second byte */
 		addr_array[1] = (uint8_t)((index / 2) >> 4);
 
-		ret = reg_write_with_delay(dev, BMI270_REG_INIT_ADDR_0, addr_array, 2,
-			BMI270_INTER_WRITE_DELAY_US);
+		ret = bmi270_reg_write_with_delay(dev, BMI270_REG_INIT_ADDR_0,
+						  addr_array, 2,
+						  BMI270_INTER_WRITE_DELAY_US);
 
 		if (ret == 0) {
-			ret = reg_write_with_delay(dev, BMI270_REG_INIT_DATA,
-				(bmi270_config_file + index),
-				BMI270_WR_LEN, BMI270_INTER_WRITE_DELAY_US);
+			ret = bmi270_reg_write_with_delay(dev,
+						BMI270_REG_INIT_DATA,
+						(bmi270_config_file + index),
+						BMI270_WR_LEN,
+						BMI270_INTER_WRITE_DELAY_US);
 		}
 	}
 
@@ -477,7 +505,7 @@ static int bmi270_sample_fetch(const struct device *dev, enum sensor_channel cha
 		return -ENOTSUP;
 	}
 
-	ret = reg_read(dev, BMI270_REG_ACC_X_LSB, data, 12);
+	ret = bmi270_reg_read(dev, BMI270_REG_ACC_X_LSB, data, 12);
 	if (ret == 0) {
 		drv_dev->ax = (int16_t)sys_get_le16(&data[0]);
 		drv_dev->ay = (int16_t)sys_get_le16(&data[2]);
@@ -584,7 +612,6 @@ static int bmi270_init(const struct device *dev)
 {
 	int ret;
 	struct bmi270_data *drv_dev = dev->data;
-	const struct bmi270_dev_config *cfg = dev->config;
 	uint8_t chip_id;
 	uint8_t soft_reset_cmd;
 	uint8_t init_ctrl;
@@ -592,9 +619,10 @@ static int bmi270_init(const struct device *dev)
 	uint8_t tries;
 	uint8_t adv_pwr_save;
 
-	if (!device_is_ready(cfg->i2c.bus)) {
-		LOG_ERR("I2C bus device not ready");
-		return -ENODEV;
+	ret = bmi270_bus_check(dev);
+	if (ret < 0) {
+		LOG_ERR("Could not initialize bus");
+		return ret;
 	}
 
 	drv_dev->acc_odr = BMI270_ACC_ODR_100_HZ;
@@ -604,7 +632,13 @@ static int bmi270_init(const struct device *dev)
 
 	k_usleep(BMI270_POWER_ON_TIME);
 
-	ret = reg_read(dev, BMI270_REG_CHIP_ID, &chip_id, 1);
+	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;
 	}
@@ -616,14 +650,14 @@ static int bmi270_init(const struct device *dev)
 	}
 
 	soft_reset_cmd = BMI270_CMD_SOFT_RESET;
-	ret = reg_write(dev, BMI270_REG_CMD, &soft_reset_cmd, 1);
+	ret = bmi270_reg_write(dev, BMI270_REG_CMD, &soft_reset_cmd, 1);
 	if (ret != 0) {
 		return ret;
 	}
 
 	k_usleep(BMI270_SOFT_RESET_TIME);
 
-	ret = reg_read(dev, BMI270_REG_PWR_CONF, &adv_pwr_save, 1);
+	ret = bmi270_reg_read(dev, BMI270_REG_PWR_CONF, &adv_pwr_save, 1);
 	if (ret != 0) {
 		return ret;
 	}
@@ -631,14 +665,15 @@ static int bmi270_init(const struct device *dev)
 	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 = reg_write_with_delay(dev, BMI270_REG_PWR_CONF, &adv_pwr_save, 1,
-		BMI270_INTER_WRITE_DELAY_US);
+	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 = reg_write(dev, BMI270_REG_INIT_CTRL, &init_ctrl, 1);
+	ret = bmi270_reg_write(dev, BMI270_REG_INIT_CTRL, &init_ctrl, 1);
 	if (ret != 0) {
 		return ret;
 	}
@@ -650,18 +685,18 @@ static int bmi270_init(const struct device *dev)
 	}
 
 	init_ctrl = BMI270_COMPLETE_CONFIG_LOAD;
-	ret = reg_write(dev, BMI270_REG_INIT_CTRL, &init_ctrl, 1);
+	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 0 by the end of the loop,
+	 * 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 = reg_read(dev, BMI270_REG_INTERNAL_STATUS, &msg, 1);
+		ret = bmi270_reg_read(dev, BMI270_REG_INTERNAL_STATUS, &msg, 1);
 		if (ret != 0) {
 			return ret;
 		}
@@ -674,15 +709,16 @@ static int bmi270_init(const struct device *dev)
 		k_usleep(BMI270_CONFIG_FILE_POLL_PERIOD_US);
 	}
 
-	if (tries == 0) {
+	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 = reg_write_with_delay(dev, BMI270_REG_PWR_CONF, &adv_pwr_save, 1,
-		BMI270_INTER_WRITE_DELAY_US);
+	ret = bmi270_reg_write_with_delay(dev, BMI270_REG_PWR_CONF,
+					  &adv_pwr_save, 1,
+					  BMI270_INTER_WRITE_DELAY_US);
 
 	return ret;
 }
@@ -693,21 +729,38 @@ static const struct sensor_driver_api bmi270_driver_api = {
 	.attr_set = bmi270_attr_set
 };
 
-#define BMI270_CREATE_INST(inst)				       \
-								       \
-	static struct bmi270_data bmi270_drv_##inst;		       \
-								       \
-	static const struct bmi270_dev_config bmi270_config_##inst = { \
-		.i2c = I2C_DT_SPEC_INST_GET(inst),		       \
-	};							       \
-								       \
-	DEVICE_DT_INST_DEFINE(inst,				       \
-			      bmi270_init,			       \
-			      NULL,				       \
-			      &bmi270_drv_##inst,		       \
-			      &bmi270_config_##inst,		       \
-			      POST_KERNEL,			       \
-			      CONFIG_SENSOR_INIT_PRIORITY,	       \
+/* 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)));			\
+									\
+	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)
diff --git a/drivers/sensor/bmi270/bmi270.h b/drivers/sensor/bmi270/bmi270.h
index 51e9d387165..50605361844 100644
--- a/drivers/sensor/bmi270/bmi270.h
+++ b/drivers/sensor/bmi270/bmi270.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2021 Bosch Sensortec GmbH
+ * Copyright (c) 2022 Nordic Semiconductor ASA
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -11,7 +12,9 @@
 #include <zephyr/sys/util.h>
 #include <zephyr/types.h>
 #include <zephyr/drivers/sensor.h>
+#include <zephyr/drivers/spi.h>
 #include <zephyr/drivers/i2c.h>
+#include <zephyr/devicetree.h>
 
 #define BMI270_REG_CHIP_ID         0x00
 #define BMI270_REG_ERROR           0x02
@@ -67,6 +70,7 @@
 #define BMI270_REG_PWR_CONF        0x7C
 #define BMI270_REG_PWR_CTRL        0x7D
 #define BMI270_REG_CMD             0x7E
+#define BMI270_REG_MASK            GENMASK(6, 0)
 
 #define BMI270_CHIP_ID 0x24
 
@@ -206,8 +210,41 @@ struct bmi270_data {
 	uint16_t gyr_range;
 };
 
-struct bmi270_dev_config {
+union bmi270_bus {
+#if CONFIG_BMI270_BUS_SPI
+	struct spi_dt_spec spi;
+#endif
+#if CONFIG_BMI270_BUS_I2C
 	struct i2c_dt_spec i2c;
+#endif
 };
 
+typedef int (*bmi270_bus_check_fn)(const union bmi270_bus *bus);
+typedef int (*bmi270_bus_init_fn)(const union bmi270_bus *bus);
+typedef int (*bmi270_reg_read_fn)(const union bmi270_bus *bus,
+				  uint8_t start,
+				  uint8_t *data,
+				  uint16_t len);
+typedef int (*bmi270_reg_write_fn)(const union bmi270_bus *bus,
+				   uint8_t start,
+				   const uint8_t *data,
+				   uint16_t len);
+
+struct bmi270_bus_io {
+	bmi270_bus_check_fn check;
+	bmi270_reg_read_fn read;
+	bmi270_reg_write_fn write;
+	bmi270_bus_init_fn init;
+};
+
+#if CONFIG_BMI270_BUS_SPI
+#define BMI270_SPI_OPERATION (SPI_WORD_SET(8) | SPI_TRANSFER_MSB)
+#define BMI270_SPI_ACC_DELAY_US 2
+extern const struct bmi270_bus_io bmi270_bus_io_spi;
+#endif
+
+#if CONFIG_BMI270_BUS_I2C
+extern const struct bmi270_bus_io bmi270_bus_io_i2c;
+#endif
+
 #endif /* ZEPHYR_DRIVERS_SENSOR_BMI270_BMI270_H_ */
diff --git a/drivers/sensor/bmi270/bmi270_i2c.c b/drivers/sensor/bmi270/bmi270_i2c.c
new file mode 100644
index 00000000000..da80001907b
--- /dev/null
+++ b/drivers/sensor/bmi270/bmi270_i2c.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/*
+ * Bus-specific functionality for BMI270s accessed via I2C.
+ */
+
+#include "bmi270.h"
+
+static int bmi270_bus_check_i2c(const union bmi270_bus *bus)
+{
+	return device_is_ready(bus->i2c.bus) ? 0 : -ENODEV;
+}
+
+static int bmi270_reg_read_i2c(const union bmi270_bus *bus,
+			       uint8_t start, uint8_t *data, uint16_t len)
+{
+	return i2c_burst_read_dt(&bus->i2c, start, data, len);
+}
+
+static int bmi270_reg_write_i2c(const union bmi270_bus *bus, uint8_t start,
+				const uint8_t *data, uint16_t len)
+{
+	return i2c_burst_write_dt(&bus->i2c, start, data, len);
+}
+
+static int bmi270_bus_init_i2c(const union bmi270_bus *bus)
+{
+	/* I2C is used by default
+	 */
+	return 0;
+}
+
+const struct bmi270_bus_io bmi270_bus_io_i2c = {
+	.check = bmi270_bus_check_i2c,
+	.read = bmi270_reg_read_i2c,
+	.write = bmi270_reg_write_i2c,
+	.init = bmi270_bus_init_i2c,
+};
diff --git a/drivers/sensor/bmi270/bmi270_spi.c b/drivers/sensor/bmi270/bmi270_spi.c
new file mode 100644
index 00000000000..4f0a01ec4c7
--- /dev/null
+++ b/drivers/sensor/bmi270/bmi270_spi.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2022 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/*
+ * Bus-specific functionality for BMI270s accessed via SPI.
+ */
+
+#include <zephyr/logging/log.h>
+#include "bmi270.h"
+
+LOG_MODULE_DECLARE(bmi270, CONFIG_SENSOR_LOG_LEVEL);
+
+static int bmi270_bus_check_spi(const union bmi270_bus *bus)
+{
+	return spi_is_ready(&bus->spi) ? 0 : -ENODEV;
+}
+
+static int bmi270_reg_read_spi(const union bmi270_bus *bus,
+			       uint8_t start, uint8_t *data, uint16_t len)
+{
+	int ret;
+	uint8_t addr;
+	uint8_t tmp[2];
+	int i;
+	const struct spi_buf tx_buf = {
+		.buf = &addr,
+		.len = 1
+	};
+	const struct spi_buf_set tx = {
+		.buffers = &tx_buf,
+		.count = 1
+	};
+	struct spi_buf rx_buf[2];
+	const struct spi_buf_set rx = {
+		.buffers = rx_buf,
+		.count = ARRAY_SIZE(rx_buf)
+	};
+
+	rx_buf[0].buf = &tmp[0];
+	rx_buf[0].len = 2;
+	rx_buf[1].len = 1;
+
+	for (i = 0; i < len; i++) {
+		addr = (start + i) | 0x80;
+		rx_buf[1].buf = &data[i];
+
+		ret = spi_transceive_dt(&bus->spi, &tx, &rx);
+		if (ret < 0) {
+			LOG_DBG("spi_transceive failed %i", ret);
+			return ret;
+		}
+	}
+
+	k_usleep(BMI270_SPI_ACC_DELAY_US);
+	return 0;
+}
+
+static int bmi270_reg_write_spi(const union bmi270_bus *bus, uint8_t start,
+				const uint8_t *data, uint16_t len)
+{
+	int ret;
+	uint8_t addr;
+	const struct spi_buf tx_buf[2] = {
+		{.buf = &addr, .len = sizeof(addr)},
+		{.buf = (uint8_t *)data, .len = len}
+	};
+	const struct spi_buf_set tx = {
+		.buffers = tx_buf,
+		.count = ARRAY_SIZE(tx_buf)
+	};
+
+	addr = start & BMI270_REG_MASK;
+
+	ret = spi_write_dt(&bus->spi, &tx);
+	if (ret < 0) {
+		LOG_ERR("spi_write_dt failed %i", ret);
+		return ret;
+	}
+
+	k_usleep(BMI270_SPI_ACC_DELAY_US);
+	return 0;
+}
+
+static int bmi270_bus_init_spi(const union bmi270_bus *bus)
+{
+	uint8_t tmp;
+
+	/* Single read of SPI initializes the chip to SPI mode
+	 */
+	return bmi270_reg_read_spi(bus, BMI270_REG_CHIP_ID, &tmp, 1);
+}
+
+const struct bmi270_bus_io bmi270_bus_io_spi = {
+	.check = bmi270_bus_check_spi,
+	.read = bmi270_reg_read_spi,
+	.write = bmi270_reg_write_spi,
+	.init = bmi270_bus_init_spi,
+};
diff --git a/dts/bindings/sensor/bosch,bmi270-i2c.yaml b/dts/bindings/sensor/bosch,bmi270-i2c.yaml
index 2e2ee307c04..ca21ba4f3ea 100644
--- a/dts/bindings/sensor/bosch,bmi270-i2c.yaml
+++ b/dts/bindings/sensor/bosch,bmi270-i2c.yaml
@@ -1,10 +1,7 @@
 # Copyright (c) 2021, Bosch Sensortec GmbH
+# Copyright (c) 2022, Nordic Semiconductor ASA
 # SPDX-License-Identifier: Apache-2.0
 
-description: |
-    The BMI270 is an inertial measurment unit. See more info at:
-    https://www.bosch-sensortec.com/products/motion-sensors/imus/bmi270.html
-
 compatible: "bosch,bmi270"
 
-include: i2c-device.yaml
+include: [i2c-device.yaml, "bosch,bmi270.yaml"]
diff --git a/dts/bindings/sensor/bosch,bmi270-spi.yaml b/dts/bindings/sensor/bosch,bmi270-spi.yaml
new file mode 100644
index 00000000000..9c76cff2868
--- /dev/null
+++ b/dts/bindings/sensor/bosch,bmi270-spi.yaml
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Nordic Semiconductor ASA
+# SPDX-License-Identifier: Apache-2.0
+
+compatible: "bosch,bmi270"
+
+include: ["spi-device.yaml", "bosch,bmi270.yaml"]
diff --git a/dts/bindings/sensor/bosch,bmi270.yaml b/dts/bindings/sensor/bosch,bmi270.yaml
new file mode 100644
index 00000000000..90f4ef2ca1e
--- /dev/null
+++ b/dts/bindings/sensor/bosch,bmi270.yaml
@@ -0,0 +1,9 @@
+# Copyright (c) 2021, Bosch Sensortec GmbH
+# Copyright (c) 2022, Nordic Semiconductor ASA
+# SPDX-License-Identifier: Apache-2.0
+
+description: |
+    The BMI270 is an inertial measurement unit. See more info at:
+    https://www.bosch-sensortec.com/products/motion-sensors/imus/bmi270.html
+
+compatible: "bosch,bmi270"

From f8e82ab706d67dba7cfefae0a10bc3b389f249b0 Mon Sep 17 00:00:00 2001
From: Dominik Chat <dominik.chat@nordicsemi.no>
Date: Thu, 18 Aug 2022 14:27:42 +0200
Subject: [PATCH 2/3] sensor: Refactor bmi270 driver data names

Make driver data names consistent in code.

Signed-off-by: Dominik Chat <dominik.chat@nordicsemi.no>
---
 drivers/sensor/bmi270/bmi270.c | 110 ++++++++++++++++-----------------
 1 file changed, 55 insertions(+), 55 deletions(-)

diff --git a/drivers/sensor/bmi270/bmi270.c b/drivers/sensor/bmi270/bmi270.c
index 45077557923..ace3d81b902 100644
--- a/drivers/sensor/bmi270/bmi270.c
+++ b/drivers/sensor/bmi270/bmi270.c
@@ -143,7 +143,7 @@ static uint8_t acc_odr_to_reg(const struct sensor_value *val)
 static int set_accel_odr_osr(const struct device *dev, const struct sensor_value *odr,
 			     const struct sensor_value *osr)
 {
-	struct bmi270_data *drv_dev = dev->data;
+	struct bmi270_data *data = dev->data;
 	uint8_t acc_conf, odr_bits, pwr_ctrl, osr_bits;
 	int ret = 0;
 
@@ -185,11 +185,11 @@ static int set_accel_odr_osr(const struct device *dev, const struct sensor_value
 						   BMI270_ACC_FILT_PWR_OPT);
 		}
 
-		drv_dev->acc_odr = odr_bits;
+		data->acc_odr = odr_bits;
 	}
 
 	if (osr) {
-		if (drv_dev->acc_odr >= BMI270_ACC_ODR_100_HZ) {
+		if (data->acc_odr >= BMI270_ACC_ODR_100_HZ) {
 			/* Performance mode */
 			/* osr->val2 should be unused */
 			switch (osr->val1) {
@@ -263,7 +263,7 @@ static int set_accel_odr_osr(const struct device *dev, const struct sensor_value
 
 static int set_accel_range(const struct device *dev, const struct sensor_value *range)
 {
-	struct bmi270_data *drv_dev = dev->data;
+	struct bmi270_data *data = dev->data;
 	int ret = 0;
 	uint8_t acc_range, reg;
 
@@ -276,19 +276,19 @@ static int set_accel_range(const struct device *dev, const struct sensor_value *
 	switch (range->val1) {
 	case 2:
 		reg = BMI270_ACC_RANGE_2G;
-		drv_dev->acc_range = 2;
+		data->acc_range = 2;
 		break;
 	case 4:
 		reg = BMI270_ACC_RANGE_4G;
-		drv_dev->acc_range = 4;
+		data->acc_range = 4;
 		break;
 	case 8:
 		reg = BMI270_ACC_RANGE_8G;
-		drv_dev->acc_range = 8;
+		data->acc_range = 8;
 		break;
 	case 16:
 		reg = BMI270_ACC_RANGE_16G;
-		drv_dev->acc_range = 16;
+		data->acc_range = 16;
 		break;
 	default:
 		return -ENOTSUP;
@@ -331,7 +331,7 @@ static uint8_t gyr_odr_to_reg(const struct sensor_value *val)
 static int set_gyro_odr_osr(const struct device *dev, const struct sensor_value *odr,
 			    const struct sensor_value *osr)
 {
-	struct bmi270_data *drv_dev = dev->data;
+	struct bmi270_data *data = dev->data;
 	uint8_t gyr_conf, odr_bits, pwr_ctrl, osr_bits;
 	int ret = 0;
 
@@ -381,7 +381,7 @@ static int set_gyro_odr_osr(const struct device *dev, const struct sensor_value
 						   BMI270_GYR_FILT_NOISE_PWR);
 		}
 
-		drv_dev->gyr_odr = odr_bits;
+		data->gyr_odr = odr_bits;
 	}
 
 	if (osr) {
@@ -422,7 +422,7 @@ static int set_gyro_odr_osr(const struct device *dev, const struct sensor_value
 
 static int set_gyro_range(const struct device *dev, const struct sensor_value *range)
 {
-	struct bmi270_data *drv_dev = dev->data;
+	struct bmi270_data *data = dev->data;
 	int ret = 0;
 	uint8_t gyr_range, reg;
 
@@ -435,23 +435,23 @@ static int set_gyro_range(const struct device *dev, const struct sensor_value *r
 	switch (range->val1) {
 	case 125:
 		reg = BMI270_GYR_RANGE_125DPS;
-		drv_dev->gyr_range = 125;
+		data->gyr_range = 125;
 		break;
 	case 250:
 		reg = BMI270_GYR_RANGE_250DPS;
-		drv_dev->gyr_range = 250;
+		data->gyr_range = 250;
 		break;
 	case 500:
 		reg = BMI270_GYR_RANGE_500DPS;
-		drv_dev->gyr_range = 500;
+		data->gyr_range = 500;
 		break;
 	case 1000:
 		reg = BMI270_GYR_RANGE_1000DPS;
-		drv_dev->gyr_range = 1000;
+		data->gyr_range = 1000;
 		break;
 	case 2000:
 		reg = BMI270_GYR_RANGE_2000DPS;
-		drv_dev->gyr_range = 2000;
+		data->gyr_range = 2000;
 		break;
 	default:
 		return -ENOTSUP;
@@ -497,29 +497,29 @@ static int8_t write_config_file(const struct device *dev)
 
 static int bmi270_sample_fetch(const struct device *dev, enum sensor_channel chan)
 {
-	struct bmi270_data *drv_dev = dev->data;
-	uint8_t data[12];
+	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, data, 12);
+	ret = bmi270_reg_read(dev, BMI270_REG_ACC_X_LSB, buf, 12);
 	if (ret == 0) {
-		drv_dev->ax = (int16_t)sys_get_le16(&data[0]);
-		drv_dev->ay = (int16_t)sys_get_le16(&data[2]);
-		drv_dev->az = (int16_t)sys_get_le16(&data[4]);
-		drv_dev->gx = (int16_t)sys_get_le16(&data[6]);
-		drv_dev->gy = (int16_t)sys_get_le16(&data[8]);
-		drv_dev->gz = (int16_t)sys_get_le16(&data[10]);
+		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 {
-		drv_dev->ax = 0;
-		drv_dev->ay = 0;
-		drv_dev->az = 0;
-		drv_dev->gx = 0;
-		drv_dev->gy = 0;
-		drv_dev->gz = 0;
+		data->ax = 0;
+		data->ay = 0;
+		data->az = 0;
+		data->gx = 0;
+		data->gy = 0;
+		data->gz = 0;
 	}
 
 	return ret;
@@ -528,34 +528,34 @@ static int bmi270_sample_fetch(const struct device *dev, enum sensor_channel cha
 static int bmi270_channel_get(const struct device *dev, enum sensor_channel chan,
 			      struct sensor_value *val)
 {
-	struct bmi270_data *drv_dev = dev->data;
+	struct bmi270_data *data = dev->data;
 
 	if (chan == SENSOR_CHAN_ACCEL_X) {
-		channel_accel_convert(val, drv_dev->ax, drv_dev->acc_range);
+		channel_accel_convert(val, data->ax, data->acc_range);
 	} else if (chan == SENSOR_CHAN_ACCEL_Y) {
-		channel_accel_convert(val, drv_dev->ay, drv_dev->acc_range);
+		channel_accel_convert(val, data->ay, data->acc_range);
 	} else if (chan == SENSOR_CHAN_ACCEL_Z) {
-		channel_accel_convert(val, drv_dev->az, drv_dev->acc_range);
+		channel_accel_convert(val, data->az, data->acc_range);
 	} else if (chan == SENSOR_CHAN_ACCEL_XYZ) {
-		channel_accel_convert(&val[0], drv_dev->ax,
-				      drv_dev->acc_range);
-		channel_accel_convert(&val[1], drv_dev->ay,
-				      drv_dev->acc_range);
-		channel_accel_convert(&val[2], drv_dev->az,
-				      drv_dev->acc_range);
+		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, drv_dev->gx, drv_dev->gyr_range);
+		channel_gyro_convert(val, data->gx, data->gyr_range);
 	} else if (chan == SENSOR_CHAN_GYRO_Y) {
-		channel_gyro_convert(val, drv_dev->gy, drv_dev->gyr_range);
+		channel_gyro_convert(val, data->gy, data->gyr_range);
 	} else if (chan == SENSOR_CHAN_GYRO_Z) {
-		channel_gyro_convert(val, drv_dev->gz, drv_dev->gyr_range);
+		channel_gyro_convert(val, data->gz, data->gyr_range);
 	} else if (chan == SENSOR_CHAN_GYRO_XYZ) {
-		channel_gyro_convert(&val[0], drv_dev->gx,
-				     drv_dev->gyr_range);
-		channel_gyro_convert(&val[1], drv_dev->gy,
-				     drv_dev->gyr_range);
-		channel_gyro_convert(&val[2], drv_dev->gz,
-				     drv_dev->gyr_range);
+		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;
 	}
@@ -611,7 +611,7 @@ static int bmi270_attr_set(const struct device *dev, enum sensor_channel chan,
 static int bmi270_init(const struct device *dev)
 {
 	int ret;
-	struct bmi270_data *drv_dev = dev->data;
+	struct bmi270_data *data = dev->data;
 	uint8_t chip_id;
 	uint8_t soft_reset_cmd;
 	uint8_t init_ctrl;
@@ -625,10 +625,10 @@ static int bmi270_init(const struct device *dev)
 		return ret;
 	}
 
-	drv_dev->acc_odr = BMI270_ACC_ODR_100_HZ;
-	drv_dev->acc_range = 8;
-	drv_dev->gyr_odr = BMI270_GYR_ODR_200_HZ;
-	drv_dev->gyr_range = 2000;
+	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);
 

From 866385b54bdecafc46232eca08c520140bde318d Mon Sep 17 00:00:00 2001
From: Dominik Chat <dominik.chat@nordicsemi.no>
Date: Thu, 22 Sep 2022 16:20:46 +0200
Subject: [PATCH 3/3] boards: Remove bmi270 int1-gpios form thingy:53 DTS

BMI270 driver does not support interrupts
and int1-gpios property produces twister failures.

Signed-off-by: Dominik Chat <dominik.chat@nordicsemi.no>
---
 boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts
index 0034a4d71df..41cb2f05034 100644
--- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts
+++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts
@@ -198,7 +198,6 @@
 		status = "disabled";
 		spi-max-frequency = <8000000>;
 		reg = <1>;
-		int1-gpios = <&gpio0 23 0>;
 	};
 
 	nrf_radio_fem_spi: fem_spi@2 {
