1// SPDX-License-Identifier: GPL-2.0-only
2/*
3* Copyright (C) 2012 Invensense, Inc.
4*/
5
6#include <linux/module.h>
7#include <linux/slab.h>
8#include <linux/i2c.h>
9#include <linux/err.h>
10#include <linux/delay.h>
11#include <linux/sysfs.h>
12#include <linux/jiffies.h>
13#include <linux/irq.h>
14#include <linux/interrupt.h>
15#include <linux/acpi.h>
16#include <linux/platform_device.h>
17#include <linux/regulator/consumer.h>
18#include <linux/pm.h>
19#include <linux/pm_runtime.h>
20#include <linux/property.h>
21
22#include <linux/iio/common/inv_sensors_timestamp.h>
23#include <linux/iio/iio.h>
24
25#include "inv_mpu_iio.h"
26#include "inv_mpu_magn.h"
27
28/*
29 * this is the gyro scale translated from dynamic range plus/minus
30 * {250, 500, 1000, 2000} to rad/s
31 */
32static const int gyro_scale_6050[] = {133090, 266181, 532362, 1064724};
33
34/*
35 * this is the accel scale translated from dynamic range plus/minus
36 * {2, 4, 8, 16} to m/s^2
37 */
38static const int accel_scale[] = {598, 1196, 2392, 4785};
39
40static const struct inv_mpu6050_reg_map reg_set_icm20602 = {
41 .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV,
42 .lpf = INV_MPU6050_REG_CONFIG,
43 .accel_lpf = INV_MPU6500_REG_ACCEL_CONFIG_2,
44 .user_ctrl = INV_MPU6050_REG_USER_CTRL,
45 .fifo_en = INV_MPU6050_REG_FIFO_EN,
46 .gyro_config = INV_MPU6050_REG_GYRO_CONFIG,
47 .accl_config = INV_MPU6050_REG_ACCEL_CONFIG,
48 .fifo_count_h = INV_MPU6050_REG_FIFO_COUNT_H,
49 .fifo_r_w = INV_MPU6050_REG_FIFO_R_W,
50 .raw_gyro = INV_MPU6050_REG_RAW_GYRO,
51 .raw_accl = INV_MPU6050_REG_RAW_ACCEL,
52 .temperature = INV_MPU6050_REG_TEMPERATURE,
53 .int_enable = INV_MPU6050_REG_INT_ENABLE,
54 .int_status = INV_MPU6050_REG_INT_STATUS,
55 .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1,
56 .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2,
57 .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG,
58 .accl_offset = INV_MPU6500_REG_ACCEL_OFFSET,
59 .gyro_offset = INV_MPU6050_REG_GYRO_OFFSET,
60 .i2c_if = INV_ICM20602_REG_I2C_IF,
61};
62
63static const struct inv_mpu6050_reg_map reg_set_6500 = {
64 .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV,
65 .lpf = INV_MPU6050_REG_CONFIG,
66 .accel_lpf = INV_MPU6500_REG_ACCEL_CONFIG_2,
67 .user_ctrl = INV_MPU6050_REG_USER_CTRL,
68 .fifo_en = INV_MPU6050_REG_FIFO_EN,
69 .gyro_config = INV_MPU6050_REG_GYRO_CONFIG,
70 .accl_config = INV_MPU6050_REG_ACCEL_CONFIG,
71 .fifo_count_h = INV_MPU6050_REG_FIFO_COUNT_H,
72 .fifo_r_w = INV_MPU6050_REG_FIFO_R_W,
73 .raw_gyro = INV_MPU6050_REG_RAW_GYRO,
74 .raw_accl = INV_MPU6050_REG_RAW_ACCEL,
75 .temperature = INV_MPU6050_REG_TEMPERATURE,
76 .int_enable = INV_MPU6050_REG_INT_ENABLE,
77 .int_status = INV_MPU6050_REG_INT_STATUS,
78 .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1,
79 .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2,
80 .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG,
81 .accl_offset = INV_MPU6500_REG_ACCEL_OFFSET,
82 .gyro_offset = INV_MPU6050_REG_GYRO_OFFSET,
83 .i2c_if = 0,
84};
85
86static const struct inv_mpu6050_reg_map reg_set_6050 = {
87 .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV,
88 .lpf = INV_MPU6050_REG_CONFIG,
89 .user_ctrl = INV_MPU6050_REG_USER_CTRL,
90 .fifo_en = INV_MPU6050_REG_FIFO_EN,
91 .gyro_config = INV_MPU6050_REG_GYRO_CONFIG,
92 .accl_config = INV_MPU6050_REG_ACCEL_CONFIG,
93 .fifo_count_h = INV_MPU6050_REG_FIFO_COUNT_H,
94 .fifo_r_w = INV_MPU6050_REG_FIFO_R_W,
95 .raw_gyro = INV_MPU6050_REG_RAW_GYRO,
96 .raw_accl = INV_MPU6050_REG_RAW_ACCEL,
97 .temperature = INV_MPU6050_REG_TEMPERATURE,
98 .int_enable = INV_MPU6050_REG_INT_ENABLE,
99 .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1,
100 .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2,
101 .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG,
102 .accl_offset = INV_MPU6050_REG_ACCEL_OFFSET,
103 .gyro_offset = INV_MPU6050_REG_GYRO_OFFSET,
104 .i2c_if = 0,
105};
106
107static const struct inv_mpu6050_chip_config chip_config_6050 = {
108 .clk = INV_CLK_INTERNAL,
109 .fsr = INV_MPU6050_FSR_2000DPS,
110 .lpf = INV_MPU6050_FILTER_20HZ,
111 .divider = INV_MPU6050_FIFO_RATE_TO_DIVIDER(50),
112 .gyro_en = true,
113 .accl_en = true,
114 .temp_en = true,
115 .magn_en = false,
116 .gyro_fifo_enable = false,
117 .accl_fifo_enable = false,
118 .temp_fifo_enable = false,
119 .magn_fifo_enable = false,
120 .accl_fs = INV_MPU6050_FS_02G,
121 .user_ctrl = 0,
122};
123
124static const struct inv_mpu6050_chip_config chip_config_6500 = {
125 .clk = INV_CLK_PLL,
126 .fsr = INV_MPU6050_FSR_2000DPS,
127 .lpf = INV_MPU6050_FILTER_20HZ,
128 .divider = INV_MPU6050_FIFO_RATE_TO_DIVIDER(50),
129 .gyro_en = true,
130 .accl_en = true,
131 .temp_en = true,
132 .magn_en = false,
133 .gyro_fifo_enable = false,
134 .accl_fifo_enable = false,
135 .temp_fifo_enable = false,
136 .magn_fifo_enable = false,
137 .accl_fs = INV_MPU6050_FS_02G,
138 .user_ctrl = 0,
139};
140
141/* Indexed by enum inv_devices */
142static const struct inv_mpu6050_hw hw_info[] = {
143 {
144 .whoami = INV_MPU6050_WHOAMI_VALUE,
145 .name = "MPU6050",
146 .reg = &reg_set_6050,
147 .config = &chip_config_6050,
148 .fifo_size = 1024,
149 .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
150 .startup_time = {INV_MPU6050_GYRO_STARTUP_TIME, INV_MPU6050_ACCEL_STARTUP_TIME},
151 },
152 {
153 .whoami = INV_MPU6500_WHOAMI_VALUE,
154 .name = "MPU6500",
155 .reg = &reg_set_6500,
156 .config = &chip_config_6500,
157 .fifo_size = 512,
158 .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
159 .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
160 },
161 {
162 .whoami = INV_MPU6515_WHOAMI_VALUE,
163 .name = "MPU6515",
164 .reg = &reg_set_6500,
165 .config = &chip_config_6500,
166 .fifo_size = 512,
167 .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
168 .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
169 },
170 {
171 .whoami = INV_MPU6880_WHOAMI_VALUE,
172 .name = "MPU6880",
173 .reg = &reg_set_6500,
174 .config = &chip_config_6500,
175 .fifo_size = 4096,
176 .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
177 .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
178 },
179 {
180 .whoami = INV_MPU6000_WHOAMI_VALUE,
181 .name = "MPU6000",
182 .reg = &reg_set_6050,
183 .config = &chip_config_6050,
184 .fifo_size = 1024,
185 .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
186 .startup_time = {INV_MPU6050_GYRO_STARTUP_TIME, INV_MPU6050_ACCEL_STARTUP_TIME},
187 },
188 {
189 .whoami = INV_MPU9150_WHOAMI_VALUE,
190 .name = "MPU9150",
191 .reg = &reg_set_6050,
192 .config = &chip_config_6050,
193 .fifo_size = 1024,
194 .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE},
195 .startup_time = {INV_MPU6050_GYRO_STARTUP_TIME, INV_MPU6050_ACCEL_STARTUP_TIME},
196 },
197 {
198 .whoami = INV_MPU9250_WHOAMI_VALUE,
199 .name = "MPU9250",
200 .reg = &reg_set_6500,
201 .config = &chip_config_6500,
202 .fifo_size = 512,
203 .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
204 .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
205 },
206 {
207 .whoami = INV_MPU9255_WHOAMI_VALUE,
208 .name = "MPU9255",
209 .reg = &reg_set_6500,
210 .config = &chip_config_6500,
211 .fifo_size = 512,
212 .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
213 .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
214 },
215 {
216 .whoami = INV_ICM20608_WHOAMI_VALUE,
217 .name = "ICM20608",
218 .reg = &reg_set_6500,
219 .config = &chip_config_6500,
220 .fifo_size = 512,
221 .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
222 .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
223 },
224 {
225 .whoami = INV_ICM20608D_WHOAMI_VALUE,
226 .name = "ICM20608D",
227 .reg = &reg_set_6500,
228 .config = &chip_config_6500,
229 .fifo_size = 512,
230 .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
231 .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
232 },
233 {
234 .whoami = INV_ICM20609_WHOAMI_VALUE,
235 .name = "ICM20609",
236 .reg = &reg_set_6500,
237 .config = &chip_config_6500,
238 .fifo_size = 4 * 1024,
239 .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
240 .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
241 },
242 {
243 .whoami = INV_ICM20689_WHOAMI_VALUE,
244 .name = "ICM20689",
245 .reg = &reg_set_6500,
246 .config = &chip_config_6500,
247 .fifo_size = 4 * 1024,
248 .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
249 .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
250 },
251 {
252 .whoami = INV_ICM20600_WHOAMI_VALUE,
253 .name = "ICM20600",
254 .reg = &reg_set_icm20602,
255 .config = &chip_config_6500,
256 .fifo_size = 1008,
257 .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
258 .startup_time = {INV_ICM20602_GYRO_STARTUP_TIME, INV_ICM20602_ACCEL_STARTUP_TIME},
259 },
260 {
261 .whoami = INV_ICM20602_WHOAMI_VALUE,
262 .name = "ICM20602",
263 .reg = &reg_set_icm20602,
264 .config = &chip_config_6500,
265 .fifo_size = 1008,
266 .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
267 .startup_time = {INV_ICM20602_GYRO_STARTUP_TIME, INV_ICM20602_ACCEL_STARTUP_TIME},
268 },
269 {
270 .whoami = INV_ICM20690_WHOAMI_VALUE,
271 .name = "ICM20690",
272 .reg = &reg_set_6500,
273 .config = &chip_config_6500,
274 .fifo_size = 1024,
275 .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
276 .startup_time = {INV_ICM20690_GYRO_STARTUP_TIME, INV_ICM20690_ACCEL_STARTUP_TIME},
277 },
278 {
279 .whoami = INV_IAM20680_WHOAMI_VALUE,
280 .name = "IAM20680",
281 .reg = &reg_set_6500,
282 .config = &chip_config_6500,
283 .fifo_size = 512,
284 .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
285 .startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
286 },
287};
288
289static int inv_mpu6050_pwr_mgmt_1_write(struct inv_mpu6050_state *st, bool sleep,
290 int clock, int temp_dis)
291{
292 u8 val;
293
294 if (clock < 0)
295 clock = st->chip_config.clk;
296 if (temp_dis < 0)
297 temp_dis = !st->chip_config.temp_en;
298
299 val = clock & INV_MPU6050_BIT_CLK_MASK;
300 if (temp_dis)
301 val |= INV_MPU6050_BIT_TEMP_DIS;
302 if (sleep)
303 val |= INV_MPU6050_BIT_SLEEP;
304
305 dev_dbg(regmap_get_device(st->map), "pwr_mgmt_1: 0x%x\n", val);
306 return regmap_write(map: st->map, reg: st->reg->pwr_mgmt_1, val);
307}
308
309static int inv_mpu6050_clock_switch(struct inv_mpu6050_state *st,
310 unsigned int clock)
311{
312 int ret;
313
314 switch (st->chip_type) {
315 case INV_MPU6050:
316 case INV_MPU6000:
317 case INV_MPU9150:
318 /* old chips: switch clock manually */
319 ret = inv_mpu6050_pwr_mgmt_1_write(st, sleep: false, clock, temp_dis: -1);
320 if (ret)
321 return ret;
322 st->chip_config.clk = clock;
323 break;
324 default:
325 /* automatic clock switching, nothing to do */
326 break;
327 }
328
329 return 0;
330}
331
332int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en,
333 unsigned int mask)
334{
335 unsigned int sleep;
336 u8 pwr_mgmt2, user_ctrl;
337 int ret;
338
339 /* delete useless requests */
340 if (mask & INV_MPU6050_SENSOR_ACCL && en == st->chip_config.accl_en)
341 mask &= ~INV_MPU6050_SENSOR_ACCL;
342 if (mask & INV_MPU6050_SENSOR_GYRO && en == st->chip_config.gyro_en)
343 mask &= ~INV_MPU6050_SENSOR_GYRO;
344 if (mask & INV_MPU6050_SENSOR_TEMP && en == st->chip_config.temp_en)
345 mask &= ~INV_MPU6050_SENSOR_TEMP;
346 if (mask & INV_MPU6050_SENSOR_MAGN && en == st->chip_config.magn_en)
347 mask &= ~INV_MPU6050_SENSOR_MAGN;
348 if (mask == 0)
349 return 0;
350
351 /* turn on/off temperature sensor */
352 if (mask & INV_MPU6050_SENSOR_TEMP) {
353 ret = inv_mpu6050_pwr_mgmt_1_write(st, sleep: false, clock: -1, temp_dis: !en);
354 if (ret)
355 return ret;
356 st->chip_config.temp_en = en;
357 }
358
359 /* update user_crtl for driving magnetometer */
360 if (mask & INV_MPU6050_SENSOR_MAGN) {
361 user_ctrl = st->chip_config.user_ctrl;
362 if (en)
363 user_ctrl |= INV_MPU6050_BIT_I2C_MST_EN;
364 else
365 user_ctrl &= ~INV_MPU6050_BIT_I2C_MST_EN;
366 ret = regmap_write(map: st->map, reg: st->reg->user_ctrl, val: user_ctrl);
367 if (ret)
368 return ret;
369 st->chip_config.user_ctrl = user_ctrl;
370 st->chip_config.magn_en = en;
371 }
372
373 /* manage accel & gyro engines */
374 if (mask & (INV_MPU6050_SENSOR_ACCL | INV_MPU6050_SENSOR_GYRO)) {
375 /* compute power management 2 current value */
376 pwr_mgmt2 = 0;
377 if (!st->chip_config.accl_en)
378 pwr_mgmt2 |= INV_MPU6050_BIT_PWR_ACCL_STBY;
379 if (!st->chip_config.gyro_en)
380 pwr_mgmt2 |= INV_MPU6050_BIT_PWR_GYRO_STBY;
381
382 /* update to new requested value */
383 if (mask & INV_MPU6050_SENSOR_ACCL) {
384 if (en)
385 pwr_mgmt2 &= ~INV_MPU6050_BIT_PWR_ACCL_STBY;
386 else
387 pwr_mgmt2 |= INV_MPU6050_BIT_PWR_ACCL_STBY;
388 }
389 if (mask & INV_MPU6050_SENSOR_GYRO) {
390 if (en)
391 pwr_mgmt2 &= ~INV_MPU6050_BIT_PWR_GYRO_STBY;
392 else
393 pwr_mgmt2 |= INV_MPU6050_BIT_PWR_GYRO_STBY;
394 }
395
396 /* switch clock to internal when turning gyro off */
397 if (mask & INV_MPU6050_SENSOR_GYRO && !en) {
398 ret = inv_mpu6050_clock_switch(st, clock: INV_CLK_INTERNAL);
399 if (ret)
400 return ret;
401 }
402
403 /* update sensors engine */
404 dev_dbg(regmap_get_device(st->map), "pwr_mgmt_2: 0x%x\n",
405 pwr_mgmt2);
406 ret = regmap_write(map: st->map, reg: st->reg->pwr_mgmt_2, val: pwr_mgmt2);
407 if (ret)
408 return ret;
409 if (mask & INV_MPU6050_SENSOR_ACCL)
410 st->chip_config.accl_en = en;
411 if (mask & INV_MPU6050_SENSOR_GYRO)
412 st->chip_config.gyro_en = en;
413
414 /* compute required time to have sensors stabilized */
415 sleep = 0;
416 if (en) {
417 if (mask & INV_MPU6050_SENSOR_ACCL) {
418 if (sleep < st->hw->startup_time.accel)
419 sleep = st->hw->startup_time.accel;
420 }
421 if (mask & INV_MPU6050_SENSOR_GYRO) {
422 if (sleep < st->hw->startup_time.gyro)
423 sleep = st->hw->startup_time.gyro;
424 }
425 } else {
426 if (mask & INV_MPU6050_SENSOR_GYRO) {
427 if (sleep < INV_MPU6050_GYRO_DOWN_TIME)
428 sleep = INV_MPU6050_GYRO_DOWN_TIME;
429 }
430 }
431 if (sleep)
432 msleep(msecs: sleep);
433
434 /* switch clock to PLL when turning gyro on */
435 if (mask & INV_MPU6050_SENSOR_GYRO && en) {
436 ret = inv_mpu6050_clock_switch(st, clock: INV_CLK_PLL);
437 if (ret)
438 return ret;
439 }
440 }
441
442 return 0;
443}
444
445static int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st,
446 bool power_on)
447{
448 int result;
449
450 result = inv_mpu6050_pwr_mgmt_1_write(st, sleep: !power_on, clock: -1, temp_dis: -1);
451 if (result)
452 return result;
453
454 if (power_on)
455 usleep_range(INV_MPU6050_REG_UP_TIME_MIN,
456 INV_MPU6050_REG_UP_TIME_MAX);
457
458 return 0;
459}
460
461static int inv_mpu6050_set_gyro_fsr(struct inv_mpu6050_state *st,
462 enum inv_mpu6050_fsr_e val)
463{
464 unsigned int gyro_shift;
465 u8 data;
466
467 switch (st->chip_type) {
468 case INV_ICM20690:
469 gyro_shift = INV_ICM20690_GYRO_CONFIG_FSR_SHIFT;
470 break;
471 default:
472 gyro_shift = INV_MPU6050_GYRO_CONFIG_FSR_SHIFT;
473 break;
474 }
475
476 data = val << gyro_shift;
477 return regmap_write(map: st->map, reg: st->reg->gyro_config, val: data);
478}
479
480/*
481 * inv_mpu6050_set_lpf_regs() - set low pass filter registers, chip dependent
482 *
483 * MPU60xx/MPU9150 use only 1 register for accelerometer + gyroscope
484 * MPU6500 and above have a dedicated register for accelerometer
485 */
486static int inv_mpu6050_set_lpf_regs(struct inv_mpu6050_state *st,
487 enum inv_mpu6050_filter_e val)
488{
489 int result;
490
491 result = regmap_write(map: st->map, reg: st->reg->lpf, val);
492 if (result)
493 return result;
494
495 /* set accel lpf */
496 switch (st->chip_type) {
497 case INV_MPU6050:
498 case INV_MPU6000:
499 case INV_MPU9150:
500 /* old chips, nothing to do */
501 return 0;
502 case INV_ICM20689:
503 case INV_ICM20690:
504 /* set FIFO size to maximum value */
505 val |= INV_ICM20689_BITS_FIFO_SIZE_MAX;
506 break;
507 default:
508 break;
509 }
510
511 return regmap_write(map: st->map, reg: st->reg->accel_lpf, val);
512}
513
514/*
515 * inv_mpu6050_init_config() - Initialize hardware, disable FIFO.
516 *
517 * Initial configuration:
518 * FSR: ± 2000DPS
519 * DLPF: 20Hz
520 * FIFO rate: 50Hz
521 * Clock source: Gyro PLL
522 */
523static int inv_mpu6050_init_config(struct iio_dev *indio_dev)
524{
525 int result;
526 u8 d;
527 struct inv_mpu6050_state *st = iio_priv(indio_dev);
528 struct inv_sensors_timestamp_chip timestamp;
529
530 result = inv_mpu6050_set_gyro_fsr(st, val: st->chip_config.fsr);
531 if (result)
532 return result;
533
534 result = inv_mpu6050_set_lpf_regs(st, val: st->chip_config.lpf);
535 if (result)
536 return result;
537
538 d = st->chip_config.divider;
539 result = regmap_write(map: st->map, reg: st->reg->sample_rate_div, val: d);
540 if (result)
541 return result;
542
543 d = (st->chip_config.accl_fs << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
544 result = regmap_write(map: st->map, reg: st->reg->accl_config, val: d);
545 if (result)
546 return result;
547
548 result = regmap_write(map: st->map, reg: st->reg->int_pin_cfg, val: st->irq_mask);
549 if (result)
550 return result;
551
552 /* clock jitter is +/- 2% */
553 timestamp.clock_period = NSEC_PER_SEC / INV_MPU6050_INTERNAL_FREQ_HZ;
554 timestamp.jitter = 20;
555 timestamp.init_period =
556 NSEC_PER_SEC / INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
557 inv_sensors_timestamp_init(ts: &st->timestamp, chip: &timestamp);
558
559 /* magn chip init, noop if not present in the chip */
560 result = inv_mpu_magn_probe(st);
561 if (result)
562 return result;
563
564 return 0;
565}
566
567static int inv_mpu6050_sensor_set(struct inv_mpu6050_state *st, int reg,
568 int axis, int val)
569{
570 int ind;
571 __be16 d = cpu_to_be16(val);
572
573 ind = (axis - IIO_MOD_X) * 2;
574
575 return regmap_bulk_write(map: st->map, reg: reg + ind, val: &d, val_count: sizeof(d));
576}
577
578static int inv_mpu6050_sensor_show(struct inv_mpu6050_state *st, int reg,
579 int axis, int *val)
580{
581 int ind, result;
582 __be16 d;
583
584 ind = (axis - IIO_MOD_X) * 2;
585 result = regmap_bulk_read(map: st->map, reg: reg + ind, val: &d, val_count: sizeof(d));
586 if (result)
587 return result;
588 *val = (short)be16_to_cpup(p: &d);
589
590 return IIO_VAL_INT;
591}
592
593static int inv_mpu6050_read_channel_data(struct iio_dev *indio_dev,
594 struct iio_chan_spec const *chan,
595 int *val)
596{
597 struct inv_mpu6050_state *st = iio_priv(indio_dev);
598 struct device *pdev = regmap_get_device(map: st->map);
599 unsigned int freq_hz, period_us, min_sleep_us, max_sleep_us;
600 int result;
601 int ret;
602
603 /* compute sample period */
604 freq_hz = INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
605 period_us = 1000000 / freq_hz;
606
607 result = pm_runtime_resume_and_get(dev: pdev);
608 if (result)
609 return result;
610
611 switch (chan->type) {
612 case IIO_ANGL_VEL:
613 if (!st->chip_config.gyro_en) {
614 result = inv_mpu6050_switch_engine(st, en: true,
615 INV_MPU6050_SENSOR_GYRO);
616 if (result)
617 goto error_power_off;
618 /* need to wait 2 periods to have first valid sample */
619 min_sleep_us = 2 * period_us;
620 max_sleep_us = 2 * (period_us + period_us / 2);
621 usleep_range(min: min_sleep_us, max: max_sleep_us);
622 }
623 ret = inv_mpu6050_sensor_show(st, reg: st->reg->raw_gyro,
624 axis: chan->channel2, val);
625 break;
626 case IIO_ACCEL:
627 if (!st->chip_config.accl_en) {
628 result = inv_mpu6050_switch_engine(st, en: true,
629 INV_MPU6050_SENSOR_ACCL);
630 if (result)
631 goto error_power_off;
632 /* wait 1 period for first sample availability */
633 min_sleep_us = period_us;
634 max_sleep_us = period_us + period_us / 2;
635 usleep_range(min: min_sleep_us, max: max_sleep_us);
636 }
637 ret = inv_mpu6050_sensor_show(st, reg: st->reg->raw_accl,
638 axis: chan->channel2, val);
639 break;
640 case IIO_TEMP:
641 /* temperature sensor work only with accel and/or gyro */
642 if (!st->chip_config.accl_en && !st->chip_config.gyro_en) {
643 result = -EBUSY;
644 goto error_power_off;
645 }
646 if (!st->chip_config.temp_en) {
647 result = inv_mpu6050_switch_engine(st, en: true,
648 INV_MPU6050_SENSOR_TEMP);
649 if (result)
650 goto error_power_off;
651 /* wait 1 period for first sample availability */
652 min_sleep_us = period_us;
653 max_sleep_us = period_us + period_us / 2;
654 usleep_range(min: min_sleep_us, max: max_sleep_us);
655 }
656 ret = inv_mpu6050_sensor_show(st, reg: st->reg->temperature,
657 axis: IIO_MOD_X, val);
658 break;
659 case IIO_MAGN:
660 if (!st->chip_config.magn_en) {
661 result = inv_mpu6050_switch_engine(st, en: true,
662 INV_MPU6050_SENSOR_MAGN);
663 if (result)
664 goto error_power_off;
665 /* frequency is limited for magnetometer */
666 if (freq_hz > INV_MPU_MAGN_FREQ_HZ_MAX) {
667 freq_hz = INV_MPU_MAGN_FREQ_HZ_MAX;
668 period_us = 1000000 / freq_hz;
669 }
670 /* need to wait 2 periods to have first valid sample */
671 min_sleep_us = 2 * period_us;
672 max_sleep_us = 2 * (period_us + period_us / 2);
673 usleep_range(min: min_sleep_us, max: max_sleep_us);
674 }
675 ret = inv_mpu_magn_read(st, axis: chan->channel2, val);
676 break;
677 default:
678 ret = -EINVAL;
679 break;
680 }
681
682 pm_runtime_mark_last_busy(dev: pdev);
683 pm_runtime_put_autosuspend(dev: pdev);
684
685 return ret;
686
687error_power_off:
688 pm_runtime_put_autosuspend(dev: pdev);
689 return result;
690}
691
692static int
693inv_mpu6050_read_raw(struct iio_dev *indio_dev,
694 struct iio_chan_spec const *chan,
695 int *val, int *val2, long mask)
696{
697 struct inv_mpu6050_state *st = iio_priv(indio_dev);
698 int ret = 0;
699
700 switch (mask) {
701 case IIO_CHAN_INFO_RAW:
702 ret = iio_device_claim_direct_mode(indio_dev);
703 if (ret)
704 return ret;
705 mutex_lock(&st->lock);
706 ret = inv_mpu6050_read_channel_data(indio_dev, chan, val);
707 mutex_unlock(lock: &st->lock);
708 iio_device_release_direct_mode(indio_dev);
709 return ret;
710 case IIO_CHAN_INFO_SCALE:
711 switch (chan->type) {
712 case IIO_ANGL_VEL:
713 mutex_lock(&st->lock);
714 *val = 0;
715 *val2 = gyro_scale_6050[st->chip_config.fsr];
716 mutex_unlock(lock: &st->lock);
717
718 return IIO_VAL_INT_PLUS_NANO;
719 case IIO_ACCEL:
720 mutex_lock(&st->lock);
721 *val = 0;
722 *val2 = accel_scale[st->chip_config.accl_fs];
723 mutex_unlock(lock: &st->lock);
724
725 return IIO_VAL_INT_PLUS_MICRO;
726 case IIO_TEMP:
727 *val = st->hw->temp.scale / 1000000;
728 *val2 = st->hw->temp.scale % 1000000;
729 return IIO_VAL_INT_PLUS_MICRO;
730 case IIO_MAGN:
731 return inv_mpu_magn_get_scale(st, chan, val, val2);
732 default:
733 return -EINVAL;
734 }
735 case IIO_CHAN_INFO_OFFSET:
736 switch (chan->type) {
737 case IIO_TEMP:
738 *val = st->hw->temp.offset;
739 return IIO_VAL_INT;
740 default:
741 return -EINVAL;
742 }
743 case IIO_CHAN_INFO_CALIBBIAS:
744 switch (chan->type) {
745 case IIO_ANGL_VEL:
746 mutex_lock(&st->lock);
747 ret = inv_mpu6050_sensor_show(st, reg: st->reg->gyro_offset,
748 axis: chan->channel2, val);
749 mutex_unlock(lock: &st->lock);
750 return ret;
751 case IIO_ACCEL:
752 mutex_lock(&st->lock);
753 ret = inv_mpu6050_sensor_show(st, reg: st->reg->accl_offset,
754 axis: chan->channel2, val);
755 mutex_unlock(lock: &st->lock);
756 return ret;
757
758 default:
759 return -EINVAL;
760 }
761 default:
762 return -EINVAL;
763 }
764}
765
766static int inv_mpu6050_write_gyro_scale(struct inv_mpu6050_state *st, int val,
767 int val2)
768{
769 int result, i;
770
771 if (val != 0)
772 return -EINVAL;
773
774 for (i = 0; i < ARRAY_SIZE(gyro_scale_6050); ++i) {
775 if (gyro_scale_6050[i] == val2) {
776 result = inv_mpu6050_set_gyro_fsr(st, val: i);
777 if (result)
778 return result;
779
780 st->chip_config.fsr = i;
781 return 0;
782 }
783 }
784
785 return -EINVAL;
786}
787
788static int inv_write_raw_get_fmt(struct iio_dev *indio_dev,
789 struct iio_chan_spec const *chan, long mask)
790{
791 switch (mask) {
792 case IIO_CHAN_INFO_SCALE:
793 switch (chan->type) {
794 case IIO_ANGL_VEL:
795 return IIO_VAL_INT_PLUS_NANO;
796 default:
797 return IIO_VAL_INT_PLUS_MICRO;
798 }
799 default:
800 return IIO_VAL_INT_PLUS_MICRO;
801 }
802
803 return -EINVAL;
804}
805
806static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val,
807 int val2)
808{
809 int result, i;
810 u8 d;
811
812 if (val != 0)
813 return -EINVAL;
814
815 for (i = 0; i < ARRAY_SIZE(accel_scale); ++i) {
816 if (accel_scale[i] == val2) {
817 d = (i << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
818 result = regmap_write(map: st->map, reg: st->reg->accl_config, val: d);
819 if (result)
820 return result;
821
822 st->chip_config.accl_fs = i;
823 return 0;
824 }
825 }
826
827 return -EINVAL;
828}
829
830static int inv_mpu6050_write_raw(struct iio_dev *indio_dev,
831 struct iio_chan_spec const *chan,
832 int val, int val2, long mask)
833{
834 struct inv_mpu6050_state *st = iio_priv(indio_dev);
835 struct device *pdev = regmap_get_device(map: st->map);
836 int result;
837
838 /*
839 * we should only update scale when the chip is disabled, i.e.
840 * not running
841 */
842 result = iio_device_claim_direct_mode(indio_dev);
843 if (result)
844 return result;
845
846 mutex_lock(&st->lock);
847 result = pm_runtime_resume_and_get(dev: pdev);
848 if (result)
849 goto error_write_raw_unlock;
850
851 switch (mask) {
852 case IIO_CHAN_INFO_SCALE:
853 switch (chan->type) {
854 case IIO_ANGL_VEL:
855 result = inv_mpu6050_write_gyro_scale(st, val, val2);
856 break;
857 case IIO_ACCEL:
858 result = inv_mpu6050_write_accel_scale(st, val, val2);
859 break;
860 default:
861 result = -EINVAL;
862 break;
863 }
864 break;
865 case IIO_CHAN_INFO_CALIBBIAS:
866 switch (chan->type) {
867 case IIO_ANGL_VEL:
868 result = inv_mpu6050_sensor_set(st,
869 reg: st->reg->gyro_offset,
870 axis: chan->channel2, val);
871 break;
872 case IIO_ACCEL:
873 result = inv_mpu6050_sensor_set(st,
874 reg: st->reg->accl_offset,
875 axis: chan->channel2, val);
876 break;
877 default:
878 result = -EINVAL;
879 break;
880 }
881 break;
882 default:
883 result = -EINVAL;
884 break;
885 }
886
887 pm_runtime_mark_last_busy(dev: pdev);
888 pm_runtime_put_autosuspend(dev: pdev);
889error_write_raw_unlock:
890 mutex_unlock(lock: &st->lock);
891 iio_device_release_direct_mode(indio_dev);
892
893 return result;
894}
895
896/*
897 * inv_mpu6050_set_lpf() - set low pass filer based on fifo rate.
898 *
899 * Based on the Nyquist principle, the bandwidth of the low
900 * pass filter must not exceed the signal sampling rate divided
901 * by 2, or there would be aliasing.
902 * This function basically search for the correct low pass
903 * parameters based on the fifo rate, e.g, sampling frequency.
904 *
905 * lpf is set automatically when setting sampling rate to avoid any aliases.
906 */
907static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate)
908{
909 static const int hz[] = {400, 200, 90, 40, 20, 10};
910 static const int d[] = {
911 INV_MPU6050_FILTER_200HZ, INV_MPU6050_FILTER_100HZ,
912 INV_MPU6050_FILTER_45HZ, INV_MPU6050_FILTER_20HZ,
913 INV_MPU6050_FILTER_10HZ, INV_MPU6050_FILTER_5HZ
914 };
915 int i, result;
916 u8 data;
917
918 data = INV_MPU6050_FILTER_5HZ;
919 for (i = 0; i < ARRAY_SIZE(hz); ++i) {
920 if (rate >= hz[i]) {
921 data = d[i];
922 break;
923 }
924 }
925 result = inv_mpu6050_set_lpf_regs(st, val: data);
926 if (result)
927 return result;
928 st->chip_config.lpf = data;
929
930 return 0;
931}
932
933/*
934 * inv_mpu6050_fifo_rate_store() - Set fifo rate.
935 */
936static ssize_t
937inv_mpu6050_fifo_rate_store(struct device *dev, struct device_attribute *attr,
938 const char *buf, size_t count)
939{
940 int fifo_rate;
941 u32 fifo_period;
942 bool fifo_on;
943 u8 d;
944 int result;
945 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
946 struct inv_mpu6050_state *st = iio_priv(indio_dev);
947 struct device *pdev = regmap_get_device(map: st->map);
948
949 if (kstrtoint(s: buf, base: 10, res: &fifo_rate))
950 return -EINVAL;
951 if (fifo_rate < INV_MPU6050_MIN_FIFO_RATE ||
952 fifo_rate > INV_MPU6050_MAX_FIFO_RATE)
953 return -EINVAL;
954
955 /* compute the chip sample rate divider */
956 d = INV_MPU6050_FIFO_RATE_TO_DIVIDER(fifo_rate);
957 /* compute back the fifo rate to handle truncation cases */
958 fifo_rate = INV_MPU6050_DIVIDER_TO_FIFO_RATE(d);
959 fifo_period = NSEC_PER_SEC / fifo_rate;
960
961 mutex_lock(&st->lock);
962 if (d == st->chip_config.divider) {
963 result = 0;
964 goto fifo_rate_fail_unlock;
965 }
966
967 fifo_on = st->chip_config.accl_fifo_enable ||
968 st->chip_config.gyro_fifo_enable ||
969 st->chip_config.magn_fifo_enable;
970 result = inv_sensors_timestamp_update_odr(ts: &st->timestamp, period: fifo_period, fifo: fifo_on);
971 if (result)
972 goto fifo_rate_fail_unlock;
973
974 result = pm_runtime_resume_and_get(dev: pdev);
975 if (result)
976 goto fifo_rate_fail_unlock;
977
978 result = regmap_write(map: st->map, reg: st->reg->sample_rate_div, val: d);
979 if (result)
980 goto fifo_rate_fail_power_off;
981 st->chip_config.divider = d;
982
983 result = inv_mpu6050_set_lpf(st, rate: fifo_rate);
984 if (result)
985 goto fifo_rate_fail_power_off;
986
987 /* update rate for magn, noop if not present in chip */
988 result = inv_mpu_magn_set_rate(st, fifo_rate);
989 if (result)
990 goto fifo_rate_fail_power_off;
991
992 pm_runtime_mark_last_busy(dev: pdev);
993fifo_rate_fail_power_off:
994 pm_runtime_put_autosuspend(dev: pdev);
995fifo_rate_fail_unlock:
996 mutex_unlock(lock: &st->lock);
997 if (result)
998 return result;
999
1000 return count;
1001}
1002
1003/*
1004 * inv_fifo_rate_show() - Get the current sampling rate.
1005 */
1006static ssize_t
1007inv_fifo_rate_show(struct device *dev, struct device_attribute *attr,
1008 char *buf)
1009{
1010 struct inv_mpu6050_state *st = iio_priv(indio_dev: dev_to_iio_dev(dev));
1011 unsigned fifo_rate;
1012
1013 mutex_lock(&st->lock);
1014 fifo_rate = INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
1015 mutex_unlock(lock: &st->lock);
1016
1017 return scnprintf(buf, PAGE_SIZE, fmt: "%u\n", fifo_rate);
1018}
1019
1020/*
1021 * inv_attr_show() - calling this function will show current
1022 * parameters.
1023 *
1024 * Deprecated in favor of IIO mounting matrix API.
1025 *
1026 * See inv_get_mount_matrix()
1027 */
1028static ssize_t inv_attr_show(struct device *dev, struct device_attribute *attr,
1029 char *buf)
1030{
1031 struct inv_mpu6050_state *st = iio_priv(indio_dev: dev_to_iio_dev(dev));
1032 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
1033 s8 *m;
1034
1035 switch (this_attr->address) {
1036 /*
1037 * In MPU6050, the two matrix are the same because gyro and accel
1038 * are integrated in one chip
1039 */
1040 case ATTR_GYRO_MATRIX:
1041 case ATTR_ACCL_MATRIX:
1042 m = st->plat_data.orientation;
1043
1044 return scnprintf(buf, PAGE_SIZE,
1045 fmt: "%d, %d, %d; %d, %d, %d; %d, %d, %d\n",
1046 m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
1047 default:
1048 return -EINVAL;
1049 }
1050}
1051
1052/**
1053 * inv_mpu6050_validate_trigger() - validate_trigger callback for invensense
1054 * MPU6050 device.
1055 * @indio_dev: The IIO device
1056 * @trig: The new trigger
1057 *
1058 * Returns: 0 if the 'trig' matches the trigger registered by the MPU6050
1059 * device, -EINVAL otherwise.
1060 */
1061static int inv_mpu6050_validate_trigger(struct iio_dev *indio_dev,
1062 struct iio_trigger *trig)
1063{
1064 struct inv_mpu6050_state *st = iio_priv(indio_dev);
1065
1066 if (st->trig != trig)
1067 return -EINVAL;
1068
1069 return 0;
1070}
1071
1072static const struct iio_mount_matrix *
1073inv_get_mount_matrix(const struct iio_dev *indio_dev,
1074 const struct iio_chan_spec *chan)
1075{
1076 struct inv_mpu6050_state *data = iio_priv(indio_dev);
1077 const struct iio_mount_matrix *matrix;
1078
1079 if (chan->type == IIO_MAGN)
1080 matrix = &data->magn_orient;
1081 else
1082 matrix = &data->orientation;
1083
1084 return matrix;
1085}
1086
1087static const struct iio_chan_spec_ext_info inv_ext_info[] = {
1088 IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, inv_get_mount_matrix),
1089 { }
1090};
1091
1092#define INV_MPU6050_CHAN(_type, _channel2, _index) \
1093 { \
1094 .type = _type, \
1095 .modified = 1, \
1096 .channel2 = _channel2, \
1097 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
1098 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
1099 BIT(IIO_CHAN_INFO_CALIBBIAS), \
1100 .scan_index = _index, \
1101 .scan_type = { \
1102 .sign = 's', \
1103 .realbits = 16, \
1104 .storagebits = 16, \
1105 .shift = 0, \
1106 .endianness = IIO_BE, \
1107 }, \
1108 .ext_info = inv_ext_info, \
1109 }
1110
1111#define INV_MPU6050_TEMP_CHAN(_index) \
1112 { \
1113 .type = IIO_TEMP, \
1114 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \
1115 | BIT(IIO_CHAN_INFO_OFFSET) \
1116 | BIT(IIO_CHAN_INFO_SCALE), \
1117 .scan_index = _index, \
1118 .scan_type = { \
1119 .sign = 's', \
1120 .realbits = 16, \
1121 .storagebits = 16, \
1122 .shift = 0, \
1123 .endianness = IIO_BE, \
1124 }, \
1125 }
1126
1127static const struct iio_chan_spec inv_mpu_channels[] = {
1128 IIO_CHAN_SOFT_TIMESTAMP(INV_MPU6050_SCAN_TIMESTAMP),
1129
1130 INV_MPU6050_TEMP_CHAN(INV_MPU6050_SCAN_TEMP),
1131
1132 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
1133 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
1134 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
1135
1136 INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
1137 INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
1138 INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
1139};
1140
1141#define INV_MPU6050_SCAN_MASK_3AXIS_ACCEL \
1142 (BIT(INV_MPU6050_SCAN_ACCL_X) \
1143 | BIT(INV_MPU6050_SCAN_ACCL_Y) \
1144 | BIT(INV_MPU6050_SCAN_ACCL_Z))
1145
1146#define INV_MPU6050_SCAN_MASK_3AXIS_GYRO \
1147 (BIT(INV_MPU6050_SCAN_GYRO_X) \
1148 | BIT(INV_MPU6050_SCAN_GYRO_Y) \
1149 | BIT(INV_MPU6050_SCAN_GYRO_Z))
1150
1151#define INV_MPU6050_SCAN_MASK_TEMP (BIT(INV_MPU6050_SCAN_TEMP))
1152
1153static const unsigned long inv_mpu_scan_masks[] = {
1154 /* 3-axis accel */
1155 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL,
1156 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_TEMP,
1157 /* 3-axis gyro */
1158 INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
1159 INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU6050_SCAN_MASK_TEMP,
1160 /* 6-axis accel + gyro */
1161 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
1162 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
1163 | INV_MPU6050_SCAN_MASK_TEMP,
1164 0,
1165};
1166
1167#define INV_MPU9X50_MAGN_CHAN(_chan2, _bits, _index) \
1168 { \
1169 .type = IIO_MAGN, \
1170 .modified = 1, \
1171 .channel2 = _chan2, \
1172 .info_mask_separate = BIT(IIO_CHAN_INFO_SCALE) | \
1173 BIT(IIO_CHAN_INFO_RAW), \
1174 .scan_index = _index, \
1175 .scan_type = { \
1176 .sign = 's', \
1177 .realbits = _bits, \
1178 .storagebits = 16, \
1179 .shift = 0, \
1180 .endianness = IIO_BE, \
1181 }, \
1182 .ext_info = inv_ext_info, \
1183 }
1184
1185static const struct iio_chan_spec inv_mpu9150_channels[] = {
1186 IIO_CHAN_SOFT_TIMESTAMP(INV_MPU9X50_SCAN_TIMESTAMP),
1187
1188 INV_MPU6050_TEMP_CHAN(INV_MPU6050_SCAN_TEMP),
1189
1190 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
1191 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
1192 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
1193
1194 INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
1195 INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
1196 INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
1197
1198 /* Magnetometer resolution is 13 bits */
1199 INV_MPU9X50_MAGN_CHAN(IIO_MOD_X, 13, INV_MPU9X50_SCAN_MAGN_X),
1200 INV_MPU9X50_MAGN_CHAN(IIO_MOD_Y, 13, INV_MPU9X50_SCAN_MAGN_Y),
1201 INV_MPU9X50_MAGN_CHAN(IIO_MOD_Z, 13, INV_MPU9X50_SCAN_MAGN_Z),
1202};
1203
1204static const struct iio_chan_spec inv_mpu9250_channels[] = {
1205 IIO_CHAN_SOFT_TIMESTAMP(INV_MPU9X50_SCAN_TIMESTAMP),
1206
1207 INV_MPU6050_TEMP_CHAN(INV_MPU6050_SCAN_TEMP),
1208
1209 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
1210 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
1211 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
1212
1213 INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
1214 INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
1215 INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
1216
1217 /* Magnetometer resolution is 16 bits */
1218 INV_MPU9X50_MAGN_CHAN(IIO_MOD_X, 16, INV_MPU9X50_SCAN_MAGN_X),
1219 INV_MPU9X50_MAGN_CHAN(IIO_MOD_Y, 16, INV_MPU9X50_SCAN_MAGN_Y),
1220 INV_MPU9X50_MAGN_CHAN(IIO_MOD_Z, 16, INV_MPU9X50_SCAN_MAGN_Z),
1221};
1222
1223#define INV_MPU9X50_SCAN_MASK_3AXIS_MAGN \
1224 (BIT(INV_MPU9X50_SCAN_MAGN_X) \
1225 | BIT(INV_MPU9X50_SCAN_MAGN_Y) \
1226 | BIT(INV_MPU9X50_SCAN_MAGN_Z))
1227
1228static const unsigned long inv_mpu9x50_scan_masks[] = {
1229 /* 3-axis accel */
1230 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL,
1231 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_TEMP,
1232 /* 3-axis gyro */
1233 INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
1234 INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU6050_SCAN_MASK_TEMP,
1235 /* 3-axis magn */
1236 INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
1237 INV_MPU9X50_SCAN_MASK_3AXIS_MAGN | INV_MPU6050_SCAN_MASK_TEMP,
1238 /* 6-axis accel + gyro */
1239 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
1240 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
1241 | INV_MPU6050_SCAN_MASK_TEMP,
1242 /* 6-axis accel + magn */
1243 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
1244 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN
1245 | INV_MPU6050_SCAN_MASK_TEMP,
1246 /* 6-axis gyro + magn */
1247 INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
1248 INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN
1249 | INV_MPU6050_SCAN_MASK_TEMP,
1250 /* 9-axis accel + gyro + magn */
1251 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
1252 | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
1253 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
1254 | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN
1255 | INV_MPU6050_SCAN_MASK_TEMP,
1256 0,
1257};
1258
1259static const unsigned long inv_icm20602_scan_masks[] = {
1260 /* 3-axis accel + temp (mandatory) */
1261 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_TEMP,
1262 /* 3-axis gyro + temp (mandatory) */
1263 INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU6050_SCAN_MASK_TEMP,
1264 /* 6-axis accel + gyro + temp (mandatory) */
1265 INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
1266 | INV_MPU6050_SCAN_MASK_TEMP,
1267 0,
1268};
1269
1270/*
1271 * The user can choose any frequency between INV_MPU6050_MIN_FIFO_RATE and
1272 * INV_MPU6050_MAX_FIFO_RATE, but only these frequencies are matched by the
1273 * low-pass filter. Specifically, each of these sampling rates are about twice
1274 * the bandwidth of a corresponding low-pass filter, which should eliminate
1275 * aliasing following the Nyquist principle. By picking a frequency different
1276 * from these, the user risks aliasing effects.
1277 */
1278static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500");
1279static IIO_CONST_ATTR(in_anglvel_scale_available,
1280 "0.000133090 0.000266181 0.000532362 0.001064724");
1281static IIO_CONST_ATTR(in_accel_scale_available,
1282 "0.000598 0.001196 0.002392 0.004785");
1283static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, inv_fifo_rate_show,
1284 inv_mpu6050_fifo_rate_store);
1285
1286/* Deprecated: kept for userspace backward compatibility. */
1287static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL,
1288 ATTR_GYRO_MATRIX);
1289static IIO_DEVICE_ATTR(in_accel_matrix, S_IRUGO, inv_attr_show, NULL,
1290 ATTR_ACCL_MATRIX);
1291
1292static struct attribute *inv_attributes[] = {
1293 &iio_dev_attr_in_gyro_matrix.dev_attr.attr, /* deprecated */
1294 &iio_dev_attr_in_accel_matrix.dev_attr.attr, /* deprecated */
1295 &iio_dev_attr_sampling_frequency.dev_attr.attr,
1296 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
1297 &iio_const_attr_in_accel_scale_available.dev_attr.attr,
1298 &iio_const_attr_in_anglvel_scale_available.dev_attr.attr,
1299 NULL,
1300};
1301
1302static const struct attribute_group inv_attribute_group = {
1303 .attrs = inv_attributes
1304};
1305
1306static int inv_mpu6050_reg_access(struct iio_dev *indio_dev,
1307 unsigned int reg,
1308 unsigned int writeval,
1309 unsigned int *readval)
1310{
1311 struct inv_mpu6050_state *st = iio_priv(indio_dev);
1312 int ret;
1313
1314 mutex_lock(&st->lock);
1315 if (readval)
1316 ret = regmap_read(map: st->map, reg, val: readval);
1317 else
1318 ret = regmap_write(map: st->map, reg, val: writeval);
1319 mutex_unlock(lock: &st->lock);
1320
1321 return ret;
1322}
1323
1324static const struct iio_info mpu_info = {
1325 .read_raw = &inv_mpu6050_read_raw,
1326 .write_raw = &inv_mpu6050_write_raw,
1327 .write_raw_get_fmt = &inv_write_raw_get_fmt,
1328 .attrs = &inv_attribute_group,
1329 .validate_trigger = inv_mpu6050_validate_trigger,
1330 .debugfs_reg_access = &inv_mpu6050_reg_access,
1331};
1332
1333/*
1334 * inv_check_and_setup_chip() - check and setup chip.
1335 */
1336static int inv_check_and_setup_chip(struct inv_mpu6050_state *st)
1337{
1338 int result;
1339 unsigned int regval, mask;
1340 int i;
1341
1342 st->hw = &hw_info[st->chip_type];
1343 st->reg = hw_info[st->chip_type].reg;
1344 memcpy(&st->chip_config, hw_info[st->chip_type].config,
1345 sizeof(st->chip_config));
1346 st->data = devm_kzalloc(dev: regmap_get_device(map: st->map), size: st->hw->fifo_size, GFP_KERNEL);
1347 if (st->data == NULL)
1348 return -ENOMEM;
1349
1350 /* check chip self-identification */
1351 result = regmap_read(map: st->map, INV_MPU6050_REG_WHOAMI, val: &regval);
1352 if (result)
1353 return result;
1354 if (regval != st->hw->whoami) {
1355 /* check whoami against all possible values */
1356 for (i = 0; i < INV_NUM_PARTS; ++i) {
1357 if (regval == hw_info[i].whoami) {
1358 dev_warn(regmap_get_device(st->map),
1359 "whoami mismatch got 0x%02x (%s) expected 0x%02x (%s)\n",
1360 regval, hw_info[i].name,
1361 st->hw->whoami, st->hw->name);
1362 break;
1363 }
1364 }
1365 if (i >= INV_NUM_PARTS) {
1366 dev_err(regmap_get_device(st->map),
1367 "invalid whoami 0x%02x expected 0x%02x (%s)\n",
1368 regval, st->hw->whoami, st->hw->name);
1369 return -ENODEV;
1370 }
1371 }
1372
1373 /* reset to make sure previous state are not there */
1374 result = regmap_write(map: st->map, reg: st->reg->pwr_mgmt_1,
1375 INV_MPU6050_BIT_H_RESET);
1376 if (result)
1377 return result;
1378 msleep(INV_MPU6050_POWER_UP_TIME);
1379 switch (st->chip_type) {
1380 case INV_MPU6000:
1381 case INV_MPU6500:
1382 case INV_MPU6515:
1383 case INV_MPU6880:
1384 case INV_MPU9250:
1385 case INV_MPU9255:
1386 /* reset signal path (required for spi connection) */
1387 regval = INV_MPU6050_BIT_TEMP_RST | INV_MPU6050_BIT_ACCEL_RST |
1388 INV_MPU6050_BIT_GYRO_RST;
1389 result = regmap_write(map: st->map, INV_MPU6050_REG_SIGNAL_PATH_RESET,
1390 val: regval);
1391 if (result)
1392 return result;
1393 msleep(INV_MPU6050_POWER_UP_TIME);
1394 break;
1395 default:
1396 break;
1397 }
1398
1399 /*
1400 * Turn power on. After reset, the sleep bit could be on
1401 * or off depending on the OTP settings. Turning power on
1402 * make it in a definite state as well as making the hardware
1403 * state align with the software state
1404 */
1405 result = inv_mpu6050_set_power_itg(st, power_on: true);
1406 if (result)
1407 return result;
1408 mask = INV_MPU6050_SENSOR_ACCL | INV_MPU6050_SENSOR_GYRO |
1409 INV_MPU6050_SENSOR_TEMP | INV_MPU6050_SENSOR_MAGN;
1410 result = inv_mpu6050_switch_engine(st, en: false, mask);
1411 if (result)
1412 goto error_power_off;
1413
1414 return 0;
1415
1416error_power_off:
1417 inv_mpu6050_set_power_itg(st, power_on: false);
1418 return result;
1419}
1420
1421static int inv_mpu_core_enable_regulator_vddio(struct inv_mpu6050_state *st)
1422{
1423 int result;
1424
1425 result = regulator_enable(regulator: st->vddio_supply);
1426 if (result) {
1427 dev_err(regmap_get_device(st->map),
1428 "Failed to enable vddio regulator: %d\n", result);
1429 } else {
1430 /* Give the device a little bit of time to start up. */
1431 usleep_range(min: 3000, max: 5000);
1432 }
1433
1434 return result;
1435}
1436
1437static int inv_mpu_core_disable_regulator_vddio(struct inv_mpu6050_state *st)
1438{
1439 int result;
1440
1441 result = regulator_disable(regulator: st->vddio_supply);
1442 if (result)
1443 dev_err(regmap_get_device(st->map),
1444 "Failed to disable vddio regulator: %d\n", result);
1445
1446 return result;
1447}
1448
1449static void inv_mpu_core_disable_regulator_action(void *_data)
1450{
1451 struct inv_mpu6050_state *st = _data;
1452 int result;
1453
1454 result = regulator_disable(regulator: st->vdd_supply);
1455 if (result)
1456 dev_err(regmap_get_device(st->map),
1457 "Failed to disable vdd regulator: %d\n", result);
1458
1459 inv_mpu_core_disable_regulator_vddio(st);
1460}
1461
1462static void inv_mpu_pm_disable(void *data)
1463{
1464 struct device *dev = data;
1465
1466 pm_runtime_disable(dev);
1467}
1468
1469int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
1470 int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type)
1471{
1472 struct inv_mpu6050_state *st;
1473 struct iio_dev *indio_dev;
1474 struct inv_mpu6050_platform_data *pdata;
1475 struct device *dev = regmap_get_device(map: regmap);
1476 int result;
1477 struct irq_data *desc;
1478 int irq_type;
1479
1480 indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*st));
1481 if (!indio_dev)
1482 return -ENOMEM;
1483
1484 BUILD_BUG_ON(ARRAY_SIZE(hw_info) != INV_NUM_PARTS);
1485 if (chip_type < 0 || chip_type >= INV_NUM_PARTS) {
1486 dev_err(dev, "Bad invensense chip_type=%d name=%s\n",
1487 chip_type, name);
1488 return -ENODEV;
1489 }
1490 st = iio_priv(indio_dev);
1491 mutex_init(&st->lock);
1492 st->chip_type = chip_type;
1493 st->irq = irq;
1494 st->map = regmap;
1495
1496 st->level_shifter = device_property_read_bool(dev,
1497 propname: "invensense,level-shifter");
1498 pdata = dev_get_platdata(dev);
1499 if (!pdata) {
1500 result = iio_read_mount_matrix(dev, matrix: &st->orientation);
1501 if (result) {
1502 dev_err(dev, "Failed to retrieve mounting matrix %d\n",
1503 result);
1504 return result;
1505 }
1506 } else {
1507 st->plat_data = *pdata;
1508 }
1509
1510 if (irq > 0) {
1511 desc = irq_get_irq_data(irq);
1512 if (!desc) {
1513 dev_err(dev, "Could not find IRQ %d\n", irq);
1514 return -EINVAL;
1515 }
1516
1517 irq_type = irqd_get_trigger_type(d: desc);
1518 if (!irq_type)
1519 irq_type = IRQF_TRIGGER_RISING;
1520 } else {
1521 /* Doesn't really matter, use the default */
1522 irq_type = IRQF_TRIGGER_RISING;
1523 }
1524
1525 if (irq_type & IRQF_TRIGGER_RISING) // rising or both-edge
1526 st->irq_mask = INV_MPU6050_ACTIVE_HIGH;
1527 else if (irq_type == IRQF_TRIGGER_FALLING)
1528 st->irq_mask = INV_MPU6050_ACTIVE_LOW;
1529 else if (irq_type == IRQF_TRIGGER_HIGH)
1530 st->irq_mask = INV_MPU6050_ACTIVE_HIGH |
1531 INV_MPU6050_LATCH_INT_EN;
1532 else if (irq_type == IRQF_TRIGGER_LOW)
1533 st->irq_mask = INV_MPU6050_ACTIVE_LOW |
1534 INV_MPU6050_LATCH_INT_EN;
1535 else {
1536 dev_err(dev, "Invalid interrupt type 0x%x specified\n",
1537 irq_type);
1538 return -EINVAL;
1539 }
1540
1541 st->vdd_supply = devm_regulator_get(dev, id: "vdd");
1542 if (IS_ERR(ptr: st->vdd_supply))
1543 return dev_err_probe(dev, err: PTR_ERR(ptr: st->vdd_supply),
1544 fmt: "Failed to get vdd regulator\n");
1545
1546 st->vddio_supply = devm_regulator_get(dev, id: "vddio");
1547 if (IS_ERR(ptr: st->vddio_supply))
1548 return dev_err_probe(dev, err: PTR_ERR(ptr: st->vddio_supply),
1549 fmt: "Failed to get vddio regulator\n");
1550
1551 result = regulator_enable(regulator: st->vdd_supply);
1552 if (result) {
1553 dev_err(dev, "Failed to enable vdd regulator: %d\n", result);
1554 return result;
1555 }
1556 msleep(INV_MPU6050_POWER_UP_TIME);
1557
1558 result = inv_mpu_core_enable_regulator_vddio(st);
1559 if (result) {
1560 regulator_disable(regulator: st->vdd_supply);
1561 return result;
1562 }
1563
1564 result = devm_add_action_or_reset(dev, inv_mpu_core_disable_regulator_action,
1565 st);
1566 if (result) {
1567 dev_err(dev, "Failed to setup regulator cleanup action %d\n",
1568 result);
1569 return result;
1570 }
1571
1572 /* fill magnetometer orientation */
1573 result = inv_mpu_magn_set_orient(st);
1574 if (result)
1575 return result;
1576
1577 /* power is turned on inside check chip type*/
1578 result = inv_check_and_setup_chip(st);
1579 if (result)
1580 return result;
1581
1582 result = inv_mpu6050_init_config(indio_dev);
1583 if (result) {
1584 dev_err(dev, "Could not initialize device.\n");
1585 goto error_power_off;
1586 }
1587
1588 dev_set_drvdata(dev, data: indio_dev);
1589 /* name will be NULL when enumerated via ACPI */
1590 if (name)
1591 indio_dev->name = name;
1592 else
1593 indio_dev->name = dev_name(dev);
1594
1595 /* requires parent device set in indio_dev */
1596 if (inv_mpu_bus_setup) {
1597 result = inv_mpu_bus_setup(indio_dev);
1598 if (result)
1599 goto error_power_off;
1600 }
1601
1602 /* chip init is done, turning on runtime power management */
1603 result = pm_runtime_set_active(dev);
1604 if (result)
1605 goto error_power_off;
1606 pm_runtime_get_noresume(dev);
1607 pm_runtime_enable(dev);
1608 pm_runtime_set_autosuspend_delay(dev, INV_MPU6050_SUSPEND_DELAY_MS);
1609 pm_runtime_use_autosuspend(dev);
1610 pm_runtime_put(dev);
1611 result = devm_add_action_or_reset(dev, inv_mpu_pm_disable, dev);
1612 if (result)
1613 return result;
1614
1615 switch (chip_type) {
1616 case INV_MPU9150:
1617 indio_dev->channels = inv_mpu9150_channels;
1618 indio_dev->num_channels = ARRAY_SIZE(inv_mpu9150_channels);
1619 indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
1620 break;
1621 case INV_MPU9250:
1622 case INV_MPU9255:
1623 indio_dev->channels = inv_mpu9250_channels;
1624 indio_dev->num_channels = ARRAY_SIZE(inv_mpu9250_channels);
1625 indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
1626 break;
1627 case INV_ICM20600:
1628 case INV_ICM20602:
1629 indio_dev->channels = inv_mpu_channels;
1630 indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
1631 indio_dev->available_scan_masks = inv_icm20602_scan_masks;
1632 break;
1633 default:
1634 indio_dev->channels = inv_mpu_channels;
1635 indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
1636 indio_dev->available_scan_masks = inv_mpu_scan_masks;
1637 break;
1638 }
1639 /*
1640 * Use magnetometer inside the chip only if there is no i2c
1641 * auxiliary device in use. Otherwise Going back to 6-axis only.
1642 */
1643 if (st->magn_disabled) {
1644 indio_dev->channels = inv_mpu_channels;
1645 indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
1646 indio_dev->available_scan_masks = inv_mpu_scan_masks;
1647 }
1648
1649 indio_dev->info = &mpu_info;
1650
1651 if (irq > 0) {
1652 /*
1653 * The driver currently only supports buffered capture with its
1654 * own trigger. So no IRQ, no trigger, no buffer
1655 */
1656 result = devm_iio_triggered_buffer_setup(dev, indio_dev,
1657 iio_pollfunc_store_time,
1658 inv_mpu6050_read_fifo,
1659 NULL);
1660 if (result) {
1661 dev_err(dev, "configure buffer fail %d\n", result);
1662 return result;
1663 }
1664
1665 result = inv_mpu6050_probe_trigger(indio_dev, irq_type);
1666 if (result) {
1667 dev_err(dev, "trigger probe fail %d\n", result);
1668 return result;
1669 }
1670 }
1671
1672 result = devm_iio_device_register(dev, indio_dev);
1673 if (result) {
1674 dev_err(dev, "IIO register fail %d\n", result);
1675 return result;
1676 }
1677
1678 return 0;
1679
1680error_power_off:
1681 inv_mpu6050_set_power_itg(st, power_on: false);
1682 return result;
1683}
1684EXPORT_SYMBOL_NS_GPL(inv_mpu_core_probe, IIO_MPU6050);
1685
1686static int inv_mpu_resume(struct device *dev)
1687{
1688 struct iio_dev *indio_dev = dev_get_drvdata(dev);
1689 struct inv_mpu6050_state *st = iio_priv(indio_dev);
1690 int result;
1691
1692 mutex_lock(&st->lock);
1693 result = inv_mpu_core_enable_regulator_vddio(st);
1694 if (result)
1695 goto out_unlock;
1696
1697 result = inv_mpu6050_set_power_itg(st, power_on: true);
1698 if (result)
1699 goto out_unlock;
1700
1701 pm_runtime_disable(dev);
1702 pm_runtime_set_active(dev);
1703 pm_runtime_enable(dev);
1704
1705 result = inv_mpu6050_switch_engine(st, en: true, mask: st->suspended_sensors);
1706 if (result)
1707 goto out_unlock;
1708
1709 if (iio_buffer_enabled(indio_dev))
1710 result = inv_mpu6050_prepare_fifo(st, enable: true);
1711
1712out_unlock:
1713 mutex_unlock(lock: &st->lock);
1714
1715 return result;
1716}
1717
1718static int inv_mpu_suspend(struct device *dev)
1719{
1720 struct iio_dev *indio_dev = dev_get_drvdata(dev);
1721 struct inv_mpu6050_state *st = iio_priv(indio_dev);
1722 int result;
1723
1724 mutex_lock(&st->lock);
1725
1726 st->suspended_sensors = 0;
1727 if (pm_runtime_suspended(dev)) {
1728 result = 0;
1729 goto out_unlock;
1730 }
1731
1732 if (iio_buffer_enabled(indio_dev)) {
1733 result = inv_mpu6050_prepare_fifo(st, enable: false);
1734 if (result)
1735 goto out_unlock;
1736 }
1737
1738 if (st->chip_config.accl_en)
1739 st->suspended_sensors |= INV_MPU6050_SENSOR_ACCL;
1740 if (st->chip_config.gyro_en)
1741 st->suspended_sensors |= INV_MPU6050_SENSOR_GYRO;
1742 if (st->chip_config.temp_en)
1743 st->suspended_sensors |= INV_MPU6050_SENSOR_TEMP;
1744 if (st->chip_config.magn_en)
1745 st->suspended_sensors |= INV_MPU6050_SENSOR_MAGN;
1746 result = inv_mpu6050_switch_engine(st, en: false, mask: st->suspended_sensors);
1747 if (result)
1748 goto out_unlock;
1749
1750 result = inv_mpu6050_set_power_itg(st, power_on: false);
1751 if (result)
1752 goto out_unlock;
1753
1754 inv_mpu_core_disable_regulator_vddio(st);
1755out_unlock:
1756 mutex_unlock(lock: &st->lock);
1757
1758 return result;
1759}
1760
1761static int inv_mpu_runtime_suspend(struct device *dev)
1762{
1763 struct inv_mpu6050_state *st = iio_priv(indio_dev: dev_get_drvdata(dev));
1764 unsigned int sensors;
1765 int ret;
1766
1767 mutex_lock(&st->lock);
1768
1769 sensors = INV_MPU6050_SENSOR_ACCL | INV_MPU6050_SENSOR_GYRO |
1770 INV_MPU6050_SENSOR_TEMP | INV_MPU6050_SENSOR_MAGN;
1771 ret = inv_mpu6050_switch_engine(st, en: false, mask: sensors);
1772 if (ret)
1773 goto out_unlock;
1774
1775 ret = inv_mpu6050_set_power_itg(st, power_on: false);
1776 if (ret)
1777 goto out_unlock;
1778
1779 inv_mpu_core_disable_regulator_vddio(st);
1780
1781out_unlock:
1782 mutex_unlock(lock: &st->lock);
1783 return ret;
1784}
1785
1786static int inv_mpu_runtime_resume(struct device *dev)
1787{
1788 struct inv_mpu6050_state *st = iio_priv(indio_dev: dev_get_drvdata(dev));
1789 int ret;
1790
1791 ret = inv_mpu_core_enable_regulator_vddio(st);
1792 if (ret)
1793 return ret;
1794
1795 return inv_mpu6050_set_power_itg(st, power_on: true);
1796}
1797
1798EXPORT_NS_GPL_DEV_PM_OPS(inv_mpu_pmops, IIO_MPU6050) = {
1799 SYSTEM_SLEEP_PM_OPS(inv_mpu_suspend, inv_mpu_resume)
1800 RUNTIME_PM_OPS(inv_mpu_runtime_suspend, inv_mpu_runtime_resume, NULL)
1801};
1802
1803MODULE_AUTHOR("Invensense Corporation");
1804MODULE_DESCRIPTION("Invensense device MPU6050 driver");
1805MODULE_LICENSE("GPL");
1806MODULE_IMPORT_NS(IIO_INV_SENSORS_TIMESTAMP);
1807

source code of linux/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c