// SPDX-License-Identifier: GPL-2.0
/*
 * IIO core driver for Bosch BMI323 6-Axis IMU.
 *
 * Copyright (C) 2023, Jagath Jog J <jagathjog1996@gmail.com>
 *
 * Datasheet: https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmi323-ds000.pdf
 */

#include <linux/bitfield.h>
#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/units.h>

#include <asm/unaligned.h>

#include <linux/iio/buffer.h>
#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>

#include "bmi323.h"

enum bmi323_sensor_type {
	BMI323_ACCEL,
	BMI323_GYRO,
	BMI323_SENSORS_CNT,
};

enum bmi323_opr_mode {
	ACC_GYRO_MODE_DISABLE = 0x00,
	GYRO_DRIVE_MODE_ENABLED = 0x01,
	ACC_GYRO_MODE_DUTYCYCLE = 0x03,
	ACC_GYRO_MODE_CONTINOUS = 0x04,
	ACC_GYRO_MODE_HIGH_PERF = 0x07,
};

enum bmi323_state {
	BMI323_IDLE,
	BMI323_BUFFER_DRDY_TRIGGERED,
	BMI323_BUFFER_FIFO,
};

enum bmi323_irq_pin {
	BMI323_IRQ_DISABLED,
	BMI323_IRQ_INT1,
	BMI323_IRQ_INT2,
};

enum bmi323_3db_bw {
	BMI323_BW_ODR_BY_2,
	BMI323_BW_ODR_BY_4,
};

enum bmi323_scan {
	BMI323_ACCEL_X,
	BMI323_ACCEL_Y,
	BMI323_ACCEL_Z,
	BMI323_GYRO_X,
	BMI323_GYRO_Y,
	BMI323_GYRO_Z,
	BMI323_CHAN_MAX
};

struct bmi323_hw {
	u8 data;
	u8 config;
	const int (*scale_table)[2];
	int scale_table_len;
};

/*
 * The accelerometer supports +-2G/4G/8G/16G ranges, and the resolution of
 * each sample is 16 bits, signed.
 * At +-8G the scale can calculated by
 * ((8 + 8) * 9.80665 / (2^16 - 1)) * 10^6 = 2394.23819 scale in micro
 *
 */
static const int bmi323_accel_scale[][2] = {
	{ 0, 598 },
	{ 0, 1197 },
	{ 0, 2394 },
	{ 0, 4788 },
};

static const int bmi323_gyro_scale[][2] = {
	{ 0, 66 },
	{ 0, 133 },
	{ 0, 266 },
	{ 0, 532 },
	{ 0, 1065 },
};

static const int bmi323_accel_gyro_avrg[] = {0, 2, 4, 8, 16, 32, 64};

static const struct bmi323_hw bmi323_hw[2] = {
	[BMI323_ACCEL] = {
		.data = BMI323_ACCEL_X_REG,
		.config = BMI323_ACC_CONF_REG,
		.scale_table = bmi323_accel_scale,
		.scale_table_len = ARRAY_SIZE(bmi323_accel_scale),
	},
	[BMI323_GYRO] = {
		.data = BMI323_GYRO_X_REG,
		.config = BMI323_GYRO_CONF_REG,
		.scale_table = bmi323_gyro_scale,
		.scale_table_len = ARRAY_SIZE(bmi323_gyro_scale),
	},
};

struct bmi323_data {
	struct device *dev;
	struct regmap *regmap;
	struct iio_mount_matrix orientation;
	enum bmi323_irq_pin irq_pin;
	struct iio_trigger *trig;
	bool drdy_trigger_enabled;
	enum bmi323_state state;
	s64 fifo_tstamp, old_fifo_tstamp;
	u32 odrns[BMI323_SENSORS_CNT];
	u32 odrhz[BMI323_SENSORS_CNT];
	unsigned int feature_events;

	/*
	 * Lock to protect the members of device's private data from concurrent
	 * access and also to serialize the access of extended registers.
	 * See bmi323_write_ext_reg(..) for more info.
	 */
	struct mutex mutex;
	int watermark;
	__le16 fifo_buff[BMI323_FIFO_FULL_IN_WORDS] __aligned(IIO_DMA_MINALIGN);
	struct {
		__le16 channels[BMI323_CHAN_MAX];
		s64 ts __aligned(8);
	} buffer;
	__le16 steps_count[BMI323_STEP_LEN];
};

static const struct iio_mount_matrix *
bmi323_get_mount_matrix(const struct iio_dev *idev,
			const struct iio_chan_spec *chan)
{
	struct bmi323_data *data = iio_priv(idev);

	return &data->orientation;
}

static const struct iio_chan_spec_ext_info bmi323_ext_info[] = {
	IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, bmi323_get_mount_matrix),
	{ }
};

static const struct iio_event_spec bmi323_step_wtrmrk_event = {
	.type = IIO_EV_TYPE_CHANGE,
	.dir = IIO_EV_DIR_NONE,
	.mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |
			       BIT(IIO_EV_INFO_VALUE),
};

static const struct iio_event_spec bmi323_accel_event[] = {
	{
		.type = IIO_EV_TYPE_MAG,
		.dir = IIO_EV_DIR_FALLING,
		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
				       BIT(IIO_EV_INFO_PERIOD) |
				       BIT(IIO_EV_INFO_HYSTERESIS) |
				       BIT(IIO_EV_INFO_ENABLE),
	},
	{
		.type = IIO_EV_TYPE_MAG,
		.dir = IIO_EV_DIR_RISING,
		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
				       BIT(IIO_EV_INFO_PERIOD) |
				       BIT(IIO_EV_INFO_HYSTERESIS) |
				       BIT(IIO_EV_INFO_ENABLE),
	},
	{
		.type = IIO_EV_TYPE_GESTURE,
		.dir = IIO_EV_DIR_SINGLETAP,
		.mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |
				       BIT(IIO_EV_INFO_VALUE) |
				       BIT(IIO_EV_INFO_RESET_TIMEOUT),
	},
	{
		.type = IIO_EV_TYPE_GESTURE,
		.dir = IIO_EV_DIR_DOUBLETAP,
		.mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |
				       BIT(IIO_EV_INFO_VALUE) |
				       BIT(IIO_EV_INFO_RESET_TIMEOUT) |
				       BIT(IIO_EV_INFO_TAP2_MIN_DELAY),
	},
};

#define BMI323_ACCEL_CHANNEL(_type, _axis, _index) {			\
	.type = _type,							\
	.modified = 1,							\
	.channel2 = IIO_MOD_##_axis,					\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
				    BIT(IIO_CHAN_INFO_SCALE) |		\
				    BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
	.info_mask_shared_by_type_available =				\
				    BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
				    BIT(IIO_CHAN_INFO_SCALE) |		\
				    BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
	.scan_index = _index,						\
	.scan_type = {							\
		.sign = 's',						\
		.realbits = 16,						\
		.storagebits = 16,					\
		.endianness = IIO_LE,					\
	},								\
	.ext_info = bmi323_ext_info,					\
	.event_spec = bmi323_accel_event,				\
	.num_event_specs = ARRAY_SIZE(bmi323_accel_event),		\
}

#define BMI323_GYRO_CHANNEL(_type, _axis, _index) {			\
	.type = _type,							\
	.modified = 1,							\
	.channel2 = IIO_MOD_##_axis,					\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
				    BIT(IIO_CHAN_INFO_SCALE) |		\
				    BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
	.info_mask_shared_by_type_available =				\
				    BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
				    BIT(IIO_CHAN_INFO_SCALE) |		\
				    BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
	.scan_index = _index,						\
	.scan_type = {							\
		.sign = 's',						\
		.realbits = 16,						\
		.storagebits = 16,					\
		.endianness = IIO_LE,					\
	},								\
	.ext_info = bmi323_ext_info,					\
}

static const struct iio_chan_spec bmi323_channels[] = {
	BMI323_ACCEL_CHANNEL(IIO_ACCEL, X, BMI323_ACCEL_X),
	BMI323_ACCEL_CHANNEL(IIO_ACCEL, Y, BMI323_ACCEL_Y),
	BMI323_ACCEL_CHANNEL(IIO_ACCEL, Z, BMI323_ACCEL_Z),
	BMI323_GYRO_CHANNEL(IIO_ANGL_VEL, X, BMI323_GYRO_X),
	BMI323_GYRO_CHANNEL(IIO_ANGL_VEL, Y, BMI323_GYRO_Y),
	BMI323_GYRO_CHANNEL(IIO_ANGL_VEL, Z, BMI323_GYRO_Z),
	{
		.type = IIO_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_OFFSET) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.scan_index = -1,
	},
	{
		.type = IIO_STEPS,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
				      BIT(IIO_CHAN_INFO_ENABLE),
		.scan_index = -1,
		.event_spec = &bmi323_step_wtrmrk_event,
		.num_event_specs = 1,

	},
	IIO_CHAN_SOFT_TIMESTAMP(BMI323_CHAN_MAX),
};

