diff mbox series

[v3,2/2] iio: imu: Add i2c driver for bmi270 imu

Message ID 20240909043254.611589-3-lanzano.alex@gmail.com (mailing list archive)
State Superseded
Headers show
Series Add I2C driver for Bosch BMI270 IMU | expand

Commit Message

Alex Lanzano Sept. 9, 2024, 4:32 a.m. UTC
Add initial i2c support for the Bosch BMI270 6-axis IMU.
Provides raw read access to acceleration and angle velocity measurements
via iio channels. Device configuration requires firmware provided by
Bosch and is requested and load from userspace.

Signed-off-by: Alex Lanzano <lanzano.alex@gmail.com>
---
 MAINTAINERS                          |   7 +
 drivers/iio/imu/Kconfig              |   1 +
 drivers/iio/imu/Makefile             |   1 +
 drivers/iio/imu/bmi270/Kconfig       |  21 +++
 drivers/iio/imu/bmi270/Makefile      |   6 +
 drivers/iio/imu/bmi270/bmi270.h      |  62 +++++++
 drivers/iio/imu/bmi270/bmi270_core.c | 251 +++++++++++++++++++++++++++
 drivers/iio/imu/bmi270/bmi270_i2c.c  |  48 +++++
 8 files changed, 397 insertions(+)
 create mode 100644 drivers/iio/imu/bmi270/Kconfig
 create mode 100644 drivers/iio/imu/bmi270/Makefile
 create mode 100644 drivers/iio/imu/bmi270/bmi270.h
 create mode 100644 drivers/iio/imu/bmi270/bmi270_core.c
 create mode 100644 drivers/iio/imu/bmi270/bmi270_i2c.c

Comments

kernel test robot Sept. 9, 2024, 5:03 p.m. UTC | #1
Hi Alex,

kernel test robot noticed the following build errors:

[auto build test ERROR on jic23-iio/togreg]
[also build test ERROR on robh/for-next linus/master v6.11-rc7 next-20240909]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Alex-Lanzano/dt-bindings-iio-imu-add-bmi270-bindings/20240909-123509
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
patch link:    https://lore.kernel.org/r/20240909043254.611589-3-lanzano.alex%40gmail.com
patch subject: [PATCH v3 2/2] iio: imu: Add i2c driver for bmi270 imu
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20240910/202409100026.17N3K11W-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240910/202409100026.17N3K11W-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409100026.17N3K11W-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/iio/imu/bmi270/bmi270_core.c: In function 'bmi270_configure_imu':
>> drivers/iio/imu/bmi270/bmi270_core.c:180:31: error: implicit declaration of function 'FIELD_PREP' [-Wimplicit-function-declaration]
     180 |                               FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
         |                               ^~~~~~~~~~


vim +/FIELD_PREP +180 drivers/iio/imu/bmi270/bmi270_core.c

   165	
   166	static int bmi270_configure_imu(struct bmi270_data *bmi270_device)
   167	{
   168		int ret;
   169		struct device *dev = bmi270_device->dev;
   170		struct regmap *regmap = bmi270_device->regmap;
   171	
   172		ret = regmap_set_bits(regmap, BMI270_PWR_CTRL_REG,
   173				      BMI270_PWR_CTRL_AUX_EN_MSK |
   174				      BMI270_PWR_CTRL_GYR_EN_MSK |
   175				      BMI270_PWR_CTRL_ACCEL_EN_MSK);
   176		if (ret)
   177			return dev_err_probe(dev, ret, "Failed to enable accelerometer and gyroscope");
   178	
   179		ret = regmap_set_bits(regmap, BMI270_ACC_CONF_REG,
 > 180				      FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
   181						 BMI270_ACC_CONF_ODR_100HZ) |
   182				      FIELD_PREP(BMI270_ACC_CONF_BWP_MSK,
   183						 BMI270_ACC_CONF_BWP_NORMAL_MODE) |
   184				      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
   185		if (ret)
   186			return dev_err_probe(dev, ret, "Failed to configure accelerometer");
   187	
   188		ret = regmap_set_bits(regmap, BMI270_GYR_CONF_REG,
   189				      FIELD_PREP(BMI270_GYR_CONF_ODR_MSK,
   190						 BMI270_GYR_CONF_ODR_200HZ) |
   191				      FIELD_PREP(BMI270_GYR_CONF_BWP_MSK,
   192						 BMI270_GYR_CONF_BWP_NORMAL_MODE) |
   193				      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
   194		if (ret)
   195			return dev_err_probe(dev, ret, "Failed to configure gyroscope");
   196	
   197		/* Enable FIFO_WKUP, Disable ADV_PWR_SAVE and FUP_EN */
   198		ret = regmap_write(regmap, BMI270_PWR_CONF_REG,
   199				   BMI270_PWR_CONF_FIFO_WKUP_MSK);
   200		if (ret)
   201			return dev_err_probe(dev, ret, "Failed to set power configuration");
   202	
   203		return 0;
   204	}
   205
kernel test robot Sept. 9, 2024, 10:13 p.m. UTC | #2
Hi Alex,

kernel test robot noticed the following build errors:

[auto build test ERROR on jic23-iio/togreg]
[also build test ERROR on robh/for-next linus/master v6.11-rc7 next-20240909]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Alex-Lanzano/dt-bindings-iio-imu-add-bmi270-bindings/20240909-123509
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
patch link:    https://lore.kernel.org/r/20240909043254.611589-3-lanzano.alex%40gmail.com
patch subject: [PATCH v3 2/2] iio: imu: Add i2c driver for bmi270 imu
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20240910/202409100526.LydCADNj-lkp@intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 05f5a91d00b02f4369f46d076411c700755ae041)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240910/202409100526.LydCADNj-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409100526.LydCADNj-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/iio/imu/bmi270/bmi270_core.c:4:
   In file included from include/linux/i2c.h:19:
   In file included from include/linux/regulator/consumer.h:35:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:25:
   In file included from include/linux/kernel_stat.h:8:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:548:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     548 |         val = __raw_readb(PCI_IOBASE + addr);
         |                           ~~~~~~~~~~ ^
   include/asm-generic/io.h:561:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     561 |         val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
      37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
         |                                                   ^
   In file included from drivers/iio/imu/bmi270/bmi270_core.c:4:
   In file included from include/linux/i2c.h:19:
   In file included from include/linux/regulator/consumer.h:35:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:25:
   In file included from include/linux/kernel_stat.h:8:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:574:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     574 |         val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
         |                                                         ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
      35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
         |                                                   ^
   In file included from drivers/iio/imu/bmi270/bmi270_core.c:4:
   In file included from include/linux/i2c.h:19:
   In file included from include/linux/regulator/consumer.h:35:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:13:
   In file included from include/linux/cgroup.h:25:
   In file included from include/linux/kernel_stat.h:8:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/hexagon/include/asm/io.h:328:
   include/asm-generic/io.h:585:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     585 |         __raw_writeb(value, PCI_IOBASE + addr);
         |                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:595:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     595 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:605:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     605 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
         |                                                       ~~~~~~~~~~ ^
   In file included from drivers/iio/imu/bmi270/bmi270_core.c:4:
   In file included from include/linux/i2c.h:19:
   In file included from include/linux/regulator/consumer.h:35:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:21:
   In file included from include/linux/mm.h:2228:
   include/linux/vmstat.h:517:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     517 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
