cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

st_lsm6dsx_buffer.c (20142B)


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