static const int bmi323_acc_gyro_odr[][2] = {
	{ 0, 781250 },
	{ 1, 562500 },
	{ 3, 125000 },
	{ 6, 250000 },
	{ 12, 500000 },
	{ 25, 0 },
	{ 50, 0 },
	{ 100, 0 },
	{ 200, 0 },
	{ 400, 0 },
	{ 800, 0 },
};

static const int bmi323_acc_gyro_odrns[] = {
	1280 * MEGA,
	640 * MEGA,
	320 * MEGA,
	160 * MEGA,
	80 * MEGA,
	40 * MEGA,
	20 * MEGA,
	10 * MEGA,
	5 * MEGA,
	2500 * KILO,
	1250 * KILO,
};

static enum bmi323_sensor_type bmi323_iio_to_sensor(enum iio_chan_type iio_type)
{
	switch (iio_type) {
	case IIO_ACCEL:
		return BMI323_ACCEL;
	case IIO_ANGL_VEL:
		return BMI323_GYRO;
	default:
		return -EINVAL;
	}
}

static int bmi323_set_mode(struct bmi323_data *data,
			   enum bmi323_sensor_type sensor,
			   enum bmi323_opr_mode mode)
{
	guard(mutex)(&data->mutex);
	return regmap_update_bits(data->regmap, bmi323_hw[sensor].config,
				  BMI323_ACC_GYRO_CONF_MODE_MSK,
				  FIELD_PREP(BMI323_ACC_GYRO_CONF_MODE_MSK,
					     mode));
}

/*
 * When writing data to extended register there must be no communication to
 * any other register before write transaction is complete.
 * See datasheet section 6.2 Extended Register Map Description.
 */
static int bmi323_write_ext_reg(struct bmi323_data *data, unsigned int ext_addr,
				unsigned int ext_data)
{
	int ret, feature_status;

	ret = regmap_read(data->regmap, BMI323_FEAT_DATA_STATUS,
			  &feature_status);
	if (ret)
		return ret;

	if (!FIELD_GET(BMI323_FEAT_DATA_TX_RDY_MSK, feature_status))
		return -EBUSY;

	ret = regmap_write(data->regmap, BMI323_FEAT_DATA_ADDR, ext_addr);
	if (ret)
		return ret;

	return regmap_write(data->regmap, BMI323_FEAT_DATA_TX, ext_data);
}

/*
 * When reading data from extended register there must be no communication to
 * any other register before read transaction is complete.
 * See datasheet section 6.2 Extended Register Map Description.
 */
static int bmi323_read_ext_reg(struct bmi323_data *data, unsigned int ext_addr,
			       unsigned int *ext_data)
{
	int ret, feature_status;

	ret = regmap_read(data->regmap, BMI323_FEAT_DATA_STATUS,
			  &feature_status);
	if (ret)
		return ret;

	if (!FIELD_GET(BMI323_FEAT_DATA_TX_RDY_MSK, feature_status))
		return -EBUSY;

	ret = regmap_write(data->regmap, BMI323_FEAT_DATA_ADDR, ext_addr);
	if (ret)
		return ret;

	return regmap_read(data->regmap, BMI323_FEAT_DATA_TX, ext_data);
}

static int bmi323_update_ext_reg(struct bmi323_data *data,
				 unsigned int ext_addr,
				 unsigned int mask, unsigned int ext_data)
{
	unsigned int value;
	int ret;

	ret = bmi323_read_ext_reg(data, ext_addr, &value);
	if (ret)
		return ret;

	set_mask_bits(&value, mask, ext_data);

	return bmi323_write_ext_reg(data, ext_addr, value);
}

static int bmi323_get_error_status(struct bmi323_data *data)
{
	int error, ret;

	guard(mutex)(&data->mutex);
	ret = regmap_read(data->regmap, BMI323_ERR_REG, &error);
	if (ret)
		return ret;

	if (error)
		dev_err(data->dev, "Sensor error 0x%x\n", error);

	return error;
}

static int bmi323_feature_engine_events(struct bmi323_data *data,
					const unsigned int event_mask,
					bool state)
{
	unsigned int value;
	int ret;

	ret = regmap_read(data->regmap, BMI323_FEAT_IO0_REG, &value);
	if (ret)
		return ret;

	/* Register must be cleared before changing an active config */
	ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, 0);
	if (ret)
		return ret;

	if (state)
		value |= event_mask;
	else
		value &= ~event_mask;

	ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, value);
	if (ret)
		return ret;

	return regmap_write(data->regmap, BMI323_FEAT_IO_STATUS_REG,
			    BMI323_FEAT_IO_STATUS_MSK);
}

static int bmi323_step_wtrmrk_en(struct bmi323_data *data, int state)
{
	enum bmi323_irq_pin step_irq;
	int ret;

	guard(mutex)(&data->mutex);
	if (!FIELD_GET(BMI323_FEAT_IO0_STP_CNT_MSK, data->feature_events))
		return -EINVAL;

	if (state)
		step_irq = data->irq_pin;
	else
		step_irq = BMI323_IRQ_DISABLED;

	ret = bmi323_update_ext_reg(data, BMI323_STEP_SC1_REG,
				    BMI323_STEP_SC1_WTRMRK_MSK,
				    FIELD_PREP(BMI323_STEP_SC1_WTRMRK_MSK,
					       state ? 1 : 0));
	if (ret)
		return ret;

	return regmap_update_bits(data->regmap, BMI323_INT_MAP1_REG,
				  BMI323_STEP_CNT_MSK,
				  FIELD_PREP(BMI323_STEP_CNT_MSK, step_irq));
}

static int bmi323_motion_config_reg(enum iio_event_direction dir)
{
	switch (dir) {
	case IIO_EV_DIR_RISING:
		return BMI323_ANYMO1_REG;
	case IIO_EV_DIR_FALLING:
		return BMI323_NOMO1_REG;
	default:
		return -EINVAL;
	}
}

static int bmi323_motion_event_en(struct bmi323_data *data,
				  enum iio_event_direction dir, int state)
{
	unsigned int state_value = state ? BMI323_FEAT_XYZ_MSK : 0;
	int config, ret, msk, raw, field_value;
	enum bmi323_irq_pin motion_irq;
	int irq_msk, irq_field_val;

	if (state)
		motion_irq = data->irq_pin;
	else
		motion_irq = BMI323_IRQ_DISABLED;

	switch (dir) {
	case IIO_EV_DIR_RISING:
		msk = BMI323_FEAT_IO0_XYZ_MOTION_MSK;
		raw = 512;
		config = BMI323_ANYMO1_REG;
		irq_msk = BMI323_MOTION_MSK;
		irq_field_val = FIELD_PREP(BMI323_MOTION_MSK, motion_irq);
		field_value = FIELD_PREP(BMI323_FEAT_IO0_XYZ_MOTION_MSK,
					 state_value);
		break;
	case IIO_EV_DIR_FALLING:
		msk = BMI323_FEAT_IO0_XYZ_NOMOTION_MSK;
		raw = 0;
		config = BMI323_NOMO1_REG;
		irq_msk = BMI323_NOMOTION_MSK;
		irq_field_val = FIELD_PREP(BMI323_NOMOTION_MSK, motion_irq);
		field_value = FIELD_PREP(BMI323_FEAT_IO0_XYZ_NOMOTION_MSK,
					 state_value);
		break;
	default:
		return -EINVAL;
	}

	guard(mutex)(&data->mutex);
	ret = bmi323_feature_engine_events(data, msk, state);
	if (ret)
		return ret;

	ret = bmi323_update_ext_reg(data, config,
				    BMI323_MO1_REF_UP_MSK,
				    FIELD_PREP(BMI323_MO1_REF_UP_MSK, 0));
	if (ret)
		return ret;

	/* Set initial value to avoid interrupts while enabling*/
	ret = bmi323_update_ext_reg(data, config,
				    BMI323_MO1_SLOPE_TH_MSK,
				    FIELD_PREP(BMI323_MO1_SLOPE_TH_MSK, raw));
	if (ret)
		return ret;

	ret = regmap_update_bits(data->regmap, BMI323_INT_MAP1_REG, irq_msk,
				 irq_field_val);
	if (ret)
		return ret;

	set_mask_bits(&data->feature_events, msk, field_value);

	return 0;
}

static int bmi323_tap_event_en(struct bmi323_data *data,
			       enum iio_event_direction dir, int state)
{
	enum bmi323_irq_pin tap_irq;
	int ret, tap_enabled;

	guard(mutex)(&data->mutex);

	if (data->odrhz[BMI323_ACCEL] < 200) {
		dev_err(data->dev, "Invalid accelerometer parameter\n");
		return -EINVAL;
	}