>> drivers/iio/imu/bmi270/bmi270_core.c:180:10: error: call to undeclared function 'FIELD_PREP'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     180 |                               FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
         |                               ^
   7 warnings and 1 error generated.


vim +/FIELD_PREP +180 drivers/iio/imu/bmi270/bmi270_core.c

   165	
   166	static int bmi270_configure_imu(struct bmi270_data *bmi270_device)
   167	{
   168		int ret;
   169		struct device *dev = bmi270_device->dev;
   170		struct regmap *regmap = bmi270_device->regmap;
   171	
   172		ret = regmap_set_bits(regmap, BMI270_PWR_CTRL_REG,
   173				      BMI270_PWR_CTRL_AUX_EN_MSK |
   174				      BMI270_PWR_CTRL_GYR_EN_MSK |
   175				      BMI270_PWR_CTRL_ACCEL_EN_MSK);
   176		if (ret)
   177			return dev_err_probe(dev, ret, "Failed to enable accelerometer and gyroscope");
   178	
   179		ret = regmap_set_bits(regmap, BMI270_ACC_CONF_REG,
 > 180				      FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
   181						 BMI270_ACC_CONF_ODR_100HZ) |
   182				      FIELD_PREP(BMI270_ACC_CONF_BWP_MSK,
   183						 BMI270_ACC_CONF_BWP_NORMAL_MODE) |
   184				      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
   185		if (ret)
   186			return dev_err_probe(dev, ret, "Failed to configure accelerometer");
   187	
   188		ret = regmap_set_bits(regmap, BMI270_GYR_CONF_REG,
   189				      FIELD_PREP(BMI270_GYR_CONF_ODR_MSK,
   190						 BMI270_GYR_CONF_ODR_200HZ) |
   191				      FIELD_PREP(BMI270_GYR_CONF_BWP_MSK,
   192						 BMI270_GYR_CONF_BWP_NORMAL_MODE) |
   193				      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
   194		if (ret)
   195			return dev_err_probe(dev, ret, "Failed to configure gyroscope");
   196	
   197		/* Enable FIFO_WKUP, Disable ADV_PWR_SAVE and FUP_EN */
   198		ret = regmap_write(regmap, BMI270_PWR_CONF_REG,
   199				   BMI270_PWR_CONF_FIFO_WKUP_MSK);
   200		if (ret)
   201			return dev_err_probe(dev, ret, "Failed to set power configuration");
   202	
   203		return 0;
   204	}
   205
Alex Lanzano Sept. 10, 2024, 3:21 a.m. UTC | #3
On Tue, Sep 10, 2024 at 01:03:04AM GMT, kernel test robot wrote:
> Hi Alex,
> 
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on jic23-iio/togreg]
> [also build test ERROR on robh/for-next linus/master v6.11-rc7 next-20240909]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Alex-Lanzano/dt-bindings-iio-imu-add-bmi270-bindings/20240909-123509
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
> patch link:    https://lore.kernel.org/r/20240909043254.611589-3-lanzano.alex%40gmail.com
> patch subject: [PATCH v3 2/2] iio: imu: Add i2c driver for bmi270 imu
> config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20240910/202409100026.17N3K11W-lkp@intel.com/config)
> compiler: m68k-linux-gcc (GCC) 14.1.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240910/202409100026.17N3K11W-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202409100026.17N3K11W-lkp@intel.com/
> 
> All errors (new ones prefixed by >>):
> 
>    drivers/iio/imu/bmi270/bmi270_core.c: In function 'bmi270_configure_imu':
> >> drivers/iio/imu/bmi270/bmi270_core.c:180:31: error: implicit declaration of function 'FIELD_PREP' [-Wimplicit-function-declaration]
>      180 |                               FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
>          |                               ^~~~~~~~~~
> 
> 
> vim +/FIELD_PREP +180 drivers/iio/imu/bmi270/bmi270_core.c
> 
>    165	
>    166	static int bmi270_configure_imu(struct bmi270_data *bmi270_device)
>    167	{
>    168		int ret;
>    169		struct device *dev = bmi270_device->dev;
>    170		struct regmap *regmap = bmi270_device->regmap;
>    171	
>    172		ret = regmap_set_bits(regmap, BMI270_PWR_CTRL_REG,
>    173				      BMI270_PWR_CTRL_AUX_EN_MSK |
>    174				      BMI270_PWR_CTRL_GYR_EN_MSK |
>    175				      BMI270_PWR_CTRL_ACCEL_EN_MSK);
>    176		if (ret)
>    177			return dev_err_probe(dev, ret, "Failed to enable accelerometer and gyroscope");
>    178	
>    179		ret = regmap_set_bits(regmap, BMI270_ACC_CONF_REG,
>  > 180				      FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
>    181						 BMI270_ACC_CONF_ODR_100HZ) |
>    182				      FIELD_PREP(BMI270_ACC_CONF_BWP_MSK,
>    183						 BMI270_ACC_CONF_BWP_NORMAL_MODE) |
>    184				      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
>    185		if (ret)
>    186			return dev_err_probe(dev, ret, "Failed to configure accelerometer");
>    187	
>    188		ret = regmap_set_bits(regmap, BMI270_GYR_CONF_REG,
>    189				      FIELD_PREP(BMI270_GYR_CONF_ODR_MSK,
>    190						 BMI270_GYR_CONF_ODR_200HZ) |
>    191				      FIELD_PREP(BMI270_GYR_CONF_BWP_MSK,
>    192						 BMI270_GYR_CONF_BWP_NORMAL_MODE) |
>    193				      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
>    194		if (ret)
>    195			return dev_err_probe(dev, ret, "Failed to configure gyroscope");
>    196	
>    197		/* Enable FIFO_WKUP, Disable ADV_PWR_SAVE and FUP_EN */
>    198		ret = regmap_write(regmap, BMI270_PWR_CONF_REG,
>    199				   BMI270_PWR_CONF_FIFO_WKUP_MSK);
>    200		if (ret)
>    201			return dev_err_probe(dev, ret, "Failed to set power configuration");
>    202	
>    203		return 0;
>    204	}
>    205	
> 
> -- 
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki

I am having trouble reproducing this build error on both jic23-iio/togreg and
linus/master v6.11.rc7 on an aarch64 box with the same compiler version.
Maybe a config option is causing this?

However, I will add #include <linux/bitfield.h> to remedy this issue if
some edge case is being hit.

Best regards,
Alex
Alex Lanzano Sept. 10, 2024, 3:24 a.m. UTC | #4
On Tue, Sep 10, 2024 at 06:13:04AM GMT, kernel test robot wrote:
> Hi Alex,
> 
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on jic23-iio/togreg]
> [also build test ERROR on robh/for-next linus/master v6.11-rc7 next-20240909]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Alex-Lanzano/dt-bindings-iio-imu-add-bmi270-bindings/20240909-123509
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
> patch link:    https://lore.kernel.org/r/20240909043254.611589-3-lanzano.alex%40gmail.com
> patch subject: [PATCH v3 2/2] iio: imu: Add i2c driver for bmi270 imu
> config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20240910/202409100526.LydCADNj-lkp@intel.com/config)
> compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 05f5a91d00b02f4369f46d076411c700755ae041)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240910/202409100526.LydCADNj-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202409100526.LydCADNj-lkp@intel.com/
> 
> All errors (new ones prefixed by >>):
> 
>    In file included from drivers/iio/imu/bmi270/bmi270_core.c:4:
>    In file included from include/linux/i2c.h:19:
>    In file included from include/linux/regulator/consumer.h:35:
>    In file included from include/linux/suspend.h:5:
>    In file included from include/linux/swap.h:9:
>    In file included from include/linux/memcontrol.h:13:
>    In file included from include/linux/cgroup.h:25:
>    In file included from include/linux/kernel_stat.h:8:
>    In file included from include/linux/interrupt.h:11:
>    In file included from include/linux/hardirq.h:11:
>    In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
>    In file included from include/asm-generic/hardirq.h:17:
>    In file included from include/linux/irq.h:20:
>    In file included from include/linux/io.h:14:
>    In file included from arch/hexagon/include/asm/io.h:328:
>    include/asm-generic/io.h:548:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>      548 |         val = __raw_readb(PCI_IOBASE + addr);
>          |                           ~~~~~~~~~~ ^
>    include/asm-generic/io.h:561:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>      561 |         val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
>          |                                                         ~~~~~~~~~~ ^
>    include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
>       37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
>          |                                                   ^
>    In file included from drivers/iio/imu/bmi270/bmi270_core.c:4:
>    In file included from include/linux/i2c.h:19:
>    In file included from include/linux/regulator/consumer.h:35:
>    In file included from include/linux/suspend.h:5:
>    In file included from include/linux/swap.h:9:
>    In file included from include/linux/memcontrol.h:13:
>    In file included from include/linux/cgroup.h:25:
>    In file included from include/linux/kernel_stat.h:8:
>    In file included from include/linux/interrupt.h:11:
>    In file included from include/linux/hardirq.h:11:
>    In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
>    In file included from include/asm-generic/hardirq.h:17:
>    In file included from include/linux/irq.h:20:
>    In file included from include/linux/io.h:14:
>    In file included from arch/hexagon/include/asm/io.h:328:
>    include/asm-generic/io.h:574:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>      574 |         val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
>          |                                                         ~~~~~~~~~~ ^
>    include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
>       35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
>          |                                                   ^
>    In file included from drivers/iio/imu/bmi270/bmi270_core.c:4:
>    In file included from include/linux/i2c.h:19:
>    In file included from include/linux/regulator/consumer.h:35:
>    In file included from include/linux/suspend.h:5:
>    In file included from include/linux/swap.h:9:
>    In file included from include/linux/memcontrol.h:13:
>    In file included from include/linux/cgroup.h:25:
>    In file included from include/linux/kernel_stat.h:8:
>    In file included from include/linux/interrupt.h:11:
>    In file included from include/linux/hardirq.h:11:
>    In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
>    In file included from include/asm-generic/hardirq.h:17:
>    In file included from include/linux/irq.h:20:
>    In file included from include/linux/io.h:14:
>    In file included from arch/hexagon/include/asm/io.h:328:
>    include/asm-generic/io.h:585:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>      585 |         __raw_writeb(value, PCI_IOBASE + addr);
>          |                             ~~~~~~~~~~ ^
>    include/asm-generic/io.h:595:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>      595 |         __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
>          |                                                       ~~~~~~~~~~ ^
>    include/asm-generic/io.h:605:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>      605 |         __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
>          |                                                       ~~~~~~~~~~ ^
>    In file included from drivers/iio/imu/bmi270/bmi270_core.c:4:
>    In file included from include/linux/i2c.h:19:
>    In file included from include/linux/regulator/consumer.h:35:
>    In file included from include/linux/suspend.h:5:
>    In file included from include/linux/swap.h:9:
>    In file included from include/linux/memcontrol.h:21:
>    In file included from include/linux/mm.h:2228:
>    include/linux/vmstat.h:517:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
>      517 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
>          |                               ~~~~~~~~~~~ ^ ~~~
> >> drivers/iio/imu/bmi270/bmi270_core.c:180:10: error: call to undeclared function 'FIELD_PREP'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
>      180 |                               FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
>          |                               ^
>    7 warnings and 1 error generated.
> 
> 
> vim +/FIELD_PREP +180 drivers/iio/imu/bmi270/bmi270_core.c
> 
>    165	
>    166	static int bmi270_configure_imu(struct bmi270_data *bmi270_device)
>    167	{
>    168		int ret;
>    169		struct device *dev = bmi270_device->dev;
>    170		struct regmap *regmap = bmi270_device->regmap;
>    171	
>    172		ret = regmap_set_bits(regmap, BMI270_PWR_CTRL_REG,
>    173				      BMI270_PWR_CTRL_AUX_EN_MSK |
>    174				      BMI270_PWR_CTRL_GYR_EN_MSK |
>    175				      BMI270_PWR_CTRL_ACCEL_EN_MSK);
>    176		if (ret)
>    177			return dev_err_probe(dev, ret, "Failed to enable accelerometer and gyroscope");
>    178	
>    179		ret = regmap_set_bits(regmap, BMI270_ACC_CONF_REG,
>  > 180				      FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
>    181						 BMI270_ACC_CONF_ODR_100HZ) |
>    182				      FIELD_PREP(BMI270_ACC_CONF_BWP_MSK,
>    183						 BMI270_ACC_CONF_BWP_NORMAL_MODE) |
>    184				      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
>    185		if (ret)
>    186			return dev_err_probe(dev, ret, "Failed to configure accelerometer");
>    187	
>    188		ret = regmap_set_bits(regmap, BMI270_GYR_CONF_REG,
>    189				      FIELD_PREP(BMI270_GYR_CONF_ODR_MSK,
>    190						 BMI270_GYR_CONF_ODR_200HZ) |
>    191				      FIELD_PREP(BMI270_GYR_CONF_BWP_MSK,
>    192						 BMI270_GYR_CONF_BWP_NORMAL_MODE) |
>    193				      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
>    194		if (ret)
>    195			return dev_err_probe(dev, ret, "Failed to configure gyroscope");
>    196	
>    197		/* Enable FIFO_WKUP, Disable ADV_PWR_SAVE and FUP_EN */
>    198		ret = regmap_write(regmap, BMI270_PWR_CONF_REG,
>    199				   BMI270_PWR_CONF_FIFO_WKUP_MSK);
>    200		if (ret)
>    201			return dev_err_probe(dev, ret, "Failed to set power configuration");
>    202	
>    203		return 0;
>    204	}
>    205	
> 
> -- 
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki

I am having trouble reproducing this build error on both jic23-iio/togreg and
linus/master v6.11.rc7 on an aarch64 box with the same compiler version.
Maybe a config option is causing this?

However, I will add #include <linux/bitfield.h> to remedy this issue if
some edge case is being hit.

Best regards,
Alex
Jonathan Cameron Sept. 14, 2024, 11:51 a.m. UTC | #5
On Mon, 9 Sep 2024 23:21:52 -0400
Alex Lanzano <lanzano.alex@gmail.com> wrote:

> On Tue, Sep 10, 2024 at 01:03:04AM GMT, kernel test robot wrote:
> > Hi Alex,
> > 
> > kernel test robot noticed the following build errors:
> > 
> > [auto build test ERROR on jic23-iio/togreg]
> > [also build test ERROR on robh/for-next linus/master v6.11-rc7 next-20240909]
> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > And when submitting patch, we suggest to use '--base' as documented in
> > https://git-scm.com/docs/git-format-patch#_base_tree_information]
> > 
> > url:    https://github.com/intel-lab-lkp/linux/commits/Alex-Lanzano/dt-bindings-iio-imu-add-bmi270-bindings/20240909-123509
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
> > patch link:    https://lore.kernel.org/r/20240909043254.611589-3-lanzano.alex%40gmail.com
> > patch subject: [PATCH v3 2/2] iio: imu: Add i2c driver for bmi270 imu
> > config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20240910/202409100026.17N3K11W-lkp@intel.com/config)
> > compiler: m68k-linux-gcc (GCC) 14.1.0
> > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240910/202409100026.17N3K11W-lkp@intel.com/reproduce)
> > 
> > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > the same patch/commit), kindly add following tags
> > | Reported-by: kernel test robot <lkp@intel.com>
> > | Closes: https://lore.kernel.org/oe-kbuild-all/202409100026.17N3K11W-lkp@intel.com/
> > 
> > All errors (new ones prefixed by >>):
> > 
> >    drivers/iio/imu/bmi270/bmi270_core.c: In function 'bmi270_configure_imu':  
> > >> drivers/iio/imu/bmi270/bmi270_core.c:180:31: error: implicit declaration of function 'FIELD_PREP' [-Wimplicit-function-declaration]  
> >      180 |                               FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
> >          |                               ^~~~~~~~~~
> > 
> > 
> > vim +/FIELD_PREP +180 drivers/iio/imu/bmi270/bmi270_core.c
> > 
> >    165	
> >    166	static int bmi270_configure_imu(struct bmi270_data *bmi270_device)
> >    167	{
> >    168		int ret;
> >    169		struct device *dev = bmi270_device->dev;
> >    170		struct regmap *regmap = bmi270_device->regmap;
> >    171	
> >    172		ret = regmap_set_bits(regmap, BMI270_PWR_CTRL_REG,
> >    173				      BMI270_PWR_CTRL_AUX_EN_MSK |
> >    174				      BMI270_PWR_CTRL_GYR_EN_MSK |
> >    175				      BMI270_PWR_CTRL_ACCEL_EN_MSK);
> >    176		if (ret)
> >    177			return dev_err_probe(dev, ret, "Failed to enable accelerometer and gyroscope");
> >    178	
> >    179		ret = regmap_set_bits(regmap, BMI270_ACC_CONF_REG,  
> >  > 180				      FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,  
> >    181						 BMI270_ACC_CONF_ODR_100HZ) |
> >    182				      FIELD_PREP(BMI270_ACC_CONF_BWP_MSK,
> >    183						 BMI270_ACC_CONF_BWP_NORMAL_MODE) |
> >    184				      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
> >    185		if (ret)
> >    186			return dev_err_probe(dev, ret, "Failed to configure accelerometer");
> >    187	
> >    188		ret = regmap_set_bits(regmap, BMI270_GYR_CONF_REG,
> >    189				      FIELD_PREP(BMI270_GYR_CONF_ODR_MSK,
> >    190						 BMI270_GYR_CONF_ODR_200HZ) |
> >    191				      FIELD_PREP(BMI270_GYR_CONF_BWP_MSK,
> >    192						 BMI270_GYR_CONF_BWP_NORMAL_MODE) |
> >    193				      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
> >    194		if (ret)
> >    195			return dev_err_probe(dev, ret, "Failed to configure gyroscope");
> >    196	
> >    197		/* Enable FIFO_WKUP, Disable ADV_PWR_SAVE and FUP_EN */
> >    198		ret = regmap_write(regmap, BMI270_PWR_CONF_REG,
> >    199				   BMI270_PWR_CONF_FIFO_WKUP_MSK);
> >    200		if (ret)
> >    201			return dev_err_probe(dev, ret, "Failed to set power configuration");
> >    202	
> >    203		return 0;
> >    204	}
> >    205	
> > 
> > -- 
> > 0-DAY CI Kernel Test Service
> > https://github.com/intel/lkp-tests/wiki  
> 
> I am having trouble reproducing this build error on both jic23-iio/togreg and
> linus/master v6.11.rc7 on an aarch64 box with the same compiler version.
> Maybe a config option is causing this?
> 
> However, I will add #include <linux/bitfield.h> to remedy this issue if
> some edge case is being hit.
Makes sense anyways roughly speaking we should aim for "include what you use"
for headers to avoid this sort of subtle build issue.
There are exceptions for one or two headers that are always included via
another path, but bitfield.h isn't one of those.

Jonathan

> 
> Best regards,
> Alex
diff mbox series

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index a2184637a5d9..6612d27525b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3928,6 +3928,13 @@  S:	Maintained
 F:	Documentation/devicetree/bindings/iio/accel/bosch,bma400.yaml
 F:	drivers/iio/accel/bma400*
 
+BOSCH SENSORTEC BMI270 IMU IIO DRIVER
+M:	Alex Lanzano <lanzano.alex@gmail.com>
+L:	linux-iio@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iio/imu/bosch,bmi270.yaml
+F:	drivers/iio/imu/bmi270/
+
 BOSCH SENSORTEC BMI323 IMU IIO DRIVER
 M:	Jagath Jog J <jagathjog1996@gmail.com>
 L:	linux-iio@vger.kernel.org
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index 782fb80e44c2..489dd898830b 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -53,6 +53,7 @@  config ADIS16480
 	  ADIS16485, ADIS16488 inertial sensors.
 
 source "drivers/iio/imu/bmi160/Kconfig"
+source "drivers/iio/imu/bmi270/Kconfig"
 source "drivers/iio/imu/bmi323/Kconfig"
 source "drivers/iio/imu/bno055/Kconfig"
 
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
index 7e2d7d5c3b7b..79f83ea6f644 100644
--- a/drivers/iio/imu/Makefile
+++ b/drivers/iio/imu/Makefile
@@ -15,6 +15,7 @@  adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
 obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
 
 obj-y += bmi160/
+obj-y += bmi270/
 obj-y += bmi323/
 obj-y += bno055/
 
diff --git a/drivers/iio/imu/bmi270/Kconfig b/drivers/iio/imu/bmi270/Kconfig
new file mode 100644
index 000000000000..3f7b4ac30f00
--- /dev/null
+++ b/drivers/iio/imu/bmi270/Kconfig
@@ -0,0 +1,21 @@ 
+# SPDX-License-Identifier: GPL-2.0
+#
+# BMI270 IMU driver
+#
+
+config BMI270
+	tristate
+	select IIO_BUFFER
+
+config BMI270_I2C
+	tristate "Bosch BMI270 I2C driver"
+	depends on I2C
+	select BMI270
+	select REGMAP_I2C
+	help
+	  Enable support for the Bosch BMI270 6-Axis IMU connected to I2C
+	  interface.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called bmi270_i2c.
+
diff --git a/drivers/iio/imu/bmi270/Makefile b/drivers/iio/imu/bmi270/Makefile
new file mode 100644
index 000000000000..ab4acaaee6d2
--- /dev/null
+++ b/drivers/iio/imu/bmi270/Makefile
@@ -0,0 +1,6 @@ 
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for Bosch BMI270 IMU
+#
+obj-$(CONFIG_BMI270) += bmi270_core.o
+obj-$(CONFIG_BMI270_I2C) += bmi270_i2c.o
diff --git a/drivers/iio/imu/bmi270/bmi270.h b/drivers/iio/imu/bmi270/bmi270.h
new file mode 100644
index 000000000000..4af4098d8e82
--- /dev/null
+++ b/drivers/iio/imu/bmi270/bmi270.h
@@ -0,0 +1,62 @@ 
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef BMI270_H_
+#define BMI270_H_
+
+#include <linux/iio/iio.h>
+
+#define BMI270_CHIP_ID_REG				0x00
+#define BMI270_CHIP_ID_VAL				0x24
+#define BMI270_CHIP_ID_MSK				GENMASK(7, 0)
+
+#define BMI270_ACCEL_X_REG				0x0c
+#define BMI270_ANG_VEL_X_REG				0x12
+
+#define BMI270_INTERNAL_STATUS_REG			0x21
+#define BMI270_INTERNAL_STATUS_MSG_MSK			GENMASK(3, 0)
+#define BMI270_INTERNAL_STATUS_MSG_INIT_OK		0x01
+
+#define BMI270_INTERNAL_STATUS_AXES_REMAP_ERR_MSK	BIT(5)
+#define BMI270_INTERNAL_STATUS_ODR_50HZ_ERR_MSK		BIT(6)
+
+#define BMI270_ACC_CONF_REG				0x40
+#define BMI270_ACC_CONF_ODR_MSK				GENMASK(3, 0)
+#define BMI270_ACC_CONF_ODR_100HZ			0x08
+#define BMI270_ACC_CONF_BWP_MSK				GENMASK(6, 4)
+#define BMI270_ACC_CONF_BWP_NORMAL_MODE			0x02
+#define BMI270_ACC_CONF_FILTER_PERF_MSK			BIT(7)
+
+#define BMI270_GYR_CONF_REG				0x42
+#define BMI270_GYR_CONF_ODR_MSK				GENMASK(3, 0)
+#define BMI270_GYR_CONF_ODR_200HZ			0x09
+#define BMI270_GYR_CONF_BWP_MSK				GENMASK(5, 4)
+#define BMI270_GYR_CONF_BWP_NORMAL_MODE			0x02
+#define BMI270_GYR_CONF_NOISE_PERF_MSK			BIT(6)
+#define BMI270_GYR_CONF_FILTER_PERF_MSK			BIT(7)
+
+#define BMI270_INIT_CTRL_REG				0x59
+#define BMI270_INIT_CTRL_LOAD_DONE_MSK			BIT(0)
+
+#define BMI270_INIT_DATA_REG				0x5e
+
+#define BMI270_PWR_CONF_REG				0x7c
+#define BMI270_PWR_CONF_ADV_PWR_SAVE_MSK		BIT(0)
+#define BMI270_PWR_CONF_FIFO_WKUP_MSK			BIT(1)
+#define BMI270_PWR_CONF_FUP_EN_MSK			BIT(2)
+
+#define BMI270_PWR_CTRL_REG				0x7d
+#define BMI270_PWR_CTRL_AUX_EN_MSK			BIT(0)
+#define BMI270_PWR_CTRL_GYR_EN_MSK			BIT(1)
+#define BMI270_PWR_CTRL_ACCEL_EN_MSK			BIT(2)
+#define BMI270_PWR_CTRL_TEMP_EN_MSK			BIT(3)
+
+struct bmi270_data {
+	struct device *dev;
+	struct regmap *regmap;
+};
+
+extern const struct regmap_config bmi270_regmap_config;
+
+int bmi270_core_probe(struct device *dev, struct regmap *regmap);
+
+#endif  /* BMI270_H_ */
diff --git a/drivers/iio/imu/bmi270/bmi270_core.c b/drivers/iio/imu/bmi270/bmi270_core.c
new file mode 100644
index 000000000000..f0f83eb51dd2
--- /dev/null
+++ b/drivers/iio/imu/bmi270/bmi270_core.c
@@ -0,0 +1,251 @@ 
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+#include <linux/firmware.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include "bmi270.h"
+
+#define BMI270_INIT_DATA_FILE "bmi270-init-data.fw"
+
+enum bmi270_scan {
+	BMI270_SCAN_ACCEL_X,
+	BMI270_SCAN_ACCEL_Y,
+	BMI270_SCAN_ACCEL_Z,
+	BMI270_SCAN_GYRO_X,
+	BMI270_SCAN_GYRO_Y,
+	BMI270_SCAN_GYRO_Z,
+};
+
+const struct regmap_config bmi270_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+};
+EXPORT_SYMBOL_NS_GPL(bmi270_regmap_config, IIO_BMI270);
+
+static int bmi270_get_data(struct bmi270_data *bmi270_device,
+			   int chan_type, int axis, int *val)
+{
+	__le16 sample;
+	int reg;
+	int ret;
+
+	switch (chan_type) {
+	case IIO_ACCEL:
+		reg = BMI270_ACCEL_X_REG + (axis - IIO_MOD_X) * sizeof(sample);
+		break;
+	case IIO_ANGL_VEL:
+		reg = BMI270_ANG_VEL_X_REG + (axis - IIO_MOD_X) * sizeof(sample);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = regmap_bulk_read(bmi270_device->regmap, reg, &sample, sizeof(sample));
+	if (ret)
+		return ret;
+
+	*val = sign_extend32(le16_to_cpu(sample), 15);
+
+	return 0;
+}
+
+static int bmi270_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val, int *val2, long mask)
+{
+	int ret;
+	struct bmi270_data *bmi270_device = iio_priv(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = bmi270_get_data(bmi270_device, chan->type, chan->channel2, val);
+		if (ret)
+			return ret;
+
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct iio_info bmi270_info = {
+	.read_raw = bmi270_read_raw,
+};
+
+#define BMI270_ACCEL_CHANNEL(_axis) {				\
+	.type = IIO_ACCEL,					\
+	.modified = 1,						\
+	.channel2 = IIO_MOD_##_axis,				\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
+	BIT(IIO_CHAN_INFO_FREQUENCY),				\
+}
+
+#define BMI270_ANG_VEL_CHANNEL(_axis) {				\
+	.type = IIO_ANGL_VEL,					\
+	.modified = 1,						\
+	.channel2 = IIO_MOD_##_axis,				\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
+	BIT(IIO_CHAN_INFO_FREQUENCY),				\
+}
+
+static const struct iio_chan_spec bmi270_channels[] = {
+	BMI270_ACCEL_CHANNEL(X),
+	BMI270_ACCEL_CHANNEL(Y),
+	BMI270_ACCEL_CHANNEL(Z),
+	BMI270_ANG_VEL_CHANNEL(X),
+	BMI270_ANG_VEL_CHANNEL(Y),
+	BMI270_ANG_VEL_CHANNEL(Z)
+};
+
+static int bmi270_validate_chip_id(struct bmi270_data *bmi270_device)
+{
+	int chip_id;
+	int ret;
+	struct device *dev = bmi270_device->dev;
+	struct regmap *regmap = bmi270_device->regmap;
+
+	ret = regmap_read(regmap, BMI270_CHIP_ID_REG, &chip_id);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to read chip id");
+
+	if (chip_id != BMI270_CHIP_ID_VAL)
+		return dev_err_probe(dev, -ENODEV, "Invalid chip id 0x%x", chip_id);
+
+	return 0;
+}
+
+static int bmi270_write_calibration_data(struct bmi270_data *bmi270_device)
+{
+	int ret;
+	int status = 0;
+	const struct firmware *init_data;
+	struct device *dev = bmi270_device->dev;
+	struct regmap *regmap = bmi270_device->regmap;
+
+	ret = regmap_clear_bits(regmap, BMI270_PWR_CONF_REG, BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to write power configuration");
+
+	usleep_range(450, 1000);
+
+	ret = regmap_clear_bits(regmap, BMI270_INIT_CTRL_REG, BMI270_INIT_CTRL_LOAD_DONE_MSK);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to prepare device to load init data");
+
+	ret = request_firmware(&init_data, BMI270_INIT_DATA_FILE, dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to load init data file");
+
+	ret = regmap_bulk_write(regmap, BMI270_INIT_DATA_REG,
+				init_data->data, init_data->size);
+	release_firmware(init_data);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to write init data");
+
+	ret = regmap_set_bits(regmap, BMI270_INIT_CTRL_REG, BMI270_INIT_CTRL_LOAD_DONE_MSK);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to stop device initialization");
+
+	usleep_range(20000, 55000);
+
+	ret = regmap_read(regmap, BMI270_INTERNAL_STATUS_REG, &status);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to read internal status");
+
+	if (status != BMI270_INTERNAL_STATUS_MSG_INIT_OK)
+		return dev_err_probe(dev, -ENODEV, "Device failed to initialize");
+
+	return 0;
+}
+
+static int bmi270_configure_imu(struct bmi270_data *bmi270_device)
+{
+	int ret;
+	struct device *dev = bmi270_device->dev;
+	struct regmap *regmap = bmi270_device->regmap;
+
+	ret = regmap_set_bits(regmap, BMI270_PWR_CTRL_REG,
+			      BMI270_PWR_CTRL_AUX_EN_MSK |
+			      BMI270_PWR_CTRL_GYR_EN_MSK |
+			      BMI270_PWR_CTRL_ACCEL_EN_MSK);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to enable accelerometer and gyroscope");
+
+	ret = regmap_set_bits(regmap, BMI270_ACC_CONF_REG,
+			      FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
+					 BMI270_ACC_CONF_ODR_100HZ) |
+			      FIELD_PREP(BMI270_ACC_CONF_BWP_MSK,
+					 BMI270_ACC_CONF_BWP_NORMAL_MODE) |
+			      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to configure accelerometer");
+
+	ret = regmap_set_bits(regmap, BMI270_GYR_CONF_REG,
+			      FIELD_PREP(BMI270_GYR_CONF_ODR_MSK,
+					 BMI270_GYR_CONF_ODR_200HZ) |
+			      FIELD_PREP(BMI270_GYR_CONF_BWP_MSK,
+					 BMI270_GYR_CONF_BWP_NORMAL_MODE) |
+			      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to configure gyroscope");
+
+	/* Enable FIFO_WKUP, Disable ADV_PWR_SAVE and FUP_EN */
+	ret = regmap_write(regmap, BMI270_PWR_CONF_REG,
+			   BMI270_PWR_CONF_FIFO_WKUP_MSK);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to set power configuration");
+
+	return 0;
+}
+
+static int bmi270_chip_init(struct bmi270_data *bmi270_device)
+{
+	int ret;
+
+	ret = bmi270_validate_chip_id(bmi270_device);
+	if (ret)
+		return ret;
+
+	ret = bmi270_write_calibration_data(bmi270_device);
+	if (ret)
+		return ret;
+
+	return bmi270_configure_imu(bmi270_device);
+}
+
+int bmi270_core_probe(struct device *dev, struct regmap *regmap)
+{
+	int ret;
+	struct bmi270_data *bmi270_device;
+	struct iio_dev *indio_dev;
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof(struct bmi270_data *));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	bmi270_device = iio_priv(indio_dev);
+	bmi270_device->dev = dev;
+	bmi270_device->regmap = regmap;
+
+	ret = bmi270_chip_init(bmi270_device);
+	if (ret)
+		return ret;
+
+	indio_dev->channels = bmi270_channels;
+	indio_dev->num_channels = ARRAY_SIZE(bmi270_channels);
+	indio_dev->name = "bmi270";
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &bmi270_info;
+
+	return devm_iio_device_register(dev, indio_dev);
+}
+EXPORT_SYMBOL_NS_GPL(bmi270_core_probe, IIO_BMI270);
+
+MODULE_AUTHOR("Alex Lanzano");
+MODULE_DESCRIPTION("BMI270 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/imu/bmi270/bmi270_i2c.c b/drivers/iio/imu/bmi270/bmi270_i2c.c
new file mode 100644
index 000000000000..f70dee2d8a64
--- /dev/null
+++ b/drivers/iio/imu/bmi270/bmi270_i2c.c
@@ -0,0 +1,48 @@ 
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/regmap.h>
+
+#include "bmi270.h"
+
+static int bmi270_i2c_probe(struct i2c_client *client)
+{
+	struct regmap *regmap;
+	struct device *dev = &client->dev;
+
+	regmap = devm_regmap_init_i2c(client, &bmi270_regmap_config);
+	if (IS_ERR(regmap))
+		return dev_err_probe(dev, PTR_ERR(regmap),
+				     "Failed to init i2c regmap");
+
+	return bmi270_core_probe(dev, regmap);
+}
+
+static const struct i2c_device_id bmi270_i2c_id[] = {
+	{ "bmi270", 0 },
+	{ }
+};
+
+static const struct of_device_id bmi270_of_match[] = {
+	{ .compatible = "bosch,bmi270" },
+	{ }
+};
+
+static struct i2c_driver bmi270_i2c_driver = {
+	.driver = {
+		.name = "bmi270_i2c",
+		.of_match_table = bmi270_of_match,
+	},
+	.probe = bmi270_i2c_probe,
+	.id_table = bmi270_i2c_id,
+};
+module_i2c_driver(bmi270_i2c_driver);
+
+MODULE_AUTHOR("Alex Lanzano");
+MODULE_DESCRIPTION("BMI270 driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(IIO_BMI270);