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