root/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. inv_scan_query
  2. inv_mpu6050_set_enable
  3. inv_mpu_data_rdy_trigger_set_state
  4. inv_mpu6050_probe_trigger

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3 * Copyright (C) 2012 Invensense, Inc.
   4 */
   5 
   6 #include "inv_mpu_iio.h"
   7 
   8 static void inv_scan_query(struct iio_dev *indio_dev)
   9 {
  10         struct inv_mpu6050_state  *st = iio_priv(indio_dev);
  11 
  12         st->chip_config.gyro_fifo_enable =
  13                 test_bit(INV_MPU6050_SCAN_GYRO_X,
  14                          indio_dev->active_scan_mask) ||
  15                 test_bit(INV_MPU6050_SCAN_GYRO_Y,
  16                          indio_dev->active_scan_mask) ||
  17                 test_bit(INV_MPU6050_SCAN_GYRO_Z,
  18                          indio_dev->active_scan_mask);
  19 
  20         st->chip_config.accl_fifo_enable =
  21                 test_bit(INV_MPU6050_SCAN_ACCL_X,
  22                          indio_dev->active_scan_mask) ||
  23                 test_bit(INV_MPU6050_SCAN_ACCL_Y,
  24                          indio_dev->active_scan_mask) ||
  25                 test_bit(INV_MPU6050_SCAN_ACCL_Z,
  26                          indio_dev->active_scan_mask);
  27 }
  28 
  29 /**
  30  *  inv_mpu6050_set_enable() - enable chip functions.
  31  *  @indio_dev: Device driver instance.
  32  *  @enable: enable/disable
  33  */
  34 static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable)
  35 {
  36         struct inv_mpu6050_state *st = iio_priv(indio_dev);
  37         int result;
  38 
  39         if (enable) {
  40                 result = inv_mpu6050_set_power_itg(st, true);
  41                 if (result)
  42                         return result;
  43                 inv_scan_query(indio_dev);
  44                 st->skip_samples = 0;
  45                 if (st->chip_config.gyro_fifo_enable) {
  46                         result = inv_mpu6050_switch_engine(st, true,
  47                                         INV_MPU6050_BIT_PWR_GYRO_STBY);
  48                         if (result)
  49                                 goto error_power_off;
  50                         /* gyro first sample is out of specs, skip it */
  51                         st->skip_samples = 1;
  52                 }
  53                 if (st->chip_config.accl_fifo_enable) {
  54                         result = inv_mpu6050_switch_engine(st, true,
  55                                         INV_MPU6050_BIT_PWR_ACCL_STBY);
  56                         if (result)
  57                                 goto error_gyro_off;
  58                 }
  59                 result = inv_reset_fifo(indio_dev);
  60                 if (result)
  61                         goto error_accl_off;
  62         } else {
  63                 result = regmap_write(st->map, st->reg->fifo_en, 0);
  64                 if (result)
  65                         goto error_accl_off;
  66 
  67                 result = regmap_write(st->map, st->reg->int_enable, 0);
  68                 if (result)
  69                         goto error_accl_off;
  70 
  71                 result = regmap_write(st->map, st->reg->user_ctrl,
  72                                       st->chip_config.user_ctrl);
  73                 if (result)
  74                         goto error_accl_off;
  75 
  76                 result = inv_mpu6050_switch_engine(st, false,
  77                                         INV_MPU6050_BIT_PWR_ACCL_STBY);
  78                 if (result)
  79                         goto error_accl_off;
  80 
  81                 result = inv_mpu6050_switch_engine(st, false,
  82                                         INV_MPU6050_BIT_PWR_GYRO_STBY);
  83                 if (result)
  84                         goto error_gyro_off;
  85 
  86                 result = inv_mpu6050_set_power_itg(st, false);
  87                 if (result)
  88                         goto error_power_off;
  89         }
  90 
  91         return 0;
  92 
  93 error_accl_off:
  94         if (st->chip_config.accl_fifo_enable)
  95                 inv_mpu6050_switch_engine(st, false,
  96                                           INV_MPU6050_BIT_PWR_ACCL_STBY);
  97 error_gyro_off:
  98         if (st->chip_config.gyro_fifo_enable)
  99                 inv_mpu6050_switch_engine(st, false,
 100                                           INV_MPU6050_BIT_PWR_GYRO_STBY);
 101 error_power_off:
 102         inv_mpu6050_set_power_itg(st, false);
 103         return result;
 104 }
 105 
 106 /**
 107  * inv_mpu_data_rdy_trigger_set_state() - set data ready interrupt state
 108  * @trig: Trigger instance
 109  * @state: Desired trigger state
 110  */
 111 static int inv_mpu_data_rdy_trigger_set_state(struct iio_trigger *trig,
 112                                               bool state)
 113 {
 114         struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
 115         struct inv_mpu6050_state *st = iio_priv(indio_dev);
 116         int result;
 117 
 118         mutex_lock(&st->lock);
 119         result = inv_mpu6050_set_enable(indio_dev, state);
 120         mutex_unlock(&st->lock);
 121 
 122         return result;
 123 }
 124 
 125 static const struct iio_trigger_ops inv_mpu_trigger_ops = {
 126         .set_trigger_state = &inv_mpu_data_rdy_trigger_set_state,
 127 };
 128 
 129 int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev, int irq_type)
 130 {
 131         int ret;
 132         struct inv_mpu6050_state *st = iio_priv(indio_dev);
 133 
 134         st->trig = devm_iio_trigger_alloc(&indio_dev->dev,
 135                                           "%s-dev%d",
 136                                           indio_dev->name,
 137                                           indio_dev->id);
 138         if (!st->trig)
 139                 return -ENOMEM;
 140 
 141         ret = devm_request_irq(&indio_dev->dev, st->irq,
 142                                &iio_trigger_generic_data_rdy_poll,
 143                                irq_type,
 144                                "inv_mpu",
 145                                st->trig);
 146         if (ret)
 147                 return ret;
 148 
 149         st->trig->dev.parent = regmap_get_device(st->map);
 150         st->trig->ops = &inv_mpu_trigger_ops;
 151         iio_trigger_set_drvdata(st->trig, indio_dev);
 152 
 153         ret = devm_iio_trigger_register(&indio_dev->dev, st->trig);
 154         if (ret)
 155                 return ret;
 156 
 157         indio_dev->trig = iio_trigger_get(st->trig);
 158 
 159         return 0;
 160 }

/* [<][>][^][v][top][bottom][index][help] */