	switch (dir) {
	case IIO_EV_DIR_SINGLETAP:
		ret = bmi323_feature_engine_events(data,
						   BMI323_FEAT_IO0_S_TAP_MSK,
						   state);
		if (ret)
			return ret;

		set_mask_bits(&data->feature_events, BMI323_FEAT_IO0_S_TAP_MSK,
			      FIELD_PREP(BMI323_FEAT_IO0_S_TAP_MSK, state));
		break;
	case IIO_EV_DIR_DOUBLETAP:
		ret = bmi323_feature_engine_events(data,
						   BMI323_FEAT_IO0_D_TAP_MSK,
						   state);
		if (ret)
			return ret;

		set_mask_bits(&data->feature_events, BMI323_FEAT_IO0_D_TAP_MSK,
			      FIELD_PREP(BMI323_FEAT_IO0_D_TAP_MSK, state));
		break;
	default:
		return -EINVAL;
	}

	tap_enabled = FIELD_GET(BMI323_FEAT_IO0_S_TAP_MSK |
				BMI323_FEAT_IO0_D_TAP_MSK,
				data->feature_events);

	if (tap_enabled)
		tap_irq = data->irq_pin;
	else
		tap_irq = BMI323_IRQ_DISABLED;

	ret = regmap_update_bits(data->regmap, BMI323_INT_MAP2_REG,
				 BMI323_TAP_MSK,
				 FIELD_PREP(BMI323_TAP_MSK, tap_irq));
	if (ret)
		return ret;

	if (!state)
		return 0;

	ret = bmi323_update_ext_reg(data, BMI323_TAP1_REG,
				    BMI323_TAP1_MAX_PEAKS_MSK,
				    FIELD_PREP(BMI323_TAP1_MAX_PEAKS_MSK,
					       0x04));
	if (ret)
		return ret;

	ret = bmi323_update_ext_reg(data, BMI323_TAP1_REG,
				    BMI323_TAP1_AXIS_SEL_MSK,
				    FIELD_PREP(BMI323_TAP1_AXIS_SEL_MSK,
					       BMI323_AXIS_XYZ_MSK));
	if (ret)
		return ret;

	return bmi323_update_ext_reg(data, BMI323_TAP1_REG,
				     BMI323_TAP1_TIMOUT_MSK,
				     FIELD_PREP(BMI323_TAP1_TIMOUT_MSK,
						0));
}

static ssize_t in_accel_gesture_tap_wait_dur_show(struct device *dev,
						  struct device_attribute *attr,
						  char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct bmi323_data *data = iio_priv(indio_dev);
	unsigned int reg_value, raw;
	int ret, val[2];

	scoped_guard(mutex, &data->mutex) {
		ret = bmi323_read_ext_reg(data, BMI323_TAP2_REG, &reg_value);
		if (ret)
			return ret;
	}

	raw = FIELD_GET(BMI323_TAP2_MAX_DUR_MSK, reg_value);
	val[0] = raw / BMI323_MAX_GES_DUR_SCALE;
	val[1] = BMI323_RAW_TO_MICRO(raw, BMI323_MAX_GES_DUR_SCALE);

	return iio_format_value(buf, IIO_VAL_INT_PLUS_MICRO, ARRAY_SIZE(val),
				val);
}

static ssize_t in_accel_gesture_tap_wait_dur_store(struct device *dev,
						   struct device_attribute *attr,
						   const char *buf, size_t len)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct bmi323_data *data = iio_priv(indio_dev);
	int ret, val_int, val_fract, raw;

	ret = iio_str_to_fixpoint(buf, 100000, &val_int, &val_fract);
	if (ret)
		return ret;

	raw = BMI323_INT_MICRO_TO_RAW(val_int, val_fract,
				      BMI323_MAX_GES_DUR_SCALE);
	if (!in_range(raw, 0, 64))
		return -EINVAL;

	guard(mutex)(&data->mutex);
	ret = bmi323_update_ext_reg(data, BMI323_TAP2_REG,
				    BMI323_TAP2_MAX_DUR_MSK,
				    FIELD_PREP(BMI323_TAP2_MAX_DUR_MSK, raw));
	if (ret)
		return ret;

	return len;
}

/*
 * Maximum duration from first tap within the second tap is expected to happen.
 * This timeout is applicable only if gesture_tap_wait_timeout is enabled.
 */
static IIO_DEVICE_ATTR_RW(in_accel_gesture_tap_wait_dur, 0);

static ssize_t in_accel_gesture_tap_wait_timeout_show(struct device *dev,
						      struct device_attribute *attr,
						      char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct bmi323_data *data = iio_priv(indio_dev);
	unsigned int reg_value, raw;
	int ret;

	scoped_guard(mutex, &data->mutex) {
		ret = bmi323_read_ext_reg(data, BMI323_TAP1_REG, &reg_value);
		if (ret)
			return ret;
	}

	raw = FIELD_GET(BMI323_TAP1_TIMOUT_MSK, reg_value);

	return iio_format_value(buf, IIO_VAL_INT, 1, &raw);
}

static ssize_t in_accel_gesture_tap_wait_timeout_store(struct device *dev,
						       struct device_attribute *attr,
						       const char *buf,
						       size_t len)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct bmi323_data *data = iio_priv(indio_dev);
	bool val;
	int ret;

	ret = kstrtobool(buf, &val);
	if (ret)
		return ret;

	guard(mutex)(&data->mutex);
	ret = bmi323_update_ext_reg(data, BMI323_TAP1_REG,
				    BMI323_TAP1_TIMOUT_MSK,
				    FIELD_PREP(BMI323_TAP1_TIMOUT_MSK, val));
	if (ret)
		return ret;

	return len;
}

/* Enable/disable gesture confirmation with wait time */
static IIO_DEVICE_ATTR_RW(in_accel_gesture_tap_wait_timeout, 0);

static IIO_CONST_ATTR(in_accel_gesture_tap_wait_dur_available,
		      "[0.0 0.04 2.52]");

static IIO_CONST_ATTR(in_accel_gesture_doubletap_tap2_min_delay_available,
		      "[0.005 0.005 0.075]");

static IIO_CONST_ATTR(in_accel_gesture_tap_reset_timeout_available,
		      "[0.04 0.04 0.6]");

static IIO_CONST_ATTR(in_accel_gesture_tap_value_available, "[0.0 0.002 1.99]");

static IIO_CONST_ATTR(in_accel_mag_value_available, "[0.0 0.002 7.99]");

static IIO_CONST_ATTR(in_accel_mag_period_available, "[0.0 0.02 162.0]");

static IIO_CONST_ATTR(in_accel_mag_hysteresis_available, "[0.0 0.002 1.99]");

static struct attribute *bmi323_event_attributes[] = {
	&iio_const_attr_in_accel_gesture_tap_value_available.dev_attr.attr,
	&iio_const_attr_in_accel_gesture_tap_reset_timeout_available.dev_attr.attr,
	&iio_const_attr_in_accel_gesture_doubletap_tap2_min_delay_available.dev_attr.attr,
	&iio_const_attr_in_accel_gesture_tap_wait_dur_available.dev_attr.attr,
	&iio_dev_attr_in_accel_gesture_tap_wait_timeout.dev_attr.attr,
	&iio_dev_attr_in_accel_gesture_tap_wait_dur.dev_attr.attr,
	&iio_const_attr_in_accel_mag_value_available.dev_attr.attr,
	&iio_const_attr_in_accel_mag_period_available.dev_attr.attr,
	&iio_const_attr_in_accel_mag_hysteresis_available.dev_attr.attr,
	NULL
};

static const struct attribute_group bmi323_event_attribute_group = {
	.attrs = bmi323_event_attributes,
};

static int bmi323_write_event_config(struct iio_dev *indio_dev,
				     const struct iio_chan_spec *chan,
				     enum iio_event_type type,
				     enum iio_event_direction dir, int state)
{
	struct bmi323_data *data = iio_priv(indio_dev);

	switch (type) {
	case IIO_EV_TYPE_MAG:
		return bmi323_motion_event_en(data, dir, state);
	case IIO_EV_TYPE_GESTURE:
		return bmi323_tap_event_en(data, dir, state);
	case IIO_EV_TYPE_CHANGE:
		return bmi323_step_wtrmrk_en(data, state);
	default:
		return -EINVAL;
	}
}

static int bmi323_read_event_config(struct iio_dev *indio_dev,
				    const struct iio_chan_spec *chan,
				    enum iio_event_type type,
				    enum iio_event_direction dir)
{
	struct bmi323_data *data = iio_priv(indio_dev);
	int ret, value, reg_val;

	guard(mutex)(&data->mutex);

	switch (chan->type) {
	case IIO_ACCEL:
		switch (dir) {
		case IIO_EV_DIR_SINGLETAP:
			ret = FIELD_GET(BMI323_FEAT_IO0_S_TAP_MSK,
					data->feature_events);
			break;
		case IIO_EV_DIR_DOUBLETAP:
			ret = FIELD_GET(BMI323_FEAT_IO0_D_TAP_MSK,
					data->feature_events);
			break;
		case IIO_EV_DIR_RISING:
			value = FIELD_GET(BMI323_FEAT_IO0_XYZ_MOTION_MSK,
					  data->feature_events);
			ret = value ? 1 : 0;
			break;
		case IIO_EV_DIR_FALLING:
			value = FIELD_GET(BMI323_FEAT_IO0_XYZ_NOMOTION_MSK,
					  data->feature_events);
			ret = value ? 1 : 0;
			break;
		default:
			ret = -EINVAL;
			break;
		}
		return ret;
	case IIO_STEPS:
		ret = regmap_read(data->regmap, BMI323_INT_MAP1_REG, &reg_val);
		if (ret)
			return ret;

		return FIELD_GET(BMI323_STEP_CNT_MSK, reg_val) ? 1 : 0;
	default:
		return -EINVAL;
	}
}

