forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
....@@ -1,14 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2012 Invensense, Inc.
3
-*
4
-* This software is licensed under the terms of the GNU General Public
5
-* License version 2, as published by the Free Software Foundation, and
6
-* may be copied, distributed, and modified under those terms.
7
-*
8
-* This program is distributed in the hope that it will be useful,
9
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
-* GNU General Public License for more details.
124 */
135
146 #include <linux/module.h>
....@@ -23,7 +15,11 @@
2315 #include <linux/iio/iio.h>
2416 #include <linux/acpi.h>
2517 #include <linux/platform_device.h>
18
+#include <linux/regulator/consumer.h>
19
+#include <linux/pm.h>
20
+#include <linux/pm_runtime.h>
2621 #include "inv_mpu_iio.h"
22
+#include "inv_mpu_magn.h"
2723
2824 /*
2925 * this is the gyro scale translated from dynamic range plus/minus
....@@ -105,11 +101,35 @@
105101 };
106102
107103 static const struct inv_mpu6050_chip_config chip_config_6050 = {
104
+ .clk = INV_CLK_INTERNAL,
108105 .fsr = INV_MPU6050_FSR_2000DPS,
109106 .lpf = INV_MPU6050_FILTER_20HZ,
110
- .divider = INV_MPU6050_FIFO_RATE_TO_DIVIDER(INV_MPU6050_INIT_FIFO_RATE),
107
+ .divider = INV_MPU6050_FIFO_RATE_TO_DIVIDER(50),
108
+ .gyro_en = true,
109
+ .accl_en = true,
110
+ .temp_en = true,
111
+ .magn_en = false,
111112 .gyro_fifo_enable = false,
112113 .accl_fifo_enable = false,
114
+ .temp_fifo_enable = false,
115
+ .magn_fifo_enable = false,
116
+ .accl_fs = INV_MPU6050_FS_02G,
117
+ .user_ctrl = 0,
118
+};
119
+
120
+static const struct inv_mpu6050_chip_config chip_config_6500 = {
121
+ .clk = INV_CLK_PLL,
122
+ .fsr = INV_MPU6050_FSR_2000DPS,
123
+ .lpf = INV_MPU6050_FILTER_20HZ,
124
+ .divider = INV_MPU6050_FIFO_RATE_TO_DIVIDER(50),
125
+ .gyro_en = true,
126
+ .accl_en = true,
127
+ .temp_en = true,
128
+ .magn_en = false,
129
+ .gyro_fifo_enable = false,
130
+ .accl_fifo_enable = false,
131
+ .temp_fifo_enable = false,
132
+ .magn_fifo_enable = false,
113133 .accl_fs = INV_MPU6050_FS_02G,
114134 .user_ctrl = 0,
115135 };
....@@ -128,7 +148,7 @@
128148 .whoami = INV_MPU6500_WHOAMI_VALUE,
129149 .name = "MPU6500",
130150 .reg = &reg_set_6500,
131
- .config = &chip_config_6050,
151
+ .config = &chip_config_6500,
132152 .fifo_size = 512,
133153 .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
134154 },
....@@ -136,7 +156,7 @@
136156 .whoami = INV_MPU6515_WHOAMI_VALUE,
137157 .name = "MPU6515",
138158 .reg = &reg_set_6500,
139
- .config = &chip_config_6050,
159
+ .config = &chip_config_6500,
140160 .fifo_size = 512,
141161 .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
142162 },
....@@ -160,7 +180,7 @@
160180 .whoami = INV_MPU9250_WHOAMI_VALUE,
161181 .name = "MPU9250",
162182 .reg = &reg_set_6500,
163
- .config = &chip_config_6050,
183
+ .config = &chip_config_6500,
164184 .fifo_size = 512,
165185 .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
166186 },
....@@ -168,7 +188,7 @@
168188 .whoami = INV_MPU9255_WHOAMI_VALUE,
169189 .name = "MPU9255",
170190 .reg = &reg_set_6500,
171
- .config = &chip_config_6050,
191
+ .config = &chip_config_6500,
172192 .fifo_size = 512,
173193 .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE},
174194 },
....@@ -176,106 +196,244 @@
176196 .whoami = INV_ICM20608_WHOAMI_VALUE,
177197 .name = "ICM20608",
178198 .reg = &reg_set_6500,
179
- .config = &chip_config_6050,
199
+ .config = &chip_config_6500,
180200 .fifo_size = 512,
201
+ .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
202
+ },
203
+ {
204
+ .whoami = INV_ICM20609_WHOAMI_VALUE,
205
+ .name = "ICM20609",
206
+ .reg = &reg_set_6500,
207
+ .config = &chip_config_6500,
208
+ .fifo_size = 4 * 1024,
209
+ .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
210
+ },
211
+ {
212
+ .whoami = INV_ICM20689_WHOAMI_VALUE,
213
+ .name = "ICM20689",
214
+ .reg = &reg_set_6500,
215
+ .config = &chip_config_6500,
216
+ .fifo_size = 4 * 1024,
181217 .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
182218 },
183219 {
184220 .whoami = INV_ICM20602_WHOAMI_VALUE,
185221 .name = "ICM20602",
186222 .reg = &reg_set_icm20602,
187
- .config = &chip_config_6050,
223
+ .config = &chip_config_6500,
188224 .fifo_size = 1008,
225
+ .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
226
+ },
227
+ {
228
+ .whoami = INV_ICM20690_WHOAMI_VALUE,
229
+ .name = "ICM20690",
230
+ .reg = &reg_set_6500,
231
+ .config = &chip_config_6500,
232
+ .fifo_size = 1024,
233
+ .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
234
+ },
235
+ {
236
+ .whoami = INV_IAM20680_WHOAMI_VALUE,
237
+ .name = "IAM20680",
238
+ .reg = &reg_set_6500,
239
+ .config = &chip_config_6500,
240
+ .fifo_size = 512,
189241 .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
190242 },
191243 };
192244
193
-int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
245
+static int inv_mpu6050_pwr_mgmt_1_write(struct inv_mpu6050_state *st, bool sleep,
246
+ int clock, int temp_dis)
194247 {
195
- unsigned int d, mgmt_1;
196
- int result;
197
- /*
198
- * switch clock needs to be careful. Only when gyro is on, can
199
- * clock source be switched to gyro. Otherwise, it must be set to
200
- * internal clock
201
- */
202
- if (mask == INV_MPU6050_BIT_PWR_GYRO_STBY) {
203
- result = regmap_read(st->map, st->reg->pwr_mgmt_1, &mgmt_1);
204
- if (result)
205
- return result;
248
+ u8 val;
206249
207
- mgmt_1 &= ~INV_MPU6050_BIT_CLK_MASK;
250
+ if (clock < 0)
251
+ clock = st->chip_config.clk;
252
+ if (temp_dis < 0)
253
+ temp_dis = !st->chip_config.temp_en;
254
+
255
+ val = clock & INV_MPU6050_BIT_CLK_MASK;
256
+ if (temp_dis)
257
+ val |= INV_MPU6050_BIT_TEMP_DIS;
258
+ if (sleep)
259
+ val |= INV_MPU6050_BIT_SLEEP;
260
+
261
+ dev_dbg(regmap_get_device(st->map), "pwr_mgmt_1: 0x%x\n", val);
262
+ return regmap_write(st->map, st->reg->pwr_mgmt_1, val);
263
+}
264
+
265
+static int inv_mpu6050_clock_switch(struct inv_mpu6050_state *st,
266
+ unsigned int clock)
267
+{
268
+ int ret;
269
+
270
+ switch (st->chip_type) {
271
+ case INV_MPU6050:
272
+ case INV_MPU6000:
273
+ case INV_MPU9150:
274
+ /* old chips: switch clock manually */
275
+ ret = inv_mpu6050_pwr_mgmt_1_write(st, false, clock, -1);
276
+ if (ret)
277
+ return ret;
278
+ st->chip_config.clk = clock;
279
+ break;
280
+ default:
281
+ /* automatic clock switching, nothing to do */
282
+ break;
208283 }
209284
210
- if ((mask == INV_MPU6050_BIT_PWR_GYRO_STBY) && (!en)) {
211
- /*
212
- * turning off gyro requires switch to internal clock first.
213
- * Then turn off gyro engine
214
- */
215
- mgmt_1 |= INV_CLK_INTERNAL;
216
- result = regmap_write(st->map, st->reg->pwr_mgmt_1, mgmt_1);
217
- if (result)
218
- return result;
285
+ return 0;
286
+}
287
+
288
+int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en,
289
+ unsigned int mask)
290
+{
291
+ unsigned int sleep;
292
+ u8 pwr_mgmt2, user_ctrl;
293
+ int ret;
294
+
295
+ /* delete useless requests */
296
+ if (mask & INV_MPU6050_SENSOR_ACCL && en == st->chip_config.accl_en)
297
+ mask &= ~INV_MPU6050_SENSOR_ACCL;
298
+ if (mask & INV_MPU6050_SENSOR_GYRO && en == st->chip_config.gyro_en)
299
+ mask &= ~INV_MPU6050_SENSOR_GYRO;
300
+ if (mask & INV_MPU6050_SENSOR_TEMP && en == st->chip_config.temp_en)
301
+ mask &= ~INV_MPU6050_SENSOR_TEMP;
302
+ if (mask & INV_MPU6050_SENSOR_MAGN && en == st->chip_config.magn_en)
303
+ mask &= ~INV_MPU6050_SENSOR_MAGN;
304
+ if (mask == 0)
305
+ return 0;
306
+
307
+ /* turn on/off temperature sensor */
308
+ if (mask & INV_MPU6050_SENSOR_TEMP) {
309
+ ret = inv_mpu6050_pwr_mgmt_1_write(st, false, -1, !en);
310
+ if (ret)
311
+ return ret;
312
+ st->chip_config.temp_en = en;
219313 }
220314
221
- result = regmap_read(st->map, st->reg->pwr_mgmt_2, &d);
222
- if (result)
223
- return result;
224
- if (en)
225
- d &= ~mask;
226
- else
227
- d |= mask;
228
- result = regmap_write(st->map, st->reg->pwr_mgmt_2, d);
229
- if (result)
230
- return result;
315
+ /* update user_crtl for driving magnetometer */
316
+ if (mask & INV_MPU6050_SENSOR_MAGN) {
317
+ user_ctrl = st->chip_config.user_ctrl;
318
+ if (en)
319
+ user_ctrl |= INV_MPU6050_BIT_I2C_MST_EN;
320
+ else
321
+ user_ctrl &= ~INV_MPU6050_BIT_I2C_MST_EN;
322
+ ret = regmap_write(st->map, st->reg->user_ctrl, user_ctrl);
323
+ if (ret)
324
+ return ret;
325
+ st->chip_config.user_ctrl = user_ctrl;
326
+ st->chip_config.magn_en = en;
327
+ }
231328
232
- if (en) {
233
- /* Wait for output to stabilize */
234
- msleep(INV_MPU6050_TEMP_UP_TIME);
235
- if (mask == INV_MPU6050_BIT_PWR_GYRO_STBY) {
236
- /* switch internal clock to PLL */
237
- mgmt_1 |= INV_CLK_PLL;
238
- result = regmap_write(st->map,
239
- st->reg->pwr_mgmt_1, mgmt_1);
240
- if (result)
241
- return result;
329
+ /* manage accel & gyro engines */
330
+ if (mask & (INV_MPU6050_SENSOR_ACCL | INV_MPU6050_SENSOR_GYRO)) {
331
+ /* compute power management 2 current value */
332
+ pwr_mgmt2 = 0;
333
+ if (!st->chip_config.accl_en)
334
+ pwr_mgmt2 |= INV_MPU6050_BIT_PWR_ACCL_STBY;
335
+ if (!st->chip_config.gyro_en)
336
+ pwr_mgmt2 |= INV_MPU6050_BIT_PWR_GYRO_STBY;
337
+
338
+ /* update to new requested value */
339
+ if (mask & INV_MPU6050_SENSOR_ACCL) {
340
+ if (en)
341
+ pwr_mgmt2 &= ~INV_MPU6050_BIT_PWR_ACCL_STBY;
342
+ else
343
+ pwr_mgmt2 |= INV_MPU6050_BIT_PWR_ACCL_STBY;
344
+ }
345
+ if (mask & INV_MPU6050_SENSOR_GYRO) {
346
+ if (en)
347
+ pwr_mgmt2 &= ~INV_MPU6050_BIT_PWR_GYRO_STBY;
348
+ else
349
+ pwr_mgmt2 |= INV_MPU6050_BIT_PWR_GYRO_STBY;
350
+ }
351
+
352
+ /* switch clock to internal when turning gyro off */
353
+ if (mask & INV_MPU6050_SENSOR_GYRO && !en) {
354
+ ret = inv_mpu6050_clock_switch(st, INV_CLK_INTERNAL);
355
+ if (ret)
356
+ return ret;
357
+ }
358
+
359
+ /* update sensors engine */
360
+ dev_dbg(regmap_get_device(st->map), "pwr_mgmt_2: 0x%x\n",
361
+ pwr_mgmt2);
362
+ ret = regmap_write(st->map, st->reg->pwr_mgmt_2, pwr_mgmt2);
363
+ if (ret)
364
+ return ret;
365
+ if (mask & INV_MPU6050_SENSOR_ACCL)
366
+ st->chip_config.accl_en = en;
367
+ if (mask & INV_MPU6050_SENSOR_GYRO)
368
+ st->chip_config.gyro_en = en;
369
+
370
+ /* compute required time to have sensors stabilized */
371
+ sleep = 0;
372
+ if (en) {
373
+ if (mask & INV_MPU6050_SENSOR_ACCL) {
374
+ if (sleep < INV_MPU6050_ACCEL_UP_TIME)
375
+ sleep = INV_MPU6050_ACCEL_UP_TIME;
376
+ }
377
+ if (mask & INV_MPU6050_SENSOR_GYRO) {
378
+ if (sleep < INV_MPU6050_GYRO_UP_TIME)
379
+ sleep = INV_MPU6050_GYRO_UP_TIME;
380
+ }
381
+ } else {
382
+ if (mask & INV_MPU6050_SENSOR_GYRO) {
383
+ if (sleep < INV_MPU6050_GYRO_DOWN_TIME)
384
+ sleep = INV_MPU6050_GYRO_DOWN_TIME;
385
+ }
386
+ }
387
+ if (sleep)
388
+ msleep(sleep);
389
+
390
+ /* switch clock to PLL when turning gyro on */
391
+ if (mask & INV_MPU6050_SENSOR_GYRO && en) {
392
+ ret = inv_mpu6050_clock_switch(st, INV_CLK_PLL);
393
+ if (ret)
394
+ return ret;
242395 }
243396 }
244397
245398 return 0;
246399 }
247400
248
-int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on)
401
+static int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st,
402
+ bool power_on)
249403 {
250404 int result;
251405
252
- if (power_on) {
253
- if (!st->powerup_count) {
254
- result = regmap_write(st->map, st->reg->pwr_mgmt_1, 0);
255
- if (result)
256
- return result;
257
- usleep_range(INV_MPU6050_REG_UP_TIME_MIN,
258
- INV_MPU6050_REG_UP_TIME_MAX);
259
- }
260
- st->powerup_count++;
261
- } else {
262
- if (st->powerup_count == 1) {
263
- result = regmap_write(st->map, st->reg->pwr_mgmt_1,
264
- INV_MPU6050_BIT_SLEEP);
265
- if (result)
266
- return result;
267
- }
268
- st->powerup_count--;
269
- }
406
+ result = inv_mpu6050_pwr_mgmt_1_write(st, !power_on, -1, -1);
407
+ if (result)
408
+ return result;
270409
271
- dev_dbg(regmap_get_device(st->map), "set power %d, count=%u\n",
272
- power_on, st->powerup_count);
410
+ if (power_on)
411
+ usleep_range(INV_MPU6050_REG_UP_TIME_MIN,
412
+ INV_MPU6050_REG_UP_TIME_MAX);
273413
274414 return 0;
275415 }
276
-EXPORT_SYMBOL_GPL(inv_mpu6050_set_power_itg);
277416
278
-/**
417
+static int inv_mpu6050_set_gyro_fsr(struct inv_mpu6050_state *st,
418
+ enum inv_mpu6050_fsr_e val)
419
+{
420
+ unsigned int gyro_shift;
421
+ u8 data;
422
+
423
+ switch (st->chip_type) {
424
+ case INV_ICM20690:
425
+ gyro_shift = INV_ICM20690_GYRO_CONFIG_FSR_SHIFT;
426
+ break;
427
+ default:
428
+ gyro_shift = INV_MPU6050_GYRO_CONFIG_FSR_SHIFT;
429
+ break;
430
+ }
431
+
432
+ data = val << gyro_shift;
433
+ return regmap_write(st->map, st->reg->gyro_config, data);
434
+}
435
+
436
+/*
279437 * inv_mpu6050_set_lpf_regs() - set low pass filter registers, chip dependent
280438 *
281439 * MPU60xx/MPU9150 use only 1 register for accelerometer + gyroscope
....@@ -290,23 +448,26 @@
290448 if (result)
291449 return result;
292450
451
+ /* set accel lpf */
293452 switch (st->chip_type) {
294453 case INV_MPU6050:
295454 case INV_MPU6000:
296455 case INV_MPU9150:
297456 /* old chips, nothing to do */
298
- result = 0;
457
+ return 0;
458
+ case INV_ICM20689:
459
+ case INV_ICM20690:
460
+ /* set FIFO size to maximum value */
461
+ val |= INV_ICM20689_BITS_FIFO_SIZE_MAX;
299462 break;
300463 default:
301
- /* set accel lpf */
302
- result = regmap_write(st->map, st->reg->accel_lpf, val);
303464 break;
304465 }
305466
306
- return result;
467
+ return regmap_write(st->map, st->reg->accel_lpf, val);
307468 }
308469
309
-/**
470
+/*
310471 * inv_mpu6050_init_config() - Initialize hardware, disable FIFO.
311472 *
312473 * Initial configuration:
....@@ -321,34 +482,27 @@
321482 u8 d;
322483 struct inv_mpu6050_state *st = iio_priv(indio_dev);
323484
324
- result = inv_mpu6050_set_power_itg(st, true);
485
+ result = inv_mpu6050_set_gyro_fsr(st, st->chip_config.fsr);
325486 if (result)
326487 return result;
327
- d = (INV_MPU6050_FSR_2000DPS << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
328
- result = regmap_write(st->map, st->reg->gyro_config, d);
329
- if (result)
330
- goto error_power_off;
331488
332
- result = inv_mpu6050_set_lpf_regs(st, INV_MPU6050_FILTER_20HZ);
489
+ result = inv_mpu6050_set_lpf_regs(st, st->chip_config.lpf);
333490 if (result)
334
- goto error_power_off;
491
+ return result;
335492
336
- d = INV_MPU6050_FIFO_RATE_TO_DIVIDER(INV_MPU6050_INIT_FIFO_RATE);
493
+ d = st->chip_config.divider;
337494 result = regmap_write(st->map, st->reg->sample_rate_div, d);
338495 if (result)
339
- goto error_power_off;
496
+ return result;
340497
341
- d = (INV_MPU6050_FS_02G << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
498
+ d = (st->chip_config.accl_fs << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
342499 result = regmap_write(st->map, st->reg->accl_config, d);
343500 if (result)
344
- goto error_power_off;
501
+ return result;
345502
346503 result = regmap_write(st->map, st->reg->int_pin_cfg, st->irq_mask);
347504 if (result)
348505 return result;
349
-
350
- memcpy(&st->chip_config, hw_info[st->chip_type].config,
351
- sizeof(struct inv_mpu6050_chip_config));
352506
353507 /*
354508 * Internal chip period is 1ms (1kHz).
....@@ -357,11 +511,12 @@
357511 */
358512 st->chip_period = NSEC_PER_MSEC;
359513
360
- return inv_mpu6050_set_power_itg(st, false);
514
+ /* magn chip init, noop if not present in the chip */
515
+ result = inv_mpu_magn_probe(st);
516
+ if (result)
517
+ return result;
361518
362
-error_power_off:
363
- inv_mpu6050_set_power_itg(st, false);
364
- return result;
519
+ return 0;
365520 }
366521
367522 static int inv_mpu6050_sensor_set(struct inv_mpu6050_state *st, int reg,
....@@ -371,7 +526,7 @@
371526 __be16 d = cpu_to_be16(val);
372527
373528 ind = (axis - IIO_MOD_X) * 2;
374
- result = regmap_bulk_write(st->map, reg + ind, (u8 *)&d, 2);
529
+ result = regmap_bulk_write(st->map, reg + ind, &d, sizeof(d));
375530 if (result)
376531 return -EINVAL;
377532
....@@ -385,7 +540,7 @@
385540 __be16 d;
386541
387542 ind = (axis - IIO_MOD_X) * 2;
388
- result = regmap_bulk_read(st->map, reg + ind, (u8 *)&d, 2);
543
+ result = regmap_bulk_read(st->map, reg + ind, &d, sizeof(d));
389544 if (result)
390545 return -EINVAL;
391546 *val = (short)be16_to_cpup(&d);
....@@ -398,57 +553,99 @@
398553 int *val)
399554 {
400555 struct inv_mpu6050_state *st = iio_priv(indio_dev);
556
+ struct device *pdev = regmap_get_device(st->map);
557
+ unsigned int freq_hz, period_us, min_sleep_us, max_sleep_us;
401558 int result;
402559 int ret;
403560
404
- result = inv_mpu6050_set_power_itg(st, true);
405
- if (result)
561
+ /* compute sample period */
562
+ freq_hz = INV_MPU6050_DIVIDER_TO_FIFO_RATE(st->chip_config.divider);
563
+ period_us = 1000000 / freq_hz;
564
+
565
+ result = pm_runtime_get_sync(pdev);
566
+ if (result < 0) {
567
+ pm_runtime_put_noidle(pdev);
406568 return result;
569
+ }
407570
408571 switch (chan->type) {
409572 case IIO_ANGL_VEL:
410
- result = inv_mpu6050_switch_engine(st, true,
411
- INV_MPU6050_BIT_PWR_GYRO_STBY);
412
- if (result)
413
- goto error_power_off;
573
+ if (!st->chip_config.gyro_en) {
574
+ result = inv_mpu6050_switch_engine(st, true,
575
+ INV_MPU6050_SENSOR_GYRO);
576
+ if (result)
577
+ goto error_power_off;
578
+ /* need to wait 2 periods to have first valid sample */
579
+ min_sleep_us = 2 * period_us;
580
+ max_sleep_us = 2 * (period_us + period_us / 2);
581
+ usleep_range(min_sleep_us, max_sleep_us);
582
+ }
414583 ret = inv_mpu6050_sensor_show(st, st->reg->raw_gyro,
415584 chan->channel2, val);
416
- result = inv_mpu6050_switch_engine(st, false,
417
- INV_MPU6050_BIT_PWR_GYRO_STBY);
418
- if (result)
419
- goto error_power_off;
420585 break;
421586 case IIO_ACCEL:
422
- result = inv_mpu6050_switch_engine(st, true,
423
- INV_MPU6050_BIT_PWR_ACCL_STBY);
424
- if (result)
425
- goto error_power_off;
587
+ if (!st->chip_config.accl_en) {
588
+ result = inv_mpu6050_switch_engine(st, true,
589
+ INV_MPU6050_SENSOR_ACCL);
590
+ if (result)
591
+ goto error_power_off;
592
+ /* wait 1 period for first sample availability */
593
+ min_sleep_us = period_us;
594
+ max_sleep_us = period_us + period_us / 2;
595
+ usleep_range(min_sleep_us, max_sleep_us);
596
+ }
426597 ret = inv_mpu6050_sensor_show(st, st->reg->raw_accl,
427598 chan->channel2, val);
428
- result = inv_mpu6050_switch_engine(st, false,
429
- INV_MPU6050_BIT_PWR_ACCL_STBY);
430
- if (result)
431
- goto error_power_off;
432599 break;
433600 case IIO_TEMP:
434
- /* wait for stablization */
435
- msleep(INV_MPU6050_SENSOR_UP_TIME);
601
+ /* temperature sensor work only with accel and/or gyro */
602
+ if (!st->chip_config.accl_en && !st->chip_config.gyro_en) {
603
+ result = -EBUSY;
604
+ goto error_power_off;
605
+ }
606
+ if (!st->chip_config.temp_en) {
607
+ result = inv_mpu6050_switch_engine(st, true,
608
+ INV_MPU6050_SENSOR_TEMP);
609
+ if (result)
610
+ goto error_power_off;
611
+ /* wait 1 period for first sample availability */
612
+ min_sleep_us = period_us;
613
+ max_sleep_us = period_us + period_us / 2;
614
+ usleep_range(min_sleep_us, max_sleep_us);
615
+ }
436616 ret = inv_mpu6050_sensor_show(st, st->reg->temperature,
437617 IIO_MOD_X, val);
618
+ break;
619
+ case IIO_MAGN:
620
+ if (!st->chip_config.magn_en) {
621
+ result = inv_mpu6050_switch_engine(st, true,
622
+ INV_MPU6050_SENSOR_MAGN);
623
+ if (result)
624
+ goto error_power_off;
625
+ /* frequency is limited for magnetometer */
626
+ if (freq_hz > INV_MPU_MAGN_FREQ_HZ_MAX) {
627
+ freq_hz = INV_MPU_MAGN_FREQ_HZ_MAX;
628
+ period_us = 1000000 / freq_hz;
629
+ }
630
+ /* need to wait 2 periods to have first valid sample */
631
+ min_sleep_us = 2 * period_us;
632
+ max_sleep_us = 2 * (period_us + period_us / 2);
633
+ usleep_range(min_sleep_us, max_sleep_us);
634
+ }
635
+ ret = inv_mpu_magn_read(st, chan->channel2, val);
438636 break;
439637 default:
440638 ret = -EINVAL;
441639 break;
442640 }
443641
444
- result = inv_mpu6050_set_power_itg(st, false);
445
- if (result)
446
- goto error_power_off;
642
+ pm_runtime_mark_last_busy(pdev);
643
+ pm_runtime_put_autosuspend(pdev);
447644
448645 return ret;
449646
450647 error_power_off:
451
- inv_mpu6050_set_power_itg(st, false);
648
+ pm_runtime_put_autosuspend(pdev);
452649 return result;
453650 }
454651
....@@ -490,6 +687,8 @@
490687 *val = st->hw->temp.scale / 1000000;
491688 *val2 = st->hw->temp.scale % 1000000;
492689 return IIO_VAL_INT_PLUS_MICRO;
690
+ case IIO_MAGN:
691
+ return inv_mpu_magn_get_scale(st, chan, val, val2);
493692 default:
494693 return -EINVAL;
495694 }
....@@ -524,15 +723,17 @@
524723 }
525724 }
526725
527
-static int inv_mpu6050_write_gyro_scale(struct inv_mpu6050_state *st, int val)
726
+static int inv_mpu6050_write_gyro_scale(struct inv_mpu6050_state *st, int val,
727
+ int val2)
528728 {
529729 int result, i;
530
- u8 d;
730
+
731
+ if (val != 0)
732
+ return -EINVAL;
531733
532734 for (i = 0; i < ARRAY_SIZE(gyro_scale_6050); ++i) {
533
- if (gyro_scale_6050[i] == val) {
534
- d = (i << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
535
- result = regmap_write(st->map, st->reg->gyro_config, d);
735
+ if (gyro_scale_6050[i] == val2) {
736
+ result = inv_mpu6050_set_gyro_fsr(st, i);
536737 if (result)
537738 return result;
538739
....@@ -562,13 +763,17 @@
562763 return -EINVAL;
563764 }
564765
565
-static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val)
766
+static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val,
767
+ int val2)
566768 {
567769 int result, i;
568770 u8 d;
569771
772
+ if (val != 0)
773
+ return -EINVAL;
774
+
570775 for (i = 0; i < ARRAY_SIZE(accel_scale); ++i) {
571
- if (accel_scale[i] == val) {
776
+ if (accel_scale[i] == val2) {
572777 d = (i << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
573778 result = regmap_write(st->map, st->reg->accl_config, d);
574779 if (result)
....@@ -587,6 +792,7 @@
587792 int val, int val2, long mask)
588793 {
589794 struct inv_mpu6050_state *st = iio_priv(indio_dev);
795
+ struct device *pdev = regmap_get_device(st->map);
590796 int result;
591797
592798 /*
....@@ -598,18 +804,20 @@
598804 return result;
599805
600806 mutex_lock(&st->lock);
601
- result = inv_mpu6050_set_power_itg(st, true);
602
- if (result)
807
+ result = pm_runtime_get_sync(pdev);
808
+ if (result < 0) {
809
+ pm_runtime_put_noidle(pdev);
603810 goto error_write_raw_unlock;
811
+ }
604812
605813 switch (mask) {
606814 case IIO_CHAN_INFO_SCALE:
607815 switch (chan->type) {
608816 case IIO_ANGL_VEL:
609
- result = inv_mpu6050_write_gyro_scale(st, val2);
817
+ result = inv_mpu6050_write_gyro_scale(st, val, val2);
610818 break;
611819 case IIO_ACCEL:
612
- result = inv_mpu6050_write_accel_scale(st, val2);
820
+ result = inv_mpu6050_write_accel_scale(st, val, val2);
613821 break;
614822 default:
615823 result = -EINVAL;
....@@ -638,7 +846,8 @@
638846 break;
639847 }
640848
641
- result |= inv_mpu6050_set_power_itg(st, false);
849
+ pm_runtime_mark_last_busy(pdev);
850
+ pm_runtime_put_autosuspend(pdev);
642851 error_write_raw_unlock:
643852 mutex_unlock(&st->lock);
644853 iio_device_release_direct_mode(indio_dev);
....@@ -646,33 +855,35 @@
646855 return result;
647856 }
648857
649
-/**
858
+/*
650859 * inv_mpu6050_set_lpf() - set low pass filer based on fifo rate.
651860 *
652
- * Based on the Nyquist principle, the sampling rate must
653
- * exceed twice of the bandwidth of the signal, or there
654
- * would be alising. This function basically search for the
655
- * correct low pass parameters based on the fifo rate, e.g,
656
- * sampling frequency.
861
+ * Based on the Nyquist principle, the bandwidth of the low
862
+ * pass filter must not exceed the signal sampling rate divided
863
+ * by 2, or there would be aliasing.
864
+ * This function basically search for the correct low pass
865
+ * parameters based on the fifo rate, e.g, sampling frequency.
657866 *
658867 * lpf is set automatically when setting sampling rate to avoid any aliases.
659868 */
660869 static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate)
661870 {
662
- static const int hz[] = {188, 98, 42, 20, 10, 5};
871
+ static const int hz[] = {400, 200, 90, 40, 20, 10};
663872 static const int d[] = {
664
- INV_MPU6050_FILTER_188HZ, INV_MPU6050_FILTER_98HZ,
665
- INV_MPU6050_FILTER_42HZ, INV_MPU6050_FILTER_20HZ,
873
+ INV_MPU6050_FILTER_200HZ, INV_MPU6050_FILTER_100HZ,
874
+ INV_MPU6050_FILTER_45HZ, INV_MPU6050_FILTER_20HZ,
666875 INV_MPU6050_FILTER_10HZ, INV_MPU6050_FILTER_5HZ
667876 };
668
- int i, h, result;
877
+ int i, result;
669878 u8 data;
670879
671
- h = (rate >> 1);
672
- i = 0;
673
- while ((h < hz[i]) && (i < ARRAY_SIZE(d) - 1))
674
- i++;
675
- data = d[i];
880
+ data = INV_MPU6050_FILTER_5HZ;
881
+ for (i = 0; i < ARRAY_SIZE(hz); ++i) {
882
+ if (rate >= hz[i]) {
883
+ data = d[i];
884
+ break;
885
+ }
886
+ }
676887 result = inv_mpu6050_set_lpf_regs(st, data);
677888 if (result)
678889 return result;
....@@ -681,7 +892,7 @@
681892 return 0;
682893 }
683894
684
-/**
895
+/*
685896 * inv_mpu6050_fifo_rate_store() - Set fifo rate.
686897 */
687898 static ssize_t
....@@ -693,16 +904,13 @@
693904 int result;
694905 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
695906 struct inv_mpu6050_state *st = iio_priv(indio_dev);
907
+ struct device *pdev = regmap_get_device(st->map);
696908
697909 if (kstrtoint(buf, 10, &fifo_rate))
698910 return -EINVAL;
699911 if (fifo_rate < INV_MPU6050_MIN_FIFO_RATE ||
700912 fifo_rate > INV_MPU6050_MAX_FIFO_RATE)
701913 return -EINVAL;
702
-
703
- result = iio_device_claim_direct_mode(indio_dev);
704
- if (result)
705
- return result;
706914
707915 /* compute the chip sample rate divider */
708916 d = INV_MPU6050_FIFO_RATE_TO_DIVIDER(fifo_rate);
....@@ -714,9 +922,11 @@
714922 result = 0;
715923 goto fifo_rate_fail_unlock;
716924 }
717
- result = inv_mpu6050_set_power_itg(st, true);
718
- if (result)
925
+ result = pm_runtime_get_sync(pdev);
926
+ if (result < 0) {
927
+ pm_runtime_put_noidle(pdev);
719928 goto fifo_rate_fail_unlock;
929
+ }
720930
721931 result = regmap_write(st->map, st->reg->sample_rate_div, d);
722932 if (result)
....@@ -727,18 +937,23 @@
727937 if (result)
728938 goto fifo_rate_fail_power_off;
729939
940
+ /* update rate for magn, noop if not present in chip */
941
+ result = inv_mpu_magn_set_rate(st, fifo_rate);
942
+ if (result)
943
+ goto fifo_rate_fail_power_off;
944
+
945
+ pm_runtime_mark_last_busy(pdev);
730946 fifo_rate_fail_power_off:
731
- result |= inv_mpu6050_set_power_itg(st, false);
947
+ pm_runtime_put_autosuspend(pdev);
732948 fifo_rate_fail_unlock:
733949 mutex_unlock(&st->lock);
734
- iio_device_release_direct_mode(indio_dev);
735950 if (result)
736951 return result;
737952
738953 return count;
739954 }
740955
741
-/**
956
+/*
742957 * inv_fifo_rate_show() - Get the current sampling rate.
743958 */
744959 static ssize_t
....@@ -755,7 +970,7 @@
755970 return scnprintf(buf, PAGE_SIZE, "%u\n", fifo_rate);
756971 }
757972
758
-/**
973
+/*
759974 * inv_attr_show() - calling this function will show current
760975 * parameters.
761976 *
....@@ -811,12 +1026,20 @@
8111026 inv_get_mount_matrix(const struct iio_dev *indio_dev,
8121027 const struct iio_chan_spec *chan)
8131028 {
814
- return &((struct inv_mpu6050_state *)iio_priv(indio_dev))->orientation;
1029
+ struct inv_mpu6050_state *data = iio_priv(indio_dev);
1030
+ const struct iio_mount_matrix *matrix;
1031
+
1032
+ if (chan->type == IIO_MAGN)
1033
+ matrix = &data->magn_orient;
1034
+ else
1035
+ matrix = &data->orientation;
1036
+
1037
+ return matrix;
8151038 }
8161039
8171040 static const struct iio_chan_spec_ext_info inv_ext_info[] = {
8181041 IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, inv_get_mount_matrix),
819
- { },
1042
+ { }
8201043 };
8211044
8221045 #define INV_MPU6050_CHAN(_type, _channel2, _index) \
....@@ -838,19 +1061,27 @@
8381061 .ext_info = inv_ext_info, \
8391062 }
8401063
1064
+#define INV_MPU6050_TEMP_CHAN(_index) \
1065
+ { \
1066
+ .type = IIO_TEMP, \
1067
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \
1068
+ | BIT(IIO_CHAN_INFO_OFFSET) \
1069
+ | BIT(IIO_CHAN_INFO_SCALE), \
1070
+ .scan_index = _index, \
1071
+ .scan_type = { \
1072
+ .sign = 's', \
1073
+ .realbits = 16, \
1074
+ .storagebits = 16, \
1075
+ .shift = 0, \
1076
+ .endianness = IIO_BE, \
1077
+ }, \
1078
+ }
1079
+
8411080 static const struct iio_chan_spec inv_mpu_channels[] = {
8421081 IIO_CHAN_SOFT_TIMESTAMP(INV_MPU6050_SCAN_TIMESTAMP),
843
- /*
844
- * Note that temperature should only be via polled reading only,
845
- * not the final scan elements output.
846
- */
847
- {
848
- .type = IIO_TEMP,
849
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
850
- | BIT(IIO_CHAN_INFO_OFFSET)
851
- | BIT(IIO_CHAN_INFO_SCALE),
852
- .scan_index = -1,
853
- },
1082
+
1083
+ INV_MPU6050_TEMP_CHAN(INV_MPU6050_SCAN_TEMP),
1084
+
8541085 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
8551086 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
8561087 INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
....@@ -860,70 +1091,132 @@
8601091 INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
8611092 };
8621093
1094
+#define INV_MPU6050_SCAN_MASK_3AXIS_ACCEL \
1095
+ (BIT(INV_MPU6050_SCAN_ACCL_X) \
1096
+ | BIT(INV_MPU6050_SCAN_ACCL_Y) \
1097
+ | BIT(INV_MPU6050_SCAN_ACCL_Z))
1098
+
1099
+#define INV_MPU6050_SCAN_MASK_3AXIS_GYRO \
1100
+ (BIT(INV_MPU6050_SCAN_GYRO_X) \
1101
+ | BIT(INV_MPU6050_SCAN_GYRO_Y) \
1102
+ | BIT(INV_MPU6050_SCAN_GYRO_Z))
1103
+
1104
+#define INV_MPU6050_SCAN_MASK_TEMP (BIT(INV_MPU6050_SCAN_TEMP))
1105
+
8631106 static const unsigned long inv_mpu_scan_masks[] = {
8641107 /* 3-axis accel */
865
- BIT(INV_MPU6050_SCAN_ACCL_X)
866
- | BIT(INV_MPU6050_SCAN_ACCL_Y)
867
- | BIT(INV_MPU6050_SCAN_ACCL_Z),
1108
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL,
1109
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_TEMP,
8681110 /* 3-axis gyro */
869
- BIT(INV_MPU6050_SCAN_GYRO_X)
870
- | BIT(INV_MPU6050_SCAN_GYRO_Y)
871
- | BIT(INV_MPU6050_SCAN_GYRO_Z),
1111
+ INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
1112
+ INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU6050_SCAN_MASK_TEMP,
8721113 /* 6-axis accel + gyro */
873
- BIT(INV_MPU6050_SCAN_ACCL_X)
874
- | BIT(INV_MPU6050_SCAN_ACCL_Y)
875
- | BIT(INV_MPU6050_SCAN_ACCL_Z)
876
- | BIT(INV_MPU6050_SCAN_GYRO_X)
877
- | BIT(INV_MPU6050_SCAN_GYRO_Y)
878
- | BIT(INV_MPU6050_SCAN_GYRO_Z),
1114
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
1115
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
1116
+ | INV_MPU6050_SCAN_MASK_TEMP,
8791117 0,
8801118 };
8811119
882
-static const struct iio_chan_spec inv_icm20602_channels[] = {
883
- IIO_CHAN_SOFT_TIMESTAMP(INV_ICM20602_SCAN_TIMESTAMP),
884
- {
885
- .type = IIO_TEMP,
886
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
887
- | BIT(IIO_CHAN_INFO_OFFSET)
888
- | BIT(IIO_CHAN_INFO_SCALE),
889
- .scan_index = INV_ICM20602_SCAN_TEMP,
890
- .scan_type = {
891
- .sign = 's',
892
- .realbits = 16,
893
- .storagebits = 16,
894
- .shift = 0,
895
- .endianness = IIO_BE,
896
- },
897
- },
1120
+#define INV_MPU9X50_MAGN_CHAN(_chan2, _bits, _index) \
1121
+ { \
1122
+ .type = IIO_MAGN, \
1123
+ .modified = 1, \
1124
+ .channel2 = _chan2, \
1125
+ .info_mask_separate = BIT(IIO_CHAN_INFO_SCALE) | \
1126
+ BIT(IIO_CHAN_INFO_RAW), \
1127
+ .scan_index = _index, \
1128
+ .scan_type = { \
1129
+ .sign = 's', \
1130
+ .realbits = _bits, \
1131
+ .storagebits = 16, \
1132
+ .shift = 0, \
1133
+ .endianness = IIO_BE, \
1134
+ }, \
1135
+ .ext_info = inv_ext_info, \
1136
+ }
8981137
899
- INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_ICM20602_SCAN_GYRO_X),
900
- INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_ICM20602_SCAN_GYRO_Y),
901
- INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_ICM20602_SCAN_GYRO_Z),
1138
+static const struct iio_chan_spec inv_mpu9150_channels[] = {
1139
+ IIO_CHAN_SOFT_TIMESTAMP(INV_MPU9X50_SCAN_TIMESTAMP),
9021140
903
- INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_ICM20602_SCAN_ACCL_Y),
904
- INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_ICM20602_SCAN_ACCL_X),
905
- INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_ICM20602_SCAN_ACCL_Z),
1141
+ INV_MPU6050_TEMP_CHAN(INV_MPU6050_SCAN_TEMP),
1142
+
1143
+ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
1144
+ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
1145
+ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
1146
+
1147
+ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
1148
+ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
1149
+ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
1150
+
1151
+ /* Magnetometer resolution is 13 bits */
1152
+ INV_MPU9X50_MAGN_CHAN(IIO_MOD_X, 13, INV_MPU9X50_SCAN_MAGN_X),
1153
+ INV_MPU9X50_MAGN_CHAN(IIO_MOD_Y, 13, INV_MPU9X50_SCAN_MAGN_Y),
1154
+ INV_MPU9X50_MAGN_CHAN(IIO_MOD_Z, 13, INV_MPU9X50_SCAN_MAGN_Z),
1155
+};
1156
+
1157
+static const struct iio_chan_spec inv_mpu9250_channels[] = {
1158
+ IIO_CHAN_SOFT_TIMESTAMP(INV_MPU9X50_SCAN_TIMESTAMP),
1159
+
1160
+ INV_MPU6050_TEMP_CHAN(INV_MPU6050_SCAN_TEMP),
1161
+
1162
+ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
1163
+ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
1164
+ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
1165
+
1166
+ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
1167
+ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
1168
+ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
1169
+
1170
+ /* Magnetometer resolution is 16 bits */
1171
+ INV_MPU9X50_MAGN_CHAN(IIO_MOD_X, 16, INV_MPU9X50_SCAN_MAGN_X),
1172
+ INV_MPU9X50_MAGN_CHAN(IIO_MOD_Y, 16, INV_MPU9X50_SCAN_MAGN_Y),
1173
+ INV_MPU9X50_MAGN_CHAN(IIO_MOD_Z, 16, INV_MPU9X50_SCAN_MAGN_Z),
1174
+};
1175
+
1176
+#define INV_MPU9X50_SCAN_MASK_3AXIS_MAGN \
1177
+ (BIT(INV_MPU9X50_SCAN_MAGN_X) \
1178
+ | BIT(INV_MPU9X50_SCAN_MAGN_Y) \
1179
+ | BIT(INV_MPU9X50_SCAN_MAGN_Z))
1180
+
1181
+static const unsigned long inv_mpu9x50_scan_masks[] = {
1182
+ /* 3-axis accel */
1183
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL,
1184
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_TEMP,
1185
+ /* 3-axis gyro */
1186
+ INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
1187
+ INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU6050_SCAN_MASK_TEMP,
1188
+ /* 3-axis magn */
1189
+ INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
1190
+ INV_MPU9X50_SCAN_MASK_3AXIS_MAGN | INV_MPU6050_SCAN_MASK_TEMP,
1191
+ /* 6-axis accel + gyro */
1192
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO,
1193
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
1194
+ | INV_MPU6050_SCAN_MASK_TEMP,
1195
+ /* 6-axis accel + magn */
1196
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
1197
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN
1198
+ | INV_MPU6050_SCAN_MASK_TEMP,
1199
+ /* 6-axis gyro + magn */
1200
+ INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
1201
+ INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN
1202
+ | INV_MPU6050_SCAN_MASK_TEMP,
1203
+ /* 9-axis accel + gyro + magn */
1204
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
1205
+ | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN,
1206
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
1207
+ | INV_MPU9X50_SCAN_MASK_3AXIS_MAGN
1208
+ | INV_MPU6050_SCAN_MASK_TEMP,
1209
+ 0,
9061210 };
9071211
9081212 static const unsigned long inv_icm20602_scan_masks[] = {
9091213 /* 3-axis accel + temp (mandatory) */
910
- BIT(INV_ICM20602_SCAN_ACCL_X)
911
- | BIT(INV_ICM20602_SCAN_ACCL_Y)
912
- | BIT(INV_ICM20602_SCAN_ACCL_Z)
913
- | BIT(INV_ICM20602_SCAN_TEMP),
1214
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_TEMP,
9141215 /* 3-axis gyro + temp (mandatory) */
915
- BIT(INV_ICM20602_SCAN_GYRO_X)
916
- | BIT(INV_ICM20602_SCAN_GYRO_Y)
917
- | BIT(INV_ICM20602_SCAN_GYRO_Z)
918
- | BIT(INV_ICM20602_SCAN_TEMP),
1216
+ INV_MPU6050_SCAN_MASK_3AXIS_GYRO | INV_MPU6050_SCAN_MASK_TEMP,
9191217 /* 6-axis accel + gyro + temp (mandatory) */
920
- BIT(INV_ICM20602_SCAN_ACCL_X)
921
- | BIT(INV_ICM20602_SCAN_ACCL_Y)
922
- | BIT(INV_ICM20602_SCAN_ACCL_Z)
923
- | BIT(INV_ICM20602_SCAN_GYRO_X)
924
- | BIT(INV_ICM20602_SCAN_GYRO_Y)
925
- | BIT(INV_ICM20602_SCAN_GYRO_Z)
926
- | BIT(INV_ICM20602_SCAN_TEMP),
1218
+ INV_MPU6050_SCAN_MASK_3AXIS_ACCEL | INV_MPU6050_SCAN_MASK_3AXIS_GYRO
1219
+ | INV_MPU6050_SCAN_MASK_TEMP,
9271220 0,
9281221 };
9291222
....@@ -963,25 +1256,46 @@
9631256 .attrs = inv_attributes
9641257 };
9651258
1259
+static int inv_mpu6050_reg_access(struct iio_dev *indio_dev,
1260
+ unsigned int reg,
1261
+ unsigned int writeval,
1262
+ unsigned int *readval)
1263
+{
1264
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
1265
+ int ret;
1266
+
1267
+ mutex_lock(&st->lock);
1268
+ if (readval)
1269
+ ret = regmap_read(st->map, reg, readval);
1270
+ else
1271
+ ret = regmap_write(st->map, reg, writeval);
1272
+ mutex_unlock(&st->lock);
1273
+
1274
+ return ret;
1275
+}
1276
+
9661277 static const struct iio_info mpu_info = {
9671278 .read_raw = &inv_mpu6050_read_raw,
9681279 .write_raw = &inv_mpu6050_write_raw,
9691280 .write_raw_get_fmt = &inv_write_raw_get_fmt,
9701281 .attrs = &inv_attribute_group,
9711282 .validate_trigger = inv_mpu6050_validate_trigger,
1283
+ .debugfs_reg_access = &inv_mpu6050_reg_access,
9721284 };
9731285
974
-/**
1286
+/*
9751287 * inv_check_and_setup_chip() - check and setup chip.
9761288 */
9771289 static int inv_check_and_setup_chip(struct inv_mpu6050_state *st)
9781290 {
9791291 int result;
980
- unsigned int regval;
1292
+ unsigned int regval, mask;
9811293 int i;
9821294
9831295 st->hw = &hw_info[st->chip_type];
9841296 st->reg = hw_info[st->chip_type].reg;
1297
+ memcpy(&st->chip_config, hw_info[st->chip_type].config,
1298
+ sizeof(st->chip_config));
9851299
9861300 /* check chip self-identification */
9871301 result = regmap_read(st->map, INV_MPU6050_REG_WHOAMI, &regval);
....@@ -1013,6 +1327,24 @@
10131327 if (result)
10141328 return result;
10151329 msleep(INV_MPU6050_POWER_UP_TIME);
1330
+ switch (st->chip_type) {
1331
+ case INV_MPU6000:
1332
+ case INV_MPU6500:
1333
+ case INV_MPU6515:
1334
+ case INV_MPU9250:
1335
+ case INV_MPU9255:
1336
+ /* reset signal path (required for spi connection) */
1337
+ regval = INV_MPU6050_BIT_TEMP_RST | INV_MPU6050_BIT_ACCEL_RST |
1338
+ INV_MPU6050_BIT_GYRO_RST;
1339
+ result = regmap_write(st->map, INV_MPU6050_REG_SIGNAL_PATH_RESET,
1340
+ regval);
1341
+ if (result)
1342
+ return result;
1343
+ msleep(INV_MPU6050_POWER_UP_TIME);
1344
+ break;
1345
+ default:
1346
+ break;
1347
+ }
10161348
10171349 /*
10181350 * Turn power on. After reset, the sleep bit could be on
....@@ -1023,21 +1355,66 @@
10231355 result = inv_mpu6050_set_power_itg(st, true);
10241356 if (result)
10251357 return result;
1026
-
1027
- result = inv_mpu6050_switch_engine(st, false,
1028
- INV_MPU6050_BIT_PWR_ACCL_STBY);
1029
- if (result)
1030
- goto error_power_off;
1031
- result = inv_mpu6050_switch_engine(st, false,
1032
- INV_MPU6050_BIT_PWR_GYRO_STBY);
1358
+ mask = INV_MPU6050_SENSOR_ACCL | INV_MPU6050_SENSOR_GYRO |
1359
+ INV_MPU6050_SENSOR_TEMP | INV_MPU6050_SENSOR_MAGN;
1360
+ result = inv_mpu6050_switch_engine(st, false, mask);
10331361 if (result)
10341362 goto error_power_off;
10351363
1036
- return inv_mpu6050_set_power_itg(st, false);
1364
+ return 0;
10371365
10381366 error_power_off:
10391367 inv_mpu6050_set_power_itg(st, false);
10401368 return result;
1369
+}
1370
+
1371
+static int inv_mpu_core_enable_regulator_vddio(struct inv_mpu6050_state *st)
1372
+{
1373
+ int result;
1374
+
1375
+ result = regulator_enable(st->vddio_supply);
1376
+ if (result) {
1377
+ dev_err(regmap_get_device(st->map),
1378
+ "Failed to enable vddio regulator: %d\n", result);
1379
+ } else {
1380
+ /* Give the device a little bit of time to start up. */
1381
+ usleep_range(3000, 5000);
1382
+ }
1383
+
1384
+ return result;
1385
+}
1386
+
1387
+static int inv_mpu_core_disable_regulator_vddio(struct inv_mpu6050_state *st)
1388
+{
1389
+ int result;
1390
+
1391
+ result = regulator_disable(st->vddio_supply);
1392
+ if (result)
1393
+ dev_err(regmap_get_device(st->map),
1394
+ "Failed to disable vddio regulator: %d\n", result);
1395
+
1396
+ return result;
1397
+}
1398
+
1399
+static void inv_mpu_core_disable_regulator_action(void *_data)
1400
+{
1401
+ struct inv_mpu6050_state *st = _data;
1402
+ int result;
1403
+
1404
+ result = regulator_disable(st->vdd_supply);
1405
+ if (result)
1406
+ dev_err(regmap_get_device(st->map),
1407
+ "Failed to disable vdd regulator: %d\n", result);
1408
+
1409
+ inv_mpu_core_disable_regulator_vddio(st);
1410
+}
1411
+
1412
+static void inv_mpu_pm_disable(void *data)
1413
+{
1414
+ struct device *dev = data;
1415
+
1416
+ pm_runtime_put_sync_suspend(dev);
1417
+ pm_runtime_disable(dev);
10411418 }
10421419
10431420 int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
....@@ -1064,14 +1441,13 @@
10641441 st = iio_priv(indio_dev);
10651442 mutex_init(&st->lock);
10661443 st->chip_type = chip_type;
1067
- st->powerup_count = 0;
10681444 st->irq = irq;
10691445 st->map = regmap;
10701446
10711447 pdata = dev_get_platdata(dev);
10721448 if (!pdata) {
1073
- result = of_iio_read_mount_matrix(dev, "mount-matrix",
1074
- &st->orientation);
1449
+ result = iio_read_mount_matrix(dev, "mount-matrix",
1450
+ &st->orientation);
10751451 if (result) {
10761452 dev_err(dev, "Failed to retrieve mounting matrix %d\n",
10771453 result);
....@@ -1090,7 +1466,7 @@
10901466 irq_type = irqd_get_trigger_type(desc);
10911467 if (!irq_type)
10921468 irq_type = IRQF_TRIGGER_RISING;
1093
- if (irq_type == IRQF_TRIGGER_RISING)
1469
+ if (irq_type & IRQF_TRIGGER_RISING) // rising or both-edge
10941470 st->irq_mask = INV_MPU6050_ACTIVE_HIGH;
10951471 else if (irq_type == IRQF_TRIGGER_FALLING)
10961472 st->irq_mask = INV_MPU6050_ACTIVE_LOW;
....@@ -1106,6 +1482,42 @@
11061482 return -EINVAL;
11071483 }
11081484
1485
+ st->vdd_supply = devm_regulator_get(dev, "vdd");
1486
+ if (IS_ERR(st->vdd_supply))
1487
+ return dev_err_probe(dev, PTR_ERR(st->vdd_supply),
1488
+ "Failed to get vdd regulator\n");
1489
+
1490
+ st->vddio_supply = devm_regulator_get(dev, "vddio");
1491
+ if (IS_ERR(st->vddio_supply))
1492
+ return dev_err_probe(dev, PTR_ERR(st->vddio_supply),
1493
+ "Failed to get vddio regulator\n");
1494
+
1495
+ result = regulator_enable(st->vdd_supply);
1496
+ if (result) {
1497
+ dev_err(dev, "Failed to enable vdd regulator: %d\n", result);
1498
+ return result;
1499
+ }
1500
+ msleep(INV_MPU6050_POWER_UP_TIME);
1501
+
1502
+ result = inv_mpu_core_enable_regulator_vddio(st);
1503
+ if (result) {
1504
+ regulator_disable(st->vdd_supply);
1505
+ return result;
1506
+ }
1507
+
1508
+ result = devm_add_action_or_reset(dev, inv_mpu_core_disable_regulator_action,
1509
+ st);
1510
+ if (result) {
1511
+ dev_err(dev, "Failed to setup regulator cleanup action %d\n",
1512
+ result);
1513
+ return result;
1514
+ }
1515
+
1516
+ /* fill magnetometer orientation */
1517
+ result = inv_mpu_magn_set_orient(st);
1518
+ if (result)
1519
+ return result;
1520
+
11091521 /* power is turned on inside check chip type*/
11101522 result = inv_check_and_setup_chip(st);
11111523 if (result)
....@@ -1114,25 +1526,64 @@
11141526 result = inv_mpu6050_init_config(indio_dev);
11151527 if (result) {
11161528 dev_err(dev, "Could not initialize device.\n");
1117
- return result;
1529
+ goto error_power_off;
11181530 }
11191531
1120
- if (inv_mpu_bus_setup)
1121
- inv_mpu_bus_setup(indio_dev);
1122
-
11231532 dev_set_drvdata(dev, indio_dev);
1124
- indio_dev->dev.parent = dev;
11251533 /* name will be NULL when enumerated via ACPI */
11261534 if (name)
11271535 indio_dev->name = name;
11281536 else
11291537 indio_dev->name = dev_name(dev);
11301538
1131
- if (chip_type == INV_ICM20602) {
1132
- indio_dev->channels = inv_icm20602_channels;
1133
- indio_dev->num_channels = ARRAY_SIZE(inv_icm20602_channels);
1539
+ /* requires parent device set in indio_dev */
1540
+ if (inv_mpu_bus_setup) {
1541
+ result = inv_mpu_bus_setup(indio_dev);
1542
+ if (result)
1543
+ goto error_power_off;
1544
+ }
1545
+
1546
+ /* chip init is done, turning on runtime power management */
1547
+ result = pm_runtime_set_active(dev);
1548
+ if (result)
1549
+ goto error_power_off;
1550
+ pm_runtime_get_noresume(dev);
1551
+ pm_runtime_enable(dev);
1552
+ pm_runtime_set_autosuspend_delay(dev, INV_MPU6050_SUSPEND_DELAY_MS);
1553
+ pm_runtime_use_autosuspend(dev);
1554
+ pm_runtime_put(dev);
1555
+ result = devm_add_action_or_reset(dev, inv_mpu_pm_disable, dev);
1556
+ if (result)
1557
+ return result;
1558
+
1559
+ switch (chip_type) {
1560
+ case INV_MPU9150:
1561
+ indio_dev->channels = inv_mpu9150_channels;
1562
+ indio_dev->num_channels = ARRAY_SIZE(inv_mpu9150_channels);
1563
+ indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
1564
+ break;
1565
+ case INV_MPU9250:
1566
+ case INV_MPU9255:
1567
+ indio_dev->channels = inv_mpu9250_channels;
1568
+ indio_dev->num_channels = ARRAY_SIZE(inv_mpu9250_channels);
1569
+ indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
1570
+ break;
1571
+ case INV_ICM20602:
1572
+ indio_dev->channels = inv_mpu_channels;
1573
+ indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
11341574 indio_dev->available_scan_masks = inv_icm20602_scan_masks;
1135
- } else {
1575
+ break;
1576
+ default:
1577
+ indio_dev->channels = inv_mpu_channels;
1578
+ indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
1579
+ indio_dev->available_scan_masks = inv_mpu_scan_masks;
1580
+ break;
1581
+ }
1582
+ /*
1583
+ * Use magnetometer inside the chip only if there is no i2c
1584
+ * auxiliary device in use. Otherwise Going back to 6-axis only.
1585
+ */
1586
+ if (st->magn_disabled) {
11361587 indio_dev->channels = inv_mpu_channels;
11371588 indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
11381589 indio_dev->available_scan_masks = inv_mpu_scan_masks;
....@@ -1162,37 +1613,129 @@
11621613 }
11631614
11641615 return 0;
1616
+
1617
+error_power_off:
1618
+ inv_mpu6050_set_power_itg(st, false);
1619
+ return result;
11651620 }
11661621 EXPORT_SYMBOL_GPL(inv_mpu_core_probe);
11671622
1168
-#ifdef CONFIG_PM_SLEEP
1169
-
1170
-static int inv_mpu_resume(struct device *dev)
1623
+static int __maybe_unused inv_mpu_resume(struct device *dev)
11711624 {
1172
- struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(dev));
1625
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
1626
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
11731627 int result;
11741628
11751629 mutex_lock(&st->lock);
1630
+ result = inv_mpu_core_enable_regulator_vddio(st);
1631
+ if (result)
1632
+ goto out_unlock;
1633
+
11761634 result = inv_mpu6050_set_power_itg(st, true);
1635
+ if (result)
1636
+ goto out_unlock;
1637
+
1638
+ pm_runtime_disable(dev);
1639
+ pm_runtime_set_active(dev);
1640
+ pm_runtime_enable(dev);
1641
+
1642
+ result = inv_mpu6050_switch_engine(st, true, st->suspended_sensors);
1643
+ if (result)
1644
+ goto out_unlock;
1645
+
1646
+ if (iio_buffer_enabled(indio_dev))
1647
+ result = inv_mpu6050_prepare_fifo(st, true);
1648
+
1649
+out_unlock:
11771650 mutex_unlock(&st->lock);
11781651
11791652 return result;
11801653 }
11811654
1182
-static int inv_mpu_suspend(struct device *dev)
1655
+static int __maybe_unused inv_mpu_suspend(struct device *dev)
11831656 {
1184
- struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(dev));
1657
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
1658
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
11851659 int result;
11861660
11871661 mutex_lock(&st->lock);
1662
+
1663
+ st->suspended_sensors = 0;
1664
+ if (pm_runtime_suspended(dev)) {
1665
+ result = 0;
1666
+ goto out_unlock;
1667
+ }
1668
+
1669
+ if (iio_buffer_enabled(indio_dev)) {
1670
+ result = inv_mpu6050_prepare_fifo(st, false);
1671
+ if (result)
1672
+ goto out_unlock;
1673
+ }
1674
+
1675
+ if (st->chip_config.accl_en)
1676
+ st->suspended_sensors |= INV_MPU6050_SENSOR_ACCL;
1677
+ if (st->chip_config.gyro_en)
1678
+ st->suspended_sensors |= INV_MPU6050_SENSOR_GYRO;
1679
+ if (st->chip_config.temp_en)
1680
+ st->suspended_sensors |= INV_MPU6050_SENSOR_TEMP;
1681
+ if (st->chip_config.magn_en)
1682
+ st->suspended_sensors |= INV_MPU6050_SENSOR_MAGN;
1683
+ result = inv_mpu6050_switch_engine(st, false, st->suspended_sensors);
1684
+ if (result)
1685
+ goto out_unlock;
1686
+
11881687 result = inv_mpu6050_set_power_itg(st, false);
1688
+ if (result)
1689
+ goto out_unlock;
1690
+
1691
+ inv_mpu_core_disable_regulator_vddio(st);
1692
+out_unlock:
11891693 mutex_unlock(&st->lock);
11901694
11911695 return result;
11921696 }
1193
-#endif /* CONFIG_PM_SLEEP */
11941697
1195
-SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume);
1698
+static int __maybe_unused inv_mpu_runtime_suspend(struct device *dev)
1699
+{
1700
+ struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(dev));
1701
+ unsigned int sensors;
1702
+ int ret;
1703
+
1704
+ mutex_lock(&st->lock);
1705
+
1706
+ sensors = INV_MPU6050_SENSOR_ACCL | INV_MPU6050_SENSOR_GYRO |
1707
+ INV_MPU6050_SENSOR_TEMP | INV_MPU6050_SENSOR_MAGN;
1708
+ ret = inv_mpu6050_switch_engine(st, false, sensors);
1709
+ if (ret)
1710
+ goto out_unlock;
1711
+
1712
+ ret = inv_mpu6050_set_power_itg(st, false);
1713
+ if (ret)
1714
+ goto out_unlock;
1715
+
1716
+ inv_mpu_core_disable_regulator_vddio(st);
1717
+
1718
+out_unlock:
1719
+ mutex_unlock(&st->lock);
1720
+ return ret;
1721
+}
1722
+
1723
+static int __maybe_unused inv_mpu_runtime_resume(struct device *dev)
1724
+{
1725
+ struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(dev));
1726
+ int ret;
1727
+
1728
+ ret = inv_mpu_core_enable_regulator_vddio(st);
1729
+ if (ret)
1730
+ return ret;
1731
+
1732
+ return inv_mpu6050_set_power_itg(st, true);
1733
+}
1734
+
1735
+const struct dev_pm_ops inv_mpu_pmops = {
1736
+ SET_SYSTEM_SLEEP_PM_OPS(inv_mpu_suspend, inv_mpu_resume)
1737
+ SET_RUNTIME_PM_OPS(inv_mpu_runtime_suspend, inv_mpu_runtime_resume, NULL)
1738
+};
11961739 EXPORT_SYMBOL_GPL(inv_mpu_pmops);
11971740
11981741 MODULE_AUTHOR("Invensense Corporation");