1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2020 Invensense, Inc.
4 */
5
6 #include <linux/kernel.h>
7 #include <linux/device.h>
8 #include <linux/module.h>
9 #include <linux/slab.h>
10 #include <linux/delay.h>
11 #include <linux/mutex.h>
12 #include <linux/interrupt.h>
13 #include <linux/irq.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/property.h>
17 #include <linux/regmap.h>
18
19 #include <linux/iio/iio.h>
20
21 #include "inv_icm42600.h"
22 #include "inv_icm42600_buffer.h"
23
24 static const struct regmap_range_cfg inv_icm42600_regmap_ranges[] = {
25 {
26 .name = "user banks",
27 .range_min = 0x0000,
28 .range_max = 0x4FFF,
29 .selector_reg = INV_ICM42600_REG_BANK_SEL,
30 .selector_mask = INV_ICM42600_BANK_SEL_MASK,
31 .selector_shift = 0,
32 .window_start = 0,
33 .window_len = 0x1000,
34 },
35 };
36
37 static const struct regmap_range inv_icm42600_regmap_volatile_yes_ranges[] = {
38 /* Sensor data registers */
39 regmap_reg_range(0x001D, 0x002A),
40 /* INT status, FIFO, APEX data */
41 regmap_reg_range(0x002D, 0x0038),
42 /* Signal path reset */
43 regmap_reg_range(0x004B, 0x004B),
44 /* FIFO lost packets */
45 regmap_reg_range(0x006C, 0x006D),
46 /* Timestamp value */
47 regmap_reg_range(0x1062, 0x1064),
48 };
49
50 static const struct regmap_range inv_icm42600_regmap_volatile_no_ranges[] = {
51 regmap_reg_range(0x0000, 0x001C),
52 regmap_reg_range(0x006E, 0x1061),
53 regmap_reg_range(0x1065, 0x4FFF),
54 };
55
56 static const struct regmap_access_table inv_icm42600_regmap_volatile_accesses[] = {
57 {
58 .yes_ranges = inv_icm42600_regmap_volatile_yes_ranges,
59 .n_yes_ranges = ARRAY_SIZE(inv_icm42600_regmap_volatile_yes_ranges),
60 .no_ranges = inv_icm42600_regmap_volatile_no_ranges,
61 .n_no_ranges = ARRAY_SIZE(inv_icm42600_regmap_volatile_no_ranges),
62 },
63 };
64
65 static const struct regmap_range inv_icm42600_regmap_rd_noinc_no_ranges[] = {
66 regmap_reg_range(0x0000, INV_ICM42600_REG_FIFO_DATA - 1),
67 regmap_reg_range(INV_ICM42600_REG_FIFO_DATA + 1, 0x4FFF),
68 };
69
70 static const struct regmap_access_table inv_icm42600_regmap_rd_noinc_accesses[] = {
71 {
72 .no_ranges = inv_icm42600_regmap_rd_noinc_no_ranges,
73 .n_no_ranges = ARRAY_SIZE(inv_icm42600_regmap_rd_noinc_no_ranges),
74 },
75 };
76
77 const struct regmap_config inv_icm42600_regmap_config = {
78 .name = "inv_icm42600",
79 .reg_bits = 8,
80 .val_bits = 8,
81 .max_register = 0x4FFF,
82 .ranges = inv_icm42600_regmap_ranges,
83 .num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges),
84 .volatile_table = inv_icm42600_regmap_volatile_accesses,
85 .rd_noinc_table = inv_icm42600_regmap_rd_noinc_accesses,
86 .cache_type = REGCACHE_RBTREE,
87 };
88 EXPORT_SYMBOL_NS_GPL(inv_icm42600_regmap_config, IIO_ICM42600);
89
90 struct inv_icm42600_hw {
91 uint8_t whoami;
92 const char *name;
93 const struct inv_icm42600_conf *conf;
94 };
95
96 /* chip initial default configuration */
97 static const struct inv_icm42600_conf inv_icm42600_default_conf = {
98 .gyro = {
99 .mode = INV_ICM42600_SENSOR_MODE_OFF,
100 .fs = INV_ICM42600_GYRO_FS_2000DPS,
101 .odr = INV_ICM42600_ODR_50HZ,
102 .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
103 },
104 .accel = {
105 .mode = INV_ICM42600_SENSOR_MODE_OFF,
106 .fs = INV_ICM42600_ACCEL_FS_16G,
107 .odr = INV_ICM42600_ODR_50HZ,
108 .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
109 },
110 .temp_en = false,
111 };
112
113 static const struct inv_icm42600_conf inv_icm42686_default_conf = {
114 .gyro = {
115 .mode = INV_ICM42600_SENSOR_MODE_OFF,
116 .fs = INV_ICM42686_GYRO_FS_4000DPS,
117 .odr = INV_ICM42600_ODR_50HZ,
118 .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
119 },
120 .accel = {
121 .mode = INV_ICM42600_SENSOR_MODE_OFF,
122 .fs = INV_ICM42686_ACCEL_FS_32G,
123 .odr = INV_ICM42600_ODR_50HZ,
124 .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
125 },
126 .temp_en = false,
127 };
128
129 static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = {
130 [INV_CHIP_ICM42600] = {
131 .whoami = INV_ICM42600_WHOAMI_ICM42600,
132 .name = "icm42600",
133 .conf = &inv_icm42600_default_conf,
134 },
135 [INV_CHIP_ICM42602] = {
136 .whoami = INV_ICM42600_WHOAMI_ICM42602,
137 .name = "icm42602",
138 .conf = &inv_icm42600_default_conf,
139 },
140 [INV_CHIP_ICM42605] = {
141 .whoami = INV_ICM42600_WHOAMI_ICM42605,
142 .name = "icm42605",
143 .conf = &inv_icm42600_default_conf,
144 },
145 [INV_CHIP_ICM42686] = {
146 .whoami = INV_ICM42600_WHOAMI_ICM42686,
147 .name = "icm42686",
148 .conf = &inv_icm42686_default_conf,
149 },
150 [INV_CHIP_ICM42622] = {
151 .whoami = INV_ICM42600_WHOAMI_ICM42622,
152 .name = "icm42622",
153 .conf = &inv_icm42600_default_conf,
154 },
155 [INV_CHIP_ICM42688] = {
156 .whoami = INV_ICM42600_WHOAMI_ICM42688,
157 .name = "icm42688",
158 .conf = &inv_icm42600_default_conf,
159 },
160 [INV_CHIP_ICM42631] = {
161 .whoami = INV_ICM42600_WHOAMI_ICM42631,
162 .name = "icm42631",
163 .conf = &inv_icm42600_default_conf,
164 },
165 };
166
167 const struct iio_mount_matrix *
inv_icm42600_get_mount_matrix(const struct iio_dev * indio_dev,const struct iio_chan_spec * chan)168 inv_icm42600_get_mount_matrix(const struct iio_dev *indio_dev,
169 const struct iio_chan_spec *chan)
170 {
171 const struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
172
173 return &st->orientation;
174 }
175
inv_icm42600_odr_to_period(enum inv_icm42600_odr odr)176 uint32_t inv_icm42600_odr_to_period(enum inv_icm42600_odr odr)
177 {
178 static uint32_t odr_periods[INV_ICM42600_ODR_NB] = {
179 /* reserved values */
180 0, 0, 0,
181 /* 8kHz */
182 125000,
183 /* 4kHz */
184 250000,
185 /* 2kHz */
186 500000,
187 /* 1kHz */
188 1000000,
189 /* 200Hz */
190 5000000,
191 /* 100Hz */
192 10000000,
193 /* 50Hz */
194 20000000,
195 /* 25Hz */
196 40000000,
197 /* 12.5Hz */
198 80000000,
199 /* 6.25Hz */
200 160000000,
201 /* 3.125Hz */
202 320000000,
203 /* 1.5625Hz */
204 640000000,
205 /* 500Hz */
206 2000000,
207 };
208
209 return odr_periods[odr];
210 }
211
inv_icm42600_set_pwr_mgmt0(struct inv_icm42600_state * st,enum inv_icm42600_sensor_mode gyro,enum inv_icm42600_sensor_mode accel,bool temp,unsigned int * sleep_ms)212 static int inv_icm42600_set_pwr_mgmt0(struct inv_icm42600_state *st,
213 enum inv_icm42600_sensor_mode gyro,
214 enum inv_icm42600_sensor_mode accel,
215 bool temp, unsigned int *sleep_ms)
216 {
217 enum inv_icm42600_sensor_mode oldgyro = st->conf.gyro.mode;
218 enum inv_icm42600_sensor_mode oldaccel = st->conf.accel.mode;
219 bool oldtemp = st->conf.temp_en;
220 unsigned int sleepval;
221 unsigned int val;
222 int ret;
223
224 /* if nothing changed, exit */
225 if (gyro == oldgyro && accel == oldaccel && temp == oldtemp)
226 return 0;
227
228 val = INV_ICM42600_PWR_MGMT0_GYRO(gyro) |
229 INV_ICM42600_PWR_MGMT0_ACCEL(accel);
230 if (!temp)
231 val |= INV_ICM42600_PWR_MGMT0_TEMP_DIS;
232 ret = regmap_write(st->map, INV_ICM42600_REG_PWR_MGMT0, val);
233 if (ret)
234 return ret;
235
236 st->conf.gyro.mode = gyro;
237 st->conf.accel.mode = accel;
238 st->conf.temp_en = temp;
239
240 /* compute required wait time for sensors to stabilize */
241 sleepval = 0;
242 /* temperature stabilization time */
243 if (temp && !oldtemp) {
244 if (sleepval < INV_ICM42600_TEMP_STARTUP_TIME_MS)
245 sleepval = INV_ICM42600_TEMP_STARTUP_TIME_MS;
246 }
247 /* accel startup time */
248 if (accel != oldaccel && oldaccel == INV_ICM42600_SENSOR_MODE_OFF) {
249 /* block any register write for at least 200 µs */
250 usleep_range(200, 300);
251 if (sleepval < INV_ICM42600_ACCEL_STARTUP_TIME_MS)
252 sleepval = INV_ICM42600_ACCEL_STARTUP_TIME_MS;
253 }
254 if (gyro != oldgyro) {
255 /* gyro startup time */
256 if (oldgyro == INV_ICM42600_SENSOR_MODE_OFF) {
257 /* block any register write for at least 200 µs */
258 usleep_range(200, 300);
259 if (sleepval < INV_ICM42600_GYRO_STARTUP_TIME_MS)
260 sleepval = INV_ICM42600_GYRO_STARTUP_TIME_MS;
261 /* gyro stop time */
262 } else if (gyro == INV_ICM42600_SENSOR_MODE_OFF) {
263 if (sleepval < INV_ICM42600_GYRO_STOP_TIME_MS)
264 sleepval = INV_ICM42600_GYRO_STOP_TIME_MS;
265 }
266 }
267
268 /* deferred sleep value if sleep pointer is provided or direct sleep */
269 if (sleep_ms)
270 *sleep_ms = sleepval;
271 else if (sleepval)
272 msleep(sleepval);
273
274 return 0;
275 }
276
inv_icm42600_set_accel_conf(struct inv_icm42600_state * st,struct inv_icm42600_sensor_conf * conf,unsigned int * sleep_ms)277 int inv_icm42600_set_accel_conf(struct inv_icm42600_state *st,
278 struct inv_icm42600_sensor_conf *conf,
279 unsigned int *sleep_ms)
280 {
281 struct inv_icm42600_sensor_conf *oldconf = &st->conf.accel;
282 unsigned int val;
283 int ret;
284
285 /* Sanitize missing values with current values */
286 if (conf->mode < 0)
287 conf->mode = oldconf->mode;
288 if (conf->fs < 0)
289 conf->fs = oldconf->fs;
290 if (conf->odr < 0)
291 conf->odr = oldconf->odr;
292 if (conf->filter < 0)
293 conf->filter = oldconf->filter;
294
295 /* force power mode against ODR when sensor is on */
296 switch (conf->mode) {
297 case INV_ICM42600_SENSOR_MODE_LOW_POWER:
298 case INV_ICM42600_SENSOR_MODE_LOW_NOISE:
299 if (conf->odr <= INV_ICM42600_ODR_1KHZ_LN) {
300 conf->mode = INV_ICM42600_SENSOR_MODE_LOW_NOISE;
301 conf->filter = INV_ICM42600_FILTER_BW_ODR_DIV_2;
302 } else if (conf->odr >= INV_ICM42600_ODR_6_25HZ_LP &&
303 conf->odr <= INV_ICM42600_ODR_1_5625HZ_LP) {
304 conf->mode = INV_ICM42600_SENSOR_MODE_LOW_POWER;
305 conf->filter = INV_ICM42600_FILTER_AVG_16X;
306 }
307 break;
308 default:
309 break;
310 }
311
312 /* set ACCEL_CONFIG0 register (accel fullscale & odr) */
313 if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
314 val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->fs) |
315 INV_ICM42600_ACCEL_CONFIG0_ODR(conf->odr);
316 ret = regmap_write(st->map, INV_ICM42600_REG_ACCEL_CONFIG0, val);
317 if (ret)
318 return ret;
319 oldconf->fs = conf->fs;
320 oldconf->odr = conf->odr;
321 }
322
323 /* set GYRO_ACCEL_CONFIG0 register (accel filter) */
324 if (conf->filter != oldconf->filter) {
325 val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(conf->filter) |
326 INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(st->conf.gyro.filter);
327 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val);
328 if (ret)
329 return ret;
330 oldconf->filter = conf->filter;
331 }
332
333 /* set PWR_MGMT0 register (accel sensor mode) */
334 return inv_icm42600_set_pwr_mgmt0(st, st->conf.gyro.mode, conf->mode,
335 st->conf.temp_en, sleep_ms);
336 }
337
inv_icm42600_set_gyro_conf(struct inv_icm42600_state * st,struct inv_icm42600_sensor_conf * conf,unsigned int * sleep_ms)338 int inv_icm42600_set_gyro_conf(struct inv_icm42600_state *st,
339 struct inv_icm42600_sensor_conf *conf,
340 unsigned int *sleep_ms)
341 {
342 struct inv_icm42600_sensor_conf *oldconf = &st->conf.gyro;
343 unsigned int val;
344 int ret;
345
346 /* sanitize missing values with current values */
347 if (conf->mode < 0)
348 conf->mode = oldconf->mode;
349 if (conf->fs < 0)
350 conf->fs = oldconf->fs;
351 if (conf->odr < 0)
352 conf->odr = oldconf->odr;
353 if (conf->filter < 0)
354 conf->filter = oldconf->filter;
355
356 /* set GYRO_CONFIG0 register (gyro fullscale & odr) */
357 if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
358 val = INV_ICM42600_GYRO_CONFIG0_FS(conf->fs) |
359 INV_ICM42600_GYRO_CONFIG0_ODR(conf->odr);
360 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_CONFIG0, val);
361 if (ret)
362 return ret;
363 oldconf->fs = conf->fs;
364 oldconf->odr = conf->odr;
365 }
366
367 /* set GYRO_ACCEL_CONFIG0 register (gyro filter) */
368 if (conf->filter != oldconf->filter) {
369 val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(st->conf.accel.filter) |
370 INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(conf->filter);
371 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val);
372 if (ret)
373 return ret;
374 oldconf->filter = conf->filter;
375 }
376
377 /* set PWR_MGMT0 register (gyro sensor mode) */
378 return inv_icm42600_set_pwr_mgmt0(st, conf->mode, st->conf.accel.mode,
379 st->conf.temp_en, sleep_ms);
380
381 return 0;
382 }
383
inv_icm42600_set_temp_conf(struct inv_icm42600_state * st,bool enable,unsigned int * sleep_ms)384 int inv_icm42600_set_temp_conf(struct inv_icm42600_state *st, bool enable,
385 unsigned int *sleep_ms)
386 {
387 return inv_icm42600_set_pwr_mgmt0(st, st->conf.gyro.mode,
388 st->conf.accel.mode, enable,
389 sleep_ms);
390 }
391
inv_icm42600_debugfs_reg(struct iio_dev * indio_dev,unsigned int reg,unsigned int writeval,unsigned int * readval)392 int inv_icm42600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg,
393 unsigned int writeval, unsigned int *readval)
394 {
395 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
396 int ret;
397
398 mutex_lock(&st->lock);
399
400 if (readval)
401 ret = regmap_read(st->map, reg, readval);
402 else
403 ret = regmap_write(st->map, reg, writeval);
404
405 mutex_unlock(&st->lock);
406
407 return ret;
408 }
409
inv_icm42600_set_conf(struct inv_icm42600_state * st,const struct inv_icm42600_conf * conf)410 static int inv_icm42600_set_conf(struct inv_icm42600_state *st,
411 const struct inv_icm42600_conf *conf)
412 {
413 unsigned int val;
414 int ret;
415
416 /* set PWR_MGMT0 register (gyro & accel sensor mode, temp enabled) */
417 val = INV_ICM42600_PWR_MGMT0_GYRO(conf->gyro.mode) |
418 INV_ICM42600_PWR_MGMT0_ACCEL(conf->accel.mode);
419 if (!conf->temp_en)
420 val |= INV_ICM42600_PWR_MGMT0_TEMP_DIS;
421 ret = regmap_write(st->map, INV_ICM42600_REG_PWR_MGMT0, val);
422 if (ret)
423 return ret;
424
425 /* set GYRO_CONFIG0 register (gyro fullscale & odr) */
426 val = INV_ICM42600_GYRO_CONFIG0_FS(conf->gyro.fs) |
427 INV_ICM42600_GYRO_CONFIG0_ODR(conf->gyro.odr);
428 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_CONFIG0, val);
429 if (ret)
430 return ret;
431
432 /* set ACCEL_CONFIG0 register (accel fullscale & odr) */
433 val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->accel.fs) |
434 INV_ICM42600_ACCEL_CONFIG0_ODR(conf->accel.odr);
435 ret = regmap_write(st->map, INV_ICM42600_REG_ACCEL_CONFIG0, val);
436 if (ret)
437 return ret;
438
439 /* set GYRO_ACCEL_CONFIG0 register (gyro & accel filters) */
440 val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(conf->accel.filter) |
441 INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(conf->gyro.filter);
442 ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val);
443 if (ret)
444 return ret;
445
446 /* update internal conf */
447 st->conf = *conf;
448
449 return 0;
450 }
451
452 /**
453 * inv_icm42600_setup() - check and setup chip
454 * @st: driver internal state
455 * @bus_setup: callback for setting up bus specific registers
456 *
457 * Returns 0 on success, a negative error code otherwise.
458 */
inv_icm42600_setup(struct inv_icm42600_state * st,inv_icm42600_bus_setup bus_setup)459 static int inv_icm42600_setup(struct inv_icm42600_state *st,
460 inv_icm42600_bus_setup bus_setup)
461 {
462 const struct inv_icm42600_hw *hw = &inv_icm42600_hw[st->chip];
463 const struct device *dev = regmap_get_device(st->map);
464 unsigned int val;
465 int ret;
466
467 /* check chip self-identification value */
468 ret = regmap_read(st->map, INV_ICM42600_REG_WHOAMI, &val);
469 if (ret)
470 return ret;
471 if (val != hw->whoami) {
472 dev_err(dev, "invalid whoami %#02x expected %#02x (%s)\n",
473 val, hw->whoami, hw->name);
474 return -ENODEV;
475 }
476 st->name = hw->name;
477
478 /* reset to make sure previous state are not there */
479 ret = regmap_write(st->map, INV_ICM42600_REG_DEVICE_CONFIG,
480 INV_ICM42600_DEVICE_CONFIG_SOFT_RESET);
481 if (ret)
482 return ret;
483 msleep(INV_ICM42600_RESET_TIME_MS);
484
485 ret = regmap_read(st->map, INV_ICM42600_REG_INT_STATUS, &val);
486 if (ret)
487 return ret;
488 if (!(val & INV_ICM42600_INT_STATUS_RESET_DONE)) {
489 dev_err(dev, "reset error, reset done bit not set\n");
490 return -ENODEV;
491 }
492
493 /* set chip bus configuration */
494 ret = bus_setup(st);
495 if (ret)
496 return ret;
497
498 /* sensor data in big-endian (default) */
499 ret = regmap_set_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0,
500 INV_ICM42600_INTF_CONFIG0_SENSOR_DATA_ENDIAN);
501 if (ret)
502 return ret;
503
504 /*
505 * Use RC clock for accel low-power to fix glitches when switching
506 * gyro on/off while accel low-power is on.
507 */
508 ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG1,
509 INV_ICM42600_INTF_CONFIG1_ACCEL_LP_CLK_RC,
510 INV_ICM42600_INTF_CONFIG1_ACCEL_LP_CLK_RC);
511 if (ret)
512 return ret;
513
514 return inv_icm42600_set_conf(st, hw->conf);
515 }
516
inv_icm42600_irq_timestamp(int irq,void * _data)517 static irqreturn_t inv_icm42600_irq_timestamp(int irq, void *_data)
518 {
519 struct inv_icm42600_state *st = _data;
520
521 st->timestamp.gyro = iio_get_time_ns(st->indio_gyro);
522 st->timestamp.accel = iio_get_time_ns(st->indio_accel);
523
524 return IRQ_WAKE_THREAD;
525 }
526
inv_icm42600_irq_handler(int irq,void * _data)527 static irqreturn_t inv_icm42600_irq_handler(int irq, void *_data)
528 {
529 struct inv_icm42600_state *st = _data;
530 struct device *dev = regmap_get_device(st->map);
531 unsigned int status;
532 int ret;
533
534 mutex_lock(&st->lock);
535
536 ret = regmap_read(st->map, INV_ICM42600_REG_INT_STATUS, &status);
537 if (ret)
538 goto out_unlock;
539
540 /* FIFO full */
541 if (status & INV_ICM42600_INT_STATUS_FIFO_FULL)
542 dev_warn(dev, "FIFO full data lost!\n");
543
544 /* FIFO threshold reached */
545 if (status & INV_ICM42600_INT_STATUS_FIFO_THS) {
546 ret = inv_icm42600_buffer_fifo_read(st, 0);
547 if (ret) {
548 dev_err(dev, "FIFO read error %d\n", ret);
549 goto out_unlock;
550 }
551 ret = inv_icm42600_buffer_fifo_parse(st);
552 if (ret)
553 dev_err(dev, "FIFO parsing error %d\n", ret);
554 }
555
556 out_unlock:
557 mutex_unlock(&st->lock);
558 return IRQ_HANDLED;
559 }
560
561 /**
562 * inv_icm42600_irq_init() - initialize int pin and interrupt handler
563 * @st: driver internal state
564 * @irq: irq number
565 * @irq_type: irq trigger type
566 * @open_drain: true if irq is open drain, false for push-pull
567 *
568 * Returns 0 on success, a negative error code otherwise.
569 */
inv_icm42600_irq_init(struct inv_icm42600_state * st,int irq,int irq_type,bool open_drain)570 static int inv_icm42600_irq_init(struct inv_icm42600_state *st, int irq,
571 int irq_type, bool open_drain)
572 {
573 struct device *dev = regmap_get_device(st->map);
574 unsigned int val;
575 int ret;
576
577 /* configure INT1 interrupt: default is active low on edge */
578 switch (irq_type) {
579 case IRQF_TRIGGER_RISING:
580 case IRQF_TRIGGER_HIGH:
581 val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_HIGH;
582 break;
583 default:
584 val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_LOW;
585 break;
586 }
587
588 switch (irq_type) {
589 case IRQF_TRIGGER_LOW:
590 case IRQF_TRIGGER_HIGH:
591 val |= INV_ICM42600_INT_CONFIG_INT1_LATCHED;
592 break;
593 default:
594 break;
595 }
596
597 if (!open_drain)
598 val |= INV_ICM42600_INT_CONFIG_INT1_PUSH_PULL;
599
600 ret = regmap_write(st->map, INV_ICM42600_REG_INT_CONFIG, val);
601 if (ret)
602 return ret;
603
604 /* Deassert async reset for proper INT pin operation (cf datasheet) */
605 ret = regmap_clear_bits(st->map, INV_ICM42600_REG_INT_CONFIG1,
606 INV_ICM42600_INT_CONFIG1_ASYNC_RESET);
607 if (ret)
608 return ret;
609
610 irq_type |= IRQF_ONESHOT;
611 return devm_request_threaded_irq(dev, irq, inv_icm42600_irq_timestamp,
612 inv_icm42600_irq_handler, irq_type,
613 "inv_icm42600", st);
614 }
615
inv_icm42600_timestamp_setup(struct inv_icm42600_state * st)616 static int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st)
617 {
618 unsigned int val;
619
620 /* enable timestamp register */
621 val = INV_ICM42600_TMST_CONFIG_TMST_TO_REGS_EN |
622 INV_ICM42600_TMST_CONFIG_TMST_EN;
623 return regmap_update_bits(st->map, INV_ICM42600_REG_TMST_CONFIG,
624 INV_ICM42600_TMST_CONFIG_MASK, val);
625 }
626
inv_icm42600_enable_regulator_vddio(struct inv_icm42600_state * st)627 static int inv_icm42600_enable_regulator_vddio(struct inv_icm42600_state *st)
628 {
629 int ret;
630
631 ret = regulator_enable(st->vddio_supply);
632 if (ret)
633 return ret;
634
635 /* wait a little for supply ramp */
636 usleep_range(3000, 4000);
637
638 return 0;
639 }
640
inv_icm42600_disable_vdd_reg(void * _data)641 static void inv_icm42600_disable_vdd_reg(void *_data)
642 {
643 struct inv_icm42600_state *st = _data;
644 const struct device *dev = regmap_get_device(st->map);
645 int ret;
646
647 ret = regulator_disable(st->vdd_supply);
648 if (ret)
649 dev_err(dev, "failed to disable vdd error %d\n", ret);
650 }
651
inv_icm42600_disable_vddio_reg(void * _data)652 static void inv_icm42600_disable_vddio_reg(void *_data)
653 {
654 struct inv_icm42600_state *st = _data;
655 const struct device *dev = regmap_get_device(st->map);
656 int ret;
657
658 ret = regulator_disable(st->vddio_supply);
659 if (ret)
660 dev_err(dev, "failed to disable vddio error %d\n", ret);
661 }
662
inv_icm42600_disable_pm(void * _data)663 static void inv_icm42600_disable_pm(void *_data)
664 {
665 struct device *dev = _data;
666
667 pm_runtime_put_sync(dev);
668 pm_runtime_disable(dev);
669 }
670
inv_icm42600_core_probe(struct regmap * regmap,int chip,int irq,inv_icm42600_bus_setup bus_setup)671 int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq,
672 inv_icm42600_bus_setup bus_setup)
673 {
674 struct device *dev = regmap_get_device(regmap);
675 struct inv_icm42600_state *st;
676 struct irq_data *irq_desc;
677 int irq_type;
678 bool open_drain;
679 int ret;
680
681 if (chip <= INV_CHIP_INVALID || chip >= INV_CHIP_NB) {
682 dev_err(dev, "invalid chip = %d\n", chip);
683 return -ENODEV;
684 }
685
686 /* get irq properties, set trigger falling by default */
687 irq_desc = irq_get_irq_data(irq);
688 if (!irq_desc) {
689 dev_err(dev, "could not find IRQ %d\n", irq);
690 return -EINVAL;
691 }
692
693 irq_type = irqd_get_trigger_type(irq_desc);
694 if (!irq_type)
695 irq_type = IRQF_TRIGGER_FALLING;
696
697 open_drain = device_property_read_bool(dev, "drive-open-drain");
698
699 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
700 if (!st)
701 return -ENOMEM;
702
703 dev_set_drvdata(dev, st);
704 mutex_init(&st->lock);
705 st->chip = chip;
706 st->map = regmap;
707
708 ret = iio_read_mount_matrix(dev, &st->orientation);
709 if (ret) {
710 dev_err(dev, "failed to retrieve mounting matrix %d\n", ret);
711 return ret;
712 }
713
714 st->vdd_supply = devm_regulator_get(dev, "vdd");
715 if (IS_ERR(st->vdd_supply))
716 return PTR_ERR(st->vdd_supply);
717
718 st->vddio_supply = devm_regulator_get(dev, "vddio");
719 if (IS_ERR(st->vddio_supply))
720 return PTR_ERR(st->vddio_supply);
721
722 ret = regulator_enable(st->vdd_supply);
723 if (ret)
724 return ret;
725 msleep(INV_ICM42600_POWER_UP_TIME_MS);
726
727 ret = devm_add_action_or_reset(dev, inv_icm42600_disable_vdd_reg, st);
728 if (ret)
729 return ret;
730
731 ret = inv_icm42600_enable_regulator_vddio(st);
732 if (ret)
733 return ret;
734
735 ret = devm_add_action_or_reset(dev, inv_icm42600_disable_vddio_reg, st);
736 if (ret)
737 return ret;
738
739 /* setup chip registers */
740 ret = inv_icm42600_setup(st, bus_setup);
741 if (ret)
742 return ret;
743
744 ret = inv_icm42600_timestamp_setup(st);
745 if (ret)
746 return ret;
747
748 ret = inv_icm42600_buffer_init(st);
749 if (ret)
750 return ret;
751
752 st->indio_gyro = inv_icm42600_gyro_init(st);
753 if (IS_ERR(st->indio_gyro))
754 return PTR_ERR(st->indio_gyro);
755
756 st->indio_accel = inv_icm42600_accel_init(st);
757 if (IS_ERR(st->indio_accel))
758 return PTR_ERR(st->indio_accel);
759
760 ret = inv_icm42600_irq_init(st, irq, irq_type, open_drain);
761 if (ret)
762 return ret;
763
764 /* setup runtime power management */
765 ret = pm_runtime_set_active(dev);
766 if (ret)
767 return ret;
768 pm_runtime_get_noresume(dev);
769 pm_runtime_enable(dev);
770 pm_runtime_set_autosuspend_delay(dev, INV_ICM42600_SUSPEND_DELAY_MS);
771 pm_runtime_use_autosuspend(dev);
772 pm_runtime_put(dev);
773
774 return devm_add_action_or_reset(dev, inv_icm42600_disable_pm, dev);
775 }
776 EXPORT_SYMBOL_NS_GPL(inv_icm42600_core_probe, IIO_ICM42600);
777
778 /*
779 * Suspend saves sensors state and turns everything off.
780 * Check first if runtime suspend has not already done the job.
781 */
inv_icm42600_suspend(struct device * dev)782 static int inv_icm42600_suspend(struct device *dev)
783 {
784 struct inv_icm42600_state *st = dev_get_drvdata(dev);
785 int ret;
786
787 mutex_lock(&st->lock);
788
789 st->suspended.gyro = st->conf.gyro.mode;
790 st->suspended.accel = st->conf.accel.mode;
791 st->suspended.temp = st->conf.temp_en;
792 if (pm_runtime_suspended(dev)) {
793 ret = 0;
794 goto out_unlock;
795 }
796
797 /* disable FIFO data streaming */
798 if (st->fifo.on) {
799 ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
800 INV_ICM42600_FIFO_CONFIG_BYPASS);
801 if (ret)
802 goto out_unlock;
803 }
804
805 ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF,
806 INV_ICM42600_SENSOR_MODE_OFF, false,
807 NULL);
808 if (ret)
809 goto out_unlock;
810
811 regulator_disable(st->vddio_supply);
812
813 out_unlock:
814 mutex_unlock(&st->lock);
815 return ret;
816 }
817
818 /*
819 * System resume gets the system back on and restores the sensors state.
820 * Manually put runtime power management in system active state.
821 */
inv_icm42600_resume(struct device * dev)822 static int inv_icm42600_resume(struct device *dev)
823 {
824 struct inv_icm42600_state *st = dev_get_drvdata(dev);
825 int ret;
826
827 mutex_lock(&st->lock);
828
829 ret = inv_icm42600_enable_regulator_vddio(st);
830 if (ret)
831 goto out_unlock;
832
833 pm_runtime_disable(dev);
834 pm_runtime_set_active(dev);
835 pm_runtime_enable(dev);
836
837 /* restore sensors state */
838 ret = inv_icm42600_set_pwr_mgmt0(st, st->suspended.gyro,
839 st->suspended.accel,
840 st->suspended.temp, NULL);
841 if (ret)
842 goto out_unlock;
843
844 /* restore FIFO data streaming */
845 if (st->fifo.on)
846 ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
847 INV_ICM42600_FIFO_CONFIG_STREAM);
848
849 out_unlock:
850 mutex_unlock(&st->lock);
851 return ret;
852 }
853
854 /* Runtime suspend will turn off sensors that are enabled by iio devices. */
inv_icm42600_runtime_suspend(struct device * dev)855 static int inv_icm42600_runtime_suspend(struct device *dev)
856 {
857 struct inv_icm42600_state *st = dev_get_drvdata(dev);
858 int ret;
859
860 mutex_lock(&st->lock);
861
862 /* disable all sensors */
863 ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF,
864 INV_ICM42600_SENSOR_MODE_OFF, false,
865 NULL);
866 if (ret)
867 goto error_unlock;
868
869 regulator_disable(st->vddio_supply);
870
871 error_unlock:
872 mutex_unlock(&st->lock);
873 return ret;
874 }
875
876 /* Sensors are enabled by iio devices, no need to turn them back on here. */
inv_icm42600_runtime_resume(struct device * dev)877 static int inv_icm42600_runtime_resume(struct device *dev)
878 {
879 struct inv_icm42600_state *st = dev_get_drvdata(dev);
880 int ret;
881
882 mutex_lock(&st->lock);
883
884 ret = inv_icm42600_enable_regulator_vddio(st);
885
886 mutex_unlock(&st->lock);
887 return ret;
888 }
889
890 EXPORT_NS_GPL_DEV_PM_OPS(inv_icm42600_pm_ops, IIO_ICM42600) = {
891 SYSTEM_SLEEP_PM_OPS(inv_icm42600_suspend, inv_icm42600_resume)
892 RUNTIME_PM_OPS(inv_icm42600_runtime_suspend,
893 inv_icm42600_runtime_resume, NULL)
894 };
895
896 MODULE_AUTHOR("InvenSense, Inc.");
897 MODULE_DESCRIPTION("InvenSense ICM-426xx device driver");
898 MODULE_LICENSE("GPL");
899 MODULE_IMPORT_NS(IIO_INV_SENSORS_TIMESTAMP);
900