static int bmi323_write_event_value(struct iio_dev *indio_dev,
				    const struct iio_chan_spec *chan,
				    enum iio_event_type type,
				    enum iio_event_direction dir,
				    enum iio_event_info info,
				    int val, int val2)
{
	struct bmi323_data *data = iio_priv(indio_dev);
	unsigned int raw;
	int reg;

	guard(mutex)(&data->mutex);

	switch (type) {
	case IIO_EV_TYPE_GESTURE:
		switch (info) {
		case IIO_EV_INFO_VALUE:
			if (!in_range(val, 0, 2))
				return -EINVAL;

			raw = BMI323_INT_MICRO_TO_RAW(val, val2,
						      BMI323_TAP_THRES_SCALE);

			return bmi323_update_ext_reg(data, BMI323_TAP2_REG,
						     BMI323_TAP2_THRES_MSK,
						     FIELD_PREP(BMI323_TAP2_THRES_MSK,
								raw));
		case IIO_EV_INFO_RESET_TIMEOUT:
			if (val || !in_range(val2, 40000, 560001))
				return -EINVAL;

			raw = BMI323_INT_MICRO_TO_RAW(val, val2,
						      BMI323_QUITE_TIM_GES_SCALE);

			return bmi323_update_ext_reg(data, BMI323_TAP3_REG,
						     BMI323_TAP3_QT_AFT_GES_MSK,
						     FIELD_PREP(BMI323_TAP3_QT_AFT_GES_MSK,
								raw));
		case IIO_EV_INFO_TAP2_MIN_DELAY:
			if (val || !in_range(val2, 5000, 70001))
				return -EINVAL;

			raw = BMI323_INT_MICRO_TO_RAW(val, val2,
						      BMI323_DUR_BW_TAP_SCALE);

			return bmi323_update_ext_reg(data, BMI323_TAP3_REG,
						     BMI323_TAP3_QT_BW_TAP_MSK,
						     FIELD_PREP(BMI323_TAP3_QT_BW_TAP_MSK,
								raw));
		default:
			return -EINVAL;
		}
	case IIO_EV_TYPE_MAG:
		reg = bmi323_motion_config_reg(dir);
		if (reg < 0)
			return -EINVAL;

		switch (info) {
		case IIO_EV_INFO_VALUE:
			if (!in_range(val, 0, 8))
				return -EINVAL;

			raw = BMI323_INT_MICRO_TO_RAW(val, val2,
						      BMI323_MOTION_THRES_SCALE);

			return bmi323_update_ext_reg(data, reg,
						     BMI323_MO1_SLOPE_TH_MSK,
						     FIELD_PREP(BMI323_MO1_SLOPE_TH_MSK,
								raw));
		case IIO_EV_INFO_PERIOD:
			if (!in_range(val, 0, 163))
				return -EINVAL;

			raw = BMI323_INT_MICRO_TO_RAW(val, val2,
						      BMI323_MOTION_DURAT_SCALE);

			return bmi323_update_ext_reg(data,
						     reg + BMI323_MO3_OFFSET,
						     BMI323_MO3_DURA_MSK,
						     FIELD_PREP(BMI323_MO3_DURA_MSK,
								raw));
		case IIO_EV_INFO_HYSTERESIS:
			if (!in_range(val, 0, 2))
				return -EINVAL;

			raw = BMI323_INT_MICRO_TO_RAW(val, val2,
						      BMI323_MOTION_HYSTR_SCALE);

			return bmi323_update_ext_reg(data,
						     reg + BMI323_MO2_OFFSET,
						     BMI323_MO2_HYSTR_MSK,
						     FIELD_PREP(BMI323_MO2_HYSTR_MSK,
								raw));
		default:
			return -EINVAL;
		}
	case IIO_EV_TYPE_CHANGE:
		if (!in_range(val, 0, 20461))
			return -EINVAL;

		raw = val / 20;
		return bmi323_update_ext_reg(data, BMI323_STEP_SC1_REG,
					     BMI323_STEP_SC1_WTRMRK_MSK,
					     FIELD_PREP(BMI323_STEP_SC1_WTRMRK_MSK,
							raw));
	default:
		return -EINVAL;
	}
}

static int bmi323_read_event_value(struct iio_dev *indio_dev,
				   const struct iio_chan_spec *chan,
				   enum iio_event_type type,
				   enum iio_event_direction dir,
				   enum iio_event_info info,
				   int *val, int *val2)
{
	struct bmi323_data *data = iio_priv(indio_dev);
	unsigned int raw, reg_value;
	int ret, reg;

	guard(mutex)(&data->mutex);

	switch (type) {
	case IIO_EV_TYPE_GESTURE:
		switch (info) {
		case IIO_EV_INFO_VALUE:
			ret = bmi323_read_ext_reg(data, BMI323_TAP2_REG,
						  &reg_value);
			if (ret)
				return ret;

			raw = FIELD_GET(BMI323_TAP2_THRES_MSK, reg_value);
			*val = raw / BMI323_TAP_THRES_SCALE;
			*val2 = BMI323_RAW_TO_MICRO(raw, BMI323_TAP_THRES_SCALE);
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_EV_INFO_RESET_TIMEOUT:
			ret = bmi323_read_ext_reg(data, BMI323_TAP3_REG,
						  &reg_value);
			if (ret)
				return ret;

			raw = FIELD_GET(BMI323_TAP3_QT_AFT_GES_MSK, reg_value);
			*val = 0;
			*val2 = BMI323_RAW_TO_MICRO(raw,
						    BMI323_QUITE_TIM_GES_SCALE);
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_EV_INFO_TAP2_MIN_DELAY:
			ret = bmi323_read_ext_reg(data, BMI323_TAP3_REG,
						  &reg_value);
			if (ret)
				return ret;

			raw = FIELD_GET(BMI323_TAP3_QT_BW_TAP_MSK, reg_value);
			*val = 0;
			*val2 = BMI323_RAW_TO_MICRO(raw,
						    BMI323_DUR_BW_TAP_SCALE);
			return IIO_VAL_INT_PLUS_MICRO;
		default:
			return -EINVAL;
		}
	case IIO_EV_TYPE_MAG:
		reg = bmi323_motion_config_reg(dir);
		if (reg < 0)
			return -EINVAL;

		switch (info) {
		case IIO_EV_INFO_VALUE:
			ret = bmi323_read_ext_reg(data, reg, &reg_value);
			if (ret)
				return ret;

			raw = FIELD_GET(BMI323_MO1_SLOPE_TH_MSK, reg_value);
			*val = raw / BMI323_MOTION_THRES_SCALE;
			*val2 = BMI323_RAW_TO_MICRO(raw,
						    BMI323_MOTION_THRES_SCALE);
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_EV_INFO_PERIOD:
			ret = bmi323_read_ext_reg(data,
						  reg + BMI323_MO3_OFFSET,
						  &reg_value);
			if (ret)
				return ret;

			raw = FIELD_GET(BMI323_MO3_DURA_MSK, reg_value);
			*val = raw / BMI323_MOTION_DURAT_SCALE;
			*val2 = BMI323_RAW_TO_MICRO(raw,
						    BMI323_MOTION_DURAT_SCALE);
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_EV_INFO_HYSTERESIS:
			ret = bmi323_read_ext_reg(data,
						  reg + BMI323_MO2_OFFSET,
						  &reg_value);
			if (ret)
				return ret;

			raw = FIELD_GET(BMI323_MO2_HYSTR_MSK, reg_value);
			*val = raw / BMI323_MOTION_HYSTR_SCALE;
			*val2 = BMI323_RAW_TO_MICRO(raw,
						    BMI323_MOTION_HYSTR_SCALE);
			return IIO_VAL_INT_PLUS_MICRO;
		default:
			return -EINVAL;
		}
	case IIO_EV_TYPE_CHANGE:
		ret = bmi323_read_ext_reg(data, BMI323_STEP_SC1_REG,
					  &reg_value);
		if (ret)
			return ret;

		raw = FIELD_GET(BMI323_STEP_SC1_WTRMRK_MSK, reg_value);
		*val = raw * 20;
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int __bmi323_fifo_flush(struct iio_dev *indio_dev)
{
	struct bmi323_data *data = iio_priv(indio_dev);
	int i, ret, fifo_lvl, frame_count, bit, index;
	__le16 *frame, *pchannels;
	u64 sample_period;
	s64 tstamp;

	guard(mutex)(&data->mutex);
	ret = regmap_read(data->regmap, BMI323_FIFO_FILL_LEVEL_REG, &fifo_lvl);
	if (ret)
		return ret;

	fifo_lvl = min(fifo_lvl, BMI323_FIFO_FULL_IN_WORDS);

	frame_count = fifo_lvl / BMI323_FIFO_FRAME_LENGTH;
	if (!frame_count)
		return -EINVAL;

	if (fifo_lvl % BMI323_FIFO_FRAME_LENGTH)
		dev_warn(data->dev, "Bad FIFO alignment\n");

	/*
	 * Approximate timestamps for each of the sample based on the sampling
	 * frequency, timestamp for last sample and number of samples.
	 */
	if (data->old_fifo_tstamp) {
		sample_period = data->fifo_tstamp - data->old_fifo_tstamp;
		do_div(sample_period, frame_count);
	} else {
		sample_period = data->odrns[BMI323_ACCEL];
	}

	tstamp = data->fifo_tstamp - (frame_count - 1) * sample_period;

	ret = regmap_noinc_read(data->regmap, BMI323_FIFO_DATA_REG,
				&data->fifo_buff[0],
				fifo_lvl * BMI323_BYTES_PER_SAMPLE);
	if (ret)
		return ret;

	for (i = 0; i < frame_count; i++) {
		frame = &data->fifo_buff[i * BMI323_FIFO_FRAME_LENGTH];
		pchannels = &data->buffer.channels[0];

		index = 0;
		for_each_set_bit(bit, indio_dev->active_scan_mask,
				 BMI323_CHAN_MAX)
			pchannels[index++] = frame[bit];

		iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
						   tstamp);

		tstamp += sample_period;
	}

	return frame_count;
}

static int bmi323_set_watermark(struct iio_dev *indio_dev, unsigned int val)
{
	struct bmi323_data *data = iio_priv(indio_dev);

	val = min(val, (u32)BMI323_FIFO_FULL_IN_FRAMES);

	guard(mutex)(&data->mutex);
	data->watermark = val;

	return 0;
}

static int bmi323_fifo_disable(struct bmi323_data *data)
{
	int ret;

	guard(mutex)(&data->mutex);
	ret = regmap_write(data->regmap, BMI323_FIFO_CONF_REG, 0);
	if (ret)
		return ret;

	ret = regmap_update_bits(data->regmap, BMI323_INT_MAP2_REG,
				 BMI323_FIFO_WTRMRK_MSK,
				 FIELD_PREP(BMI323_FIFO_WTRMRK_MSK, 0));
	if (ret)
		return ret;

	data->fifo_tstamp = 0;
	data->state = BMI323_IDLE;

	return 0;
}

static int bmi323_buffer_predisable(struct iio_dev *indio_dev)
{
	struct bmi323_data *data = iio_priv(indio_dev);

	if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED)
		return 0;

	return bmi323_fifo_disable(data);
}

