1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * BMG160 Gyro Sensor driver |
4 | * Copyright (c) 2014, Intel Corporation. |
5 | */ |
6 | |
7 | #include <linux/module.h> |
8 | #include <linux/interrupt.h> |
9 | #include <linux/delay.h> |
10 | #include <linux/slab.h> |
11 | #include <linux/acpi.h> |
12 | #include <linux/pm.h> |
13 | #include <linux/pm_runtime.h> |
14 | #include <linux/iio/iio.h> |
15 | #include <linux/iio/sysfs.h> |
16 | #include <linux/iio/buffer.h> |
17 | #include <linux/iio/trigger.h> |
18 | #include <linux/iio/events.h> |
19 | #include <linux/iio/trigger_consumer.h> |
20 | #include <linux/iio/triggered_buffer.h> |
21 | #include <linux/regmap.h> |
22 | #include <linux/regulator/consumer.h> |
23 | #include "bmg160.h" |
24 | |
25 | #define BMG160_IRQ_NAME "bmg160_event" |
26 | |
27 | #define BMG160_REG_CHIP_ID 0x00 |
28 | #define BMG160_CHIP_ID_VAL 0x0F |
29 | |
30 | #define BMG160_REG_PMU_LPW 0x11 |
31 | #define BMG160_MODE_NORMAL 0x00 |
32 | #define BMG160_MODE_DEEP_SUSPEND 0x20 |
33 | #define BMG160_MODE_SUSPEND 0x80 |
34 | |
35 | #define BMG160_REG_RANGE 0x0F |
36 | |
37 | #define BMG160_RANGE_2000DPS 0 |
38 | #define BMG160_RANGE_1000DPS 1 |
39 | #define BMG160_RANGE_500DPS 2 |
40 | #define BMG160_RANGE_250DPS 3 |
41 | #define BMG160_RANGE_125DPS 4 |
42 | |
43 | #define BMG160_REG_PMU_BW 0x10 |
44 | #define BMG160_NO_FILTER 0 |
45 | #define BMG160_DEF_BW 100 |
46 | #define BMG160_REG_PMU_BW_RES BIT(7) |
47 | |
48 | #define BMG160_GYRO_REG_RESET 0x14 |
49 | #define BMG160_GYRO_RESET_VAL 0xb6 |
50 | |
51 | #define BMG160_REG_INT_MAP_0 0x17 |
52 | #define BMG160_INT_MAP_0_BIT_ANY BIT(1) |
53 | |
54 | #define BMG160_REG_INT_MAP_1 0x18 |
55 | #define BMG160_INT_MAP_1_BIT_NEW_DATA BIT(0) |
56 | |
57 | #define BMG160_REG_INT_RST_LATCH 0x21 |
58 | #define BMG160_INT_MODE_LATCH_RESET 0x80 |
59 | #define BMG160_INT_MODE_LATCH_INT 0x0F |
60 | #define BMG160_INT_MODE_NON_LATCH_INT 0x00 |
61 | |
62 | #define BMG160_REG_INT_EN_0 0x15 |
63 | #define BMG160_DATA_ENABLE_INT BIT(7) |
64 | |
65 | #define BMG160_REG_INT_EN_1 0x16 |
66 | #define BMG160_INT1_BIT_OD BIT(1) |
67 | |
68 | #define BMG160_REG_XOUT_L 0x02 |
69 | #define BMG160_AXIS_TO_REG(axis) (BMG160_REG_XOUT_L + (axis * 2)) |
70 | |
71 | #define BMG160_REG_SLOPE_THRES 0x1B |
72 | #define BMG160_SLOPE_THRES_MASK 0x0F |
73 | |
74 | #define BMG160_REG_MOTION_INTR 0x1C |
75 | #define BMG160_INT_MOTION_X BIT(0) |
76 | #define BMG160_INT_MOTION_Y BIT(1) |
77 | #define BMG160_INT_MOTION_Z BIT(2) |
78 | #define BMG160_ANY_DUR_MASK 0x30 |
79 | #define BMG160_ANY_DUR_SHIFT 4 |
80 | |
81 | #define BMG160_REG_INT_STATUS_2 0x0B |
82 | #define BMG160_ANY_MOTION_MASK 0x07 |
83 | #define BMG160_ANY_MOTION_BIT_X BIT(0) |
84 | #define BMG160_ANY_MOTION_BIT_Y BIT(1) |
85 | #define BMG160_ANY_MOTION_BIT_Z BIT(2) |
86 | |
87 | #define BMG160_REG_TEMP 0x08 |
88 | #define BMG160_TEMP_CENTER_VAL 23 |
89 | |
90 | #define BMG160_MAX_STARTUP_TIME_MS 80 |
91 | |
92 | #define BMG160_AUTO_SUSPEND_DELAY_MS 2000 |
93 | |
94 | struct bmg160_data { |
95 | struct regmap *regmap; |
96 | struct iio_trigger *dready_trig; |
97 | struct iio_trigger *motion_trig; |
98 | struct iio_mount_matrix orientation; |
99 | struct mutex mutex; |
100 | /* Ensure naturally aligned timestamp */ |
101 | struct { |
102 | s16 chans[3]; |
103 | s64 timestamp __aligned(8); |
104 | } scan; |
105 | u32 dps_range; |
106 | int ev_enable_state; |
107 | int slope_thres; |
108 | bool dready_trigger_on; |
109 | bool motion_trigger_on; |
110 | int irq; |
111 | }; |
112 | |
113 | enum bmg160_axis { |
114 | AXIS_X, |
115 | AXIS_Y, |
116 | AXIS_Z, |
117 | AXIS_MAX, |
118 | }; |
119 | |
120 | static const struct { |
121 | int odr; |
122 | int filter; |
123 | int bw_bits; |
124 | } bmg160_samp_freq_table[] = { {100, 32, 0x07}, |
125 | {200, 64, 0x06}, |
126 | {100, 12, 0x05}, |
127 | {200, 23, 0x04}, |
128 | {400, 47, 0x03}, |
129 | {1000, 116, 0x02}, |
130 | {2000, 230, 0x01} }; |
131 | |
132 | static const struct { |
133 | int scale; |
134 | int dps_range; |
135 | } bmg160_scale_table[] = { { 1065, BMG160_RANGE_2000DPS}, |
136 | { 532, BMG160_RANGE_1000DPS}, |
137 | { 266, BMG160_RANGE_500DPS}, |
138 | { 133, BMG160_RANGE_250DPS}, |
139 | { 66, BMG160_RANGE_125DPS} }; |
140 | |
141 | static int bmg160_set_mode(struct bmg160_data *data, u8 mode) |
142 | { |
143 | struct device *dev = regmap_get_device(map: data->regmap); |
144 | int ret; |
145 | |
146 | ret = regmap_write(map: data->regmap, BMG160_REG_PMU_LPW, val: mode); |
147 | if (ret < 0) { |
148 | dev_err(dev, "Error writing reg_pmu_lpw\n" ); |
149 | return ret; |
150 | } |
151 | |
152 | return 0; |
153 | } |
154 | |
155 | static int bmg160_convert_freq_to_bit(int val) |
156 | { |
157 | int i; |
158 | |
159 | for (i = 0; i < ARRAY_SIZE(bmg160_samp_freq_table); ++i) { |
160 | if (bmg160_samp_freq_table[i].odr == val) |
161 | return bmg160_samp_freq_table[i].bw_bits; |
162 | } |
163 | |
164 | return -EINVAL; |
165 | } |
166 | |
167 | static int bmg160_set_bw(struct bmg160_data *data, int val) |
168 | { |
169 | struct device *dev = regmap_get_device(map: data->regmap); |
170 | int ret; |
171 | int bw_bits; |
172 | |
173 | bw_bits = bmg160_convert_freq_to_bit(val); |
174 | if (bw_bits < 0) |
175 | return bw_bits; |
176 | |
177 | ret = regmap_write(map: data->regmap, BMG160_REG_PMU_BW, val: bw_bits); |
178 | if (ret < 0) { |
179 | dev_err(dev, "Error writing reg_pmu_bw\n" ); |
180 | return ret; |
181 | } |
182 | |
183 | return 0; |
184 | } |
185 | |
186 | static int bmg160_get_filter(struct bmg160_data *data, int *val) |
187 | { |
188 | struct device *dev = regmap_get_device(map: data->regmap); |
189 | int ret; |
190 | int i; |
191 | unsigned int bw_bits; |
192 | |
193 | ret = regmap_read(map: data->regmap, BMG160_REG_PMU_BW, val: &bw_bits); |
194 | if (ret < 0) { |
195 | dev_err(dev, "Error reading reg_pmu_bw\n" ); |
196 | return ret; |
197 | } |
198 | |
199 | /* Ignore the readonly reserved bit. */ |
200 | bw_bits &= ~BMG160_REG_PMU_BW_RES; |
201 | |
202 | for (i = 0; i < ARRAY_SIZE(bmg160_samp_freq_table); ++i) { |
203 | if (bmg160_samp_freq_table[i].bw_bits == bw_bits) |
204 | break; |
205 | } |
206 | |
207 | *val = bmg160_samp_freq_table[i].filter; |
208 | |
209 | return ret ? ret : IIO_VAL_INT; |
210 | } |
211 | |
212 | |
213 | static int bmg160_set_filter(struct bmg160_data *data, int val) |
214 | { |
215 | struct device *dev = regmap_get_device(map: data->regmap); |
216 | int ret; |
217 | int i; |
218 | |
219 | for (i = 0; i < ARRAY_SIZE(bmg160_samp_freq_table); ++i) { |
220 | if (bmg160_samp_freq_table[i].filter == val) |
221 | break; |
222 | } |
223 | |
224 | ret = regmap_write(map: data->regmap, BMG160_REG_PMU_BW, |
225 | val: bmg160_samp_freq_table[i].bw_bits); |
226 | if (ret < 0) { |
227 | dev_err(dev, "Error writing reg_pmu_bw\n" ); |
228 | return ret; |
229 | } |
230 | |
231 | return 0; |
232 | } |
233 | |
234 | static int bmg160_chip_init(struct bmg160_data *data) |
235 | { |
236 | struct device *dev = regmap_get_device(map: data->regmap); |
237 | int ret; |
238 | unsigned int val; |
239 | |
240 | /* |
241 | * Reset chip to get it in a known good state. A delay of 30ms after |
242 | * reset is required according to the datasheet. |
243 | */ |
244 | regmap_write(map: data->regmap, BMG160_GYRO_REG_RESET, |
245 | BMG160_GYRO_RESET_VAL); |
246 | usleep_range(min: 30000, max: 30700); |
247 | |
248 | ret = regmap_read(map: data->regmap, BMG160_REG_CHIP_ID, val: &val); |
249 | if (ret < 0) { |
250 | dev_err(dev, "Error reading reg_chip_id\n" ); |
251 | return ret; |
252 | } |
253 | |
254 | dev_dbg(dev, "Chip Id %x\n" , val); |
255 | if (val != BMG160_CHIP_ID_VAL) { |
256 | dev_err(dev, "invalid chip %x\n" , val); |
257 | return -ENODEV; |
258 | } |
259 | |
260 | ret = bmg160_set_mode(data, BMG160_MODE_NORMAL); |
261 | if (ret < 0) |
262 | return ret; |
263 | |
264 | /* Wait upto 500 ms to be ready after changing mode */ |
265 | usleep_range(min: 500, max: 1000); |
266 | |
267 | /* Set Bandwidth */ |
268 | ret = bmg160_set_bw(data, BMG160_DEF_BW); |
269 | if (ret < 0) |
270 | return ret; |
271 | |
272 | /* Set Default Range */ |
273 | ret = regmap_write(map: data->regmap, BMG160_REG_RANGE, BMG160_RANGE_500DPS); |
274 | if (ret < 0) { |
275 | dev_err(dev, "Error writing reg_range\n" ); |
276 | return ret; |
277 | } |
278 | data->dps_range = BMG160_RANGE_500DPS; |
279 | |
280 | ret = regmap_read(map: data->regmap, BMG160_REG_SLOPE_THRES, val: &val); |
281 | if (ret < 0) { |
282 | dev_err(dev, "Error reading reg_slope_thres\n" ); |
283 | return ret; |
284 | } |
285 | data->slope_thres = val; |
286 | |
287 | /* Set default interrupt mode */ |
288 | ret = regmap_update_bits(map: data->regmap, BMG160_REG_INT_EN_1, |
289 | BMG160_INT1_BIT_OD, val: 0); |
290 | if (ret < 0) { |
291 | dev_err(dev, "Error updating bits in reg_int_en_1\n" ); |
292 | return ret; |
293 | } |
294 | |
295 | ret = regmap_write(map: data->regmap, BMG160_REG_INT_RST_LATCH, |
296 | BMG160_INT_MODE_LATCH_INT | |
297 | BMG160_INT_MODE_LATCH_RESET); |
298 | if (ret < 0) { |
299 | dev_err(dev, |
300 | "Error writing reg_motion_intr\n" ); |
301 | return ret; |
302 | } |
303 | |
304 | return 0; |
305 | } |
306 | |
307 | static int bmg160_set_power_state(struct bmg160_data *data, bool on) |
308 | { |
309 | #ifdef CONFIG_PM |
310 | struct device *dev = regmap_get_device(map: data->regmap); |
311 | int ret; |
312 | |
313 | if (on) |
314 | ret = pm_runtime_get_sync(dev); |
315 | else { |
316 | pm_runtime_mark_last_busy(dev); |
317 | ret = pm_runtime_put_autosuspend(dev); |
318 | } |
319 | |
320 | if (ret < 0) { |
321 | dev_err(dev, "Failed: bmg160_set_power_state for %d\n" , on); |
322 | |
323 | if (on) |
324 | pm_runtime_put_noidle(dev); |
325 | |
326 | return ret; |
327 | } |
328 | #endif |
329 | |
330 | return 0; |
331 | } |
332 | |
333 | static int bmg160_setup_any_motion_interrupt(struct bmg160_data *data, |
334 | bool status) |
335 | { |
336 | struct device *dev = regmap_get_device(map: data->regmap); |
337 | int ret; |
338 | |
339 | /* Enable/Disable INT_MAP0 mapping */ |
340 | ret = regmap_update_bits(map: data->regmap, BMG160_REG_INT_MAP_0, |
341 | BMG160_INT_MAP_0_BIT_ANY, |
342 | val: (status ? BMG160_INT_MAP_0_BIT_ANY : 0)); |
343 | if (ret < 0) { |
344 | dev_err(dev, "Error updating bits reg_int_map0\n" ); |
345 | return ret; |
346 | } |
347 | |
348 | /* Enable/Disable slope interrupts */ |
349 | if (status) { |
350 | /* Update slope thres */ |
351 | ret = regmap_write(map: data->regmap, BMG160_REG_SLOPE_THRES, |
352 | val: data->slope_thres); |
353 | if (ret < 0) { |
354 | dev_err(dev, "Error writing reg_slope_thres\n" ); |
355 | return ret; |
356 | } |
357 | |
358 | ret = regmap_write(map: data->regmap, BMG160_REG_MOTION_INTR, |
359 | BMG160_INT_MOTION_X | BMG160_INT_MOTION_Y | |
360 | BMG160_INT_MOTION_Z); |
361 | if (ret < 0) { |
362 | dev_err(dev, "Error writing reg_motion_intr\n" ); |
363 | return ret; |
364 | } |
365 | |
366 | /* |
367 | * New data interrupt is always non-latched, |
368 | * which will have higher priority, so no need |
369 | * to set latched mode, we will be flooded anyway with INTR |
370 | */ |
371 | if (!data->dready_trigger_on) { |
372 | ret = regmap_write(map: data->regmap, |
373 | BMG160_REG_INT_RST_LATCH, |
374 | BMG160_INT_MODE_LATCH_INT | |
375 | BMG160_INT_MODE_LATCH_RESET); |
376 | if (ret < 0) { |
377 | dev_err(dev, "Error writing reg_rst_latch\n" ); |
378 | return ret; |
379 | } |
380 | } |
381 | |
382 | ret = regmap_write(map: data->regmap, BMG160_REG_INT_EN_0, |
383 | BMG160_DATA_ENABLE_INT); |
384 | |
385 | } else { |
386 | ret = regmap_write(map: data->regmap, BMG160_REG_INT_EN_0, val: 0); |
387 | } |
388 | |
389 | if (ret < 0) { |
390 | dev_err(dev, "Error writing reg_int_en0\n" ); |
391 | return ret; |
392 | } |
393 | |
394 | return 0; |
395 | } |
396 | |
397 | static int bmg160_setup_new_data_interrupt(struct bmg160_data *data, |
398 | bool status) |
399 | { |
400 | struct device *dev = regmap_get_device(map: data->regmap); |
401 | int ret; |
402 | |
403 | /* Enable/Disable INT_MAP1 mapping */ |
404 | ret = regmap_update_bits(map: data->regmap, BMG160_REG_INT_MAP_1, |
405 | BMG160_INT_MAP_1_BIT_NEW_DATA, |
406 | val: (status ? BMG160_INT_MAP_1_BIT_NEW_DATA : 0)); |
407 | if (ret < 0) { |
408 | dev_err(dev, "Error updating bits in reg_int_map1\n" ); |
409 | return ret; |
410 | } |
411 | |
412 | if (status) { |
413 | ret = regmap_write(map: data->regmap, BMG160_REG_INT_RST_LATCH, |
414 | BMG160_INT_MODE_NON_LATCH_INT | |
415 | BMG160_INT_MODE_LATCH_RESET); |
416 | if (ret < 0) { |
417 | dev_err(dev, "Error writing reg_rst_latch\n" ); |
418 | return ret; |
419 | } |
420 | |
421 | ret = regmap_write(map: data->regmap, BMG160_REG_INT_EN_0, |
422 | BMG160_DATA_ENABLE_INT); |
423 | |
424 | } else { |
425 | /* Restore interrupt mode */ |
426 | ret = regmap_write(map: data->regmap, BMG160_REG_INT_RST_LATCH, |
427 | BMG160_INT_MODE_LATCH_INT | |
428 | BMG160_INT_MODE_LATCH_RESET); |
429 | if (ret < 0) { |
430 | dev_err(dev, "Error writing reg_rst_latch\n" ); |
431 | return ret; |
432 | } |
433 | |
434 | ret = regmap_write(map: data->regmap, BMG160_REG_INT_EN_0, val: 0); |
435 | } |
436 | |
437 | if (ret < 0) { |
438 | dev_err(dev, "Error writing reg_int_en0\n" ); |
439 | return ret; |
440 | } |
441 | |
442 | return 0; |
443 | } |
444 | |
445 | static int bmg160_get_bw(struct bmg160_data *data, int *val) |
446 | { |
447 | struct device *dev = regmap_get_device(map: data->regmap); |
448 | int i; |
449 | unsigned int bw_bits; |
450 | int ret; |
451 | |
452 | ret = regmap_read(map: data->regmap, BMG160_REG_PMU_BW, val: &bw_bits); |
453 | if (ret < 0) { |
454 | dev_err(dev, "Error reading reg_pmu_bw\n" ); |
455 | return ret; |
456 | } |
457 | |
458 | /* Ignore the readonly reserved bit. */ |
459 | bw_bits &= ~BMG160_REG_PMU_BW_RES; |
460 | |
461 | for (i = 0; i < ARRAY_SIZE(bmg160_samp_freq_table); ++i) { |
462 | if (bmg160_samp_freq_table[i].bw_bits == bw_bits) { |
463 | *val = bmg160_samp_freq_table[i].odr; |
464 | return IIO_VAL_INT; |
465 | } |
466 | } |
467 | |
468 | return -EINVAL; |
469 | } |
470 | |
471 | static int bmg160_set_scale(struct bmg160_data *data, int val) |
472 | { |
473 | struct device *dev = regmap_get_device(map: data->regmap); |
474 | int ret, i; |
475 | |
476 | for (i = 0; i < ARRAY_SIZE(bmg160_scale_table); ++i) { |
477 | if (bmg160_scale_table[i].scale == val) { |
478 | ret = regmap_write(map: data->regmap, BMG160_REG_RANGE, |
479 | val: bmg160_scale_table[i].dps_range); |
480 | if (ret < 0) { |
481 | dev_err(dev, "Error writing reg_range\n" ); |
482 | return ret; |
483 | } |
484 | data->dps_range = bmg160_scale_table[i].dps_range; |
485 | return 0; |
486 | } |
487 | } |
488 | |
489 | return -EINVAL; |
490 | } |
491 | |
492 | static int bmg160_get_temp(struct bmg160_data *data, int *val) |
493 | { |
494 | struct device *dev = regmap_get_device(map: data->regmap); |
495 | int ret; |
496 | unsigned int raw_val; |
497 | |
498 | mutex_lock(&data->mutex); |
499 | ret = bmg160_set_power_state(data, on: true); |
500 | if (ret < 0) { |
501 | mutex_unlock(lock: &data->mutex); |
502 | return ret; |
503 | } |
504 | |
505 | ret = regmap_read(map: data->regmap, BMG160_REG_TEMP, val: &raw_val); |
506 | if (ret < 0) { |
507 | dev_err(dev, "Error reading reg_temp\n" ); |
508 | bmg160_set_power_state(data, on: false); |
509 | mutex_unlock(lock: &data->mutex); |
510 | return ret; |
511 | } |
512 | |
513 | *val = sign_extend32(value: raw_val, index: 7); |
514 | ret = bmg160_set_power_state(data, on: false); |
515 | mutex_unlock(lock: &data->mutex); |
516 | if (ret < 0) |
517 | return ret; |
518 | |
519 | return IIO_VAL_INT; |
520 | } |
521 | |
522 | static int bmg160_get_axis(struct bmg160_data *data, int axis, int *val) |
523 | { |
524 | struct device *dev = regmap_get_device(map: data->regmap); |
525 | int ret; |
526 | __le16 raw_val; |
527 | |
528 | mutex_lock(&data->mutex); |
529 | ret = bmg160_set_power_state(data, on: true); |
530 | if (ret < 0) { |
531 | mutex_unlock(lock: &data->mutex); |
532 | return ret; |
533 | } |
534 | |
535 | ret = regmap_bulk_read(map: data->regmap, BMG160_AXIS_TO_REG(axis), val: &raw_val, |
536 | val_count: sizeof(raw_val)); |
537 | if (ret < 0) { |
538 | dev_err(dev, "Error reading axis %d\n" , axis); |
539 | bmg160_set_power_state(data, on: false); |
540 | mutex_unlock(lock: &data->mutex); |
541 | return ret; |
542 | } |
543 | |
544 | *val = sign_extend32(le16_to_cpu(raw_val), index: 15); |
545 | ret = bmg160_set_power_state(data, on: false); |
546 | mutex_unlock(lock: &data->mutex); |
547 | if (ret < 0) |
548 | return ret; |
549 | |
550 | return IIO_VAL_INT; |
551 | } |
552 | |
553 | static int bmg160_read_raw(struct iio_dev *indio_dev, |
554 | struct iio_chan_spec const *chan, |
555 | int *val, int *val2, long mask) |
556 | { |
557 | struct bmg160_data *data = iio_priv(indio_dev); |
558 | int ret; |
559 | |
560 | switch (mask) { |
561 | case IIO_CHAN_INFO_RAW: |
562 | switch (chan->type) { |
563 | case IIO_TEMP: |
564 | return bmg160_get_temp(data, val); |
565 | case IIO_ANGL_VEL: |
566 | if (iio_buffer_enabled(indio_dev)) |
567 | return -EBUSY; |
568 | else |
569 | return bmg160_get_axis(data, axis: chan->scan_index, |
570 | val); |
571 | default: |
572 | return -EINVAL; |
573 | } |
574 | case IIO_CHAN_INFO_OFFSET: |
575 | if (chan->type == IIO_TEMP) { |
576 | *val = BMG160_TEMP_CENTER_VAL; |
577 | return IIO_VAL_INT; |
578 | } else |
579 | return -EINVAL; |
580 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: |
581 | return bmg160_get_filter(data, val); |
582 | case IIO_CHAN_INFO_SCALE: |
583 | switch (chan->type) { |
584 | case IIO_TEMP: |
585 | *val = 500; |
586 | return IIO_VAL_INT; |
587 | case IIO_ANGL_VEL: |
588 | { |
589 | int i; |
590 | |
591 | for (i = 0; i < ARRAY_SIZE(bmg160_scale_table); ++i) { |
592 | if (bmg160_scale_table[i].dps_range == |
593 | data->dps_range) { |
594 | *val = 0; |
595 | *val2 = bmg160_scale_table[i].scale; |
596 | return IIO_VAL_INT_PLUS_MICRO; |
597 | } |
598 | } |
599 | return -EINVAL; |
600 | } |
601 | default: |
602 | return -EINVAL; |
603 | } |
604 | case IIO_CHAN_INFO_SAMP_FREQ: |
605 | *val2 = 0; |
606 | mutex_lock(&data->mutex); |
607 | ret = bmg160_get_bw(data, val); |
608 | mutex_unlock(lock: &data->mutex); |
609 | return ret; |
610 | default: |
611 | return -EINVAL; |
612 | } |
613 | } |
614 | |
615 | static int bmg160_write_raw(struct iio_dev *indio_dev, |
616 | struct iio_chan_spec const *chan, |
617 | int val, int val2, long mask) |
618 | { |
619 | struct bmg160_data *data = iio_priv(indio_dev); |
620 | int ret; |
621 | |
622 | switch (mask) { |
623 | case IIO_CHAN_INFO_SAMP_FREQ: |
624 | mutex_lock(&data->mutex); |
625 | /* |
626 | * Section 4.2 of spec |
627 | * In suspend mode, the only supported operations are reading |
628 | * registers as well as writing to the (0x14) softreset |
629 | * register. Since we will be in suspend mode by default, change |
630 | * mode to power on for other writes. |
631 | */ |
632 | ret = bmg160_set_power_state(data, on: true); |
633 | if (ret < 0) { |
634 | mutex_unlock(lock: &data->mutex); |
635 | return ret; |
636 | } |
637 | ret = bmg160_set_bw(data, val); |
638 | if (ret < 0) { |
639 | bmg160_set_power_state(data, on: false); |
640 | mutex_unlock(lock: &data->mutex); |
641 | return ret; |
642 | } |
643 | ret = bmg160_set_power_state(data, on: false); |
644 | mutex_unlock(lock: &data->mutex); |
645 | return ret; |
646 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: |
647 | if (val2) |
648 | return -EINVAL; |
649 | |
650 | mutex_lock(&data->mutex); |
651 | ret = bmg160_set_power_state(data, on: true); |
652 | if (ret < 0) { |
653 | bmg160_set_power_state(data, on: false); |
654 | mutex_unlock(lock: &data->mutex); |
655 | return ret; |
656 | } |
657 | ret = bmg160_set_filter(data, val); |
658 | if (ret < 0) { |
659 | bmg160_set_power_state(data, on: false); |
660 | mutex_unlock(lock: &data->mutex); |
661 | return ret; |
662 | } |
663 | ret = bmg160_set_power_state(data, on: false); |
664 | mutex_unlock(lock: &data->mutex); |
665 | return ret; |
666 | case IIO_CHAN_INFO_SCALE: |
667 | if (val) |
668 | return -EINVAL; |
669 | |
670 | mutex_lock(&data->mutex); |
671 | /* Refer to comments above for the suspend mode ops */ |
672 | ret = bmg160_set_power_state(data, on: true); |
673 | if (ret < 0) { |
674 | mutex_unlock(lock: &data->mutex); |
675 | return ret; |
676 | } |
677 | ret = bmg160_set_scale(data, val: val2); |
678 | if (ret < 0) { |
679 | bmg160_set_power_state(data, on: false); |
680 | mutex_unlock(lock: &data->mutex); |
681 | return ret; |
682 | } |
683 | ret = bmg160_set_power_state(data, on: false); |
684 | mutex_unlock(lock: &data->mutex); |
685 | return ret; |
686 | default: |
687 | return -EINVAL; |
688 | } |
689 | |
690 | return -EINVAL; |
691 | } |
692 | |
693 | static int bmg160_read_event(struct iio_dev *indio_dev, |
694 | const struct iio_chan_spec *chan, |
695 | enum iio_event_type type, |
696 | enum iio_event_direction dir, |
697 | enum iio_event_info info, |
698 | int *val, int *val2) |
699 | { |
700 | struct bmg160_data *data = iio_priv(indio_dev); |
701 | |
702 | *val2 = 0; |
703 | switch (info) { |
704 | case IIO_EV_INFO_VALUE: |
705 | *val = data->slope_thres & BMG160_SLOPE_THRES_MASK; |
706 | break; |
707 | default: |
708 | return -EINVAL; |
709 | } |
710 | |
711 | return IIO_VAL_INT; |
712 | } |
713 | |
714 | static int bmg160_write_event(struct iio_dev *indio_dev, |
715 | const struct iio_chan_spec *chan, |
716 | enum iio_event_type type, |
717 | enum iio_event_direction dir, |
718 | enum iio_event_info info, |
719 | int val, int val2) |
720 | { |
721 | struct bmg160_data *data = iio_priv(indio_dev); |
722 | |
723 | switch (info) { |
724 | case IIO_EV_INFO_VALUE: |
725 | if (data->ev_enable_state) |
726 | return -EBUSY; |
727 | data->slope_thres &= ~BMG160_SLOPE_THRES_MASK; |
728 | data->slope_thres |= (val & BMG160_SLOPE_THRES_MASK); |
729 | break; |
730 | default: |
731 | return -EINVAL; |
732 | } |
733 | |
734 | return 0; |
735 | } |
736 | |
737 | static int bmg160_read_event_config(struct iio_dev *indio_dev, |
738 | const struct iio_chan_spec *chan, |
739 | enum iio_event_type type, |
740 | enum iio_event_direction dir) |
741 | { |
742 | |
743 | struct bmg160_data *data = iio_priv(indio_dev); |
744 | |
745 | return data->ev_enable_state; |
746 | } |
747 | |
748 | static int bmg160_write_event_config(struct iio_dev *indio_dev, |
749 | const struct iio_chan_spec *chan, |
750 | enum iio_event_type type, |
751 | enum iio_event_direction dir, |
752 | int state) |
753 | { |
754 | struct bmg160_data *data = iio_priv(indio_dev); |
755 | int ret; |
756 | |
757 | if (state && data->ev_enable_state) |
758 | return 0; |
759 | |
760 | mutex_lock(&data->mutex); |
761 | |
762 | if (!state && data->motion_trigger_on) { |
763 | data->ev_enable_state = 0; |
764 | mutex_unlock(lock: &data->mutex); |
765 | return 0; |
766 | } |
767 | /* |
768 | * We will expect the enable and disable to do operation |
769 | * in reverse order. This will happen here anyway as our |
770 | * resume operation uses sync mode runtime pm calls, the |
771 | * suspend operation will be delayed by autosuspend delay |
772 | * So the disable operation will still happen in reverse of |
773 | * enable operation. When runtime pm is disabled the mode |
774 | * is always on so sequence doesn't matter |
775 | */ |
776 | ret = bmg160_set_power_state(data, on: state); |
777 | if (ret < 0) { |
778 | mutex_unlock(lock: &data->mutex); |
779 | return ret; |
780 | } |
781 | |
782 | ret = bmg160_setup_any_motion_interrupt(data, status: state); |
783 | if (ret < 0) { |
784 | bmg160_set_power_state(data, on: false); |
785 | mutex_unlock(lock: &data->mutex); |
786 | return ret; |
787 | } |
788 | |
789 | data->ev_enable_state = state; |
790 | mutex_unlock(lock: &data->mutex); |
791 | |
792 | return 0; |
793 | } |
794 | |
795 | static const struct iio_mount_matrix * |
796 | bmg160_get_mount_matrix(const struct iio_dev *indio_dev, |
797 | const struct iio_chan_spec *chan) |
798 | { |
799 | struct bmg160_data *data = iio_priv(indio_dev); |
800 | |
801 | return &data->orientation; |
802 | } |
803 | |
804 | static const struct iio_chan_spec_ext_info bmg160_ext_info[] = { |
805 | IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bmg160_get_mount_matrix), |
806 | { } |
807 | }; |
808 | |
809 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100 200 400 1000 2000" ); |
810 | |
811 | static IIO_CONST_ATTR(in_anglvel_scale_available, |
812 | "0.001065 0.000532 0.000266 0.000133 0.000066" ); |
813 | |
814 | static struct attribute *bmg160_attributes[] = { |
815 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, |
816 | &iio_const_attr_in_anglvel_scale_available.dev_attr.attr, |
817 | NULL, |
818 | }; |
819 | |
820 | static const struct attribute_group bmg160_attrs_group = { |
821 | .attrs = bmg160_attributes, |
822 | }; |
823 | |
824 | static const struct iio_event_spec bmg160_event = { |
825 | .type = IIO_EV_TYPE_ROC, |
826 | .dir = IIO_EV_DIR_EITHER, |
827 | .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | |
828 | BIT(IIO_EV_INFO_ENABLE) |
829 | }; |
830 | |
831 | #define BMG160_CHANNEL(_axis) { \ |
832 | .type = IIO_ANGL_VEL, \ |
833 | .modified = 1, \ |
834 | .channel2 = IIO_MOD_##_axis, \ |
835 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
836 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ |
837 | BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ |
838 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ |
839 | .scan_index = AXIS_##_axis, \ |
840 | .scan_type = { \ |
841 | .sign = 's', \ |
842 | .realbits = 16, \ |
843 | .storagebits = 16, \ |
844 | .endianness = IIO_LE, \ |
845 | }, \ |
846 | .ext_info = bmg160_ext_info, \ |
847 | .event_spec = &bmg160_event, \ |
848 | .num_event_specs = 1 \ |
849 | } |
850 | |
851 | static const struct iio_chan_spec bmg160_channels[] = { |
852 | { |
853 | .type = IIO_TEMP, |
854 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | |
855 | BIT(IIO_CHAN_INFO_SCALE) | |
856 | BIT(IIO_CHAN_INFO_OFFSET), |
857 | .scan_index = -1, |
858 | }, |
859 | BMG160_CHANNEL(X), |
860 | BMG160_CHANNEL(Y), |
861 | BMG160_CHANNEL(Z), |
862 | IIO_CHAN_SOFT_TIMESTAMP(3), |
863 | }; |
864 | |
865 | static const struct iio_info bmg160_info = { |
866 | .attrs = &bmg160_attrs_group, |
867 | .read_raw = bmg160_read_raw, |
868 | .write_raw = bmg160_write_raw, |
869 | .read_event_value = bmg160_read_event, |
870 | .write_event_value = bmg160_write_event, |
871 | .write_event_config = bmg160_write_event_config, |
872 | .read_event_config = bmg160_read_event_config, |
873 | }; |
874 | |
875 | static const unsigned long bmg160_accel_scan_masks[] = { |
876 | BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), |
877 | 0}; |
878 | |
879 | static irqreturn_t bmg160_trigger_handler(int irq, void *p) |
880 | { |
881 | struct iio_poll_func *pf = p; |
882 | struct iio_dev *indio_dev = pf->indio_dev; |
883 | struct bmg160_data *data = iio_priv(indio_dev); |
884 | int ret; |
885 | |
886 | mutex_lock(&data->mutex); |
887 | ret = regmap_bulk_read(map: data->regmap, BMG160_REG_XOUT_L, |
888 | val: data->scan.chans, val_count: AXIS_MAX * 2); |
889 | mutex_unlock(lock: &data->mutex); |
890 | if (ret < 0) |
891 | goto err; |
892 | |
893 | iio_push_to_buffers_with_timestamp(indio_dev, data: &data->scan, |
894 | timestamp: pf->timestamp); |
895 | err: |
896 | iio_trigger_notify_done(trig: indio_dev->trig); |
897 | |
898 | return IRQ_HANDLED; |
899 | } |
900 | |
901 | static void bmg160_trig_reen(struct iio_trigger *trig) |
902 | { |
903 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); |
904 | struct bmg160_data *data = iio_priv(indio_dev); |
905 | struct device *dev = regmap_get_device(map: data->regmap); |
906 | int ret; |
907 | |
908 | /* new data interrupts don't need ack */ |
909 | if (data->dready_trigger_on) |
910 | return; |
911 | |
912 | /* Set latched mode interrupt and clear any latched interrupt */ |
913 | ret = regmap_write(map: data->regmap, BMG160_REG_INT_RST_LATCH, |
914 | BMG160_INT_MODE_LATCH_INT | |
915 | BMG160_INT_MODE_LATCH_RESET); |
916 | if (ret < 0) |
917 | dev_err(dev, "Error writing reg_rst_latch\n" ); |
918 | } |
919 | |
920 | static int bmg160_data_rdy_trigger_set_state(struct iio_trigger *trig, |
921 | bool state) |
922 | { |
923 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); |
924 | struct bmg160_data *data = iio_priv(indio_dev); |
925 | int ret; |
926 | |
927 | mutex_lock(&data->mutex); |
928 | |
929 | if (!state && data->ev_enable_state && data->motion_trigger_on) { |
930 | data->motion_trigger_on = false; |
931 | mutex_unlock(lock: &data->mutex); |
932 | return 0; |
933 | } |
934 | |
935 | /* |
936 | * Refer to comment in bmg160_write_event_config for |
937 | * enable/disable operation order |
938 | */ |
939 | ret = bmg160_set_power_state(data, on: state); |
940 | if (ret < 0) { |
941 | mutex_unlock(lock: &data->mutex); |
942 | return ret; |
943 | } |
944 | if (data->motion_trig == trig) |
945 | ret = bmg160_setup_any_motion_interrupt(data, status: state); |
946 | else |
947 | ret = bmg160_setup_new_data_interrupt(data, status: state); |
948 | if (ret < 0) { |
949 | bmg160_set_power_state(data, on: false); |
950 | mutex_unlock(lock: &data->mutex); |
951 | return ret; |
952 | } |
953 | if (data->motion_trig == trig) |
954 | data->motion_trigger_on = state; |
955 | else |
956 | data->dready_trigger_on = state; |
957 | |
958 | mutex_unlock(lock: &data->mutex); |
959 | |
960 | return 0; |
961 | } |
962 | |
963 | static const struct iio_trigger_ops bmg160_trigger_ops = { |
964 | .set_trigger_state = bmg160_data_rdy_trigger_set_state, |
965 | .reenable = bmg160_trig_reen, |
966 | }; |
967 | |
968 | static irqreturn_t bmg160_event_handler(int irq, void *private) |
969 | { |
970 | struct iio_dev *indio_dev = private; |
971 | struct bmg160_data *data = iio_priv(indio_dev); |
972 | struct device *dev = regmap_get_device(map: data->regmap); |
973 | int ret; |
974 | int dir; |
975 | unsigned int val; |
976 | |
977 | ret = regmap_read(map: data->regmap, BMG160_REG_INT_STATUS_2, val: &val); |
978 | if (ret < 0) { |
979 | dev_err(dev, "Error reading reg_int_status2\n" ); |
980 | goto ack_intr_status; |
981 | } |
982 | |
983 | if (val & 0x08) |
984 | dir = IIO_EV_DIR_RISING; |
985 | else |
986 | dir = IIO_EV_DIR_FALLING; |
987 | |
988 | if (val & BMG160_ANY_MOTION_BIT_X) |
989 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ANGL_VEL, |
990 | 0, |
991 | IIO_MOD_X, |
992 | IIO_EV_TYPE_ROC, |
993 | dir), |
994 | timestamp: iio_get_time_ns(indio_dev)); |
995 | if (val & BMG160_ANY_MOTION_BIT_Y) |
996 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ANGL_VEL, |
997 | 0, |
998 | IIO_MOD_Y, |
999 | IIO_EV_TYPE_ROC, |
1000 | dir), |
1001 | timestamp: iio_get_time_ns(indio_dev)); |
1002 | if (val & BMG160_ANY_MOTION_BIT_Z) |
1003 | iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ANGL_VEL, |
1004 | 0, |
1005 | IIO_MOD_Z, |
1006 | IIO_EV_TYPE_ROC, |
1007 | dir), |
1008 | timestamp: iio_get_time_ns(indio_dev)); |
1009 | |
1010 | ack_intr_status: |
1011 | if (!data->dready_trigger_on) { |
1012 | ret = regmap_write(map: data->regmap, BMG160_REG_INT_RST_LATCH, |
1013 | BMG160_INT_MODE_LATCH_INT | |
1014 | BMG160_INT_MODE_LATCH_RESET); |
1015 | if (ret < 0) |
1016 | dev_err(dev, "Error writing reg_rst_latch\n" ); |
1017 | } |
1018 | |
1019 | return IRQ_HANDLED; |
1020 | } |
1021 | |
1022 | static irqreturn_t bmg160_data_rdy_trig_poll(int irq, void *private) |
1023 | { |
1024 | struct iio_dev *indio_dev = private; |
1025 | struct bmg160_data *data = iio_priv(indio_dev); |
1026 | |
1027 | if (data->dready_trigger_on) |
1028 | iio_trigger_poll(trig: data->dready_trig); |
1029 | else if (data->motion_trigger_on) |
1030 | iio_trigger_poll(trig: data->motion_trig); |
1031 | |
1032 | if (data->ev_enable_state) |
1033 | return IRQ_WAKE_THREAD; |
1034 | else |
1035 | return IRQ_HANDLED; |
1036 | |
1037 | } |
1038 | |
1039 | static int bmg160_buffer_preenable(struct iio_dev *indio_dev) |
1040 | { |
1041 | struct bmg160_data *data = iio_priv(indio_dev); |
1042 | |
1043 | return bmg160_set_power_state(data, on: true); |
1044 | } |
1045 | |
1046 | static int bmg160_buffer_postdisable(struct iio_dev *indio_dev) |
1047 | { |
1048 | struct bmg160_data *data = iio_priv(indio_dev); |
1049 | |
1050 | return bmg160_set_power_state(data, on: false); |
1051 | } |
1052 | |
1053 | static const struct iio_buffer_setup_ops bmg160_buffer_setup_ops = { |
1054 | .preenable = bmg160_buffer_preenable, |
1055 | .postdisable = bmg160_buffer_postdisable, |
1056 | }; |
1057 | |
1058 | static const char *bmg160_match_acpi_device(struct device *dev) |
1059 | { |
1060 | const struct acpi_device_id *id; |
1061 | |
1062 | id = acpi_match_device(ids: dev->driver->acpi_match_table, dev); |
1063 | if (!id) |
1064 | return NULL; |
1065 | |
1066 | return dev_name(dev); |
1067 | } |
1068 | |
1069 | int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq, |
1070 | const char *name) |
1071 | { |
1072 | static const char * const regulators[] = { "vdd" , "vddio" }; |
1073 | struct bmg160_data *data; |
1074 | struct iio_dev *indio_dev; |
1075 | int ret; |
1076 | |
1077 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*data)); |
1078 | if (!indio_dev) |
1079 | return -ENOMEM; |
1080 | |
1081 | data = iio_priv(indio_dev); |
1082 | dev_set_drvdata(dev, data: indio_dev); |
1083 | data->irq = irq; |
1084 | data->regmap = regmap; |
1085 | |
1086 | ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators), |
1087 | id: regulators); |
1088 | if (ret) |
1089 | return dev_err_probe(dev, err: ret, fmt: "Failed to get regulators\n" ); |
1090 | |
1091 | ret = iio_read_mount_matrix(dev, matrix: &data->orientation); |
1092 | if (ret) |
1093 | return ret; |
1094 | |
1095 | ret = bmg160_chip_init(data); |
1096 | if (ret < 0) |
1097 | return ret; |
1098 | |
1099 | mutex_init(&data->mutex); |
1100 | |
1101 | if (ACPI_HANDLE(dev)) |
1102 | name = bmg160_match_acpi_device(dev); |
1103 | |
1104 | indio_dev->channels = bmg160_channels; |
1105 | indio_dev->num_channels = ARRAY_SIZE(bmg160_channels); |
1106 | indio_dev->name = name; |
1107 | indio_dev->available_scan_masks = bmg160_accel_scan_masks; |
1108 | indio_dev->modes = INDIO_DIRECT_MODE; |
1109 | indio_dev->info = &bmg160_info; |
1110 | |
1111 | if (data->irq > 0) { |
1112 | ret = devm_request_threaded_irq(dev, |
1113 | irq: data->irq, |
1114 | handler: bmg160_data_rdy_trig_poll, |
1115 | thread_fn: bmg160_event_handler, |
1116 | IRQF_TRIGGER_RISING, |
1117 | BMG160_IRQ_NAME, |
1118 | dev_id: indio_dev); |
1119 | if (ret) |
1120 | return ret; |
1121 | |
1122 | data->dready_trig = devm_iio_trigger_alloc(dev, |
1123 | "%s-dev%d" , |
1124 | indio_dev->name, |
1125 | iio_device_id(indio_dev)); |
1126 | if (!data->dready_trig) |
1127 | return -ENOMEM; |
1128 | |
1129 | data->motion_trig = devm_iio_trigger_alloc(dev, |
1130 | "%s-any-motion-dev%d" , |
1131 | indio_dev->name, |
1132 | iio_device_id(indio_dev)); |
1133 | if (!data->motion_trig) |
1134 | return -ENOMEM; |
1135 | |
1136 | data->dready_trig->ops = &bmg160_trigger_ops; |
1137 | iio_trigger_set_drvdata(trig: data->dready_trig, data: indio_dev); |
1138 | ret = iio_trigger_register(trig_info: data->dready_trig); |
1139 | if (ret) |
1140 | return ret; |
1141 | |
1142 | data->motion_trig->ops = &bmg160_trigger_ops; |
1143 | iio_trigger_set_drvdata(trig: data->motion_trig, data: indio_dev); |
1144 | ret = iio_trigger_register(trig_info: data->motion_trig); |
1145 | if (ret) { |
1146 | data->motion_trig = NULL; |
1147 | goto err_trigger_unregister; |
1148 | } |
1149 | } |
1150 | |
1151 | ret = iio_triggered_buffer_setup(indio_dev, |
1152 | iio_pollfunc_store_time, |
1153 | bmg160_trigger_handler, |
1154 | &bmg160_buffer_setup_ops); |
1155 | if (ret < 0) { |
1156 | dev_err(dev, |
1157 | "iio triggered buffer setup failed\n" ); |
1158 | goto err_trigger_unregister; |
1159 | } |
1160 | |
1161 | ret = pm_runtime_set_active(dev); |
1162 | if (ret) |
1163 | goto err_buffer_cleanup; |
1164 | |
1165 | pm_runtime_enable(dev); |
1166 | pm_runtime_set_autosuspend_delay(dev, |
1167 | BMG160_AUTO_SUSPEND_DELAY_MS); |
1168 | pm_runtime_use_autosuspend(dev); |
1169 | |
1170 | ret = iio_device_register(indio_dev); |
1171 | if (ret < 0) { |
1172 | dev_err(dev, "unable to register iio device\n" ); |
1173 | goto err_pm_cleanup; |
1174 | } |
1175 | |
1176 | return 0; |
1177 | |
1178 | err_pm_cleanup: |
1179 | pm_runtime_dont_use_autosuspend(dev); |
1180 | pm_runtime_disable(dev); |
1181 | err_buffer_cleanup: |
1182 | iio_triggered_buffer_cleanup(indio_dev); |
1183 | err_trigger_unregister: |
1184 | if (data->dready_trig) |
1185 | iio_trigger_unregister(trig_info: data->dready_trig); |
1186 | if (data->motion_trig) |
1187 | iio_trigger_unregister(trig_info: data->motion_trig); |
1188 | |
1189 | return ret; |
1190 | } |
1191 | EXPORT_SYMBOL_GPL(bmg160_core_probe); |
1192 | |
1193 | void bmg160_core_remove(struct device *dev) |
1194 | { |
1195 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1196 | struct bmg160_data *data = iio_priv(indio_dev); |
1197 | |
1198 | iio_device_unregister(indio_dev); |
1199 | |
1200 | pm_runtime_disable(dev); |
1201 | pm_runtime_set_suspended(dev); |
1202 | pm_runtime_put_noidle(dev); |
1203 | |
1204 | iio_triggered_buffer_cleanup(indio_dev); |
1205 | |
1206 | if (data->dready_trig) { |
1207 | iio_trigger_unregister(trig_info: data->dready_trig); |
1208 | iio_trigger_unregister(trig_info: data->motion_trig); |
1209 | } |
1210 | |
1211 | mutex_lock(&data->mutex); |
1212 | bmg160_set_mode(data, BMG160_MODE_DEEP_SUSPEND); |
1213 | mutex_unlock(lock: &data->mutex); |
1214 | } |
1215 | EXPORT_SYMBOL_GPL(bmg160_core_remove); |
1216 | |
1217 | #ifdef CONFIG_PM_SLEEP |
1218 | static int bmg160_suspend(struct device *dev) |
1219 | { |
1220 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1221 | struct bmg160_data *data = iio_priv(indio_dev); |
1222 | |
1223 | mutex_lock(&data->mutex); |
1224 | bmg160_set_mode(data, BMG160_MODE_SUSPEND); |
1225 | mutex_unlock(lock: &data->mutex); |
1226 | |
1227 | return 0; |
1228 | } |
1229 | |
1230 | static int bmg160_resume(struct device *dev) |
1231 | { |
1232 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1233 | struct bmg160_data *data = iio_priv(indio_dev); |
1234 | |
1235 | mutex_lock(&data->mutex); |
1236 | if (data->dready_trigger_on || data->motion_trigger_on || |
1237 | data->ev_enable_state) |
1238 | bmg160_set_mode(data, BMG160_MODE_NORMAL); |
1239 | mutex_unlock(lock: &data->mutex); |
1240 | |
1241 | return 0; |
1242 | } |
1243 | #endif |
1244 | |
1245 | #ifdef CONFIG_PM |
1246 | static int bmg160_runtime_suspend(struct device *dev) |
1247 | { |
1248 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1249 | struct bmg160_data *data = iio_priv(indio_dev); |
1250 | int ret; |
1251 | |
1252 | ret = bmg160_set_mode(data, BMG160_MODE_SUSPEND); |
1253 | if (ret < 0) { |
1254 | dev_err(dev, "set mode failed\n" ); |
1255 | return -EAGAIN; |
1256 | } |
1257 | |
1258 | return 0; |
1259 | } |
1260 | |
1261 | static int bmg160_runtime_resume(struct device *dev) |
1262 | { |
1263 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1264 | struct bmg160_data *data = iio_priv(indio_dev); |
1265 | int ret; |
1266 | |
1267 | ret = bmg160_set_mode(data, BMG160_MODE_NORMAL); |
1268 | if (ret < 0) |
1269 | return ret; |
1270 | |
1271 | msleep_interruptible(BMG160_MAX_STARTUP_TIME_MS); |
1272 | |
1273 | return 0; |
1274 | } |
1275 | #endif |
1276 | |
1277 | const struct dev_pm_ops bmg160_pm_ops = { |
1278 | SET_SYSTEM_SLEEP_PM_OPS(bmg160_suspend, bmg160_resume) |
1279 | SET_RUNTIME_PM_OPS(bmg160_runtime_suspend, |
1280 | bmg160_runtime_resume, NULL) |
1281 | }; |
1282 | EXPORT_SYMBOL_GPL(bmg160_pm_ops); |
1283 | |
1284 | MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>" ); |
1285 | MODULE_LICENSE("GPL v2" ); |
1286 | MODULE_DESCRIPTION("BMG160 Gyro driver" ); |
1287 | |