0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007 #include <linux/device.h>
0008 #include <linux/mutex.h>
0009 #include <linux/pm_runtime.h>
0010 #include <linux/regmap.h>
0011 #include <linux/delay.h>
0012 #include <linux/math64.h>
0013 #include <linux/iio/iio.h>
0014 #include <linux/iio/buffer.h>
0015 #include <linux/iio/kfifo_buf.h>
0016
0017 #include "inv_icm42600.h"
0018 #include "inv_icm42600_temp.h"
0019 #include "inv_icm42600_buffer.h"
0020 #include "inv_icm42600_timestamp.h"
0021
0022 #define INV_ICM42600_ACCEL_CHAN(_modifier, _index, _ext_info) \
0023 { \
0024 .type = IIO_ACCEL, \
0025 .modified = 1, \
0026 .channel2 = _modifier, \
0027 .info_mask_separate = \
0028 BIT(IIO_CHAN_INFO_RAW) | \
0029 BIT(IIO_CHAN_INFO_CALIBBIAS), \
0030 .info_mask_shared_by_type = \
0031 BIT(IIO_CHAN_INFO_SCALE), \
0032 .info_mask_shared_by_type_available = \
0033 BIT(IIO_CHAN_INFO_SCALE) | \
0034 BIT(IIO_CHAN_INFO_CALIBBIAS), \
0035 .info_mask_shared_by_all = \
0036 BIT(IIO_CHAN_INFO_SAMP_FREQ), \
0037 .info_mask_shared_by_all_available = \
0038 BIT(IIO_CHAN_INFO_SAMP_FREQ), \
0039 .scan_index = _index, \
0040 .scan_type = { \
0041 .sign = 's', \
0042 .realbits = 16, \
0043 .storagebits = 16, \
0044 .endianness = IIO_BE, \
0045 }, \
0046 .ext_info = _ext_info, \
0047 }
0048
0049 enum inv_icm42600_accel_scan {
0050 INV_ICM42600_ACCEL_SCAN_X,
0051 INV_ICM42600_ACCEL_SCAN_Y,
0052 INV_ICM42600_ACCEL_SCAN_Z,
0053 INV_ICM42600_ACCEL_SCAN_TEMP,
0054 INV_ICM42600_ACCEL_SCAN_TIMESTAMP,
0055 };
0056
0057 static const struct iio_chan_spec_ext_info inv_icm42600_accel_ext_infos[] = {
0058 IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, inv_icm42600_get_mount_matrix),
0059 {},
0060 };
0061
0062 static const struct iio_chan_spec inv_icm42600_accel_channels[] = {
0063 INV_ICM42600_ACCEL_CHAN(IIO_MOD_X, INV_ICM42600_ACCEL_SCAN_X,
0064 inv_icm42600_accel_ext_infos),
0065 INV_ICM42600_ACCEL_CHAN(IIO_MOD_Y, INV_ICM42600_ACCEL_SCAN_Y,
0066 inv_icm42600_accel_ext_infos),
0067 INV_ICM42600_ACCEL_CHAN(IIO_MOD_Z, INV_ICM42600_ACCEL_SCAN_Z,
0068 inv_icm42600_accel_ext_infos),
0069 INV_ICM42600_TEMP_CHAN(INV_ICM42600_ACCEL_SCAN_TEMP),
0070 IIO_CHAN_SOFT_TIMESTAMP(INV_ICM42600_ACCEL_SCAN_TIMESTAMP),
0071 };
0072
0073
0074
0075
0076
0077 struct inv_icm42600_accel_buffer {
0078 struct inv_icm42600_fifo_sensor_data accel;
0079 int16_t temp;
0080 int64_t timestamp __aligned(8);
0081 };
0082
0083 #define INV_ICM42600_SCAN_MASK_ACCEL_3AXIS \
0084 (BIT(INV_ICM42600_ACCEL_SCAN_X) | \
0085 BIT(INV_ICM42600_ACCEL_SCAN_Y) | \
0086 BIT(INV_ICM42600_ACCEL_SCAN_Z))
0087
0088 #define INV_ICM42600_SCAN_MASK_TEMP BIT(INV_ICM42600_ACCEL_SCAN_TEMP)
0089
0090 static const unsigned long inv_icm42600_accel_scan_masks[] = {
0091
0092 INV_ICM42600_SCAN_MASK_ACCEL_3AXIS | INV_ICM42600_SCAN_MASK_TEMP,
0093 0,
0094 };
0095
0096
0097 static int inv_icm42600_accel_update_scan_mode(struct iio_dev *indio_dev,
0098 const unsigned long *scan_mask)
0099 {
0100 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
0101 struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
0102 struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
0103 unsigned int fifo_en = 0;
0104 unsigned int sleep_temp = 0;
0105 unsigned int sleep_accel = 0;
0106 unsigned int sleep;
0107 int ret;
0108
0109 mutex_lock(&st->lock);
0110
0111 if (*scan_mask & INV_ICM42600_SCAN_MASK_TEMP) {
0112
0113 ret = inv_icm42600_set_temp_conf(st, true, &sleep_temp);
0114 if (ret)
0115 goto out_unlock;
0116 fifo_en |= INV_ICM42600_SENSOR_TEMP;
0117 }
0118
0119 if (*scan_mask & INV_ICM42600_SCAN_MASK_ACCEL_3AXIS) {
0120
0121 conf.mode = INV_ICM42600_SENSOR_MODE_LOW_NOISE;
0122 ret = inv_icm42600_set_accel_conf(st, &conf, &sleep_accel);
0123 if (ret)
0124 goto out_unlock;
0125 fifo_en |= INV_ICM42600_SENSOR_ACCEL;
0126 }
0127
0128
0129 inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0);
0130 ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
0131 if (ret)
0132 goto out_unlock;
0133
0134 ret = inv_icm42600_buffer_update_watermark(st);
0135
0136 out_unlock:
0137 mutex_unlock(&st->lock);
0138
0139 if (sleep_accel > sleep_temp)
0140 sleep = sleep_accel;
0141 else
0142 sleep = sleep_temp;
0143 if (sleep)
0144 msleep(sleep);
0145 return ret;
0146 }
0147
0148 static int inv_icm42600_accel_read_sensor(struct inv_icm42600_state *st,
0149 struct iio_chan_spec const *chan,
0150 int16_t *val)
0151 {
0152 struct device *dev = regmap_get_device(st->map);
0153 struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
0154 unsigned int reg;
0155 __be16 *data;
0156 int ret;
0157
0158 if (chan->type != IIO_ACCEL)
0159 return -EINVAL;
0160
0161 switch (chan->channel2) {
0162 case IIO_MOD_X:
0163 reg = INV_ICM42600_REG_ACCEL_DATA_X;
0164 break;
0165 case IIO_MOD_Y:
0166 reg = INV_ICM42600_REG_ACCEL_DATA_Y;
0167 break;
0168 case IIO_MOD_Z:
0169 reg = INV_ICM42600_REG_ACCEL_DATA_Z;
0170 break;
0171 default:
0172 return -EINVAL;
0173 }
0174
0175 pm_runtime_get_sync(dev);
0176 mutex_lock(&st->lock);
0177
0178
0179 conf.mode = INV_ICM42600_SENSOR_MODE_LOW_NOISE;
0180 ret = inv_icm42600_set_accel_conf(st, &conf, NULL);
0181 if (ret)
0182 goto exit;
0183
0184
0185 data = (__be16 *)&st->buffer[0];
0186 ret = regmap_bulk_read(st->map, reg, data, sizeof(*data));
0187 if (ret)
0188 goto exit;
0189
0190 *val = (int16_t)be16_to_cpup(data);
0191 if (*val == INV_ICM42600_DATA_INVALID)
0192 ret = -EINVAL;
0193 exit:
0194 mutex_unlock(&st->lock);
0195 pm_runtime_mark_last_busy(dev);
0196 pm_runtime_put_autosuspend(dev);
0197 return ret;
0198 }
0199
0200
0201 static const int inv_icm42600_accel_scale[] = {
0202
0203 [2 * INV_ICM42600_ACCEL_FS_16G] = 0,
0204 [2 * INV_ICM42600_ACCEL_FS_16G + 1] = 4788403,
0205
0206 [2 * INV_ICM42600_ACCEL_FS_8G] = 0,
0207 [2 * INV_ICM42600_ACCEL_FS_8G + 1] = 2394202,
0208
0209 [2 * INV_ICM42600_ACCEL_FS_4G] = 0,
0210 [2 * INV_ICM42600_ACCEL_FS_4G + 1] = 1197101,
0211
0212 [2 * INV_ICM42600_ACCEL_FS_2G] = 0,
0213 [2 * INV_ICM42600_ACCEL_FS_2G + 1] = 598550,
0214 };
0215
0216 static int inv_icm42600_accel_read_scale(struct inv_icm42600_state *st,
0217 int *val, int *val2)
0218 {
0219 unsigned int idx;
0220
0221 idx = st->conf.accel.fs;
0222
0223 *val = inv_icm42600_accel_scale[2 * idx];
0224 *val2 = inv_icm42600_accel_scale[2 * idx + 1];
0225 return IIO_VAL_INT_PLUS_NANO;
0226 }
0227
0228 static int inv_icm42600_accel_write_scale(struct inv_icm42600_state *st,
0229 int val, int val2)
0230 {
0231 struct device *dev = regmap_get_device(st->map);
0232 unsigned int idx;
0233 struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
0234 int ret;
0235
0236 for (idx = 0; idx < ARRAY_SIZE(inv_icm42600_accel_scale); idx += 2) {
0237 if (val == inv_icm42600_accel_scale[idx] &&
0238 val2 == inv_icm42600_accel_scale[idx + 1])
0239 break;
0240 }
0241 if (idx >= ARRAY_SIZE(inv_icm42600_accel_scale))
0242 return -EINVAL;
0243
0244 conf.fs = idx / 2;
0245
0246 pm_runtime_get_sync(dev);
0247 mutex_lock(&st->lock);
0248
0249 ret = inv_icm42600_set_accel_conf(st, &conf, NULL);
0250
0251 mutex_unlock(&st->lock);
0252 pm_runtime_mark_last_busy(dev);
0253 pm_runtime_put_autosuspend(dev);
0254
0255 return ret;
0256 }
0257
0258
0259 static const int inv_icm42600_accel_odr[] = {
0260
0261 12, 500000,
0262
0263 25, 0,
0264
0265 50, 0,
0266
0267 100, 0,
0268
0269 200, 0,
0270
0271 1000, 0,
0272
0273 2000, 0,
0274
0275 4000, 0,
0276 };
0277
0278 static const int inv_icm42600_accel_odr_conv[] = {
0279 INV_ICM42600_ODR_12_5HZ,
0280 INV_ICM42600_ODR_25HZ,
0281 INV_ICM42600_ODR_50HZ,
0282 INV_ICM42600_ODR_100HZ,
0283 INV_ICM42600_ODR_200HZ,
0284 INV_ICM42600_ODR_1KHZ_LN,
0285 INV_ICM42600_ODR_2KHZ_LN,
0286 INV_ICM42600_ODR_4KHZ_LN,
0287 };
0288
0289 static int inv_icm42600_accel_read_odr(struct inv_icm42600_state *st,
0290 int *val, int *val2)
0291 {
0292 unsigned int odr;
0293 unsigned int i;
0294
0295 odr = st->conf.accel.odr;
0296
0297 for (i = 0; i < ARRAY_SIZE(inv_icm42600_accel_odr_conv); ++i) {
0298 if (inv_icm42600_accel_odr_conv[i] == odr)
0299 break;
0300 }
0301 if (i >= ARRAY_SIZE(inv_icm42600_accel_odr_conv))
0302 return -EINVAL;
0303
0304 *val = inv_icm42600_accel_odr[2 * i];
0305 *val2 = inv_icm42600_accel_odr[2 * i + 1];
0306
0307 return IIO_VAL_INT_PLUS_MICRO;
0308 }
0309
0310 static int inv_icm42600_accel_write_odr(struct iio_dev *indio_dev,
0311 int val, int val2)
0312 {
0313 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
0314 struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
0315 struct device *dev = regmap_get_device(st->map);
0316 unsigned int idx;
0317 struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
0318 int ret;
0319
0320 for (idx = 0; idx < ARRAY_SIZE(inv_icm42600_accel_odr); idx += 2) {
0321 if (val == inv_icm42600_accel_odr[idx] &&
0322 val2 == inv_icm42600_accel_odr[idx + 1])
0323 break;
0324 }
0325 if (idx >= ARRAY_SIZE(inv_icm42600_accel_odr))
0326 return -EINVAL;
0327
0328 conf.odr = inv_icm42600_accel_odr_conv[idx / 2];
0329
0330 pm_runtime_get_sync(dev);
0331 mutex_lock(&st->lock);
0332
0333 ret = inv_icm42600_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr),
0334 iio_buffer_enabled(indio_dev));
0335 if (ret)
0336 goto out_unlock;
0337
0338 ret = inv_icm42600_set_accel_conf(st, &conf, NULL);
0339 if (ret)
0340 goto out_unlock;
0341 inv_icm42600_buffer_update_fifo_period(st);
0342 inv_icm42600_buffer_update_watermark(st);
0343
0344 out_unlock:
0345 mutex_unlock(&st->lock);
0346 pm_runtime_mark_last_busy(dev);
0347 pm_runtime_put_autosuspend(dev);
0348
0349 return ret;
0350 }
0351
0352
0353
0354
0355
0356 static int inv_icm42600_accel_calibbias[] = {
0357 -10, 42010,
0358 0, 4903,
0359 10, 37106,
0360 };
0361
0362 static int inv_icm42600_accel_read_offset(struct inv_icm42600_state *st,
0363 struct iio_chan_spec const *chan,
0364 int *val, int *val2)
0365 {
0366 struct device *dev = regmap_get_device(st->map);
0367 int64_t val64;
0368 int32_t bias;
0369 unsigned int reg;
0370 int16_t offset;
0371 uint8_t data[2];
0372 int ret;
0373
0374 if (chan->type != IIO_ACCEL)
0375 return -EINVAL;
0376
0377 switch (chan->channel2) {
0378 case IIO_MOD_X:
0379 reg = INV_ICM42600_REG_OFFSET_USER4;
0380 break;
0381 case IIO_MOD_Y:
0382 reg = INV_ICM42600_REG_OFFSET_USER6;
0383 break;
0384 case IIO_MOD_Z:
0385 reg = INV_ICM42600_REG_OFFSET_USER7;
0386 break;
0387 default:
0388 return -EINVAL;
0389 }
0390
0391 pm_runtime_get_sync(dev);
0392 mutex_lock(&st->lock);
0393
0394 ret = regmap_bulk_read(st->map, reg, st->buffer, sizeof(data));
0395 memcpy(data, st->buffer, sizeof(data));
0396
0397 mutex_unlock(&st->lock);
0398 pm_runtime_mark_last_busy(dev);
0399 pm_runtime_put_autosuspend(dev);
0400 if (ret)
0401 return ret;
0402
0403
0404 switch (chan->channel2) {
0405 case IIO_MOD_X:
0406 offset = sign_extend32(((data[0] & 0xF0) << 4) | data[1], 11);
0407 break;
0408 case IIO_MOD_Y:
0409 offset = sign_extend32(((data[1] & 0x0F) << 8) | data[0], 11);
0410 break;
0411 case IIO_MOD_Z:
0412 offset = sign_extend32(((data[0] & 0xF0) << 4) | data[1], 11);
0413 break;
0414 default:
0415 return -EINVAL;
0416 }
0417
0418
0419
0420
0421
0422
0423
0424
0425 val64 = (int64_t)offset * 5LL * 9806650LL;
0426
0427 if (val64 >= 0)
0428 val64 += 10000LL / 2LL;
0429 else
0430 val64 -= 10000LL / 2LL;
0431 bias = div_s64(val64, 10000L);
0432 *val = bias / 1000000L;
0433 *val2 = bias % 1000000L;
0434
0435 return IIO_VAL_INT_PLUS_MICRO;
0436 }
0437
0438 static int inv_icm42600_accel_write_offset(struct inv_icm42600_state *st,
0439 struct iio_chan_spec const *chan,
0440 int val, int val2)
0441 {
0442 struct device *dev = regmap_get_device(st->map);
0443 int64_t val64;
0444 int32_t min, max;
0445 unsigned int reg, regval;
0446 int16_t offset;
0447 int ret;
0448
0449 if (chan->type != IIO_ACCEL)
0450 return -EINVAL;
0451
0452 switch (chan->channel2) {
0453 case IIO_MOD_X:
0454 reg = INV_ICM42600_REG_OFFSET_USER4;
0455 break;
0456 case IIO_MOD_Y:
0457 reg = INV_ICM42600_REG_OFFSET_USER6;
0458 break;
0459 case IIO_MOD_Z:
0460 reg = INV_ICM42600_REG_OFFSET_USER7;
0461 break;
0462 default:
0463 return -EINVAL;
0464 }
0465
0466
0467 min = inv_icm42600_accel_calibbias[0] * 1000000L +
0468 inv_icm42600_accel_calibbias[1];
0469 max = inv_icm42600_accel_calibbias[4] * 1000000L +
0470 inv_icm42600_accel_calibbias[5];
0471 val64 = (int64_t)val * 1000000LL + (int64_t)val2;
0472 if (val64 < min || val64 > max)
0473 return -EINVAL;
0474
0475
0476
0477
0478
0479
0480
0481
0482 val64 = val64 * 10000LL;
0483
0484 if (val64 >= 0)
0485 val64 += 9806650 * 5 / 2;
0486 else
0487 val64 -= 9806650 * 5 / 2;
0488 offset = div_s64(val64, 9806650 * 5);
0489
0490
0491 if (offset < -2048)
0492 offset = -2048;
0493 else if (offset > 2047)
0494 offset = 2047;
0495
0496 pm_runtime_get_sync(dev);
0497 mutex_lock(&st->lock);
0498
0499 switch (chan->channel2) {
0500 case IIO_MOD_X:
0501
0502 ret = regmap_read(st->map, INV_ICM42600_REG_OFFSET_USER4,
0503 ®val);
0504 if (ret)
0505 goto out_unlock;
0506 st->buffer[0] = ((offset & 0xF00) >> 4) | (regval & 0x0F);
0507 st->buffer[1] = offset & 0xFF;
0508 break;
0509 case IIO_MOD_Y:
0510
0511 ret = regmap_read(st->map, INV_ICM42600_REG_OFFSET_USER7,
0512 ®val);
0513 if (ret)
0514 goto out_unlock;
0515 st->buffer[0] = offset & 0xFF;
0516 st->buffer[1] = ((offset & 0xF00) >> 8) | (regval & 0xF0);
0517 break;
0518 case IIO_MOD_Z:
0519
0520 ret = regmap_read(st->map, INV_ICM42600_REG_OFFSET_USER7,
0521 ®val);
0522 if (ret)
0523 goto out_unlock;
0524 st->buffer[0] = ((offset & 0xF00) >> 4) | (regval & 0x0F);
0525 st->buffer[1] = offset & 0xFF;
0526 break;
0527 default:
0528 ret = -EINVAL;
0529 goto out_unlock;
0530 }
0531
0532 ret = regmap_bulk_write(st->map, reg, st->buffer, 2);
0533
0534 out_unlock:
0535 mutex_unlock(&st->lock);
0536 pm_runtime_mark_last_busy(dev);
0537 pm_runtime_put_autosuspend(dev);
0538 return ret;
0539 }
0540
0541 static int inv_icm42600_accel_read_raw(struct iio_dev *indio_dev,
0542 struct iio_chan_spec const *chan,
0543 int *val, int *val2, long mask)
0544 {
0545 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
0546 int16_t data;
0547 int ret;
0548
0549 switch (chan->type) {
0550 case IIO_ACCEL:
0551 break;
0552 case IIO_TEMP:
0553 return inv_icm42600_temp_read_raw(indio_dev, chan, val, val2, mask);
0554 default:
0555 return -EINVAL;
0556 }
0557
0558 switch (mask) {
0559 case IIO_CHAN_INFO_RAW:
0560 ret = iio_device_claim_direct_mode(indio_dev);
0561 if (ret)
0562 return ret;
0563 ret = inv_icm42600_accel_read_sensor(st, chan, &data);
0564 iio_device_release_direct_mode(indio_dev);
0565 if (ret)
0566 return ret;
0567 *val = data;
0568 return IIO_VAL_INT;
0569 case IIO_CHAN_INFO_SCALE:
0570 return inv_icm42600_accel_read_scale(st, val, val2);
0571 case IIO_CHAN_INFO_SAMP_FREQ:
0572 return inv_icm42600_accel_read_odr(st, val, val2);
0573 case IIO_CHAN_INFO_CALIBBIAS:
0574 return inv_icm42600_accel_read_offset(st, chan, val, val2);
0575 default:
0576 return -EINVAL;
0577 }
0578 }
0579
0580 static int inv_icm42600_accel_read_avail(struct iio_dev *indio_dev,
0581 struct iio_chan_spec const *chan,
0582 const int **vals,
0583 int *type, int *length, long mask)
0584 {
0585 if (chan->type != IIO_ACCEL)
0586 return -EINVAL;
0587
0588 switch (mask) {
0589 case IIO_CHAN_INFO_SCALE:
0590 *vals = inv_icm42600_accel_scale;
0591 *type = IIO_VAL_INT_PLUS_NANO;
0592 *length = ARRAY_SIZE(inv_icm42600_accel_scale);
0593 return IIO_AVAIL_LIST;
0594 case IIO_CHAN_INFO_SAMP_FREQ:
0595 *vals = inv_icm42600_accel_odr;
0596 *type = IIO_VAL_INT_PLUS_MICRO;
0597 *length = ARRAY_SIZE(inv_icm42600_accel_odr);
0598 return IIO_AVAIL_LIST;
0599 case IIO_CHAN_INFO_CALIBBIAS:
0600 *vals = inv_icm42600_accel_calibbias;
0601 *type = IIO_VAL_INT_PLUS_MICRO;
0602 return IIO_AVAIL_RANGE;
0603 default:
0604 return -EINVAL;
0605 }
0606 }
0607
0608 static int inv_icm42600_accel_write_raw(struct iio_dev *indio_dev,
0609 struct iio_chan_spec const *chan,
0610 int val, int val2, long mask)
0611 {
0612 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
0613 int ret;
0614
0615 if (chan->type != IIO_ACCEL)
0616 return -EINVAL;
0617
0618 switch (mask) {
0619 case IIO_CHAN_INFO_SCALE:
0620 ret = iio_device_claim_direct_mode(indio_dev);
0621 if (ret)
0622 return ret;
0623 ret = inv_icm42600_accel_write_scale(st, val, val2);
0624 iio_device_release_direct_mode(indio_dev);
0625 return ret;
0626 case IIO_CHAN_INFO_SAMP_FREQ:
0627 return inv_icm42600_accel_write_odr(indio_dev, val, val2);
0628 case IIO_CHAN_INFO_CALIBBIAS:
0629 ret = iio_device_claim_direct_mode(indio_dev);
0630 if (ret)
0631 return ret;
0632 ret = inv_icm42600_accel_write_offset(st, chan, val, val2);
0633 iio_device_release_direct_mode(indio_dev);
0634 return ret;
0635 default:
0636 return -EINVAL;
0637 }
0638 }
0639
0640 static int inv_icm42600_accel_write_raw_get_fmt(struct iio_dev *indio_dev,
0641 struct iio_chan_spec const *chan,
0642 long mask)
0643 {
0644 if (chan->type != IIO_ACCEL)
0645 return -EINVAL;
0646
0647 switch (mask) {
0648 case IIO_CHAN_INFO_SCALE:
0649 return IIO_VAL_INT_PLUS_NANO;
0650 case IIO_CHAN_INFO_SAMP_FREQ:
0651 return IIO_VAL_INT_PLUS_MICRO;
0652 case IIO_CHAN_INFO_CALIBBIAS:
0653 return IIO_VAL_INT_PLUS_MICRO;
0654 default:
0655 return -EINVAL;
0656 }
0657 }
0658
0659 static int inv_icm42600_accel_hwfifo_set_watermark(struct iio_dev *indio_dev,
0660 unsigned int val)
0661 {
0662 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
0663 int ret;
0664
0665 mutex_lock(&st->lock);
0666
0667 st->fifo.watermark.accel = val;
0668 ret = inv_icm42600_buffer_update_watermark(st);
0669
0670 mutex_unlock(&st->lock);
0671
0672 return ret;
0673 }
0674
0675 static int inv_icm42600_accel_hwfifo_flush(struct iio_dev *indio_dev,
0676 unsigned int count)
0677 {
0678 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
0679 int ret;
0680
0681 if (count == 0)
0682 return 0;
0683
0684 mutex_lock(&st->lock);
0685
0686 ret = inv_icm42600_buffer_hwfifo_flush(st, count);
0687 if (!ret)
0688 ret = st->fifo.nb.accel;
0689
0690 mutex_unlock(&st->lock);
0691
0692 return ret;
0693 }
0694
0695 static const struct iio_info inv_icm42600_accel_info = {
0696 .read_raw = inv_icm42600_accel_read_raw,
0697 .read_avail = inv_icm42600_accel_read_avail,
0698 .write_raw = inv_icm42600_accel_write_raw,
0699 .write_raw_get_fmt = inv_icm42600_accel_write_raw_get_fmt,
0700 .debugfs_reg_access = inv_icm42600_debugfs_reg,
0701 .update_scan_mode = inv_icm42600_accel_update_scan_mode,
0702 .hwfifo_set_watermark = inv_icm42600_accel_hwfifo_set_watermark,
0703 .hwfifo_flush_to_buffer = inv_icm42600_accel_hwfifo_flush,
0704 };
0705
0706 struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st)
0707 {
0708 struct device *dev = regmap_get_device(st->map);
0709 const char *name;
0710 struct inv_icm42600_timestamp *ts;
0711 struct iio_dev *indio_dev;
0712 int ret;
0713
0714 name = devm_kasprintf(dev, GFP_KERNEL, "%s-accel", st->name);
0715 if (!name)
0716 return ERR_PTR(-ENOMEM);
0717
0718 indio_dev = devm_iio_device_alloc(dev, sizeof(*ts));
0719 if (!indio_dev)
0720 return ERR_PTR(-ENOMEM);
0721
0722 ts = iio_priv(indio_dev);
0723 inv_icm42600_timestamp_init(ts, inv_icm42600_odr_to_period(st->conf.accel.odr));
0724
0725 iio_device_set_drvdata(indio_dev, st);
0726 indio_dev->name = name;
0727 indio_dev->info = &inv_icm42600_accel_info;
0728 indio_dev->modes = INDIO_DIRECT_MODE;
0729 indio_dev->channels = inv_icm42600_accel_channels;
0730 indio_dev->num_channels = ARRAY_SIZE(inv_icm42600_accel_channels);
0731 indio_dev->available_scan_masks = inv_icm42600_accel_scan_masks;
0732
0733 ret = devm_iio_kfifo_buffer_setup(dev, indio_dev,
0734 &inv_icm42600_buffer_ops);
0735 if (ret)
0736 return ERR_PTR(ret);
0737
0738 ret = devm_iio_device_register(dev, indio_dev);
0739 if (ret)
0740 return ERR_PTR(ret);
0741
0742 return indio_dev;
0743 }
0744
0745 int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev)
0746 {
0747 struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
0748 struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
0749 ssize_t i, size;
0750 unsigned int no;
0751 const void *accel, *gyro, *timestamp;
0752 const int8_t *temp;
0753 unsigned int odr;
0754 int64_t ts_val;
0755 struct inv_icm42600_accel_buffer buffer;
0756
0757
0758 for (i = 0, no = 0; i < st->fifo.count; i += size, ++no) {
0759 size = inv_icm42600_fifo_decode_packet(&st->fifo.data[i],
0760 &accel, &gyro, &temp, ×tamp, &odr);
0761
0762 if (size <= 0)
0763 return size;
0764
0765
0766 if (accel == NULL || !inv_icm42600_fifo_is_data_valid(accel))
0767 continue;
0768
0769
0770 if (odr & INV_ICM42600_SENSOR_ACCEL)
0771 inv_icm42600_timestamp_apply_odr(ts, st->fifo.period,
0772 st->fifo.nb.total, no);
0773
0774
0775 memset(&buffer, 0, sizeof(buffer));
0776 memcpy(&buffer.accel, accel, sizeof(buffer.accel));
0777
0778 buffer.temp = temp ? (*temp * 64) : 0;
0779 ts_val = inv_icm42600_timestamp_pop(ts);
0780 iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts_val);
0781 }
0782
0783 return 0;
0784 }