static int bmi323_update_watermark(struct bmi323_data *data)
{
	int wtrmrk;

	wtrmrk = data->watermark * BMI323_FIFO_FRAME_LENGTH;

	return regmap_write(data->regmap, BMI323_FIFO_WTRMRK_REG, wtrmrk);
}

static int bmi323_fifo_enable(struct bmi323_data *data)
{
	int ret;

	guard(mutex)(&data->mutex);
	ret = regmap_update_bits(data->regmap, BMI323_FIFO_CONF_REG,
				 BMI323_FIFO_CONF_ACC_GYR_EN_MSK,
				 FIELD_PREP(BMI323_FIFO_CONF_ACC_GYR_EN_MSK,
					    BMI323_FIFO_ACC_GYR_MSK));
	if (ret)
		return ret;

	ret = regmap_update_bits(data->regmap, BMI323_INT_MAP2_REG,
				 BMI323_FIFO_WTRMRK_MSK,
				 FIELD_PREP(BMI323_FIFO_WTRMRK_MSK,
					    data->irq_pin));
	if (ret)
		return ret;

	ret = bmi323_update_watermark(data);
	if (ret)
		return ret;

	ret = regmap_write(data->regmap, BMI323_FIFO_CTRL_REG,
			   BMI323_FIFO_FLUSH_MSK);
	if (ret)
		return ret;

	data->state = BMI323_BUFFER_FIFO;

	return 0;
}

static int bmi323_buffer_preenable(struct iio_dev *indio_dev)
{
	struct bmi323_data *data = iio_priv(indio_dev);

	guard(mutex)(&data->mutex);
	/*
	 * When the ODR of the accelerometer and gyroscope do not match, the
	 * maximum ODR value between the accelerometer and gyroscope is used
	 * for FIFO and the signal with lower ODR will insert dummy frame.
	 * So allow buffer read only when ODR's of accelero and gyro are equal.
	 * See datasheet section 5.7 "FIFO Data Buffering".
	 */
	if (data->odrns[BMI323_ACCEL] != data->odrns[BMI323_GYRO]) {
		dev_err(data->dev, "Accelero and Gyro ODR doesn't match\n");
		return -EINVAL;
	}

	return 0;
}

static int bmi323_buffer_postenable(struct iio_dev *indio_dev)
{
	struct bmi323_data *data = iio_priv(indio_dev);

	if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED)
		return 0;

	return bmi323_fifo_enable(data);
}

static ssize_t hwfifo_watermark_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct bmi323_data *data = iio_priv(indio_dev);
	int wm;

	scoped_guard(mutex, &data->mutex)
		wm = data->watermark;

	return sysfs_emit(buf, "%d\n", wm);
}
static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0);

static ssize_t hwfifo_enabled_show(struct device *dev,
				   struct device_attribute *attr,
				   char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct bmi323_data *data = iio_priv(indio_dev);
	bool state;

	scoped_guard(mutex, &data->mutex)
		state = data->state == BMI323_BUFFER_FIFO;

	return sysfs_emit(buf, "%d\n", state);
}
static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0);

static const struct iio_dev_attr *bmi323_fifo_attributes[] = {
	&iio_dev_attr_hwfifo_watermark,
	&iio_dev_attr_hwfifo_enabled,
	NULL
};

static const struct iio_buffer_setup_ops bmi323_buffer_ops = {
	.preenable = bmi323_buffer_preenable,
	.postenable = bmi323_buffer_postenable,
	.predisable = bmi323_buffer_predisable,
};

static irqreturn_t bmi323_irq_thread_handler(int irq, void *private)
{
	struct iio_dev *indio_dev = private;
	struct bmi323_data *data = iio_priv(indio_dev);
	unsigned int status_addr, status, feature_event;
	s64 timestamp = iio_get_time_ns(indio_dev);
	int ret;

	if (data->irq_pin == BMI323_IRQ_INT1)
		status_addr = BMI323_STATUS_INT1_REG;
	else
		status_addr = BMI323_STATUS_INT2_REG;

	scoped_guard(mutex, &data->mutex) {
		ret = regmap_read(data->regmap, status_addr, &status);
		if (ret)
			return IRQ_NONE;
	}

	if (!status || FIELD_GET(BMI323_STATUS_ERROR_MSK, status))
		return IRQ_NONE;

	if (FIELD_GET(BMI323_STATUS_FIFO_WTRMRK_MSK, status)) {
		data->old_fifo_tstamp = data->fifo_tstamp;
		data->fifo_tstamp = iio_get_time_ns(indio_dev);
		ret = __bmi323_fifo_flush(indio_dev);
		if (ret < 0)
			return IRQ_NONE;
	}

	if (FIELD_GET(BMI323_STATUS_ACC_GYR_DRDY_MSK, status))
		iio_trigger_poll_nested(data->trig);

	if (FIELD_GET(BMI323_STATUS_MOTION_MSK, status))
		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0,
							     IIO_MOD_X_OR_Y_OR_Z,
							     IIO_EV_TYPE_MAG,
							     IIO_EV_DIR_RISING),
			       timestamp);

	if (FIELD_GET(BMI323_STATUS_NOMOTION_MSK, status))
		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0,
							     IIO_MOD_X_OR_Y_OR_Z,
							     IIO_EV_TYPE_MAG,
							     IIO_EV_DIR_FALLING),
			       timestamp);

	if (FIELD_GET(BMI323_STATUS_STP_WTR_MSK, status))
		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_STEPS, 0,
							     IIO_NO_MOD,
							     IIO_EV_TYPE_CHANGE,
							     IIO_EV_DIR_NONE),
			       timestamp);

	if (FIELD_GET(BMI323_STATUS_TAP_MSK, status)) {
		scoped_guard(mutex, &data->mutex) {
			ret = regmap_read(data->regmap,
					  BMI323_FEAT_EVNT_EXT_REG,
					  &feature_event);
			if (ret)
				return IRQ_NONE;
		}

		if (FIELD_GET(BMI323_FEAT_EVNT_EXT_S_MSK, feature_event)) {
			iio_push_event(indio_dev,
				       IIO_MOD_EVENT_CODE(IIO_ACCEL, 0,
							  IIO_MOD_X_OR_Y_OR_Z,
							  IIO_EV_TYPE_GESTURE,
							  IIO_EV_DIR_SINGLETAP),
				       timestamp);
		}

		if (FIELD_GET(BMI323_FEAT_EVNT_EXT_D_MSK, feature_event))
			iio_push_event(indio_dev,
				       IIO_MOD_EVENT_CODE(IIO_ACCEL, 0,
							  IIO_MOD_X_OR_Y_OR_Z,
							  IIO_EV_TYPE_GESTURE,
							  IIO_EV_DIR_DOUBLETAP),
				       timestamp);
	}

	return IRQ_HANDLED;
}

