linux/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * STMicroelectronics st_lsm6dsx FIFO buffer library driver
   4 *
   5 * LSM6DS3/LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C:
   6 * The FIFO buffer can be configured to store data from gyroscope and
   7 * accelerometer. Samples are queued without any tag according to a
   8 * specific pattern based on 'FIFO data sets' (6 bytes each):
   9 *  - 1st data set is reserved for gyroscope data
  10 *  - 2nd data set is reserved for accelerometer data
  11 * The FIFO pattern changes depending on the ODRs and decimation factors
  12 * assigned to the FIFO data sets. The first sequence of data stored in FIFO
  13 * buffer contains the data of all the enabled FIFO data sets
  14 * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated depending on the
  15 * value of the decimation factor and ODR set for each FIFO data set.
  16 *
  17 * LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/LSM6DSRX/ISM330DHCX:
  18 * The FIFO buffer can be configured to store data from gyroscope and
  19 * accelerometer. Each sample is queued with a tag (1B) indicating data
  20 * source (gyroscope, accelerometer, hw timer).
  21 *
  22 * FIFO supported modes:
  23 *  - BYPASS: FIFO disabled
  24 *  - CONTINUOUS: FIFO enabled. When the buffer is full, the FIFO index
  25 *    restarts from the beginning and the oldest sample is overwritten
  26 *
  27 * Copyright 2016 STMicroelectronics Inc.
  28 *
  29 * Lorenzo Bianconi <lorenzo.bianconi@st.com>
  30 * Denis Ciocca <denis.ciocca@st.com>
  31 */
  32#include <linux/module.h>
  33#include <linux/iio/kfifo_buf.h>
  34#include <linux/iio/iio.h>
  35#include <linux/iio/buffer.h>
  36#include <linux/regmap.h>
  37#include <linux/bitfield.h>
  38
  39#include <linux/platform_data/st_sensors_pdata.h>
  40
  41#include "st_lsm6dsx.h"
  42
  43#define ST_LSM6DSX_REG_FIFO_MODE_ADDR           0x0a
  44#define ST_LSM6DSX_FIFO_MODE_MASK               GENMASK(2, 0)
  45#define ST_LSM6DSX_FIFO_ODR_MASK                GENMASK(6, 3)
  46#define ST_LSM6DSX_FIFO_EMPTY_MASK              BIT(12)
  47#define ST_LSM6DSX_REG_FIFO_OUTL_ADDR           0x3e
  48#define ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR        0x78
  49#define ST_LSM6DSX_REG_TS_RESET_ADDR            0x42
  50
  51#define ST_LSM6DSX_MAX_FIFO_ODR_VAL             0x08
  52
  53#define ST_LSM6DSX_TS_RESET_VAL                 0xaa
  54
  55struct st_lsm6dsx_decimator_entry {
  56        u8 decimator;
  57        u8 val;
  58};
  59
  60enum st_lsm6dsx_fifo_tag {
  61        ST_LSM6DSX_GYRO_TAG = 0x01,
  62        ST_LSM6DSX_ACC_TAG = 0x02,
  63        ST_LSM6DSX_TS_TAG = 0x04,
  64        ST_LSM6DSX_EXT0_TAG = 0x0f,
  65        ST_LSM6DSX_EXT1_TAG = 0x10,
  66        ST_LSM6DSX_EXT2_TAG = 0x11,
  67};
  68
  69static const
  70struct st_lsm6dsx_decimator_entry st_lsm6dsx_decimator_table[] = {
  71        {  0, 0x0 },
  72        {  1, 0x1 },
  73        {  2, 0x2 },
  74        {  3, 0x3 },
  75        {  4, 0x4 },
  76        {  8, 0x5 },
  77        { 16, 0x6 },
  78        { 32, 0x7 },
  79};
  80
  81static int
  82st_lsm6dsx_get_decimator_val(struct st_lsm6dsx_sensor *sensor, u32 max_odr)
  83{
  84        const int max_size = ARRAY_SIZE(st_lsm6dsx_decimator_table);
  85        u32 decimator =  max_odr / sensor->odr;
  86        int i;
  87
  88        if (decimator > 1)
  89                decimator = round_down(decimator, 2);
  90
  91        for (i = 0; i < max_size; i++) {
  92                if (st_lsm6dsx_decimator_table[i].decimator == decimator)
  93                        break;
  94        }
  95
  96        return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val;
  97}
  98
  99static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw,
 100                                       u32 *max_odr, u32 *min_odr)
 101{
 102        struct st_lsm6dsx_sensor *sensor;
 103        int i;
 104
 105        *max_odr = 0, *min_odr = ~0;
 106        for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
 107                if (!hw->iio_devs[i])
 108                        continue;
 109
 110                sensor = iio_priv(hw->iio_devs[i]);
 111
 112                if (!(hw->enable_mask & BIT(sensor->id)))
 113                        continue;
 114
 115                *max_odr = max_t(u32, *max_odr, sensor->odr);
 116                *min_odr = min_t(u32, *min_odr, sensor->odr);
 117        }
 118}
 119
 120static u8 st_lsm6dsx_get_sip(struct st_lsm6dsx_sensor *sensor, u32 min_odr)
 121{
 122        u8 sip = sensor->odr / min_odr;
 123
 124        return sip > 1 ? round_down(sip, 2) : sip;
 125}
 126
 127static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
 128{
 129        const struct st_lsm6dsx_reg *ts_dec_reg;
 130        struct st_lsm6dsx_sensor *sensor;
 131        u16 sip = 0, ts_sip = 0;
 132        u32 max_odr, min_odr;
 133        int err = 0, i;
 134        u8 data;
 135
 136        st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr);
 137
 138        for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
 139                const struct st_lsm6dsx_reg *dec_reg;
 140
 141                if (!hw->iio_devs[i])
 142                        continue;
 143
 144                sensor = iio_priv(hw->iio_devs[i]);
 145                /* update fifo decimators and sample in pattern */
 146                if (hw->enable_mask & BIT(sensor->id)) {
 147                        sensor->sip = st_lsm6dsx_get_sip(sensor, min_odr);
 148                        data = st_lsm6dsx_get_decimator_val(sensor, max_odr);
 149                } else {
 150                        sensor->sip = 0;
 151                        data = 0;
 152                }
 153                ts_sip = max_t(u16, ts_sip, sensor->sip);
 154
 155                dec_reg = &hw->settings->decimator[sensor->id];
 156                if (dec_reg->addr) {
 157                        int val = ST_LSM6DSX_SHIFT_VAL(data, dec_reg->mask);
 158
 159                        err = st_lsm6dsx_update_bits_locked(hw, dec_reg->addr,
 160                                                            dec_reg->mask,
 161                                                            val);
 162                        if (err < 0)
 163                                return err;
 164                }
 165                sip += sensor->sip;
 166        }
 167        hw->sip = sip + ts_sip;
 168        hw->ts_sip = ts_sip;
 169
 170        /*
 171         * update hw ts decimator if necessary. Decimator for hw timestamp
 172         * is always 1 or 0 in order to have a ts sample for each data
 173         * sample in FIFO
 174         */
 175        ts_dec_reg = &hw->settings->ts_settings.decimator;
 176        if (ts_dec_reg->addr) {
 177                int val, ts_dec = !!hw->ts_sip;
 178
 179                val = ST_LSM6DSX_SHIFT_VAL(ts_dec, ts_dec_reg->mask);
 180                err = st_lsm6dsx_update_bits_locked(hw, ts_dec_reg->addr,
 181                                                    ts_dec_reg->mask, val);
 182        }
 183        return err;
 184}
 185
 186int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
 187                             enum st_lsm6dsx_fifo_mode fifo_mode)
 188{
 189        unsigned int data;
 190
 191        data = FIELD_PREP(ST_LSM6DSX_FIFO_MODE_MASK, fifo_mode);
 192        return st_lsm6dsx_update_bits_locked(hw, ST_LSM6DSX_REG_FIFO_MODE_ADDR,
 193                                             ST_LSM6DSX_FIFO_MODE_MASK, data);
 194}
 195
 196static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor,
 197                                   bool enable)
 198{
 199        struct st_lsm6dsx_hw *hw = sensor->hw;
 200        const struct st_lsm6dsx_reg *batch_reg;
 201        u8 data;
 202
 203        batch_reg = &hw->settings->batch[sensor->id];
 204        if (batch_reg->addr) {
 205                int val;
 206
 207                if (enable) {
 208                        int err;
 209
 210                        err = st_lsm6dsx_check_odr(sensor, sensor->odr,
 211                                                   &data);
 212                        if (err < 0)
 213                                return err;
 214                } else {
 215                        data = 0;
 216                }
 217                val = ST_LSM6DSX_SHIFT_VAL(data, batch_reg->mask);
 218                return st_lsm6dsx_update_bits_locked(hw, batch_reg->addr,
 219                                                     batch_reg->mask, val);
 220        } else {
 221                data = hw->enable_mask ? ST_LSM6DSX_MAX_FIFO_ODR_VAL : 0;
 222                return st_lsm6dsx_update_bits_locked(hw,
 223                                        ST_LSM6DSX_REG_FIFO_MODE_ADDR,
 224                                        ST_LSM6DSX_FIFO_ODR_MASK,
 225                                        FIELD_PREP(ST_LSM6DSX_FIFO_ODR_MASK,
 226                                                   data));
 227        }
 228}
 229
 230int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
 231{
 232        u16 fifo_watermark = ~0, cur_watermark, fifo_th_mask;
 233        struct st_lsm6dsx_hw *hw = sensor->hw;
 234        struct st_lsm6dsx_sensor *cur_sensor;
 235        int i, err, data;
 236        __le16 wdata;
 237
 238        if (!hw->sip)
 239                return 0;
 240
 241        for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
 242                if (!hw->iio_devs[i])
 243                        continue;
 244
 245                cur_sensor = iio_priv(hw->iio_devs[i]);
 246
 247                if (!(hw->enable_mask & BIT(cur_sensor->id)))
 248                        continue;
 249
 250                cur_watermark = (cur_sensor == sensor) ? watermark
 251                                                       : cur_sensor->watermark;
 252
 253                fifo_watermark = min_t(u16, fifo_watermark, cur_watermark);
 254        }
 255
 256        fifo_watermark = max_t(u16, fifo_watermark, hw->sip);
 257        fifo_watermark = (fifo_watermark / hw->sip) * hw->sip;
 258        fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl;
 259
 260        mutex_lock(&hw->page_lock);
 261        err = regmap_read(hw->regmap, hw->settings->fifo_ops.fifo_th.addr + 1,
 262                          &data);
 263        if (err < 0)
 264                goto out;
 265
 266        fifo_th_mask = hw->settings->fifo_ops.fifo_th.mask;
 267        fifo_watermark = ((data << 8) & ~fifo_th_mask) |
 268                         (fifo_watermark & fifo_th_mask);
 269
 270        wdata = cpu_to_le16(fifo_watermark);
 271        err = regmap_bulk_write(hw->regmap,
 272                                hw->settings->fifo_ops.fifo_th.addr,
 273                                &wdata, sizeof(wdata));
 274out:
 275        mutex_unlock(&hw->page_lock);
 276        return err;
 277}
 278
 279static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw)
 280{
 281        struct st_lsm6dsx_sensor *sensor;
 282        int i, err;
 283
 284        /* reset hw ts counter */
 285        err = st_lsm6dsx_write_locked(hw, ST_LSM6DSX_REG_TS_RESET_ADDR,
 286                                      ST_LSM6DSX_TS_RESET_VAL);
 287        if (err < 0)
 288                return err;
 289
 290        for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
 291                if (!hw->iio_devs[i])
 292                        continue;
 293
 294                sensor = iio_priv(hw->iio_devs[i]);
 295                /*
 296                 * store enable buffer timestamp as reference for
 297                 * hw timestamp
 298                 */
 299                sensor->ts_ref = iio_get_time_ns(hw->iio_devs[i]);
 300        }
 301        return 0;
 302}
 303
 304/*
 305 * Set max bulk read to ST_LSM6DSX_MAX_WORD_LEN/ST_LSM6DSX_MAX_TAGGED_WORD_LEN
 306 * in order to avoid a kmalloc for each bus access
 307 */
 308static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr,
 309                                        u8 *data, unsigned int data_len,
 310                                        unsigned int max_word_len)
 311{
 312        unsigned int word_len, read_len = 0;
 313        int err;
 314
 315        while (read_len < data_len) {
 316                word_len = min_t(unsigned int, data_len - read_len,
 317                                 max_word_len);
 318                err = st_lsm6dsx_read_locked(hw, addr, data + read_len,
 319                                             word_len);
 320                if (err < 0)
 321                        return err;
 322                read_len += word_len;
 323        }
 324        return 0;
 325}
 326
 327#define ST_LSM6DSX_IIO_BUFF_SIZE        (ALIGN(ST_LSM6DSX_SAMPLE_SIZE, \
 328                                               sizeof(s64)) + sizeof(s64))
 329/**
 330 * st_lsm6dsx_read_fifo() - hw FIFO read routine
 331 * @hw: Pointer to instance of struct st_lsm6dsx_hw.
 332 *
 333 * Read samples from the hw FIFO and push them to IIO buffers.
 334 *
 335 * Return: Number of bytes read from the FIFO
 336 */
 337int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
 338{
 339        u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
 340        u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
 341        int err, acc_sip, gyro_sip, ts_sip, read_len, offset;
 342        struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor;
 343        u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
 344        u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
 345        bool reset_ts = false;
 346        __le16 fifo_status;
 347        s64 ts = 0;
 348
 349        err = st_lsm6dsx_read_locked(hw,
 350                                     hw->settings->fifo_ops.fifo_diff.addr,
 351                                     &fifo_status, sizeof(fifo_status));
 352        if (err < 0) {
 353                dev_err(hw->dev, "failed to read fifo status (err=%d)\n",
 354                        err);
 355                return err;
 356        }
 357
 358        if (fifo_status & cpu_to_le16(ST_LSM6DSX_FIFO_EMPTY_MASK))
 359                return 0;
 360
 361        fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
 362                   ST_LSM6DSX_CHAN_SIZE;
 363        fifo_len = (fifo_len / pattern_len) * pattern_len;
 364
 365        acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
 366        gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
 367
 368        for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
 369                err = st_lsm6dsx_read_block(hw, ST_LSM6DSX_REG_FIFO_OUTL_ADDR,
 370                                            hw->buff, pattern_len,
 371                                            ST_LSM6DSX_MAX_WORD_LEN);
 372                if (err < 0) {
 373                        dev_err(hw->dev,
 374                                "failed to read pattern from fifo (err=%d)\n",
 375                                err);
 376                        return err;
 377                }
 378
 379                /*
 380                 * Data are written to the FIFO with a specific pattern
 381                 * depending on the configured ODRs. The first sequence of data
 382                 * stored in FIFO contains the data of all enabled sensors
 383                 * (e.g. Gx, Gy, Gz, Ax, Ay, Az, Ts), then data are repeated
 384                 * depending on the value of the decimation factor set for each
 385                 * sensor.
 386                 *
 387                 * Supposing the FIFO is storing data from gyroscope and
 388                 * accelerometer at different ODRs:
 389                 *   - gyroscope ODR = 208Hz, accelerometer ODR = 104Hz
 390                 * Since the gyroscope ODR is twice the accelerometer one, the
 391                 * following pattern is repeated every 9 samples:
 392                 *   - Gx, Gy, Gz, Ax, Ay, Az, Ts, Gx, Gy, Gz, Ts, Gx, ..
 393                 */
 394                gyro_sip = gyro_sensor->sip;
 395                acc_sip = acc_sensor->sip;
 396                ts_sip = hw->ts_sip;
 397                offset = 0;
 398
 399                while (acc_sip > 0 || gyro_sip > 0) {
 400                        if (gyro_sip > 0) {
 401                                memcpy(gyro_buff, &hw->buff[offset],
 402                                       ST_LSM6DSX_SAMPLE_SIZE);
 403                                offset += ST_LSM6DSX_SAMPLE_SIZE;
 404                        }
 405                        if (acc_sip > 0) {
 406                                memcpy(acc_buff, &hw->buff[offset],
 407                                       ST_LSM6DSX_SAMPLE_SIZE);
 408                                offset += ST_LSM6DSX_SAMPLE_SIZE;
 409                        }
 410
 411                        if (ts_sip-- > 0) {
 412                                u8 data[ST_LSM6DSX_SAMPLE_SIZE];
 413
 414                                memcpy(data, &hw->buff[offset], sizeof(data));
 415                                /*
 416                                 * hw timestamp is 3B long and it is stored
 417                                 * in FIFO using 6B as 4th FIFO data set
 418                                 * according to this schema:
 419                                 * B0 = ts[15:8], B1 = ts[23:16], B3 = ts[7:0]
 420                                 */
 421                                ts = data[1] << 16 | data[0] << 8 | data[3];
 422                                /*
 423                                 * check if hw timestamp engine is going to
 424                                 * reset (the sensor generates an interrupt
 425                                 * to signal the hw timestamp will reset in
 426                                 * 1.638s)
 427                                 */
 428                                if (!reset_ts && ts >= 0xff0000)
 429                                        reset_ts = true;
 430                                ts *= hw->ts_gain;
 431
 432                                offset += ST_LSM6DSX_SAMPLE_SIZE;
 433                        }
 434
 435                        if (gyro_sip-- > 0)
 436                                iio_push_to_buffers_with_timestamp(
 437                                        hw->iio_devs[ST_LSM6DSX_ID_GYRO],
 438                                        gyro_buff, gyro_sensor->ts_ref + ts);
 439                        if (acc_sip-- > 0)
 440                                iio_push_to_buffers_with_timestamp(
 441                                        hw->iio_devs[ST_LSM6DSX_ID_ACC],
 442                                        acc_buff, acc_sensor->ts_ref + ts);
 443                }
 444        }
 445
 446        if (unlikely(reset_ts)) {
 447                err = st_lsm6dsx_reset_hw_ts(hw);
 448                if (err < 0) {
 449                        dev_err(hw->dev, "failed to reset hw ts (err=%d)\n",
 450                                err);
 451                        return err;
 452                }
 453        }
 454        return read_len;
 455}
 456
 457#define ST_LSM6DSX_INVALID_SAMPLE       0x7ffd
 458static int
 459st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag,
 460                            u8 *data, s64 ts)
 461{
 462        s16 val = le16_to_cpu(*(__le16 *)data);
 463        struct st_lsm6dsx_sensor *sensor;
 464        struct iio_dev *iio_dev;
 465
 466        /* invalid sample during bootstrap phase */
 467        if (val >= ST_LSM6DSX_INVALID_SAMPLE)
 468                return -EINVAL;
 469
 470        /*
 471         * EXT_TAG are managed in FIFO fashion so ST_LSM6DSX_EXT0_TAG
 472         * corresponds to the first enabled channel, ST_LSM6DSX_EXT1_TAG
 473         * to the second one and ST_LSM6DSX_EXT2_TAG to the last enabled
 474         * channel
 475         */
 476        switch (tag) {
 477        case ST_LSM6DSX_GYRO_TAG:
 478                iio_dev = hw->iio_devs[ST_LSM6DSX_ID_GYRO];
 479                break;
 480        case ST_LSM6DSX_ACC_TAG:
 481                iio_dev = hw->iio_devs[ST_LSM6DSX_ID_ACC];
 482                break;
 483        case ST_LSM6DSX_EXT0_TAG:
 484                if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0))
 485                        iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT0];
 486                else if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1))
 487                        iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1];
 488                else
 489                        iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2];
 490                break;
 491        case ST_LSM6DSX_EXT1_TAG:
 492                if ((hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0)) &&
 493                    (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1)))
 494                        iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1];
 495                else
 496                        iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2];
 497                break;
 498        case ST_LSM6DSX_EXT2_TAG:
 499                iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2];
 500                break;
 501        default:
 502                return -EINVAL;
 503        }
 504
 505        sensor = iio_priv(iio_dev);
 506        iio_push_to_buffers_with_timestamp(iio_dev, data,
 507                                           ts + sensor->ts_ref);
 508
 509        return 0;
 510}
 511
 512/**
 513 * st_lsm6dsx_read_tagged_fifo() - tagged hw FIFO read routine
 514 * @hw: Pointer to instance of struct st_lsm6dsx_hw.
 515 *
 516 * Read samples from the hw FIFO and push them to IIO buffers.
 517 *
 518 * Return: Number of bytes read from the FIFO
 519 */
 520int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
 521{
 522        u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
 523        u16 fifo_len, fifo_diff_mask;
 524        u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE], tag;
 525        bool reset_ts = false;
 526        int i, err, read_len;
 527        __le16 fifo_status;
 528        s64 ts = 0;
 529
 530        err = st_lsm6dsx_read_locked(hw,
 531                                     hw->settings->fifo_ops.fifo_diff.addr,
 532                                     &fifo_status, sizeof(fifo_status));
 533        if (err < 0) {
 534                dev_err(hw->dev, "failed to read fifo status (err=%d)\n",
 535                        err);
 536                return err;
 537        }
 538
 539        fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
 540        fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
 541                   ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
 542        if (!fifo_len)
 543                return 0;
 544
 545        for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
 546                err = st_lsm6dsx_read_block(hw,
 547                                            ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR,
 548                                            hw->buff, pattern_len,
 549                                            ST_LSM6DSX_MAX_TAGGED_WORD_LEN);
 550                if (err < 0) {
 551                        dev_err(hw->dev,
 552                                "failed to read pattern from fifo (err=%d)\n",
 553                                err);
 554                        return err;
 555                }
 556
 557                for (i = 0; i < pattern_len;
 558                     i += ST_LSM6DSX_TAGGED_SAMPLE_SIZE) {
 559                        memcpy(iio_buff, &hw->buff[i + ST_LSM6DSX_TAG_SIZE],
 560                               ST_LSM6DSX_SAMPLE_SIZE);
 561
 562                        tag = hw->buff[i] >> 3;
 563                        if (tag == ST_LSM6DSX_TS_TAG) {
 564                                /*
 565                                 * hw timestamp is 4B long and it is stored
 566                                 * in FIFO according to this schema:
 567                                 * B0 = ts[7:0], B1 = ts[15:8], B2 = ts[23:16],
 568                                 * B3 = ts[31:24]
 569                                 */
 570                                ts = le32_to_cpu(*((__le32 *)iio_buff));
 571                                /*
 572                                 * check if hw timestamp engine is going to
 573                                 * reset (the sensor generates an interrupt
 574                                 * to signal the hw timestamp will reset in
 575                                 * 1.638s)
 576                                 */
 577                                if (!reset_ts && ts >= 0xffff0000)
 578                                        reset_ts = true;
 579                                ts *= hw->ts_gain;
 580                        } else {
 581                                st_lsm6dsx_push_tagged_data(hw, tag, iio_buff,
 582                                                            ts);
 583                        }
 584                }
 585        }
 586
 587        if (unlikely(reset_ts)) {
 588                err = st_lsm6dsx_reset_hw_ts(hw);
 589                if (err < 0)
 590                        return err;
 591        }
 592        return read_len;
 593}
 594
 595int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
 596{
 597        int err;
 598
 599        if (!hw->settings->fifo_ops.read_fifo)
 600                return -ENOTSUPP;
 601
 602        mutex_lock(&hw->fifo_lock);
 603
 604        hw->settings->fifo_ops.read_fifo(hw);
 605        err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_BYPASS);
 606
 607        mutex_unlock(&hw->fifo_lock);
 608
 609        return err;
 610}
 611
 612int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable)
 613{
 614        struct st_lsm6dsx_hw *hw = sensor->hw;
 615        u8 fifo_mask;
 616        int err;
 617
 618        mutex_lock(&hw->conf_lock);
 619
 620        if (enable)
 621                fifo_mask = hw->fifo_mask | BIT(sensor->id);
 622        else
 623                fifo_mask = hw->fifo_mask & ~BIT(sensor->id);
 624
 625        if (hw->fifo_mask) {
 626                err = st_lsm6dsx_flush_fifo(hw);
 627                if (err < 0)
 628                        goto out;
 629        }
 630
 631        if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
 632            sensor->id == ST_LSM6DSX_ID_EXT1 ||
 633            sensor->id == ST_LSM6DSX_ID_EXT2) {
 634                err = st_lsm6dsx_shub_set_enable(sensor, enable);
 635                if (err < 0)
 636                        goto out;
 637        } else {
 638                err = st_lsm6dsx_sensor_set_enable(sensor, enable);
 639                if (err < 0)
 640                        goto out;
 641
 642                err = st_lsm6dsx_set_fifo_odr(sensor, enable);
 643                if (err < 0)
 644                        goto out;
 645        }
 646
 647        err = st_lsm6dsx_update_decimators(hw);
 648        if (err < 0)
 649                goto out;
 650
 651        err = st_lsm6dsx_update_watermark(sensor, sensor->watermark);
 652        if (err < 0)
 653                goto out;
 654
 655        if (fifo_mask) {
 656                /* reset hw ts counter */
 657                err = st_lsm6dsx_reset_hw_ts(hw);
 658                if (err < 0)
 659                        goto out;
 660
 661                err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
 662                if (err < 0)
 663                        goto out;
 664        }
 665
 666        hw->fifo_mask = fifo_mask;
 667
 668out:
 669        mutex_unlock(&hw->conf_lock);
 670
 671        return err;
 672}
 673
 674static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev)
 675{
 676        struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
 677        struct st_lsm6dsx_hw *hw = sensor->hw;
 678
 679        if (!hw->settings->fifo_ops.update_fifo)
 680                return -ENOTSUPP;
 681
 682        return hw->settings->fifo_ops.update_fifo(sensor, true);
 683}
 684
 685static int st_lsm6dsx_buffer_postdisable(struct iio_dev *iio_dev)
 686{
 687        struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
 688        struct st_lsm6dsx_hw *hw = sensor->hw;
 689
 690        if (!hw->settings->fifo_ops.update_fifo)
 691                return -ENOTSUPP;
 692
 693        return hw->settings->fifo_ops.update_fifo(sensor, false);
 694}
 695
 696static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = {
 697        .preenable = st_lsm6dsx_buffer_preenable,
 698        .postdisable = st_lsm6dsx_buffer_postdisable,
 699};
 700
 701int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw)
 702{
 703        struct iio_buffer *buffer;
 704        int i;
 705
 706        for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
 707                if (!hw->iio_devs[i])
 708                        continue;
 709
 710                buffer = devm_iio_kfifo_allocate(hw->dev);
 711                if (!buffer)
 712                        return -ENOMEM;
 713
 714                iio_device_attach_buffer(hw->iio_devs[i], buffer);
 715                hw->iio_devs[i]->modes |= INDIO_BUFFER_SOFTWARE;
 716                hw->iio_devs[i]->setup_ops = &st_lsm6dsx_buffer_ops;
 717        }
 718
 719        return 0;
 720}
 721