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

inv_icm42600_buffer.c (16445B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (C) 2020 Invensense, Inc.
      4 */
      5
      6#include <linux/kernel.h>
      7#include <linux/device.h>
      8#include <linux/mutex.h>
      9#include <linux/pm_runtime.h>
     10#include <linux/regmap.h>
     11#include <linux/delay.h>
     12#include <linux/iio/iio.h>
     13#include <linux/iio/buffer.h>
     14
     15#include "inv_icm42600.h"
     16#include "inv_icm42600_timestamp.h"
     17#include "inv_icm42600_buffer.h"
     18
     19/* FIFO header: 1 byte */
     20#define INV_ICM42600_FIFO_HEADER_MSG		BIT(7)
     21#define INV_ICM42600_FIFO_HEADER_ACCEL		BIT(6)
     22#define INV_ICM42600_FIFO_HEADER_GYRO		BIT(5)
     23#define INV_ICM42600_FIFO_HEADER_TMST_FSYNC	GENMASK(3, 2)
     24#define INV_ICM42600_FIFO_HEADER_ODR_ACCEL	BIT(1)
     25#define INV_ICM42600_FIFO_HEADER_ODR_GYRO	BIT(0)
     26
     27struct inv_icm42600_fifo_1sensor_packet {
     28	uint8_t header;
     29	struct inv_icm42600_fifo_sensor_data data;
     30	int8_t temp;
     31} __packed;
     32#define INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE		8
     33
     34struct inv_icm42600_fifo_2sensors_packet {
     35	uint8_t header;
     36	struct inv_icm42600_fifo_sensor_data accel;
     37	struct inv_icm42600_fifo_sensor_data gyro;
     38	int8_t temp;
     39	__be16 timestamp;
     40} __packed;
     41#define INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE		16
     42
     43ssize_t inv_icm42600_fifo_decode_packet(const void *packet, const void **accel,
     44					const void **gyro, const int8_t **temp,
     45					const void **timestamp, unsigned int *odr)
     46{
     47	const struct inv_icm42600_fifo_1sensor_packet *pack1 = packet;
     48	const struct inv_icm42600_fifo_2sensors_packet *pack2 = packet;
     49	uint8_t header = *((const uint8_t *)packet);
     50
     51	/* FIFO empty */
     52	if (header & INV_ICM42600_FIFO_HEADER_MSG) {
     53		*accel = NULL;
     54		*gyro = NULL;
     55		*temp = NULL;
     56		*timestamp = NULL;
     57		*odr = 0;
     58		return 0;
     59	}
     60
     61	/* handle odr flags */
     62	*odr = 0;
     63	if (header & INV_ICM42600_FIFO_HEADER_ODR_GYRO)
     64		*odr |= INV_ICM42600_SENSOR_GYRO;
     65	if (header & INV_ICM42600_FIFO_HEADER_ODR_ACCEL)
     66		*odr |= INV_ICM42600_SENSOR_ACCEL;
     67
     68	/* accel + gyro */
     69	if ((header & INV_ICM42600_FIFO_HEADER_ACCEL) &&
     70	    (header & INV_ICM42600_FIFO_HEADER_GYRO)) {
     71		*accel = &pack2->accel;
     72		*gyro = &pack2->gyro;
     73		*temp = &pack2->temp;
     74		*timestamp = &pack2->timestamp;
     75		return INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE;
     76	}
     77
     78	/* accel only */
     79	if (header & INV_ICM42600_FIFO_HEADER_ACCEL) {
     80		*accel = &pack1->data;
     81		*gyro = NULL;
     82		*temp = &pack1->temp;
     83		*timestamp = NULL;
     84		return INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE;
     85	}
     86
     87	/* gyro only */
     88	if (header & INV_ICM42600_FIFO_HEADER_GYRO) {
     89		*accel = NULL;
     90		*gyro = &pack1->data;
     91		*temp = &pack1->temp;
     92		*timestamp = NULL;
     93		return INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE;
     94	}
     95
     96	/* invalid packet if here */
     97	return -EINVAL;
     98}
     99
    100void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st)
    101{
    102	uint32_t period_gyro, period_accel, period;
    103
    104	if (st->fifo.en & INV_ICM42600_SENSOR_GYRO)
    105		period_gyro = inv_icm42600_odr_to_period(st->conf.gyro.odr);
    106	else
    107		period_gyro = U32_MAX;
    108
    109	if (st->fifo.en & INV_ICM42600_SENSOR_ACCEL)
    110		period_accel = inv_icm42600_odr_to_period(st->conf.accel.odr);
    111	else
    112		period_accel = U32_MAX;
    113
    114	if (period_gyro <= period_accel)
    115		period = period_gyro;
    116	else
    117		period = period_accel;
    118
    119	st->fifo.period = period;
    120}
    121
    122int inv_icm42600_buffer_set_fifo_en(struct inv_icm42600_state *st,
    123				    unsigned int fifo_en)
    124{
    125	unsigned int mask, val;
    126	int ret;
    127
    128	/* update only FIFO EN bits */
    129	mask = INV_ICM42600_FIFO_CONFIG1_TMST_FSYNC_EN |
    130		INV_ICM42600_FIFO_CONFIG1_TEMP_EN |
    131		INV_ICM42600_FIFO_CONFIG1_GYRO_EN |
    132		INV_ICM42600_FIFO_CONFIG1_ACCEL_EN;
    133
    134	val = 0;
    135	if (fifo_en & INV_ICM42600_SENSOR_GYRO)
    136		val |= INV_ICM42600_FIFO_CONFIG1_GYRO_EN;
    137	if (fifo_en & INV_ICM42600_SENSOR_ACCEL)
    138		val |= INV_ICM42600_FIFO_CONFIG1_ACCEL_EN;
    139	if (fifo_en & INV_ICM42600_SENSOR_TEMP)
    140		val |= INV_ICM42600_FIFO_CONFIG1_TEMP_EN;
    141
    142	ret = regmap_update_bits(st->map, INV_ICM42600_REG_FIFO_CONFIG1, mask, val);
    143	if (ret)
    144		return ret;
    145
    146	st->fifo.en = fifo_en;
    147	inv_icm42600_buffer_update_fifo_period(st);
    148
    149	return 0;
    150}
    151
    152static size_t inv_icm42600_get_packet_size(unsigned int fifo_en)
    153{
    154	size_t packet_size;
    155
    156	if ((fifo_en & INV_ICM42600_SENSOR_GYRO) &&
    157	    (fifo_en & INV_ICM42600_SENSOR_ACCEL))
    158		packet_size = INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE;
    159	else
    160		packet_size = INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE;
    161
    162	return packet_size;
    163}
    164
    165static unsigned int inv_icm42600_wm_truncate(unsigned int watermark,
    166					     size_t packet_size)
    167{
    168	size_t wm_size;
    169	unsigned int wm;
    170
    171	wm_size = watermark * packet_size;
    172	if (wm_size > INV_ICM42600_FIFO_WATERMARK_MAX)
    173		wm_size = INV_ICM42600_FIFO_WATERMARK_MAX;
    174
    175	wm = wm_size / packet_size;
    176
    177	return wm;
    178}
    179
    180/**
    181 * inv_icm42600_buffer_update_watermark - update watermark FIFO threshold
    182 * @st:	driver internal state
    183 *
    184 * Returns 0 on success, a negative error code otherwise.
    185 *
    186 * FIFO watermark threshold is computed based on the required watermark values
    187 * set for gyro and accel sensors. Since watermark is all about acceptable data
    188 * latency, use the smallest setting between the 2. It means choosing the
    189 * smallest latency but this is not as simple as choosing the smallest watermark
    190 * value. Latency depends on watermark and ODR. It requires several steps:
    191 * 1) compute gyro and accel latencies and choose the smallest value.
    192 * 2) adapt the choosen latency so that it is a multiple of both gyro and accel
    193 *    ones. Otherwise it is possible that you don't meet a requirement. (for
    194 *    example with gyro @100Hz wm 4 and accel @100Hz with wm 6, choosing the
    195 *    value of 4 will not meet accel latency requirement because 6 is not a
    196 *    multiple of 4. You need to use the value 2.)
    197 * 3) Since all periods are multiple of each others, watermark is computed by
    198 *    dividing this computed latency by the smallest period, which corresponds
    199 *    to the FIFO frequency. Beware that this is only true because we are not
    200 *    using 500Hz frequency which is not a multiple of the others.
    201 */
    202int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st)
    203{
    204	size_t packet_size, wm_size;
    205	unsigned int wm_gyro, wm_accel, watermark;
    206	uint32_t period_gyro, period_accel, period;
    207	uint32_t latency_gyro, latency_accel, latency;
    208	bool restore;
    209	__le16 raw_wm;
    210	int ret;
    211
    212	packet_size = inv_icm42600_get_packet_size(st->fifo.en);
    213
    214	/* compute sensors latency, depending on sensor watermark and odr */
    215	wm_gyro = inv_icm42600_wm_truncate(st->fifo.watermark.gyro, packet_size);
    216	wm_accel = inv_icm42600_wm_truncate(st->fifo.watermark.accel, packet_size);
    217	/* use us for odr to avoid overflow using 32 bits values */
    218	period_gyro = inv_icm42600_odr_to_period(st->conf.gyro.odr) / 1000UL;
    219	period_accel = inv_icm42600_odr_to_period(st->conf.accel.odr) / 1000UL;
    220	latency_gyro = period_gyro * wm_gyro;
    221	latency_accel = period_accel * wm_accel;
    222
    223	/* 0 value for watermark means that the sensor is turned off */
    224	if (latency_gyro == 0) {
    225		watermark = wm_accel;
    226	} else if (latency_accel == 0) {
    227		watermark = wm_gyro;
    228	} else {
    229		/* compute the smallest latency that is a multiple of both */
    230		if (latency_gyro <= latency_accel)
    231			latency = latency_gyro - (latency_accel % latency_gyro);
    232		else
    233			latency = latency_accel - (latency_gyro % latency_accel);
    234		/* use the shortest period */
    235		if (period_gyro <= period_accel)
    236			period = period_gyro;
    237		else
    238			period = period_accel;
    239		/* all this works because periods are multiple of each others */
    240		watermark = latency / period;
    241		if (watermark < 1)
    242			watermark = 1;
    243	}
    244
    245	/* compute watermark value in bytes */
    246	wm_size = watermark * packet_size;
    247
    248	/* changing FIFO watermark requires to turn off watermark interrupt */
    249	ret = regmap_update_bits_check(st->map, INV_ICM42600_REG_INT_SOURCE0,
    250				       INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN,
    251				       0, &restore);
    252	if (ret)
    253		return ret;
    254
    255	raw_wm = INV_ICM42600_FIFO_WATERMARK_VAL(wm_size);
    256	memcpy(st->buffer, &raw_wm, sizeof(raw_wm));
    257	ret = regmap_bulk_write(st->map, INV_ICM42600_REG_FIFO_WATERMARK,
    258				st->buffer, sizeof(raw_wm));
    259	if (ret)
    260		return ret;
    261
    262	/* restore watermark interrupt */
    263	if (restore) {
    264		ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0,
    265					 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN,
    266					 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN);
    267		if (ret)
    268			return ret;
    269	}
    270
    271	return 0;
    272}
    273
    274static int inv_icm42600_buffer_preenable(struct iio_dev *indio_dev)
    275{
    276	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
    277	struct device *dev = regmap_get_device(st->map);
    278
    279	pm_runtime_get_sync(dev);
    280
    281	return 0;
    282}
    283
    284/*
    285 * update_scan_mode callback is turning sensors on and setting data FIFO enable
    286 * bits.
    287 */
    288static int inv_icm42600_buffer_postenable(struct iio_dev *indio_dev)
    289{
    290	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
    291	int ret;
    292
    293	mutex_lock(&st->lock);
    294
    295	/* exit if FIFO is already on */
    296	if (st->fifo.on) {
    297		ret = 0;
    298		goto out_on;
    299	}
    300
    301	/* set FIFO threshold interrupt */
    302	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0,
    303				 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN,
    304				 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN);
    305	if (ret)
    306		goto out_unlock;
    307
    308	/* flush FIFO data */
    309	ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET,
    310			   INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH);
    311	if (ret)
    312		goto out_unlock;
    313
    314	/* set FIFO in streaming mode */
    315	ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
    316			   INV_ICM42600_FIFO_CONFIG_STREAM);
    317	if (ret)
    318		goto out_unlock;
    319
    320	/* workaround: first read of FIFO count after reset is always 0 */
    321	ret = regmap_bulk_read(st->map, INV_ICM42600_REG_FIFO_COUNT, st->buffer, 2);
    322	if (ret)
    323		goto out_unlock;
    324
    325out_on:
    326	/* increase FIFO on counter */
    327	st->fifo.on++;
    328out_unlock:
    329	mutex_unlock(&st->lock);
    330	return ret;
    331}
    332
    333static int inv_icm42600_buffer_predisable(struct iio_dev *indio_dev)
    334{
    335	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
    336	int ret;
    337
    338	mutex_lock(&st->lock);
    339
    340	/* exit if there are several sensors using the FIFO */
    341	if (st->fifo.on > 1) {
    342		ret = 0;
    343		goto out_off;
    344	}
    345
    346	/* set FIFO in bypass mode */
    347	ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
    348			   INV_ICM42600_FIFO_CONFIG_BYPASS);
    349	if (ret)
    350		goto out_unlock;
    351
    352	/* flush FIFO data */
    353	ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET,
    354			   INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH);
    355	if (ret)
    356		goto out_unlock;
    357
    358	/* disable FIFO threshold interrupt */
    359	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0,
    360				 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN, 0);
    361	if (ret)
    362		goto out_unlock;
    363
    364out_off:
    365	/* decrease FIFO on counter */
    366	st->fifo.on--;
    367out_unlock:
    368	mutex_unlock(&st->lock);
    369	return ret;
    370}
    371
    372static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev)
    373{
    374	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
    375	struct device *dev = regmap_get_device(st->map);
    376	unsigned int sensor;
    377	unsigned int *watermark;
    378	struct inv_icm42600_timestamp *ts;
    379	struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
    380	unsigned int sleep_temp = 0;
    381	unsigned int sleep_sensor = 0;
    382	unsigned int sleep;
    383	int ret;
    384
    385	if (indio_dev == st->indio_gyro) {
    386		sensor = INV_ICM42600_SENSOR_GYRO;
    387		watermark = &st->fifo.watermark.gyro;
    388		ts = iio_priv(st->indio_gyro);
    389	} else if (indio_dev == st->indio_accel) {
    390		sensor = INV_ICM42600_SENSOR_ACCEL;
    391		watermark = &st->fifo.watermark.accel;
    392		ts = iio_priv(st->indio_accel);
    393	} else {
    394		return -EINVAL;
    395	}
    396
    397	mutex_lock(&st->lock);
    398
    399	ret = inv_icm42600_buffer_set_fifo_en(st, st->fifo.en & ~sensor);
    400	if (ret)
    401		goto out_unlock;
    402
    403	*watermark = 0;
    404	ret = inv_icm42600_buffer_update_watermark(st);
    405	if (ret)
    406		goto out_unlock;
    407
    408	conf.mode = INV_ICM42600_SENSOR_MODE_OFF;
    409	if (sensor == INV_ICM42600_SENSOR_GYRO)
    410		ret = inv_icm42600_set_gyro_conf(st, &conf, &sleep_sensor);
    411	else
    412		ret = inv_icm42600_set_accel_conf(st, &conf, &sleep_sensor);
    413	if (ret)
    414		goto out_unlock;
    415
    416	/* if FIFO is off, turn temperature off */
    417	if (!st->fifo.on)
    418		ret = inv_icm42600_set_temp_conf(st, false, &sleep_temp);
    419
    420	inv_icm42600_timestamp_reset(ts);
    421
    422out_unlock:
    423	mutex_unlock(&st->lock);
    424
    425	/* sleep maximum required time */
    426	if (sleep_sensor > sleep_temp)
    427		sleep = sleep_sensor;
    428	else
    429		sleep = sleep_temp;
    430	if (sleep)
    431		msleep(sleep);
    432
    433	pm_runtime_mark_last_busy(dev);
    434	pm_runtime_put_autosuspend(dev);
    435
    436	return ret;
    437}
    438
    439const struct iio_buffer_setup_ops inv_icm42600_buffer_ops = {
    440	.preenable = inv_icm42600_buffer_preenable,
    441	.postenable = inv_icm42600_buffer_postenable,
    442	.predisable = inv_icm42600_buffer_predisable,
    443	.postdisable = inv_icm42600_buffer_postdisable,
    444};
    445
    446int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st,
    447				  unsigned int max)
    448{
    449	size_t max_count;
    450	__be16 *raw_fifo_count;
    451	ssize_t i, size;
    452	const void *accel, *gyro, *timestamp;
    453	const int8_t *temp;
    454	unsigned int odr;
    455	int ret;
    456
    457	/* reset all samples counters */
    458	st->fifo.count = 0;
    459	st->fifo.nb.gyro = 0;
    460	st->fifo.nb.accel = 0;
    461	st->fifo.nb.total = 0;
    462
    463	/* compute maximum FIFO read size */
    464	if (max == 0)
    465		max_count = sizeof(st->fifo.data);
    466	else
    467		max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
    468
    469	/* read FIFO count value */
    470	raw_fifo_count = (__be16 *)st->buffer;
    471	ret = regmap_bulk_read(st->map, INV_ICM42600_REG_FIFO_COUNT,
    472			       raw_fifo_count, sizeof(*raw_fifo_count));
    473	if (ret)
    474		return ret;
    475	st->fifo.count = be16_to_cpup(raw_fifo_count);
    476
    477	/* check and clamp FIFO count value */
    478	if (st->fifo.count == 0)
    479		return 0;
    480	if (st->fifo.count > max_count)
    481		st->fifo.count = max_count;
    482
    483	/* read all FIFO data in internal buffer */
    484	ret = regmap_noinc_read(st->map, INV_ICM42600_REG_FIFO_DATA,
    485				st->fifo.data, st->fifo.count);
    486	if (ret)
    487		return ret;
    488
    489	/* compute number of samples for each sensor */
    490	for (i = 0; i < st->fifo.count; i += size) {
    491		size = inv_icm42600_fifo_decode_packet(&st->fifo.data[i],
    492				&accel, &gyro, &temp, &timestamp, &odr);
    493		if (size <= 0)
    494			break;
    495		if (gyro != NULL && inv_icm42600_fifo_is_data_valid(gyro))
    496			st->fifo.nb.gyro++;
    497		if (accel != NULL && inv_icm42600_fifo_is_data_valid(accel))
    498			st->fifo.nb.accel++;
    499		st->fifo.nb.total++;
    500	}
    501
    502	return 0;
    503}
    504
    505int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
    506{
    507	struct inv_icm42600_timestamp *ts;
    508	int ret;
    509
    510	if (st->fifo.nb.total == 0)
    511		return 0;
    512
    513	/* handle gyroscope timestamp and FIFO data parsing */
    514	ts = iio_priv(st->indio_gyro);
    515	inv_icm42600_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
    516					 st->fifo.nb.gyro, st->timestamp.gyro);
    517	if (st->fifo.nb.gyro > 0) {
    518		ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
    519		if (ret)
    520			return ret;
    521	}
    522
    523	/* handle accelerometer timestamp and FIFO data parsing */
    524	ts = iio_priv(st->indio_accel);
    525	inv_icm42600_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
    526					 st->fifo.nb.accel, st->timestamp.accel);
    527	if (st->fifo.nb.accel > 0) {
    528		ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
    529		if (ret)
    530			return ret;
    531	}
    532
    533	return 0;
    534}
    535
    536int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
    537				     unsigned int count)
    538{
    539	struct inv_icm42600_timestamp *ts;
    540	int64_t gyro_ts, accel_ts;
    541	int ret;
    542
    543	gyro_ts = iio_get_time_ns(st->indio_gyro);
    544	accel_ts = iio_get_time_ns(st->indio_accel);
    545
    546	ret = inv_icm42600_buffer_fifo_read(st, count);
    547	if (ret)
    548		return ret;
    549
    550	if (st->fifo.nb.total == 0)
    551		return 0;
    552
    553	if (st->fifo.nb.gyro > 0) {
    554		ts = iio_priv(st->indio_gyro);
    555		inv_icm42600_timestamp_interrupt(ts, st->fifo.period,
    556						 st->fifo.nb.total, st->fifo.nb.gyro,
    557						 gyro_ts);
    558		ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
    559		if (ret)
    560			return ret;
    561	}
    562
    563	if (st->fifo.nb.accel > 0) {
    564		ts = iio_priv(st->indio_accel);
    565		inv_icm42600_timestamp_interrupt(ts, st->fifo.period,
    566						 st->fifo.nb.total, st->fifo.nb.accel,
    567						 accel_ts);
    568		ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
    569		if (ret)
    570			return ret;
    571	}
    572
    573	return 0;
    574}
    575
    576int inv_icm42600_buffer_init(struct inv_icm42600_state *st)
    577{
    578	unsigned int val;
    579	int ret;
    580
    581	/*
    582	 * Default FIFO configuration (bits 7 to 5)
    583	 * - use invalid value
    584	 * - FIFO count in bytes
    585	 * - FIFO count in big endian
    586	 */
    587	val = INV_ICM42600_INTF_CONFIG0_FIFO_COUNT_ENDIAN;
    588	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0,
    589				 GENMASK(7, 5), val);
    590	if (ret)
    591		return ret;
    592
    593	/*
    594	 * Enable FIFO partial read and continuous watermark interrupt.
    595	 * Disable all FIFO EN bits.
    596	 */
    597	val = INV_ICM42600_FIFO_CONFIG1_RESUME_PARTIAL_RD |
    598	      INV_ICM42600_FIFO_CONFIG1_WM_GT_TH;
    599	return regmap_update_bits(st->map, INV_ICM42600_REG_FIFO_CONFIG1,
    600				  GENMASK(6, 5) | GENMASK(3, 0), val);
    601}