static int bmi323_set_drdy_irq(struct bmi323_data *data,
			       enum bmi323_irq_pin irq_pin)
{
	int ret;

	ret = regmap_update_bits(data->regmap, BMI323_INT_MAP2_REG,
				 BMI323_GYR_DRDY_MSK,
				 FIELD_PREP(BMI323_GYR_DRDY_MSK, irq_pin));
	if (ret)
		return ret;

	return regmap_update_bits(data->regmap, BMI323_INT_MAP2_REG,
				  BMI323_ACC_DRDY_MSK,
				  FIELD_PREP(BMI323_ACC_DRDY_MSK, irq_pin));
}

static int bmi323_data_rdy_trigger_set_state(struct iio_trigger *trig,
					     bool state)
{
	struct bmi323_data *data = iio_trigger_get_drvdata(trig);
	enum bmi323_irq_pin irq_pin;

	guard(mutex)(&data->mutex);

	if (data->state == BMI323_BUFFER_FIFO) {
		dev_warn(data->dev, "Can't set trigger when FIFO enabled\n");
		return -EBUSY;
	}

	if (state) {
		data->state = BMI323_BUFFER_DRDY_TRIGGERED;
		irq_pin = data->irq_pin;
	} else {
		data->state = BMI323_IDLE;
		irq_pin = BMI323_IRQ_DISABLED;
	}

	return bmi323_set_drdy_irq(data, irq_pin);
}

static const struct iio_trigger_ops bmi323_trigger_ops = {
	.set_trigger_state = &bmi323_data_rdy_trigger_set_state,
};

static irqreturn_t bmi323_trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct bmi323_data *data = iio_priv(indio_dev);
	int ret, bit, index = 0;

	/* Lock to protect the data->buffer */
	guard(mutex)(&data->mutex);

	if (*indio_dev->active_scan_mask == BMI323_ALL_CHAN_MSK) {
		ret = regmap_bulk_read(data->regmap, BMI323_ACCEL_X_REG,
				       &data->buffer.channels,
				       ARRAY_SIZE(data->buffer.channels));
		if (ret)
			return IRQ_NONE;
	} else {
		for_each_set_bit(bit, indio_dev->active_scan_mask,
				 BMI323_CHAN_MAX) {
			ret = regmap_raw_read(data->regmap,
					      BMI323_ACCEL_X_REG + bit,
					      &data->buffer.channels[index++],
					      BMI323_BYTES_PER_SAMPLE);
			if (ret)
				return IRQ_NONE;
		}
	}

	iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
					   iio_get_time_ns(indio_dev));

	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

static int bmi323_set_average(struct bmi323_data *data,
			      enum bmi323_sensor_type sensor, int avg)
{
	int raw = ARRAY_SIZE(bmi323_accel_gyro_avrg);

	while (raw--)
		if (avg == bmi323_accel_gyro_avrg[raw])
			break;
	if (raw < 0)
		return -EINVAL;

	guard(mutex)(&data->mutex);
	return regmap_update_bits(data->regmap, bmi323_hw[sensor].config,
				 BMI323_ACC_GYRO_CONF_AVG_MSK,
				 FIELD_PREP(BMI323_ACC_GYRO_CONF_AVG_MSK,
					    raw));
}

static int bmi323_get_average(struct bmi323_data *data,
			      enum bmi323_sensor_type sensor, int *avg)
{
	int ret, value, raw;

	scoped_guard(mutex, &data->mutex) {
		ret = regmap_read(data->regmap, bmi323_hw[sensor].config, &value);
		if (ret)
			return ret;
	}

	raw = FIELD_GET(BMI323_ACC_GYRO_CONF_AVG_MSK, value);
	*avg = bmi323_accel_gyro_avrg[raw];

	return IIO_VAL_INT;
}

static int bmi323_enable_steps(struct bmi323_data *data, int val)
{
	int ret;

	guard(mutex)(&data->mutex);
	if (data->odrhz[BMI323_ACCEL] < 200) {
		dev_err(data->dev, "Invalid accelerometer parameter\n");
		return -EINVAL;
	}

	ret = bmi323_feature_engine_events(data, BMI323_FEAT_IO0_STP_CNT_MSK,
					   val ? 1 : 0);
	if (ret)
		return ret;

	set_mask_bits(&data->feature_events, BMI323_FEAT_IO0_STP_CNT_MSK,
		      FIELD_PREP(BMI323_FEAT_IO0_STP_CNT_MSK, val ? 1 : 0));

	return 0;
}

static int bmi323_read_steps(struct bmi323_data *data, int *val)
{
	int ret;

	guard(mutex)(&data->mutex);
	if (!FIELD_GET(BMI323_FEAT_IO0_STP_CNT_MSK, data->feature_events))
		return -EINVAL;

	ret = regmap_bulk_read(data->regmap, BMI323_FEAT_IO2_REG,
			       data->steps_count,
			       ARRAY_SIZE(data->steps_count));
	if (ret)
		return ret;

	*val = get_unaligned_le32(data->steps_count);

	return IIO_VAL_INT;
}

static int bmi323_read_axis(struct bmi323_data *data,
			    struct iio_chan_spec const *chan, int *val)
{
	enum bmi323_sensor_type sensor;
	unsigned int value;
	u8 addr;
	int ret;

	ret = bmi323_get_error_status(data);
	if (ret)
		return -EINVAL;

	sensor = bmi323_iio_to_sensor(chan->type);
	addr = bmi323_hw[sensor].data + (chan->channel2 - IIO_MOD_X);

	scoped_guard(mutex, &data->mutex) {
		ret = regmap_read(data->regmap, addr, &value);
		if (ret)
			return ret;
	}

	*val = sign_extend32(value, chan->scan_type.realbits - 1);

	return IIO_VAL_INT;
}

static int bmi323_get_temp_data(struct bmi323_data *data, int *val)
{
	unsigned int value;
	int ret;

	ret = bmi323_get_error_status(data);
	if (ret)
		return -EINVAL;

	scoped_guard(mutex, &data->mutex) {
		ret = regmap_read(data->regmap, BMI323_TEMP_REG, &value);
		if (ret)
			return ret;
	}

	*val = sign_extend32(value, 15);

	return IIO_VAL_INT;
}

static int bmi323_get_odr(struct bmi323_data *data,
			  enum bmi323_sensor_type sensor, int *odr, int *uodr)
{
	int ret, value, odr_raw;

	scoped_guard(mutex, &data->mutex) {
		ret = regmap_read(data->regmap, bmi323_hw[sensor].config, &value);
		if (ret)
			return ret;
	}

	odr_raw = FIELD_GET(BMI323_ACC_GYRO_CONF_ODR_MSK, value);
	*odr = bmi323_acc_gyro_odr[odr_raw - 1][0];
	*uodr = bmi323_acc_gyro_odr[odr_raw - 1][1];

	return IIO_VAL_INT_PLUS_MICRO;
}

static int bmi323_configure_power_mode(struct bmi323_data *data,
				       enum bmi323_sensor_type sensor,
				       int odr_index)
{
	enum bmi323_opr_mode mode;

	if (bmi323_acc_gyro_odr[odr_index][0] > 25)
		mode = ACC_GYRO_MODE_CONTINOUS;
	else
		mode = ACC_GYRO_MODE_DUTYCYCLE;

	return bmi323_set_mode(data, sensor, mode);
}

static int bmi323_set_odr(struct bmi323_data *data,
			  enum bmi323_sensor_type sensor, int odr, int uodr)
{
	int odr_raw, ret;

	odr_raw = ARRAY_SIZE(bmi323_acc_gyro_odr);

	while (odr_raw--)
		if (odr == bmi323_acc_gyro_odr[odr_raw][0] &&
		    uodr == bmi323_acc_gyro_odr[odr_raw][1])
			break;
	if (odr_raw < 0)
		return -EINVAL;

	ret = bmi323_configure_power_mode(data, sensor, odr_raw);
	if (ret)
		return -EINVAL;

	guard(mutex)(&data->mutex);
	data->odrhz[sensor] = bmi323_acc_gyro_odr[odr_raw][0];
	data->odrns[sensor] = bmi323_acc_gyro_odrns[odr_raw];

	odr_raw++;

	return regmap_update_bits(data->regmap, bmi323_hw[sensor].config,
				  BMI323_ACC_GYRO_CONF_ODR_MSK,
				  FIELD_PREP(BMI323_ACC_GYRO_CONF_ODR_MSK,
					     odr_raw));
}

