xref: /linux/drivers/iio/imu/bmi270/bmi270_core.c (revision d723c456ef5ad60d368e62791004fd152c4380aa)
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 
3 #include <linux/bitfield.h>
4 #include <linux/firmware.h>
5 #include <linux/i2c.h>
6 #include <linux/module.h>
7 #include <linux/regmap.h>
8 
9 #include <linux/iio/iio.h>
10 
11 #include "bmi270.h"
12 
13 #define BMI270_CHIP_ID_REG				0x00
14 #define BMI270_CHIP_ID_VAL				0x24
15 #define BMI270_CHIP_ID_MSK				GENMASK(7, 0)
16 
17 #define BMI270_ACCEL_X_REG				0x0c
18 #define BMI270_ANG_VEL_X_REG				0x12
19 
20 #define BMI270_INTERNAL_STATUS_REG			0x21
21 #define BMI270_INTERNAL_STATUS_MSG_MSK			GENMASK(3, 0)
22 #define BMI270_INTERNAL_STATUS_MSG_INIT_OK		0x01
23 
24 #define BMI270_INTERNAL_STATUS_AXES_REMAP_ERR_MSK	BIT(5)
25 #define BMI270_INTERNAL_STATUS_ODR_50HZ_ERR_MSK		BIT(6)
26 
27 #define BMI270_ACC_CONF_REG				0x40
28 #define BMI270_ACC_CONF_ODR_MSK				GENMASK(3, 0)
29 #define BMI270_ACC_CONF_ODR_100HZ			0x08
30 #define BMI270_ACC_CONF_BWP_MSK				GENMASK(6, 4)
31 #define BMI270_ACC_CONF_BWP_NORMAL_MODE			0x02
32 #define BMI270_ACC_CONF_FILTER_PERF_MSK			BIT(7)
33 
34 #define BMI270_GYR_CONF_REG				0x42
35 #define BMI270_GYR_CONF_ODR_MSK				GENMASK(3, 0)
36 #define BMI270_GYR_CONF_ODR_200HZ			0x09
37 #define BMI270_GYR_CONF_BWP_MSK				GENMASK(5, 4)
38 #define BMI270_GYR_CONF_BWP_NORMAL_MODE			0x02
39 #define BMI270_GYR_CONF_NOISE_PERF_MSK			BIT(6)
40 #define BMI270_GYR_CONF_FILTER_PERF_MSK			BIT(7)
41 
42 #define BMI270_INIT_CTRL_REG				0x59
43 #define BMI270_INIT_CTRL_LOAD_DONE_MSK			BIT(0)
44 
45 #define BMI270_INIT_DATA_REG				0x5e
46 
47 #define BMI270_PWR_CONF_REG				0x7c
48 #define BMI270_PWR_CONF_ADV_PWR_SAVE_MSK		BIT(0)
49 #define BMI270_PWR_CONF_FIFO_WKUP_MSK			BIT(1)
50 #define BMI270_PWR_CONF_FUP_EN_MSK			BIT(2)
51 
52 #define BMI270_PWR_CTRL_REG				0x7d
53 #define BMI270_PWR_CTRL_AUX_EN_MSK			BIT(0)
54 #define BMI270_PWR_CTRL_GYR_EN_MSK			BIT(1)
55 #define BMI270_PWR_CTRL_ACCEL_EN_MSK			BIT(2)
56 #define BMI270_PWR_CTRL_TEMP_EN_MSK			BIT(3)
57 
58 #define BMI270_INIT_DATA_FILE "bmi270-init-data.fw"
59 
60 enum bmi270_scan {
61 	BMI270_SCAN_ACCEL_X,
62 	BMI270_SCAN_ACCEL_Y,
63 	BMI270_SCAN_ACCEL_Z,
64 	BMI270_SCAN_GYRO_X,
65 	BMI270_SCAN_GYRO_Y,
66 	BMI270_SCAN_GYRO_Z,
67 };
68 
69 static int bmi270_get_data(struct bmi270_data *bmi270_device,
70 			   int chan_type, int axis, int *val)
71 {
72 	__le16 sample;
73 	int reg;
74 	int ret;
75 
76 	switch (chan_type) {
77 	case IIO_ACCEL:
78 		reg = BMI270_ACCEL_X_REG + (axis - IIO_MOD_X) * 2;
79 		break;
80 	case IIO_ANGL_VEL:
81 		reg = BMI270_ANG_VEL_X_REG + (axis - IIO_MOD_X) * 2;
82 		break;
83 	default:
84 		return -EINVAL;
85 	}
86 
87 	ret = regmap_bulk_read(bmi270_device->regmap, reg, &sample, sizeof(sample));
88 	if (ret)
89 		return ret;
90 
91 	*val = sign_extend32(le16_to_cpu(sample), 15);
92 
93 	return 0;
94 }
95 
96 static int bmi270_read_raw(struct iio_dev *indio_dev,
97 			   struct iio_chan_spec const *chan,
98 			   int *val, int *val2, long mask)
99 {
100 	int ret;
101 	struct bmi270_data *bmi270_device = iio_priv(indio_dev);
102 
103 	switch (mask) {
104 	case IIO_CHAN_INFO_RAW:
105 		ret = bmi270_get_data(bmi270_device, chan->type, chan->channel2, val);
106 		if (ret)
107 			return ret;
108 
109 		return IIO_VAL_INT;
110 	default:
111 		return -EINVAL;
112 	}
113 }
114 
115 static const struct iio_info bmi270_info = {
116 	.read_raw = bmi270_read_raw,
117 };
118 
119 #define BMI270_ACCEL_CHANNEL(_axis) {				\
120 	.type = IIO_ACCEL,					\
121 	.modified = 1,						\
122 	.channel2 = IIO_MOD_##_axis,				\
123 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
124 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
125 		BIT(IIO_CHAN_INFO_FREQUENCY),			\
126 }
127 
128 #define BMI270_ANG_VEL_CHANNEL(_axis) {				\
129 	.type = IIO_ANGL_VEL,					\
130 	.modified = 1,						\
131 	.channel2 = IIO_MOD_##_axis,				\
132 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
133 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
134 		BIT(IIO_CHAN_INFO_FREQUENCY),			\
135 }
136 
137 static const struct iio_chan_spec bmi270_channels[] = {
138 	BMI270_ACCEL_CHANNEL(X),
139 	BMI270_ACCEL_CHANNEL(Y),
140 	BMI270_ACCEL_CHANNEL(Z),
141 	BMI270_ANG_VEL_CHANNEL(X),
142 	BMI270_ANG_VEL_CHANNEL(Y),
143 	BMI270_ANG_VEL_CHANNEL(Z),
144 };
145 
146 static int bmi270_validate_chip_id(struct bmi270_data *bmi270_device)
147 {
148 	int chip_id;
149 	int ret;
150 	struct device *dev = bmi270_device->dev;
151 	struct regmap *regmap = bmi270_device->regmap;
152 
153 	ret = regmap_read(regmap, BMI270_CHIP_ID_REG, &chip_id);
154 	if (ret)
155 		return dev_err_probe(dev, ret, "Failed to read chip id");
156 
157 	if (chip_id != BMI270_CHIP_ID_VAL)
158 		dev_info(dev, "Unknown chip id 0x%x", chip_id);
159 
160 	return 0;
161 }
162 
163 static int bmi270_write_calibration_data(struct bmi270_data *bmi270_device)
164 {
165 	int ret;
166 	int status = 0;
167 	const struct firmware *init_data;
168 	struct device *dev = bmi270_device->dev;
169 	struct regmap *regmap = bmi270_device->regmap;
170 
171 	ret = regmap_clear_bits(regmap, BMI270_PWR_CONF_REG,
172 				BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
173 	if (ret)
174 		return dev_err_probe(dev, ret,
175 				     "Failed to write power configuration");
176 
177 	/*
178 	 * After disabling advanced power save, all registers are accessible
179 	 * after a 450us delay. This delay is specified in table A of the
180 	 * datasheet.
181 	 */
182 	usleep_range(450, 1000);
183 
184 	ret = regmap_clear_bits(regmap, BMI270_INIT_CTRL_REG,
185 				BMI270_INIT_CTRL_LOAD_DONE_MSK);
186 	if (ret)
187 		return dev_err_probe(dev, ret,
188 				     "Failed to prepare device to load init data");
189 
190 	ret = request_firmware(&init_data, BMI270_INIT_DATA_FILE, dev);
191 	if (ret)
192 		return dev_err_probe(dev, ret, "Failed to load init data file");
193 
194 	ret = regmap_bulk_write(regmap, BMI270_INIT_DATA_REG,
195 				init_data->data, init_data->size);
196 	release_firmware(init_data);
197 	if (ret)
198 		return dev_err_probe(dev, ret, "Failed to write init data");
199 
200 	ret = regmap_set_bits(regmap, BMI270_INIT_CTRL_REG,
201 			      BMI270_INIT_CTRL_LOAD_DONE_MSK);
202 	if (ret)
203 		return dev_err_probe(dev, ret,
204 				     "Failed to stop device initialization");
205 
206 	/*
207 	 * Wait at least 140ms for the device to complete configuration.
208 	 * This delay is specified in table C of the datasheet.
209 	 */
210 	usleep_range(140000, 160000);
211 
212 	ret = regmap_read(regmap, BMI270_INTERNAL_STATUS_REG, &status);
213 	if (ret)
214 		return dev_err_probe(dev, ret, "Failed to read internal status");
215 
216 	if (status != BMI270_INTERNAL_STATUS_MSG_INIT_OK)
217 		return dev_err_probe(dev, -ENODEV, "Device failed to initialize");
218 
219 	return 0;
220 }
221 
222 static int bmi270_configure_imu(struct bmi270_data *bmi270_device)
223 {
224 	int ret;
225 	struct device *dev = bmi270_device->dev;
226 	struct regmap *regmap = bmi270_device->regmap;
227 
228 	ret = regmap_set_bits(regmap, BMI270_PWR_CTRL_REG,
229 			      BMI270_PWR_CTRL_AUX_EN_MSK |
230 			      BMI270_PWR_CTRL_GYR_EN_MSK |
231 			      BMI270_PWR_CTRL_ACCEL_EN_MSK);
232 	if (ret)
233 		return dev_err_probe(dev, ret, "Failed to enable accelerometer and gyroscope");
234 
235 	ret = regmap_set_bits(regmap, BMI270_ACC_CONF_REG,
236 			      FIELD_PREP(BMI270_ACC_CONF_ODR_MSK,
237 					 BMI270_ACC_CONF_ODR_100HZ) |
238 			      FIELD_PREP(BMI270_ACC_CONF_BWP_MSK,
239 					 BMI270_ACC_CONF_BWP_NORMAL_MODE) |
240 			      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
241 	if (ret)
242 		return dev_err_probe(dev, ret, "Failed to configure accelerometer");
243 
244 	ret = regmap_set_bits(regmap, BMI270_GYR_CONF_REG,
245 			      FIELD_PREP(BMI270_GYR_CONF_ODR_MSK,
246 					 BMI270_GYR_CONF_ODR_200HZ) |
247 			      FIELD_PREP(BMI270_GYR_CONF_BWP_MSK,
248 					 BMI270_GYR_CONF_BWP_NORMAL_MODE) |
249 			      BMI270_PWR_CONF_ADV_PWR_SAVE_MSK);
250 	if (ret)
251 		return dev_err_probe(dev, ret, "Failed to configure gyroscope");
252 
253 	/* Enable FIFO_WKUP, Disable ADV_PWR_SAVE and FUP_EN */
254 	ret = regmap_write(regmap, BMI270_PWR_CONF_REG,
255 			   BMI270_PWR_CONF_FIFO_WKUP_MSK);
256 	if (ret)
257 		return dev_err_probe(dev, ret, "Failed to set power configuration");
258 
259 	return 0;
260 }
261 
262 static int bmi270_chip_init(struct bmi270_data *bmi270_device)
263 {
264 	int ret;
265 
266 	ret = bmi270_validate_chip_id(bmi270_device);
267 	if (ret)
268 		return ret;
269 
270 	ret = bmi270_write_calibration_data(bmi270_device);
271 	if (ret)
272 		return ret;
273 
274 	return bmi270_configure_imu(bmi270_device);
275 }
276 
277 int bmi270_core_probe(struct device *dev, struct regmap *regmap)
278 {
279 	int ret;
280 	struct bmi270_data *bmi270_device;
281 	struct iio_dev *indio_dev;
282 
283 	indio_dev = devm_iio_device_alloc(dev, sizeof(*bmi270_device));
284 	if (!indio_dev)
285 		return -ENOMEM;
286 
287 	bmi270_device = iio_priv(indio_dev);
288 	bmi270_device->dev = dev;
289 	bmi270_device->regmap = regmap;
290 
291 	ret = bmi270_chip_init(bmi270_device);
292 	if (ret)
293 		return ret;
294 
295 	indio_dev->channels = bmi270_channels;
296 	indio_dev->num_channels = ARRAY_SIZE(bmi270_channels);
297 	indio_dev->name = "bmi270";
298 	indio_dev->modes = INDIO_DIRECT_MODE;
299 	indio_dev->info = &bmi270_info;
300 
301 	return devm_iio_device_register(dev, indio_dev);
302 }
303 EXPORT_SYMBOL_NS_GPL(bmi270_core_probe, IIO_BMI270);
304 
305 MODULE_AUTHOR("Alex Lanzano");
306 MODULE_DESCRIPTION("BMI270 driver");
307 MODULE_LICENSE("GPL");
308