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