static int bmi323_get_scale(struct bmi323_data *data,
			    enum bmi323_sensor_type sensor, int *val2)
{
	int ret, value, scale_raw;

	scoped_guard(mutex, &data->mutex) {
		ret = regmap_read(data->regmap, bmi323_hw[sensor].config,
				  &value);
		if (ret)
			return ret;
	}

	scale_raw = FIELD_GET(BMI323_ACC_GYRO_CONF_SCL_MSK, value);
	*val2 = bmi323_hw[sensor].scale_table[scale_raw][1];

	return IIO_VAL_INT_PLUS_MICRO;
}

static int bmi323_set_scale(struct bmi323_data *data,
			    enum bmi323_sensor_type sensor, int val, int val2)
{
	int scale_raw;

	scale_raw = bmi323_hw[sensor].scale_table_len;

	while (scale_raw--)
		if (val == bmi323_hw[sensor].scale_table[scale_raw][0] &&
		    val2 == bmi323_hw[sensor].scale_table[scale_raw][1])
			break;
	if (scale_raw < 0)
		return -EINVAL;

	guard(mutex)(&data->mutex);
	return regmap_update_bits(data->regmap, bmi323_hw[sensor].config,
				  BMI323_ACC_GYRO_CONF_SCL_MSK,
				  FIELD_PREP(BMI323_ACC_GYRO_CONF_SCL_MSK,
					     scale_raw));
}

static int bmi323_read_avail(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     const int **vals, int *type, int *length,
			     long mask)
{
	enum bmi323_sensor_type sensor;

	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		*type = IIO_VAL_INT_PLUS_MICRO;
		*vals = (const int *)bmi323_acc_gyro_odr;
		*length = ARRAY_SIZE(bmi323_acc_gyro_odr) * 2;
		return IIO_AVAIL_LIST;
	case IIO_CHAN_INFO_SCALE:
		sensor = bmi323_iio_to_sensor(chan->type);
		*type = IIO_VAL_INT_PLUS_MICRO;
		*vals = (const int *)bmi323_hw[sensor].scale_table;
		*length = bmi323_hw[sensor].scale_table_len * 2;
		return IIO_AVAIL_LIST;
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		*type = IIO_VAL_INT;
		*vals = (const int *)bmi323_accel_gyro_avrg;
		*length = ARRAY_SIZE(bmi323_accel_gyro_avrg);
		return IIO_AVAIL_LIST;
	default:
		return -EINVAL;
	}
}

static int bmi323_write_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int val,
			    int val2, long mask)
{
	struct bmi323_data *data = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		ret = iio_device_claim_direct_mode(indio_dev);
		if (ret)
			return ret;

		ret = bmi323_set_odr(data, bmi323_iio_to_sensor(chan->type),
				     val, val2);
		iio_device_release_direct_mode(indio_dev);
		return ret;
	case IIO_CHAN_INFO_SCALE:
		ret = iio_device_claim_direct_mode(indio_dev);
		if (ret)
			return ret;

		ret = bmi323_set_scale(data, bmi323_iio_to_sensor(chan->type),
				       val, val2);
		iio_device_release_direct_mode(indio_dev);
		return ret;
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		ret = iio_device_claim_direct_mode(indio_dev);
		if (ret)
			return ret;

		ret = bmi323_set_average(data, bmi323_iio_to_sensor(chan->type),
					 val);

		iio_device_release_direct_mode(indio_dev);
		return ret;
	case IIO_CHAN_INFO_ENABLE:
		return bmi323_enable_steps(data, val);
	case IIO_CHAN_INFO_PROCESSED:
		scoped_guard(mutex, &data->mutex) {
			if (val || !FIELD_GET(BMI323_FEAT_IO0_STP_CNT_MSK,
					      data->feature_events))
				return -EINVAL;

			/* Clear step counter value */
			ret = bmi323_update_ext_reg(data, BMI323_STEP_SC1_REG,
						    BMI323_STEP_SC1_RST_CNT_MSK,
						    FIELD_PREP(BMI323_STEP_SC1_RST_CNT_MSK,
							       1));
		}
		return ret;
	default:
		return -EINVAL;
	}
}

