1 // SPDX-License-Identifier: GPL-2.0
3 * I2C driver for Bosch BMI323 6-Axis IMU.
5 * Copyright (C) 2023, Jagath Jog J <jagathjog1996@gmail.com>
9 #include <linux/mod_devicetable.h>
10 #include <linux/module.h>
11 #include <linux/regmap.h>
15 struct bmi323_i2c_priv
{
16 struct i2c_client
*i2c
;
17 u8 i2c_rx_buffer
[BMI323_FIFO_LENGTH_IN_BYTES
+ BMI323_I2C_DUMMY
];
21 * From BMI323 datasheet section 4: Notes on the Serial Interface Support.
22 * Each I2C register read operation requires to read two dummy bytes before
25 static int bmi323_regmap_i2c_read(void *context
, const void *reg_buf
,
26 size_t reg_size
, void *val_buf
,
29 struct bmi323_i2c_priv
*priv
= context
;
30 struct i2c_msg msgs
[2];
33 msgs
[0].addr
= priv
->i2c
->addr
;
34 msgs
[0].flags
= priv
->i2c
->flags
;
35 msgs
[0].len
= reg_size
;
36 msgs
[0].buf
= (u8
*)reg_buf
;
38 msgs
[1].addr
= priv
->i2c
->addr
;
39 msgs
[1].len
= val_size
+ BMI323_I2C_DUMMY
;
40 msgs
[1].buf
= priv
->i2c_rx_buffer
;
41 msgs
[1].flags
= priv
->i2c
->flags
| I2C_M_RD
;
43 ret
= i2c_transfer(priv
->i2c
->adapter
, msgs
, ARRAY_SIZE(msgs
));
47 memcpy(val_buf
, priv
->i2c_rx_buffer
+ BMI323_I2C_DUMMY
, val_size
);
52 static int bmi323_regmap_i2c_write(void *context
, const void *data
,
55 struct bmi323_i2c_priv
*priv
= context
;
59 return i2c_smbus_write_i2c_block_data(priv
->i2c
, reg
,
64 static const struct regmap_bus bmi323_regmap_bus
= {
65 .read
= bmi323_regmap_i2c_read
,
66 .write
= bmi323_regmap_i2c_write
,
69 static const struct regmap_config bmi323_i2c_regmap_config
= {
72 .max_register
= BMI323_CFG_RES_REG
,
73 .val_format_endian
= REGMAP_ENDIAN_LITTLE
,
76 static int bmi323_i2c_probe(struct i2c_client
*i2c
)
78 struct device
*dev
= &i2c
->dev
;
79 struct bmi323_i2c_priv
*priv
;
80 struct regmap
*regmap
;
82 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
87 regmap
= devm_regmap_init(dev
, &bmi323_regmap_bus
, priv
,
88 &bmi323_i2c_regmap_config
);
90 return dev_err_probe(dev
, PTR_ERR(regmap
),
91 "Failed to initialize I2C Regmap\n");
93 return bmi323_core_probe(dev
);
96 static const struct acpi_device_id bmi323_acpi_match
[] = {
98 * The "BOSC0200" identifier used here is not unique to bmi323 devices.
99 * The same "BOSC0200" identifier is found in the ACPI tables of devices
100 * using the bmc150 chip. This creates a conflict with duplicate ACPI
101 * identifiers which multiple drivers want to use. If a non-bmi323
102 * device starts to load with this "BOSC0200" ACPI match here, then the
103 * chip ID check portion should fail because the chip IDs received (via
104 * i2c) are unique between bmc150 and bmi323 and the driver should
105 * relinquish the device. If and when a different driver (such as
106 * bmc150) starts to load with the "BOSC0200" ACPI match, a short reset
107 * should ensure that the device is not in a bad state during that
108 * driver initialization. This device reset does occur in both the
109 * bmi323 and bmc150 init sequences.
114 MODULE_DEVICE_TABLE(acpi
, bmi323_acpi_match
);
116 static const struct i2c_device_id bmi323_i2c_ids
[] = {
120 MODULE_DEVICE_TABLE(i2c
, bmi323_i2c_ids
);
122 static const struct of_device_id bmi323_of_i2c_match
[] = {
123 { .compatible
= "bosch,bmi323" },
126 MODULE_DEVICE_TABLE(of
, bmi323_of_i2c_match
);
128 static struct i2c_driver bmi323_i2c_driver
= {
131 .pm
= pm_ptr(&bmi323_core_pm_ops
),
132 .of_match_table
= bmi323_of_i2c_match
,
133 .acpi_match_table
= bmi323_acpi_match
,
135 .probe
= bmi323_i2c_probe
,
136 .id_table
= bmi323_i2c_ids
,
138 module_i2c_driver(bmi323_i2c_driver
);
140 MODULE_DESCRIPTION("Bosch BMI323 IMU driver");
141 MODULE_AUTHOR("Jagath Jog J <jagathjog1996@gmail.com>");
142 MODULE_LICENSE("GPL");
143 MODULE_IMPORT_NS("IIO_BMI323");