0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <linux/module.h>
0034 #include <linux/iio/kfifo_buf.h>
0035 #include <linux/iio/iio.h>
0036 #include <linux/iio/buffer.h>
0037 #include <linux/regmap.h>
0038 #include <linux/bitfield.h>
0039
0040 #include <linux/platform_data/st_sensors_pdata.h>
0041
0042 #include "st_lsm6dsx.h"
0043
0044 #define ST_LSM6DSX_REG_FIFO_MODE_ADDR 0x0a
0045 #define ST_LSM6DSX_FIFO_MODE_MASK GENMASK(2, 0)
0046 #define ST_LSM6DSX_FIFO_ODR_MASK GENMASK(6, 3)
0047 #define ST_LSM6DSX_FIFO_EMPTY_MASK BIT(12)
0048 #define ST_LSM6DSX_REG_FIFO_OUTL_ADDR 0x3e
0049 #define ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR 0x78
0050 #define ST_LSM6DSX_REG_TS_RESET_ADDR 0x42
0051
0052 #define ST_LSM6DSX_MAX_FIFO_ODR_VAL 0x08
0053
0054 #define ST_LSM6DSX_TS_RESET_VAL 0xaa
0055
0056 struct st_lsm6dsx_decimator_entry {
0057 u8 decimator;
0058 u8 val;
0059 };
0060
0061 enum st_lsm6dsx_fifo_tag {
0062 ST_LSM6DSX_GYRO_TAG = 0x01,
0063 ST_LSM6DSX_ACC_TAG = 0x02,
0064 ST_LSM6DSX_TS_TAG = 0x04,
0065 ST_LSM6DSX_EXT0_TAG = 0x0f,
0066 ST_LSM6DSX_EXT1_TAG = 0x10,
0067 ST_LSM6DSX_EXT2_TAG = 0x11,
0068 };
0069
0070 static const
0071 struct st_lsm6dsx_decimator_entry st_lsm6dsx_decimator_table[] = {
0072 { 0, 0x0 },
0073 { 1, 0x1 },
0074 { 2, 0x2 },
0075 { 3, 0x3 },
0076 { 4, 0x4 },
0077 { 8, 0x5 },
0078 { 16, 0x6 },
0079 { 32, 0x7 },
0080 };
0081
0082 static int
0083 st_lsm6dsx_get_decimator_val(struct st_lsm6dsx_sensor *sensor, u32 max_odr)
0084 {
0085 const int max_size = ARRAY_SIZE(st_lsm6dsx_decimator_table);
0086 u32 decimator = max_odr / sensor->odr;
0087 int i;
0088
0089 if (decimator > 1)
0090 decimator = round_down(decimator, 2);
0091
0092 for (i = 0; i < max_size; i++) {
0093 if (st_lsm6dsx_decimator_table[i].decimator == decimator)
0094 break;
0095 }
0096
0097 sensor->decimator = decimator;
0098 return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val;
0099 }
0100
0101 static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw,
0102 u32 *max_odr, u32 *min_odr)
0103 {
0104 struct st_lsm6dsx_sensor *sensor;
0105 int i;
0106
0107 *max_odr = 0, *min_odr = ~0;
0108 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
0109 if (!hw->iio_devs[i])
0110 continue;
0111
0112 sensor = iio_priv(hw->iio_devs[i]);
0113
0114 if (!(hw->enable_mask & BIT(sensor->id)))
0115 continue;
0116
0117 *max_odr = max_t(u32, *max_odr, sensor->odr);
0118 *min_odr = min_t(u32, *min_odr, sensor->odr);
0119 }
0120 }
0121
0122 static u8 st_lsm6dsx_get_sip(struct st_lsm6dsx_sensor *sensor, u32 min_odr)
0123 {
0124 u8 sip = sensor->odr / min_odr;
0125
0126 return sip > 1 ? round_down(sip, 2) : sip;
0127 }
0128
0129 static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
0130 {
0131 const struct st_lsm6dsx_reg *ts_dec_reg;
0132 struct st_lsm6dsx_sensor *sensor;
0133 u16 sip = 0, ts_sip = 0;
0134 u32 max_odr, min_odr;
0135 int err = 0, i;
0136 u8 data;
0137
0138 st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr);
0139
0140 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
0141 const struct st_lsm6dsx_reg *dec_reg;
0142
0143 if (!hw->iio_devs[i])
0144 continue;
0145
0146 sensor = iio_priv(hw->iio_devs[i]);
0147
0148 if (hw->enable_mask & BIT(sensor->id)) {
0149 sensor->sip = st_lsm6dsx_get_sip(sensor, min_odr);
0150 data = st_lsm6dsx_get_decimator_val(sensor, max_odr);
0151 } else {
0152 sensor->sip = 0;
0153 data = 0;
0154 }
0155 ts_sip = max_t(u16, ts_sip, sensor->sip);
0156
0157 dec_reg = &hw->settings->decimator[sensor->id];
0158 if (dec_reg->addr) {
0159 int val = ST_LSM6DSX_SHIFT_VAL(data, dec_reg->mask);
0160
0161 err = st_lsm6dsx_update_bits_locked(hw, dec_reg->addr,
0162 dec_reg->mask,
0163 val);
0164 if (err < 0)
0165 return err;
0166 }
0167 sip += sensor->sip;
0168 }
0169 hw->sip = sip + ts_sip;
0170 hw->ts_sip = ts_sip;
0171
0172
0173
0174
0175
0176
0177 ts_dec_reg = &hw->settings->ts_settings.decimator;
0178 if (ts_dec_reg->addr) {
0179 int val, ts_dec = !!hw->ts_sip;
0180
0181 val = ST_LSM6DSX_SHIFT_VAL(ts_dec, ts_dec_reg->mask);
0182 err = st_lsm6dsx_update_bits_locked(hw, ts_dec_reg->addr,
0183 ts_dec_reg->mask, val);
0184 }
0185 return err;
0186 }
0187
0188 static int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
0189 enum st_lsm6dsx_fifo_mode fifo_mode)
0190 {
0191 unsigned int data;
0192
0193 data = FIELD_PREP(ST_LSM6DSX_FIFO_MODE_MASK, fifo_mode);
0194 return st_lsm6dsx_update_bits_locked(hw, ST_LSM6DSX_REG_FIFO_MODE_ADDR,
0195 ST_LSM6DSX_FIFO_MODE_MASK, data);
0196 }
0197
0198 static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor,
0199 bool enable)
0200 {
0201 struct st_lsm6dsx_hw *hw = sensor->hw;
0202 const struct st_lsm6dsx_reg *batch_reg;
0203 u8 data;
0204
0205 batch_reg = &hw->settings->batch[sensor->id];
0206 if (batch_reg->addr) {
0207 int val;
0208
0209 if (enable) {
0210 int err;
0211
0212 err = st_lsm6dsx_check_odr(sensor, sensor->odr,
0213 &data);
0214 if (err < 0)
0215 return err;
0216 } else {
0217 data = 0;
0218 }
0219 val = ST_LSM6DSX_SHIFT_VAL(data, batch_reg->mask);
0220 return st_lsm6dsx_update_bits_locked(hw, batch_reg->addr,
0221 batch_reg->mask, val);
0222 } else {
0223 data = hw->enable_mask ? ST_LSM6DSX_MAX_FIFO_ODR_VAL : 0;
0224 return st_lsm6dsx_update_bits_locked(hw,
0225 ST_LSM6DSX_REG_FIFO_MODE_ADDR,
0226 ST_LSM6DSX_FIFO_ODR_MASK,
0227 FIELD_PREP(ST_LSM6DSX_FIFO_ODR_MASK,
0228 data));
0229 }
0230 }
0231
0232 int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
0233 {
0234 u16 fifo_watermark = ~0, cur_watermark, fifo_th_mask;
0235 struct st_lsm6dsx_hw *hw = sensor->hw;
0236 struct st_lsm6dsx_sensor *cur_sensor;
0237 int i, err, data;
0238 __le16 wdata;
0239
0240 if (!hw->sip)
0241 return 0;
0242
0243 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
0244 if (!hw->iio_devs[i])
0245 continue;
0246
0247 cur_sensor = iio_priv(hw->iio_devs[i]);
0248
0249 if (!(hw->enable_mask & BIT(cur_sensor->id)))
0250 continue;
0251
0252 cur_watermark = (cur_sensor == sensor) ? watermark
0253 : cur_sensor->watermark;
0254
0255 fifo_watermark = min_t(u16, fifo_watermark, cur_watermark);
0256 }
0257
0258 fifo_watermark = max_t(u16, fifo_watermark, hw->sip);
0259 fifo_watermark = (fifo_watermark / hw->sip) * hw->sip;
0260 fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl;
0261
0262 mutex_lock(&hw->page_lock);
0263 err = regmap_read(hw->regmap, hw->settings->fifo_ops.fifo_th.addr + 1,
0264 &data);
0265 if (err < 0)
0266 goto out;
0267
0268 fifo_th_mask = hw->settings->fifo_ops.fifo_th.mask;
0269 fifo_watermark = ((data << 8) & ~fifo_th_mask) |
0270 (fifo_watermark & fifo_th_mask);
0271
0272 wdata = cpu_to_le16(fifo_watermark);
0273 err = regmap_bulk_write(hw->regmap,
0274 hw->settings->fifo_ops.fifo_th.addr,
0275 &wdata, sizeof(wdata));
0276 out:
0277 mutex_unlock(&hw->page_lock);
0278 return err;
0279 }
0280
0281 static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw)
0282 {
0283 struct st_lsm6dsx_sensor *sensor;
0284 int i, err;
0285
0286
0287 err = st_lsm6dsx_write_locked(hw, ST_LSM6DSX_REG_TS_RESET_ADDR,
0288 ST_LSM6DSX_TS_RESET_VAL);
0289 if (err < 0)
0290 return err;
0291
0292 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
0293 if (!hw->iio_devs[i])
0294 continue;
0295
0296 sensor = iio_priv(hw->iio_devs[i]);
0297
0298
0299
0300
0301 sensor->ts_ref = iio_get_time_ns(hw->iio_devs[i]);
0302 }
0303 return 0;
0304 }
0305
0306 int st_lsm6dsx_resume_fifo(struct st_lsm6dsx_hw *hw)
0307 {
0308 int err;
0309
0310
0311 err = st_lsm6dsx_reset_hw_ts(hw);
0312 if (err < 0)
0313 return err;
0314
0315 return st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
0316 }
0317
0318
0319
0320
0321
0322 static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr,
0323 u8 *data, unsigned int data_len,
0324 unsigned int max_word_len)
0325 {
0326 unsigned int word_len, read_len = 0;
0327 int err;
0328
0329 while (read_len < data_len) {
0330 word_len = min_t(unsigned int, data_len - read_len,
0331 max_word_len);
0332 err = st_lsm6dsx_read_locked(hw, addr, data + read_len,
0333 word_len);
0334 if (err < 0)
0335 return err;
0336 read_len += word_len;
0337 }
0338 return 0;
0339 }
0340
0341 #define ST_LSM6DSX_IIO_BUFF_SIZE (ALIGN(ST_LSM6DSX_SAMPLE_SIZE, \
0342 sizeof(s64)) + sizeof(s64))
0343
0344
0345
0346
0347
0348
0349
0350
0351 int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
0352 {
0353 struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor, *ext_sensor = NULL;
0354 int err, sip, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset;
0355 u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
0356 u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
0357 bool reset_ts = false;
0358 __le16 fifo_status;
0359 s64 ts = 0;
0360
0361 err = st_lsm6dsx_read_locked(hw,
0362 hw->settings->fifo_ops.fifo_diff.addr,
0363 &fifo_status, sizeof(fifo_status));
0364 if (err < 0) {
0365 dev_err(hw->dev, "failed to read fifo status (err=%d)\n",
0366 err);
0367 return err;
0368 }
0369
0370 if (fifo_status & cpu_to_le16(ST_LSM6DSX_FIFO_EMPTY_MASK))
0371 return 0;
0372
0373 fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
0374 ST_LSM6DSX_CHAN_SIZE;
0375 fifo_len = (fifo_len / pattern_len) * pattern_len;
0376
0377 acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
0378 gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
0379 if (hw->iio_devs[ST_LSM6DSX_ID_EXT0])
0380 ext_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_EXT0]);
0381
0382 for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
0383 err = st_lsm6dsx_read_block(hw, ST_LSM6DSX_REG_FIFO_OUTL_ADDR,
0384 hw->buff, pattern_len,
0385 ST_LSM6DSX_MAX_WORD_LEN);
0386 if (err < 0) {
0387 dev_err(hw->dev,
0388 "failed to read pattern from fifo (err=%d)\n",
0389 err);
0390 return err;
0391 }
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408 ext_sip = ext_sensor ? ext_sensor->sip : 0;
0409 gyro_sip = gyro_sensor->sip;
0410 acc_sip = acc_sensor->sip;
0411 ts_sip = hw->ts_sip;
0412 offset = 0;
0413 sip = 0;
0414
0415 while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) {
0416 if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
0417 memcpy(hw->scan[ST_LSM6DSX_ID_GYRO].channels,
0418 &hw->buff[offset],
0419 sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels));
0420 offset += sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels);
0421 }
0422 if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
0423 memcpy(hw->scan[ST_LSM6DSX_ID_ACC].channels,
0424 &hw->buff[offset],
0425 sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels));
0426 offset += sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels);
0427 }
0428 if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
0429 memcpy(hw->scan[ST_LSM6DSX_ID_EXT0].channels,
0430 &hw->buff[offset],
0431 sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels));
0432 offset += sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels);
0433 }
0434
0435 if (ts_sip-- > 0) {
0436 u8 data[ST_LSM6DSX_SAMPLE_SIZE];
0437
0438 memcpy(data, &hw->buff[offset], sizeof(data));
0439
0440
0441
0442
0443
0444
0445 ts = data[1] << 16 | data[0] << 8 | data[3];
0446
0447
0448
0449
0450
0451
0452 if (!reset_ts && ts >= 0xff0000)
0453 reset_ts = true;
0454 ts *= hw->ts_gain;
0455
0456 offset += ST_LSM6DSX_SAMPLE_SIZE;
0457 }
0458
0459 if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
0460 iio_push_to_buffers_with_timestamp(
0461 hw->iio_devs[ST_LSM6DSX_ID_GYRO],
0462 &hw->scan[ST_LSM6DSX_ID_GYRO],
0463 gyro_sensor->ts_ref + ts);
0464 gyro_sip--;
0465 }
0466 if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
0467 iio_push_to_buffers_with_timestamp(
0468 hw->iio_devs[ST_LSM6DSX_ID_ACC],
0469 &hw->scan[ST_LSM6DSX_ID_ACC],
0470 acc_sensor->ts_ref + ts);
0471 acc_sip--;
0472 }
0473 if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
0474 iio_push_to_buffers_with_timestamp(
0475 hw->iio_devs[ST_LSM6DSX_ID_EXT0],
0476 &hw->scan[ST_LSM6DSX_ID_EXT0],
0477 ext_sensor->ts_ref + ts);
0478 ext_sip--;
0479 }
0480 sip++;
0481 }
0482 }
0483
0484 if (unlikely(reset_ts)) {
0485 err = st_lsm6dsx_reset_hw_ts(hw);
0486 if (err < 0) {
0487 dev_err(hw->dev, "failed to reset hw ts (err=%d)\n",
0488 err);
0489 return err;
0490 }
0491 }
0492 return read_len;
0493 }
0494
0495 #define ST_LSM6DSX_INVALID_SAMPLE 0x7ffd
0496 static int
0497 st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag,
0498 u8 *data, s64 ts)
0499 {
0500 s16 val = le16_to_cpu(*(__le16 *)data);
0501 struct st_lsm6dsx_sensor *sensor;
0502 struct iio_dev *iio_dev;
0503
0504
0505 if (val >= ST_LSM6DSX_INVALID_SAMPLE)
0506 return -EINVAL;
0507
0508
0509
0510
0511
0512
0513
0514 switch (tag) {
0515 case ST_LSM6DSX_GYRO_TAG:
0516 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_GYRO];
0517 break;
0518 case ST_LSM6DSX_ACC_TAG:
0519 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_ACC];
0520 break;
0521 case ST_LSM6DSX_EXT0_TAG:
0522 if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0))
0523 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT0];
0524 else if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1))
0525 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1];
0526 else
0527 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2];
0528 break;
0529 case ST_LSM6DSX_EXT1_TAG:
0530 if ((hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0)) &&
0531 (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1)))
0532 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1];
0533 else
0534 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2];
0535 break;
0536 case ST_LSM6DSX_EXT2_TAG:
0537 iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2];
0538 break;
0539 default:
0540 return -EINVAL;
0541 }
0542
0543 sensor = iio_priv(iio_dev);
0544 iio_push_to_buffers_with_timestamp(iio_dev, data,
0545 ts + sensor->ts_ref);
0546
0547 return 0;
0548 }
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558 int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
0559 {
0560 u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
0561 u16 fifo_len, fifo_diff_mask;
0562
0563
0564
0565
0566
0567
0568 u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8);
0569 u8 tag;
0570 bool reset_ts = false;
0571 int i, err, read_len;
0572 __le16 fifo_status;
0573 s64 ts = 0;
0574
0575 err = st_lsm6dsx_read_locked(hw,
0576 hw->settings->fifo_ops.fifo_diff.addr,
0577 &fifo_status, sizeof(fifo_status));
0578 if (err < 0) {
0579 dev_err(hw->dev, "failed to read fifo status (err=%d)\n",
0580 err);
0581 return err;
0582 }
0583
0584 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
0585 fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
0586 ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
0587 if (!fifo_len)
0588 return 0;
0589
0590 for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
0591 err = st_lsm6dsx_read_block(hw,
0592 ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR,
0593 hw->buff, pattern_len,
0594 ST_LSM6DSX_MAX_TAGGED_WORD_LEN);
0595 if (err < 0) {
0596 dev_err(hw->dev,
0597 "failed to read pattern from fifo (err=%d)\n",
0598 err);
0599 return err;
0600 }
0601
0602 for (i = 0; i < pattern_len;
0603 i += ST_LSM6DSX_TAGGED_SAMPLE_SIZE) {
0604 memcpy(iio_buff, &hw->buff[i + ST_LSM6DSX_TAG_SIZE],
0605 ST_LSM6DSX_SAMPLE_SIZE);
0606
0607 tag = hw->buff[i] >> 3;
0608 if (tag == ST_LSM6DSX_TS_TAG) {
0609
0610
0611
0612
0613
0614
0615 ts = le32_to_cpu(*((__le32 *)iio_buff));
0616
0617
0618
0619
0620
0621
0622 if (!reset_ts && ts >= 0xffff0000)
0623 reset_ts = true;
0624 ts *= hw->ts_gain;
0625 } else {
0626 st_lsm6dsx_push_tagged_data(hw, tag, iio_buff,
0627 ts);
0628 }
0629 }
0630 }
0631
0632 if (unlikely(reset_ts)) {
0633 err = st_lsm6dsx_reset_hw_ts(hw);
0634 if (err < 0)
0635 return err;
0636 }
0637 return read_len;
0638 }
0639
0640 int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
0641 {
0642 int err;
0643
0644 if (!hw->settings->fifo_ops.read_fifo)
0645 return -ENOTSUPP;
0646
0647 mutex_lock(&hw->fifo_lock);
0648
0649 hw->settings->fifo_ops.read_fifo(hw);
0650 err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_BYPASS);
0651
0652 mutex_unlock(&hw->fifo_lock);
0653
0654 return err;
0655 }
0656
0657 int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable)
0658 {
0659 struct st_lsm6dsx_hw *hw = sensor->hw;
0660 u8 fifo_mask;
0661 int err;
0662
0663 mutex_lock(&hw->conf_lock);
0664
0665 if (enable)
0666 fifo_mask = hw->fifo_mask | BIT(sensor->id);
0667 else
0668 fifo_mask = hw->fifo_mask & ~BIT(sensor->id);
0669
0670 if (hw->fifo_mask) {
0671 err = st_lsm6dsx_flush_fifo(hw);
0672 if (err < 0)
0673 goto out;
0674 }
0675
0676 if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
0677 sensor->id == ST_LSM6DSX_ID_EXT1 ||
0678 sensor->id == ST_LSM6DSX_ID_EXT2) {
0679 err = st_lsm6dsx_shub_set_enable(sensor, enable);
0680 if (err < 0)
0681 goto out;
0682 } else {
0683 err = st_lsm6dsx_sensor_set_enable(sensor, enable);
0684 if (err < 0)
0685 goto out;
0686 }
0687
0688 err = st_lsm6dsx_set_fifo_odr(sensor, enable);
0689 if (err < 0)
0690 goto out;
0691
0692 err = st_lsm6dsx_update_decimators(hw);
0693 if (err < 0)
0694 goto out;
0695
0696 err = st_lsm6dsx_update_watermark(sensor, sensor->watermark);
0697 if (err < 0)
0698 goto out;
0699
0700 if (fifo_mask) {
0701 err = st_lsm6dsx_resume_fifo(hw);
0702 if (err < 0)
0703 goto out;
0704 }
0705
0706 hw->fifo_mask = fifo_mask;
0707
0708 out:
0709 mutex_unlock(&hw->conf_lock);
0710
0711 return err;
0712 }
0713
0714 static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev)
0715 {
0716 struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
0717 struct st_lsm6dsx_hw *hw = sensor->hw;
0718
0719 if (!hw->settings->fifo_ops.update_fifo)
0720 return -ENOTSUPP;
0721
0722 return hw->settings->fifo_ops.update_fifo(sensor, true);
0723 }
0724
0725 static int st_lsm6dsx_buffer_postdisable(struct iio_dev *iio_dev)
0726 {
0727 struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
0728 struct st_lsm6dsx_hw *hw = sensor->hw;
0729
0730 if (!hw->settings->fifo_ops.update_fifo)
0731 return -ENOTSUPP;
0732
0733 return hw->settings->fifo_ops.update_fifo(sensor, false);
0734 }
0735
0736 static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = {
0737 .preenable = st_lsm6dsx_buffer_preenable,
0738 .postdisable = st_lsm6dsx_buffer_postdisable,
0739 };
0740
0741 int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw)
0742 {
0743 int i, ret;
0744
0745 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
0746 if (!hw->iio_devs[i])
0747 continue;
0748
0749 ret = devm_iio_kfifo_buffer_setup(hw->dev, hw->iio_devs[i],
0750 &st_lsm6dsx_buffer_ops);
0751 if (ret)
0752 return ret;
0753 }
0754
0755 return 0;
0756 }