static int bmi323_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan, int *val,
			   int *val2, long mask)
{
	struct bmi323_data *data = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_PROCESSED:
		return bmi323_read_steps(data, val);
	case IIO_CHAN_INFO_RAW:
		switch (chan->type) {
		case IIO_ACCEL:
		case IIO_ANGL_VEL:
			ret = iio_device_claim_direct_mode(indio_dev);
			if (ret)
				return ret;

			ret = bmi323_read_axis(data, chan, val);

			iio_device_release_direct_mode(indio_dev);
			return ret;
		case IIO_TEMP:
			return bmi323_get_temp_data(data, val);
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_SAMP_FREQ:
		return bmi323_get_odr(data, bmi323_iio_to_sensor(chan->type),
				      val, val2);
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_ACCEL:
		case IIO_ANGL_VEL:
			*val = 0;
			return bmi323_get_scale(data,
						bmi323_iio_to_sensor(chan->type),
						val2);
		case IIO_TEMP:
			*val = BMI323_TEMP_SCALE / MEGA;
			*val2 = BMI323_TEMP_SCALE % MEGA;
			return IIO_VAL_INT_PLUS_MICRO;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		return bmi323_get_average(data,
					  bmi323_iio_to_sensor(chan->type),
					  val);
	case IIO_CHAN_INFO_OFFSET:
		switch (chan->type) {
		case IIO_TEMP:
			*val = BMI323_TEMP_OFFSET;
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_ENABLE:
		scoped_guard(mutex, &data->mutex)
			*val = FIELD_GET(BMI323_FEAT_IO0_STP_CNT_MSK,
					 data->feature_events);
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static const struct iio_info bmi323_info = {
	.read_raw = bmi323_read_raw,
	.write_raw = bmi323_write_raw,
	.read_avail = bmi323_read_avail,
	.hwfifo_set_watermark = bmi323_set_watermark,
	.write_event_config = bmi323_write_event_config,
	.read_event_config = bmi323_read_event_config,
	.write_event_value = bmi323_write_event_value,
	.read_event_value = bmi323_read_event_value,
	.event_attrs = &bmi323_event_attribute_group,
};

#define BMI323_SCAN_MASK_ACCEL_3AXIS		\
	(BIT(BMI323_ACCEL_X) | BIT(BMI323_ACCEL_Y) | BIT(BMI323_ACCEL_Z))

#define BMI323_SCAN_MASK_GYRO_3AXIS		\
	(BIT(BMI323_GYRO_X) | BIT(BMI323_GYRO_Y) | BIT(BMI323_GYRO_Z))

static const unsigned long bmi323_avail_scan_masks[] = {
	/* 3-axis accel */
	BMI323_SCAN_MASK_ACCEL_3AXIS,
	/* 3-axis gyro */
	BMI323_SCAN_MASK_GYRO_3AXIS,
	/* 3-axis accel + 3-axis gyro */
	BMI323_SCAN_MASK_ACCEL_3AXIS | BMI323_SCAN_MASK_GYRO_3AXIS,
	0
};

static int bmi323_int_pin_config(struct bmi323_data *data,
				 enum bmi323_irq_pin irq_pin,
				 bool active_high, bool open_drain, bool latch)
{
	unsigned int mask, field_value;
	int ret;

	ret = regmap_update_bits(data->regmap, BMI323_IO_INT_CONF_REG,
				 BMI323_IO_INT_LTCH_MSK,
				 FIELD_PREP(BMI323_IO_INT_LTCH_MSK, latch));
	if (ret)
		return ret;

	ret = bmi323_update_ext_reg(data, BMI323_GEN_SET1_REG,
				    BMI323_GEN_HOLD_DUR_MSK,
				    FIELD_PREP(BMI323_GEN_HOLD_DUR_MSK, 0));
	if (ret)
		return ret;

	switch (irq_pin) {
	case BMI323_IRQ_INT1:
		mask = BMI323_IO_INT1_LVL_OD_OP_MSK;

		field_value = FIELD_PREP(BMI323_IO_INT1_LVL_MSK, active_high) |
			      FIELD_PREP(BMI323_IO_INT1_OD_MSK, open_drain) |
			      FIELD_PREP(BMI323_IO_INT1_OP_EN_MSK, 1);
		break;
	case BMI323_IRQ_INT2:
		mask = BMI323_IO_INT2_LVL_OD_OP_MSK;

		field_value = FIELD_PREP(BMI323_IO_INT2_LVL_MSK, active_high) |
			      FIELD_PREP(BMI323_IO_INT2_OD_MSK, open_drain) |
			      FIELD_PREP(BMI323_IO_INT2_OP_EN_MSK, 1);
		break;
	default:
		return -EINVAL;
	}

	return regmap_update_bits(data->regmap, BMI323_IO_INT_CTR_REG, mask,
				  field_value);
}

static int bmi323_trigger_probe(struct bmi323_data *data,
				struct iio_dev *indio_dev)
{
	bool open_drain, active_high, latch;
	struct fwnode_handle *fwnode;
	enum bmi323_irq_pin irq_pin;
	int ret, irq, irq_type;
	struct irq_data *desc;

	fwnode = dev_fwnode(data->dev);
	if (!fwnode)
		return -ENODEV;

	irq = fwnode_irq_get_byname(fwnode, "INT1");
	if (irq > 0) {
		irq_pin = BMI323_IRQ_INT1;
	} else {
		irq = fwnode_irq_get_byname(fwnode, "INT2");
		if (irq < 0)
			return 0;

		irq_pin = BMI323_IRQ_INT2;
	}

	desc = irq_get_irq_data(irq);
	if (!desc)
		return dev_err_probe(data->dev, -EINVAL,
				     "Could not find IRQ %d\n", irq);

	irq_type = irqd_get_trigger_type(desc);
	switch (irq_type) {
	case IRQF_TRIGGER_RISING:
		latch = false;
		active_high = true;
		break;
	case IRQF_TRIGGER_HIGH:
		latch = true;
		active_high = true;
		break;
	case IRQF_TRIGGER_FALLING:
		latch = false;
		active_high = false;
		break;
	case IRQF_TRIGGER_LOW:
		latch = true;
		active_high = false;
		break;
	default:
		return dev_err_probe(data->dev, -EINVAL,
				     "Invalid interrupt type 0x%x specified\n",
				     irq_type);
	}

	open_drain = fwnode_property_read_bool(fwnode, "drive-open-drain");

	ret = bmi323_int_pin_config(data, irq_pin, active_high, open_drain,
				    latch);
	if (ret)
		return dev_err_probe(data->dev, ret,
				     "Failed to configure irq line\n");

	data->trig = devm_iio_trigger_alloc(data->dev, "%s-trig-%d",
					    indio_dev->name, irq_pin);
	if (!data->trig)
		return -ENOMEM;

	data->trig->ops = &bmi323_trigger_ops;
	iio_trigger_set_drvdata(data->trig, data);

	ret = devm_request_threaded_irq(data->dev, irq, NULL,
					bmi323_irq_thread_handler,
					IRQF_ONESHOT, "bmi323-int", indio_dev);
	if (ret)
		return dev_err_probe(data->dev, ret, "Failed to request IRQ\n");

	ret = devm_iio_trigger_register(data->dev, data->trig);
	if (ret)
		return dev_err_probe(data->dev, ret,
				     "Trigger registration failed\n");

	data->irq_pin = irq_pin;

	return 0;
}

static int bmi323_feature_engine_enable(struct bmi323_data *data, bool en)
{
	unsigned int feature_status;
	int ret;

	if (!en)
		return regmap_write(data->regmap, BMI323_FEAT_CTRL_REG, 0);

	ret = regmap_write(data->regmap, BMI323_FEAT_IO2_REG, 0x012c);
	if (ret)
		return ret;

	ret = regmap_write(data->regmap, BMI323_FEAT_IO_STATUS_REG,
			   BMI323_FEAT_IO_STATUS_MSK);
	if (ret)
		return ret;

	ret = regmap_write(data->regmap, BMI323_FEAT_CTRL_REG,
			   BMI323_FEAT_ENG_EN_MSK);
	if (ret)
		return ret;

	/*
	 * It takes around 4 msec to enable the Feature engine, so check
	 * the status of the feature engine every 2 msec for a maximum
	 * of 5 trials.
	 */
	ret = regmap_read_poll_timeout(data->regmap, BMI323_FEAT_IO1_REG,
				       feature_status,
				       FIELD_GET(BMI323_FEAT_IO1_ERR_MSK,
						 feature_status) == 1,
				       BMI323_FEAT_ENG_POLL,
				       BMI323_FEAT_ENG_TIMEOUT);
	if (ret)
		return dev_err_probe(data->dev, -EINVAL,
				"Failed to enable feature engine\n");

	return 0;
}

static void bmi323_disable(void *data_ptr)
{
	struct bmi323_data *data = data_ptr;

	bmi323_set_mode(data, BMI323_ACCEL, ACC_GYRO_MODE_DISABLE);
	bmi323_set_mode(data, BMI323_GYRO, ACC_GYRO_MODE_DISABLE);
}

static int bmi323_set_bw(struct bmi323_data *data,
			 enum bmi323_sensor_type sensor, enum bmi323_3db_bw bw)
{
	return regmap_update_bits(data->regmap, bmi323_hw[sensor].config,
				  BMI323_ACC_GYRO_CONF_BW_MSK,
				  FIELD_PREP(BMI323_ACC_GYRO_CONF_BW_MSK, bw));
}

static int bmi323_init(struct bmi323_data *data)
{
	int ret, val;

	/*
	 * Perform soft reset to make sure the device is in a known state after
	 * start up. A delay of 1.5 ms is required after reset.
	 * See datasheet section 5.17 "Soft Reset".
	 */
	ret = regmap_write(data->regmap, BMI323_CMD_REG, BMI323_RST_VAL);
	if (ret)
		return ret;

	usleep_range(1500, 2000);

	/*
	 * Dummy read is required to enable SPI interface after reset.
	 * See datasheet section 7.2.1 "Protocol Selection".
	 */
	regmap_read(data->regmap, BMI323_CHIP_ID_REG, &val);

	ret = regmap_read(data->regmap, BMI323_STATUS_REG, &val);
	if (ret)
		return ret;

	if (!FIELD_GET(BMI323_STATUS_POR_MSK, val))
		return dev_err_probe(data->dev, -EINVAL,
				     "Sensor initialization error\n");

	ret = regmap_read(data->regmap, BMI323_CHIP_ID_REG, &val);
	if (ret)
		return ret;

	if (FIELD_GET(BMI323_CHIP_ID_MSK, val) != BMI323_CHIP_ID_VAL)
		return dev_err_probe(data->dev, -EINVAL, "Chip ID mismatch\n");

	ret = bmi323_feature_engine_enable(data, true);
	if (ret)
		return ret;

	ret = regmap_read(data->regmap, BMI323_ERR_REG, &val);
	if (ret)
		return ret;

	if (val)
		return dev_err_probe(data->dev, -EINVAL,
				     "Sensor power error = 0x%x\n", val);

	/*
	 * Set the Bandwidth coefficient which defines the 3 dB cutoff
	 * frequency in relation to the ODR.
	 */
	ret = bmi323_set_bw(data, BMI323_ACCEL, BMI323_BW_ODR_BY_2);
	if (ret)
		return ret;

	ret = bmi323_set_bw(data, BMI323_GYRO, BMI323_BW_ODR_BY_2);
	if (ret)
		return ret;

	ret = bmi323_set_odr(data, BMI323_ACCEL, 25, 0);
	if (ret)
		return ret;

	ret = bmi323_set_odr(data, BMI323_GYRO, 25, 0);
	if (ret)
		return ret;

	return devm_add_action_or_reset(data->dev, bmi323_disable, data);
}

int bmi323_core_probe(struct device *dev)
{
	static const char * const regulator_names[] = { "vdd", "vddio" };
	struct iio_dev *indio_dev;
	struct bmi323_data *data;
	struct regmap *regmap;
	int ret;

	regmap = dev_get_regmap(dev, NULL);
	if (!regmap)
		return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n");

	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
	if (!indio_dev)
		return dev_err_probe(dev, -ENOMEM,
				     "Failed to allocate device\n");

	ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names),
					     regulator_names);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to enable regulators\n");

	data = iio_priv(indio_dev);
	data->dev = dev;
	data->regmap = regmap;
	mutex_init(&data->mutex);

	ret = bmi323_init(data);
	if (ret)
		return -EINVAL;

	ret = iio_read_mount_matrix(dev, &data->orientation);
	if (ret)
		return ret;

	indio_dev->name = "bmi323-imu";
	indio_dev->info = &bmi323_info;
	indio_dev->channels = bmi323_channels;
	indio_dev->num_channels = ARRAY_SIZE(bmi323_channels);
	indio_dev->available_scan_masks = bmi323_avail_scan_masks;
	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
	dev_set_drvdata(data->dev, indio_dev);

	ret = bmi323_trigger_probe(data, indio_dev);
	if (ret)
		return -EINVAL;

	ret = devm_iio_triggered_buffer_setup_ext(data->dev, indio_dev,
						  &iio_pollfunc_store_time,
						  bmi323_trigger_handler,
						  IIO_BUFFER_DIRECTION_IN,
						  &bmi323_buffer_ops,
						  bmi323_fifo_attributes);
	if (ret)
		return dev_err_probe(data->dev, ret,
				     "Failed to setup trigger buffer\n");

	ret = devm_iio_device_register(data->dev, indio_dev);
	if (ret)
		return dev_err_probe(data->dev, ret,
				     "Unable to register iio device\n");

	return 0;
}
EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323);

MODULE_DESCRIPTION("Bosch BMI323 IMU driver");
MODULE_AUTHOR("Jagath Jog J <jagathjog1996@gmail.com>");
MODULE_LICENSE("GPL");
