1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * BMI160 - Bosch IMU (accel, gyro plus external magnetometer) |
4 | * |
5 | * Copyright (c) 2016, Intel Corporation. |
6 | * Copyright (c) 2019, Martin Kelly. |
7 | * |
8 | * IIO core driver for BMI160, with support for I2C/SPI busses |
9 | * |
10 | * TODO: magnetometer, hardware FIFO |
11 | */ |
12 | #include <linux/module.h> |
13 | #include <linux/regmap.h> |
14 | #include <linux/delay.h> |
15 | #include <linux/irq.h> |
16 | #include <linux/property.h> |
17 | #include <linux/regulator/consumer.h> |
18 | |
19 | #include <linux/iio/iio.h> |
20 | #include <linux/iio/triggered_buffer.h> |
21 | #include <linux/iio/trigger_consumer.h> |
22 | #include <linux/iio/buffer.h> |
23 | #include <linux/iio/sysfs.h> |
24 | #include <linux/iio/trigger.h> |
25 | |
26 | #include "bmi160.h" |
27 | |
28 | #define BMI160_REG_CHIP_ID 0x00 |
29 | #define BMI160_CHIP_ID_VAL 0xD1 |
30 | |
31 | #define BMI160_REG_PMU_STATUS 0x03 |
32 | |
33 | /* X axis data low byte address, the rest can be obtained using axis offset */ |
34 | #define BMI160_REG_DATA_MAGN_XOUT_L 0x04 |
35 | #define BMI160_REG_DATA_GYRO_XOUT_L 0x0C |
36 | #define BMI160_REG_DATA_ACCEL_XOUT_L 0x12 |
37 | |
38 | #define BMI160_REG_ACCEL_CONFIG 0x40 |
39 | #define BMI160_ACCEL_CONFIG_ODR_MASK GENMASK(3, 0) |
40 | #define BMI160_ACCEL_CONFIG_BWP_MASK GENMASK(6, 4) |
41 | |
42 | #define BMI160_REG_ACCEL_RANGE 0x41 |
43 | #define BMI160_ACCEL_RANGE_2G 0x03 |
44 | #define BMI160_ACCEL_RANGE_4G 0x05 |
45 | #define BMI160_ACCEL_RANGE_8G 0x08 |
46 | #define BMI160_ACCEL_RANGE_16G 0x0C |
47 | |
48 | #define BMI160_REG_GYRO_CONFIG 0x42 |
49 | #define BMI160_GYRO_CONFIG_ODR_MASK GENMASK(3, 0) |
50 | #define BMI160_GYRO_CONFIG_BWP_MASK GENMASK(5, 4) |
51 | |
52 | #define BMI160_REG_GYRO_RANGE 0x43 |
53 | #define BMI160_GYRO_RANGE_2000DPS 0x00 |
54 | #define BMI160_GYRO_RANGE_1000DPS 0x01 |
55 | #define BMI160_GYRO_RANGE_500DPS 0x02 |
56 | #define BMI160_GYRO_RANGE_250DPS 0x03 |
57 | #define BMI160_GYRO_RANGE_125DPS 0x04 |
58 | |
59 | #define BMI160_REG_CMD 0x7E |
60 | #define BMI160_CMD_ACCEL_PM_SUSPEND 0x10 |
61 | #define BMI160_CMD_ACCEL_PM_NORMAL 0x11 |
62 | #define BMI160_CMD_ACCEL_PM_LOW_POWER 0x12 |
63 | #define BMI160_CMD_GYRO_PM_SUSPEND 0x14 |
64 | #define BMI160_CMD_GYRO_PM_NORMAL 0x15 |
65 | #define BMI160_CMD_GYRO_PM_FAST_STARTUP 0x17 |
66 | #define BMI160_CMD_SOFTRESET 0xB6 |
67 | |
68 | #define BMI160_REG_INT_EN 0x51 |
69 | #define BMI160_DRDY_INT_EN BIT(4) |
70 | |
71 | #define BMI160_REG_INT_OUT_CTRL 0x53 |
72 | #define BMI160_INT_OUT_CTRL_MASK 0x0f |
73 | #define BMI160_INT1_OUT_CTRL_SHIFT 0 |
74 | #define BMI160_INT2_OUT_CTRL_SHIFT 4 |
75 | #define BMI160_EDGE_TRIGGERED BIT(0) |
76 | #define BMI160_ACTIVE_HIGH BIT(1) |
77 | #define BMI160_OPEN_DRAIN BIT(2) |
78 | #define BMI160_OUTPUT_EN BIT(3) |
79 | |
80 | #define BMI160_REG_INT_LATCH 0x54 |
81 | #define BMI160_INT1_LATCH_MASK BIT(4) |
82 | #define BMI160_INT2_LATCH_MASK BIT(5) |
83 | |
84 | /* INT1 and INT2 are in the opposite order as in INT_OUT_CTRL! */ |
85 | #define BMI160_REG_INT_MAP 0x56 |
86 | #define BMI160_INT1_MAP_DRDY_EN 0x80 |
87 | #define BMI160_INT2_MAP_DRDY_EN 0x08 |
88 | |
89 | #define BMI160_REG_DUMMY 0x7F |
90 | |
91 | #define BMI160_NORMAL_WRITE_USLEEP 2 |
92 | #define BMI160_SUSPENDED_WRITE_USLEEP 450 |
93 | |
94 | #define BMI160_ACCEL_PMU_MIN_USLEEP 3800 |
95 | #define BMI160_GYRO_PMU_MIN_USLEEP 80000 |
96 | #define BMI160_SOFTRESET_USLEEP 1000 |
97 | |
98 | #define BMI160_CHANNEL(_type, _axis, _index) { \ |
99 | .type = _type, \ |
100 | .modified = 1, \ |
101 | .channel2 = IIO_MOD_##_axis, \ |
102 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
103 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ |
104 | BIT(IIO_CHAN_INFO_SAMP_FREQ), \ |
105 | .scan_index = _index, \ |
106 | .scan_type = { \ |
107 | .sign = 's', \ |
108 | .realbits = 16, \ |
109 | .storagebits = 16, \ |
110 | .endianness = IIO_LE, \ |
111 | }, \ |
112 | .ext_info = bmi160_ext_info, \ |
113 | } |
114 | |
115 | /* scan indexes follow DATA register order */ |
116 | enum bmi160_scan_axis { |
117 | BMI160_SCAN_EXT_MAGN_X = 0, |
118 | BMI160_SCAN_EXT_MAGN_Y, |
119 | BMI160_SCAN_EXT_MAGN_Z, |
120 | BMI160_SCAN_RHALL, |
121 | BMI160_SCAN_GYRO_X, |
122 | BMI160_SCAN_GYRO_Y, |
123 | BMI160_SCAN_GYRO_Z, |
124 | BMI160_SCAN_ACCEL_X, |
125 | BMI160_SCAN_ACCEL_Y, |
126 | BMI160_SCAN_ACCEL_Z, |
127 | BMI160_SCAN_TIMESTAMP, |
128 | }; |
129 | |
130 | enum bmi160_sensor_type { |
131 | BMI160_ACCEL = 0, |
132 | BMI160_GYRO, |
133 | BMI160_EXT_MAGN, |
134 | BMI160_NUM_SENSORS /* must be last */ |
135 | }; |
136 | |
137 | enum bmi160_int_pin { |
138 | BMI160_PIN_INT1, |
139 | BMI160_PIN_INT2 |
140 | }; |
141 | |
142 | const struct regmap_config bmi160_regmap_config = { |
143 | .reg_bits = 8, |
144 | .val_bits = 8, |
145 | }; |
146 | EXPORT_SYMBOL_NS(bmi160_regmap_config, IIO_BMI160); |
147 | |
148 | struct bmi160_regs { |
149 | u8 data; /* LSB byte register for X-axis */ |
150 | u8 config; |
151 | u8 config_odr_mask; |
152 | u8 config_bwp_mask; |
153 | u8 range; |
154 | u8 pmu_cmd_normal; |
155 | u8 pmu_cmd_suspend; |
156 | }; |
157 | |
158 | static struct bmi160_regs bmi160_regs[] = { |
159 | [BMI160_ACCEL] = { |
160 | .data = BMI160_REG_DATA_ACCEL_XOUT_L, |
161 | .config = BMI160_REG_ACCEL_CONFIG, |
162 | .config_odr_mask = BMI160_ACCEL_CONFIG_ODR_MASK, |
163 | .config_bwp_mask = BMI160_ACCEL_CONFIG_BWP_MASK, |
164 | .range = BMI160_REG_ACCEL_RANGE, |
165 | .pmu_cmd_normal = BMI160_CMD_ACCEL_PM_NORMAL, |
166 | .pmu_cmd_suspend = BMI160_CMD_ACCEL_PM_SUSPEND, |
167 | }, |
168 | [BMI160_GYRO] = { |
169 | .data = BMI160_REG_DATA_GYRO_XOUT_L, |
170 | .config = BMI160_REG_GYRO_CONFIG, |
171 | .config_odr_mask = BMI160_GYRO_CONFIG_ODR_MASK, |
172 | .config_bwp_mask = BMI160_GYRO_CONFIG_BWP_MASK, |
173 | .range = BMI160_REG_GYRO_RANGE, |
174 | .pmu_cmd_normal = BMI160_CMD_GYRO_PM_NORMAL, |
175 | .pmu_cmd_suspend = BMI160_CMD_GYRO_PM_SUSPEND, |
176 | }, |
177 | }; |
178 | |
179 | static unsigned long bmi160_pmu_time[] = { |
180 | [BMI160_ACCEL] = BMI160_ACCEL_PMU_MIN_USLEEP, |
181 | [BMI160_GYRO] = BMI160_GYRO_PMU_MIN_USLEEP, |
182 | }; |
183 | |
184 | struct bmi160_scale { |
185 | u8 bits; |
186 | int uscale; |
187 | }; |
188 | |
189 | struct bmi160_odr { |
190 | u8 bits; |
191 | int odr; |
192 | int uodr; |
193 | }; |
194 | |
195 | static const struct bmi160_scale bmi160_accel_scale[] = { |
196 | { BMI160_ACCEL_RANGE_2G, 598}, |
197 | { BMI160_ACCEL_RANGE_4G, 1197}, |
198 | { BMI160_ACCEL_RANGE_8G, 2394}, |
199 | { BMI160_ACCEL_RANGE_16G, 4788}, |
200 | }; |
201 | |
202 | static const struct bmi160_scale bmi160_gyro_scale[] = { |
203 | { BMI160_GYRO_RANGE_2000DPS, 1065}, |
204 | { BMI160_GYRO_RANGE_1000DPS, 532}, |
205 | { BMI160_GYRO_RANGE_500DPS, 266}, |
206 | { BMI160_GYRO_RANGE_250DPS, 133}, |
207 | { BMI160_GYRO_RANGE_125DPS, 66}, |
208 | }; |
209 | |
210 | struct bmi160_scale_item { |
211 | const struct bmi160_scale *tbl; |
212 | int num; |
213 | }; |
214 | |
215 | static const struct bmi160_scale_item bmi160_scale_table[] = { |
216 | [BMI160_ACCEL] = { |
217 | .tbl = bmi160_accel_scale, |
218 | .num = ARRAY_SIZE(bmi160_accel_scale), |
219 | }, |
220 | [BMI160_GYRO] = { |
221 | .tbl = bmi160_gyro_scale, |
222 | .num = ARRAY_SIZE(bmi160_gyro_scale), |
223 | }, |
224 | }; |
225 | |
226 | static const struct bmi160_odr bmi160_accel_odr[] = { |
227 | {0x01, 0, 781250}, |
228 | {0x02, 1, 562500}, |
229 | {0x03, 3, 125000}, |
230 | {0x04, 6, 250000}, |
231 | {0x05, 12, 500000}, |
232 | {0x06, 25, 0}, |
233 | {0x07, 50, 0}, |
234 | {0x08, 100, 0}, |
235 | {0x09, 200, 0}, |
236 | {0x0A, 400, 0}, |
237 | {0x0B, 800, 0}, |
238 | {0x0C, 1600, 0}, |
239 | }; |
240 | |
241 | static const struct bmi160_odr bmi160_gyro_odr[] = { |
242 | {0x06, 25, 0}, |
243 | {0x07, 50, 0}, |
244 | {0x08, 100, 0}, |
245 | {0x09, 200, 0}, |
246 | {0x0A, 400, 0}, |
247 | {0x0B, 800, 0}, |
248 | {0x0C, 1600, 0}, |
249 | {0x0D, 3200, 0}, |
250 | }; |
251 | |
252 | struct bmi160_odr_item { |
253 | const struct bmi160_odr *tbl; |
254 | int num; |
255 | }; |
256 | |
257 | static const struct bmi160_odr_item bmi160_odr_table[] = { |
258 | [BMI160_ACCEL] = { |
259 | .tbl = bmi160_accel_odr, |
260 | .num = ARRAY_SIZE(bmi160_accel_odr), |
261 | }, |
262 | [BMI160_GYRO] = { |
263 | .tbl = bmi160_gyro_odr, |
264 | .num = ARRAY_SIZE(bmi160_gyro_odr), |
265 | }, |
266 | }; |
267 | |
268 | static const struct iio_mount_matrix * |
269 | bmi160_get_mount_matrix(const struct iio_dev *indio_dev, |
270 | const struct iio_chan_spec *chan) |
271 | { |
272 | struct bmi160_data *data = iio_priv(indio_dev); |
273 | |
274 | return &data->orientation; |
275 | } |
276 | |
277 | static const struct iio_chan_spec_ext_info bmi160_ext_info[] = { |
278 | IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bmi160_get_mount_matrix), |
279 | { } |
280 | }; |
281 | |
282 | static const struct iio_chan_spec bmi160_channels[] = { |
283 | BMI160_CHANNEL(IIO_ACCEL, X, BMI160_SCAN_ACCEL_X), |
284 | BMI160_CHANNEL(IIO_ACCEL, Y, BMI160_SCAN_ACCEL_Y), |
285 | BMI160_CHANNEL(IIO_ACCEL, Z, BMI160_SCAN_ACCEL_Z), |
286 | BMI160_CHANNEL(IIO_ANGL_VEL, X, BMI160_SCAN_GYRO_X), |
287 | BMI160_CHANNEL(IIO_ANGL_VEL, Y, BMI160_SCAN_GYRO_Y), |
288 | BMI160_CHANNEL(IIO_ANGL_VEL, Z, BMI160_SCAN_GYRO_Z), |
289 | IIO_CHAN_SOFT_TIMESTAMP(BMI160_SCAN_TIMESTAMP), |
290 | }; |
291 | |
292 | static enum bmi160_sensor_type bmi160_to_sensor(enum iio_chan_type iio_type) |
293 | { |
294 | switch (iio_type) { |
295 | case IIO_ACCEL: |
296 | return BMI160_ACCEL; |
297 | case IIO_ANGL_VEL: |
298 | return BMI160_GYRO; |
299 | default: |
300 | return -EINVAL; |
301 | } |
302 | } |
303 | |
304 | static |
305 | int bmi160_set_mode(struct bmi160_data *data, enum bmi160_sensor_type t, |
306 | bool mode) |
307 | { |
308 | int ret; |
309 | u8 cmd; |
310 | |
311 | if (mode) |
312 | cmd = bmi160_regs[t].pmu_cmd_normal; |
313 | else |
314 | cmd = bmi160_regs[t].pmu_cmd_suspend; |
315 | |
316 | ret = regmap_write(map: data->regmap, BMI160_REG_CMD, val: cmd); |
317 | if (ret) |
318 | return ret; |
319 | |
320 | usleep_range(min: bmi160_pmu_time[t], max: bmi160_pmu_time[t] + 1000); |
321 | |
322 | return 0; |
323 | } |
324 | |
325 | static |
326 | int bmi160_set_scale(struct bmi160_data *data, enum bmi160_sensor_type t, |
327 | int uscale) |
328 | { |
329 | int i; |
330 | |
331 | for (i = 0; i < bmi160_scale_table[t].num; i++) |
332 | if (bmi160_scale_table[t].tbl[i].uscale == uscale) |
333 | break; |
334 | |
335 | if (i == bmi160_scale_table[t].num) |
336 | return -EINVAL; |
337 | |
338 | return regmap_write(map: data->regmap, reg: bmi160_regs[t].range, |
339 | val: bmi160_scale_table[t].tbl[i].bits); |
340 | } |
341 | |
342 | static |
343 | int bmi160_get_scale(struct bmi160_data *data, enum bmi160_sensor_type t, |
344 | int *uscale) |
345 | { |
346 | int i, ret, val; |
347 | |
348 | ret = regmap_read(map: data->regmap, reg: bmi160_regs[t].range, val: &val); |
349 | if (ret) |
350 | return ret; |
351 | |
352 | for (i = 0; i < bmi160_scale_table[t].num; i++) |
353 | if (bmi160_scale_table[t].tbl[i].bits == val) { |
354 | *uscale = bmi160_scale_table[t].tbl[i].uscale; |
355 | return 0; |
356 | } |
357 | |
358 | return -EINVAL; |
359 | } |
360 | |
361 | static int bmi160_get_data(struct bmi160_data *data, int chan_type, |
362 | int axis, int *val) |
363 | { |
364 | u8 reg; |
365 | int ret; |
366 | __le16 sample; |
367 | enum bmi160_sensor_type t = bmi160_to_sensor(iio_type: chan_type); |
368 | |
369 | reg = bmi160_regs[t].data + (axis - IIO_MOD_X) * sizeof(sample); |
370 | |
371 | ret = regmap_bulk_read(map: data->regmap, reg, val: &sample, val_count: sizeof(sample)); |
372 | if (ret) |
373 | return ret; |
374 | |
375 | *val = sign_extend32(le16_to_cpu(sample), index: 15); |
376 | |
377 | return 0; |
378 | } |
379 | |
380 | static |
381 | int bmi160_set_odr(struct bmi160_data *data, enum bmi160_sensor_type t, |
382 | int odr, int uodr) |
383 | { |
384 | int i; |
385 | |
386 | for (i = 0; i < bmi160_odr_table[t].num; i++) |
387 | if (bmi160_odr_table[t].tbl[i].odr == odr && |
388 | bmi160_odr_table[t].tbl[i].uodr == uodr) |
389 | break; |
390 | |
391 | if (i >= bmi160_odr_table[t].num) |
392 | return -EINVAL; |
393 | |
394 | return regmap_update_bits(map: data->regmap, |
395 | reg: bmi160_regs[t].config, |
396 | mask: bmi160_regs[t].config_odr_mask, |
397 | val: bmi160_odr_table[t].tbl[i].bits); |
398 | } |
399 | |
400 | static int bmi160_get_odr(struct bmi160_data *data, enum bmi160_sensor_type t, |
401 | int *odr, int *uodr) |
402 | { |
403 | int i, val, ret; |
404 | |
405 | ret = regmap_read(map: data->regmap, reg: bmi160_regs[t].config, val: &val); |
406 | if (ret) |
407 | return ret; |
408 | |
409 | val &= bmi160_regs[t].config_odr_mask; |
410 | |
411 | for (i = 0; i < bmi160_odr_table[t].num; i++) |
412 | if (val == bmi160_odr_table[t].tbl[i].bits) |
413 | break; |
414 | |
415 | if (i >= bmi160_odr_table[t].num) |
416 | return -EINVAL; |
417 | |
418 | *odr = bmi160_odr_table[t].tbl[i].odr; |
419 | *uodr = bmi160_odr_table[t].tbl[i].uodr; |
420 | |
421 | return 0; |
422 | } |
423 | |
424 | static irqreturn_t bmi160_trigger_handler(int irq, void *p) |
425 | { |
426 | struct iio_poll_func *pf = p; |
427 | struct iio_dev *indio_dev = pf->indio_dev; |
428 | struct bmi160_data *data = iio_priv(indio_dev); |
429 | int i, ret, j = 0, base = BMI160_REG_DATA_MAGN_XOUT_L; |
430 | __le16 sample; |
431 | |
432 | for_each_set_bit(i, indio_dev->active_scan_mask, |
433 | indio_dev->masklength) { |
434 | ret = regmap_bulk_read(map: data->regmap, reg: base + i * sizeof(sample), |
435 | val: &sample, val_count: sizeof(sample)); |
436 | if (ret) |
437 | goto done; |
438 | data->buf[j++] = sample; |
439 | } |
440 | |
441 | iio_push_to_buffers_with_timestamp(indio_dev, data: data->buf, timestamp: pf->timestamp); |
442 | done: |
443 | iio_trigger_notify_done(trig: indio_dev->trig); |
444 | return IRQ_HANDLED; |
445 | } |
446 | |
447 | static int bmi160_read_raw(struct iio_dev *indio_dev, |
448 | struct iio_chan_spec const *chan, |
449 | int *val, int *val2, long mask) |
450 | { |
451 | int ret; |
452 | struct bmi160_data *data = iio_priv(indio_dev); |
453 | |
454 | switch (mask) { |
455 | case IIO_CHAN_INFO_RAW: |
456 | ret = bmi160_get_data(data, chan_type: chan->type, axis: chan->channel2, val); |
457 | if (ret) |
458 | return ret; |
459 | return IIO_VAL_INT; |
460 | case IIO_CHAN_INFO_SCALE: |
461 | *val = 0; |
462 | ret = bmi160_get_scale(data, |
463 | t: bmi160_to_sensor(iio_type: chan->type), uscale: val2); |
464 | return ret ? ret : IIO_VAL_INT_PLUS_MICRO; |
465 | case IIO_CHAN_INFO_SAMP_FREQ: |
466 | ret = bmi160_get_odr(data, t: bmi160_to_sensor(iio_type: chan->type), |
467 | odr: val, uodr: val2); |
468 | return ret ? ret : IIO_VAL_INT_PLUS_MICRO; |
469 | default: |
470 | return -EINVAL; |
471 | } |
472 | |
473 | return 0; |
474 | } |
475 | |
476 | static int bmi160_write_raw(struct iio_dev *indio_dev, |
477 | struct iio_chan_spec const *chan, |
478 | int val, int val2, long mask) |
479 | { |
480 | struct bmi160_data *data = iio_priv(indio_dev); |
481 | |
482 | switch (mask) { |
483 | case IIO_CHAN_INFO_SCALE: |
484 | return bmi160_set_scale(data, |
485 | t: bmi160_to_sensor(iio_type: chan->type), uscale: val2); |
486 | case IIO_CHAN_INFO_SAMP_FREQ: |
487 | return bmi160_set_odr(data, t: bmi160_to_sensor(iio_type: chan->type), |
488 | odr: val, uodr: val2); |
489 | default: |
490 | return -EINVAL; |
491 | } |
492 | |
493 | return 0; |
494 | } |
495 | |
496 | static |
497 | IIO_CONST_ATTR(in_accel_sampling_frequency_available, |
498 | "0.78125 1.5625 3.125 6.25 12.5 25 50 100 200 400 800 1600" ); |
499 | static |
500 | IIO_CONST_ATTR(in_anglvel_sampling_frequency_available, |
501 | "25 50 100 200 400 800 1600 3200" ); |
502 | static |
503 | IIO_CONST_ATTR(in_accel_scale_available, |
504 | "0.000598 0.001197 0.002394 0.004788" ); |
505 | static |
506 | IIO_CONST_ATTR(in_anglvel_scale_available, |
507 | "0.001065 0.000532 0.000266 0.000133 0.000066" ); |
508 | |
509 | static struct attribute *bmi160_attrs[] = { |
510 | &iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr, |
511 | &iio_const_attr_in_anglvel_sampling_frequency_available.dev_attr.attr, |
512 | &iio_const_attr_in_accel_scale_available.dev_attr.attr, |
513 | &iio_const_attr_in_anglvel_scale_available.dev_attr.attr, |
514 | NULL, |
515 | }; |
516 | |
517 | static const struct attribute_group bmi160_attrs_group = { |
518 | .attrs = bmi160_attrs, |
519 | }; |
520 | |
521 | static const struct iio_info bmi160_info = { |
522 | .read_raw = bmi160_read_raw, |
523 | .write_raw = bmi160_write_raw, |
524 | .attrs = &bmi160_attrs_group, |
525 | }; |
526 | |
527 | static int bmi160_write_conf_reg(struct regmap *regmap, unsigned int reg, |
528 | unsigned int mask, unsigned int bits, |
529 | unsigned int write_usleep) |
530 | { |
531 | int ret; |
532 | unsigned int val; |
533 | |
534 | ret = regmap_read(map: regmap, reg, val: &val); |
535 | if (ret) |
536 | return ret; |
537 | |
538 | val = (val & ~mask) | bits; |
539 | |
540 | ret = regmap_write(map: regmap, reg, val); |
541 | if (ret) |
542 | return ret; |
543 | |
544 | /* |
545 | * We need to wait after writing before we can write again. See the |
546 | * datasheet, page 93. |
547 | */ |
548 | usleep_range(min: write_usleep, max: write_usleep + 1000); |
549 | |
550 | return 0; |
551 | } |
552 | |
553 | static int bmi160_config_pin(struct regmap *regmap, enum bmi160_int_pin pin, |
554 | bool open_drain, u8 irq_mask, |
555 | unsigned long write_usleep) |
556 | { |
557 | int ret; |
558 | struct device *dev = regmap_get_device(map: regmap); |
559 | u8 int_out_ctrl_shift; |
560 | u8 int_latch_mask; |
561 | u8 int_map_mask; |
562 | u8 int_out_ctrl_mask; |
563 | u8 int_out_ctrl_bits; |
564 | const char *pin_name; |
565 | |
566 | switch (pin) { |
567 | case BMI160_PIN_INT1: |
568 | int_out_ctrl_shift = BMI160_INT1_OUT_CTRL_SHIFT; |
569 | int_latch_mask = BMI160_INT1_LATCH_MASK; |
570 | int_map_mask = BMI160_INT1_MAP_DRDY_EN; |
571 | break; |
572 | case BMI160_PIN_INT2: |
573 | int_out_ctrl_shift = BMI160_INT2_OUT_CTRL_SHIFT; |
574 | int_latch_mask = BMI160_INT2_LATCH_MASK; |
575 | int_map_mask = BMI160_INT2_MAP_DRDY_EN; |
576 | break; |
577 | } |
578 | int_out_ctrl_mask = BMI160_INT_OUT_CTRL_MASK << int_out_ctrl_shift; |
579 | |
580 | /* |
581 | * Enable the requested pin with the right settings: |
582 | * - Push-pull/open-drain |
583 | * - Active low/high |
584 | * - Edge/level triggered |
585 | */ |
586 | int_out_ctrl_bits = BMI160_OUTPUT_EN; |
587 | if (open_drain) |
588 | /* Default is push-pull. */ |
589 | int_out_ctrl_bits |= BMI160_OPEN_DRAIN; |
590 | int_out_ctrl_bits |= irq_mask; |
591 | int_out_ctrl_bits <<= int_out_ctrl_shift; |
592 | |
593 | ret = bmi160_write_conf_reg(regmap, BMI160_REG_INT_OUT_CTRL, |
594 | mask: int_out_ctrl_mask, bits: int_out_ctrl_bits, |
595 | write_usleep); |
596 | if (ret) |
597 | return ret; |
598 | |
599 | /* Set the pin to input mode with no latching. */ |
600 | ret = bmi160_write_conf_reg(regmap, BMI160_REG_INT_LATCH, |
601 | mask: int_latch_mask, bits: int_latch_mask, |
602 | write_usleep); |
603 | if (ret) |
604 | return ret; |
605 | |
606 | /* Map interrupts to the requested pin. */ |
607 | ret = bmi160_write_conf_reg(regmap, BMI160_REG_INT_MAP, |
608 | mask: int_map_mask, bits: int_map_mask, |
609 | write_usleep); |
610 | if (ret) { |
611 | switch (pin) { |
612 | case BMI160_PIN_INT1: |
613 | pin_name = "INT1" ; |
614 | break; |
615 | case BMI160_PIN_INT2: |
616 | pin_name = "INT2" ; |
617 | break; |
618 | } |
619 | dev_err(dev, "Failed to configure %s IRQ pin" , pin_name); |
620 | } |
621 | |
622 | return ret; |
623 | } |
624 | |
625 | int bmi160_enable_irq(struct regmap *regmap, bool enable) |
626 | { |
627 | unsigned int enable_bit = 0; |
628 | |
629 | if (enable) |
630 | enable_bit = BMI160_DRDY_INT_EN; |
631 | |
632 | return bmi160_write_conf_reg(regmap, BMI160_REG_INT_EN, |
633 | BMI160_DRDY_INT_EN, bits: enable_bit, |
634 | BMI160_NORMAL_WRITE_USLEEP); |
635 | } |
636 | EXPORT_SYMBOL_NS(bmi160_enable_irq, IIO_BMI160); |
637 | |
638 | static int bmi160_get_irq(struct fwnode_handle *fwnode, enum bmi160_int_pin *pin) |
639 | { |
640 | int irq; |
641 | |
642 | /* Use INT1 if possible, otherwise fall back to INT2. */ |
643 | irq = fwnode_irq_get_byname(fwnode, name: "INT1" ); |
644 | if (irq > 0) { |
645 | *pin = BMI160_PIN_INT1; |
646 | return irq; |
647 | } |
648 | |
649 | irq = fwnode_irq_get_byname(fwnode, name: "INT2" ); |
650 | if (irq > 0) |
651 | *pin = BMI160_PIN_INT2; |
652 | |
653 | return irq; |
654 | } |
655 | |
656 | static int bmi160_config_device_irq(struct iio_dev *indio_dev, int irq_type, |
657 | enum bmi160_int_pin pin) |
658 | { |
659 | bool open_drain; |
660 | u8 irq_mask; |
661 | struct bmi160_data *data = iio_priv(indio_dev); |
662 | struct device *dev = regmap_get_device(map: data->regmap); |
663 | |
664 | /* Level-triggered, active-low is the default if we set all zeroes. */ |
665 | if (irq_type == IRQF_TRIGGER_RISING) |
666 | irq_mask = BMI160_ACTIVE_HIGH | BMI160_EDGE_TRIGGERED; |
667 | else if (irq_type == IRQF_TRIGGER_FALLING) |
668 | irq_mask = BMI160_EDGE_TRIGGERED; |
669 | else if (irq_type == IRQF_TRIGGER_HIGH) |
670 | irq_mask = BMI160_ACTIVE_HIGH; |
671 | else if (irq_type == IRQF_TRIGGER_LOW) |
672 | irq_mask = 0; |
673 | else { |
674 | dev_err(&indio_dev->dev, |
675 | "Invalid interrupt type 0x%x specified\n" , irq_type); |
676 | return -EINVAL; |
677 | } |
678 | |
679 | open_drain = device_property_read_bool(dev, propname: "drive-open-drain" ); |
680 | |
681 | return bmi160_config_pin(regmap: data->regmap, pin, open_drain, irq_mask, |
682 | BMI160_NORMAL_WRITE_USLEEP); |
683 | } |
684 | |
685 | static int bmi160_setup_irq(struct iio_dev *indio_dev, int irq, |
686 | enum bmi160_int_pin pin) |
687 | { |
688 | struct irq_data *desc; |
689 | u32 irq_type; |
690 | int ret; |
691 | |
692 | desc = irq_get_irq_data(irq); |
693 | if (!desc) { |
694 | dev_err(&indio_dev->dev, "Could not find IRQ %d\n" , irq); |
695 | return -EINVAL; |
696 | } |
697 | |
698 | irq_type = irqd_get_trigger_type(d: desc); |
699 | |
700 | ret = bmi160_config_device_irq(indio_dev, irq_type, pin); |
701 | if (ret) |
702 | return ret; |
703 | |
704 | return bmi160_probe_trigger(indio_dev, irq, irq_type); |
705 | } |
706 | |
707 | static int bmi160_chip_init(struct bmi160_data *data, bool use_spi) |
708 | { |
709 | int ret; |
710 | unsigned int val; |
711 | struct device *dev = regmap_get_device(map: data->regmap); |
712 | |
713 | ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), consumers: data->supplies); |
714 | if (ret) { |
715 | dev_err(dev, "Failed to enable regulators: %d\n" , ret); |
716 | return ret; |
717 | } |
718 | |
719 | ret = regmap_write(map: data->regmap, BMI160_REG_CMD, BMI160_CMD_SOFTRESET); |
720 | if (ret) |
721 | goto disable_regulator; |
722 | |
723 | usleep_range(BMI160_SOFTRESET_USLEEP, BMI160_SOFTRESET_USLEEP + 1); |
724 | |
725 | /* |
726 | * CS rising edge is needed before starting SPI, so do a dummy read |
727 | * See Section 3.2.1, page 86 of the datasheet |
728 | */ |
729 | if (use_spi) { |
730 | ret = regmap_read(map: data->regmap, BMI160_REG_DUMMY, val: &val); |
731 | if (ret) |
732 | goto disable_regulator; |
733 | } |
734 | |
735 | ret = regmap_read(map: data->regmap, BMI160_REG_CHIP_ID, val: &val); |
736 | if (ret) { |
737 | dev_err(dev, "Error reading chip id\n" ); |
738 | goto disable_regulator; |
739 | } |
740 | if (val != BMI160_CHIP_ID_VAL) { |
741 | dev_err(dev, "Wrong chip id, got %x expected %x\n" , |
742 | val, BMI160_CHIP_ID_VAL); |
743 | ret = -ENODEV; |
744 | goto disable_regulator; |
745 | } |
746 | |
747 | ret = bmi160_set_mode(data, t: BMI160_ACCEL, mode: true); |
748 | if (ret) |
749 | goto disable_regulator; |
750 | |
751 | ret = bmi160_set_mode(data, t: BMI160_GYRO, mode: true); |
752 | if (ret) |
753 | goto disable_accel; |
754 | |
755 | return 0; |
756 | |
757 | disable_accel: |
758 | bmi160_set_mode(data, t: BMI160_ACCEL, mode: false); |
759 | |
760 | disable_regulator: |
761 | regulator_bulk_disable(ARRAY_SIZE(data->supplies), consumers: data->supplies); |
762 | return ret; |
763 | } |
764 | |
765 | static int bmi160_data_rdy_trigger_set_state(struct iio_trigger *trig, |
766 | bool enable) |
767 | { |
768 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); |
769 | struct bmi160_data *data = iio_priv(indio_dev); |
770 | |
771 | return bmi160_enable_irq(data->regmap, enable); |
772 | } |
773 | |
774 | static const struct iio_trigger_ops bmi160_trigger_ops = { |
775 | .set_trigger_state = &bmi160_data_rdy_trigger_set_state, |
776 | }; |
777 | |
778 | int bmi160_probe_trigger(struct iio_dev *indio_dev, int irq, u32 irq_type) |
779 | { |
780 | struct bmi160_data *data = iio_priv(indio_dev); |
781 | int ret; |
782 | |
783 | data->trig = devm_iio_trigger_alloc(&indio_dev->dev, "%s-dev%d" , |
784 | indio_dev->name, |
785 | iio_device_id(indio_dev)); |
786 | |
787 | if (data->trig == NULL) |
788 | return -ENOMEM; |
789 | |
790 | ret = devm_request_irq(dev: &indio_dev->dev, irq, |
791 | handler: &iio_trigger_generic_data_rdy_poll, |
792 | irqflags: irq_type, devname: "bmi160" , dev_id: data->trig); |
793 | if (ret) |
794 | return ret; |
795 | |
796 | data->trig->dev.parent = regmap_get_device(map: data->regmap); |
797 | data->trig->ops = &bmi160_trigger_ops; |
798 | iio_trigger_set_drvdata(trig: data->trig, data: indio_dev); |
799 | |
800 | ret = devm_iio_trigger_register(dev: &indio_dev->dev, trig_info: data->trig); |
801 | if (ret) |
802 | return ret; |
803 | |
804 | indio_dev->trig = iio_trigger_get(trig: data->trig); |
805 | |
806 | return 0; |
807 | } |
808 | |
809 | static void bmi160_chip_uninit(void *data) |
810 | { |
811 | struct bmi160_data *bmi_data = data; |
812 | struct device *dev = regmap_get_device(map: bmi_data->regmap); |
813 | int ret; |
814 | |
815 | bmi160_set_mode(data: bmi_data, t: BMI160_GYRO, mode: false); |
816 | bmi160_set_mode(data: bmi_data, t: BMI160_ACCEL, mode: false); |
817 | |
818 | ret = regulator_bulk_disable(ARRAY_SIZE(bmi_data->supplies), |
819 | consumers: bmi_data->supplies); |
820 | if (ret) |
821 | dev_err(dev, "Failed to disable regulators: %d\n" , ret); |
822 | } |
823 | |
824 | int bmi160_core_probe(struct device *dev, struct regmap *regmap, |
825 | const char *name, bool use_spi) |
826 | { |
827 | struct iio_dev *indio_dev; |
828 | struct bmi160_data *data; |
829 | int irq; |
830 | enum bmi160_int_pin int_pin; |
831 | int ret; |
832 | |
833 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*data)); |
834 | if (!indio_dev) |
835 | return -ENOMEM; |
836 | |
837 | data = iio_priv(indio_dev); |
838 | dev_set_drvdata(dev, data: indio_dev); |
839 | data->regmap = regmap; |
840 | |
841 | data->supplies[0].supply = "vdd" ; |
842 | data->supplies[1].supply = "vddio" ; |
843 | ret = devm_regulator_bulk_get(dev, |
844 | ARRAY_SIZE(data->supplies), |
845 | consumers: data->supplies); |
846 | if (ret) { |
847 | dev_err(dev, "Failed to get regulators: %d\n" , ret); |
848 | return ret; |
849 | } |
850 | |
851 | ret = iio_read_mount_matrix(dev, matrix: &data->orientation); |
852 | if (ret) |
853 | return ret; |
854 | |
855 | ret = bmi160_chip_init(data, use_spi); |
856 | if (ret) |
857 | return ret; |
858 | |
859 | ret = devm_add_action_or_reset(dev, bmi160_chip_uninit, data); |
860 | if (ret) |
861 | return ret; |
862 | |
863 | indio_dev->channels = bmi160_channels; |
864 | indio_dev->num_channels = ARRAY_SIZE(bmi160_channels); |
865 | indio_dev->name = name; |
866 | indio_dev->modes = INDIO_DIRECT_MODE; |
867 | indio_dev->info = &bmi160_info; |
868 | |
869 | ret = devm_iio_triggered_buffer_setup(dev, indio_dev, |
870 | iio_pollfunc_store_time, |
871 | bmi160_trigger_handler, NULL); |
872 | if (ret) |
873 | return ret; |
874 | |
875 | irq = bmi160_get_irq(dev_fwnode(dev), pin: &int_pin); |
876 | if (irq > 0) { |
877 | ret = bmi160_setup_irq(indio_dev, irq, pin: int_pin); |
878 | if (ret) |
879 | dev_err(&indio_dev->dev, "Failed to setup IRQ %d\n" , |
880 | irq); |
881 | } else { |
882 | dev_info(&indio_dev->dev, "Not setting up IRQ trigger\n" ); |
883 | } |
884 | |
885 | return devm_iio_device_register(dev, indio_dev); |
886 | } |
887 | EXPORT_SYMBOL_NS_GPL(bmi160_core_probe, IIO_BMI160); |
888 | |
889 | MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>" ); |
890 | MODULE_DESCRIPTION("Bosch BMI160 driver" ); |
891 | MODULE_LICENSE("GPL v2" ); |
892 | |