// SPDX-License-Identifier: GPL-2.0-only
/*
 * ADXL355 3-Axis Digital Accelerometer IIO core driver
 *
 * Copyright (c) 2021 Puranjay Mohan <puranjay12@gmail.com>
 *
 * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/adxl354_adxl355.pdf
 */

#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/limits.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/units.h>

#include <linux/unaligned.h>

#include "adxl355.h"

/* ADXL355 Register Definitions */
#define ADXL355_DEVID_AD_REG		0x00
#define ADXL355_DEVID_MST_REG		0x01
#define ADXL355_PARTID_REG		0x02
#define ADXL355_STATUS_REG		0x04
#define ADXL355_FIFO_ENTRIES_REG	0x05
#define ADXL355_TEMP2_REG		0x06
#define ADXL355_XDATA3_REG		0x08
#define ADXL355_YDATA3_REG		0x0B
#define ADXL355_ZDATA3_REG		0x0E
#define ADXL355_FIFO_DATA_REG		0x11
#define ADXL355_OFFSET_X_H_REG		0x1E
#define ADXL355_OFFSET_Y_H_REG		0x20
#define ADXL355_OFFSET_Z_H_REG		0x22
#define ADXL355_ACT_EN_REG		0x24
#define ADXL355_ACT_THRESH_H_REG	0x25
#define ADXL355_ACT_THRESH_L_REG	0x26
#define ADXL355_ACT_COUNT_REG		0x27
#define ADXL355_FILTER_REG		0x28
#define  ADXL355_FILTER_ODR_MSK GENMASK(3, 0)
#define  ADXL355_FILTER_HPF_MSK	GENMASK(6, 4)
#define ADXL355_FIFO_SAMPLES_REG	0x29
#define ADXL355_INT_MAP_REG		0x2A
#define ADXL355_SYNC_REG		0x2B
#define ADXL355_RANGE_REG		0x2C
#define ADXL355_POWER_CTL_REG		0x2D
#define  ADXL355_POWER_CTL_MODE_MSK	GENMASK(1, 0)
#define  ADXL355_POWER_CTL_DRDY_MSK	BIT(2)
#define ADXL355_SELF_TEST_REG		0x2E
#define ADXL355_RESET_REG		0x2F

#define ADXL355_DEVID_AD_VAL		0xAD
#define ADXL355_DEVID_MST_VAL		0x1D
#define ADXL355_PARTID_VAL		0xED
#define ADXL359_PARTID_VAL		0xE9
#define ADXL355_RESET_CODE		0x52

static const struct regmap_range adxl355_read_reg_range[] = {
	regmap_reg_range(ADXL355_DEVID_AD_REG, ADXL355_FIFO_DATA_REG),
	regmap_reg_range(ADXL355_OFFSET_X_H_REG, ADXL355_SELF_TEST_REG),
};

const struct regmap_access_table adxl355_readable_regs_tbl = {
	.yes_ranges = adxl355_read_reg_range,
	.n_yes_ranges = ARRAY_SIZE(adxl355_read_reg_range),
};
EXPORT_SYMBOL_NS_GPL(adxl355_readable_regs_tbl, IIO_ADXL355);

static const struct regmap_range adxl355_write_reg_range[] = {
	regmap_reg_range(ADXL355_OFFSET_X_H_REG, ADXL355_RESET_REG),
};

const struct regmap_access_table adxl355_writeable_regs_tbl = {
	.yes_ranges = adxl355_write_reg_range,
	.n_yes_ranges = ARRAY_SIZE(adxl355_write_reg_range),
};
EXPORT_SYMBOL_NS_GPL(adxl355_writeable_regs_tbl, IIO_ADXL355);

const struct adxl355_chip_info adxl35x_chip_info[] = {
	[ADXL355] = {
		.name = "adxl355",
		.part_id = ADXL355_PARTID_VAL,
		/*
		 * At +/- 2g with 20-bit resolution, scale is given in datasheet
		 * as 3.9ug/LSB = 0.0000039 * 9.80665 = 0.00003824593 m/s^2.
		 */
		.accel_scale = {
			.integer = 0,
			.decimal = 38245,
		},
		/*
		 * The datasheet defines an intercept of 1885 LSB at 25 degC
		 * and a slope of -9.05 LSB/C. The following formula can be used
		 * to find the temperature:
		 * Temp = ((RAW - 1885)/(-9.05)) + 25 but this doesn't follow
		 * the format of the IIO which is Temp = (RAW + OFFSET) * SCALE.
		 * Hence using some rearranging we get the scale as -110.497238
		 * and offset as -2111.25.
		 */
		.temp_offset = {
			.integer =  -2111,
			.decimal = 250000,
		},
	},
	[ADXL359] = {
		.name = "adxl359",
		.part_id = ADXL359_PARTID_VAL,
		/*
		 * At +/- 10g with 20-bit resolution, scale is given in datasheet
		 * as 19.5ug/LSB = 0.0000195 * 9.80665 = 0.0.00019122967 m/s^2.
		 */
		.accel_scale = {
			.integer = 0,
			.decimal = 191229,
		},
		/*
		 * The datasheet defines an intercept of 1852 LSB at 25 degC
		 * and a slope of -9.05 LSB/C. The following formula can be used
		 * to find the temperature:
		 * Temp = ((RAW - 1852)/(-9.05)) + 25 but this doesn't follow
		 * the format of the IIO which is Temp = (RAW + OFFSET) * SCALE.
		 * Hence using some rearranging we get the scale as -110.497238
		 * and offset as -2079.25.
		 */
		.temp_offset = {
			.integer = -2079,
			.decimal = 250000,
		},
	},
};
EXPORT_SYMBOL_NS_GPL(adxl35x_chip_info, IIO_ADXL355);

enum adxl355_op_mode {
	ADXL355_MEASUREMENT,
	ADXL355_STANDBY,
	ADXL355_TEMP_OFF,
};

enum adxl355_odr {
	ADXL355_ODR_4000HZ,
	ADXL355_ODR_2000HZ,
	ADXL355_ODR_1000HZ,
	ADXL355_ODR_500HZ,
	ADXL355_ODR_250HZ,
	ADXL355_ODR_125HZ,
	ADXL355_ODR_62_5HZ,
	ADXL355_ODR_31_25HZ,
	ADXL355_ODR_15_625HZ,
	ADXL355_ODR_7_813HZ,
	ADXL355_ODR_3_906HZ,
};

enum adxl355_hpf_3db {
	ADXL355_HPF_OFF,
	ADXL355_HPF_24_7,
	ADXL355_HPF_6_2084,
	ADXL355_HPF_1_5545,
	ADXL355_HPF_0_3862,
	ADXL355_HPF_0_0954,
	ADXL355_HPF_0_0238,
};

static const int adxl355_odr_table[][2] = {
	[0] = {4000, 0},
	[1] = {2000, 0},
	[2] = {1000, 0},
	[3] = {500, 0},
	[4] = {250, 0},
	[5] = {125, 0},
	[6] = {62, 500000},
	[7] = {31, 250000},
	[8] = {15, 625000},
	[9] = {7, 813000},
	[10] = {3, 906000},
};

static const int adxl355_hpf_3db_multipliers[] = {
	0,
	247000,
	62084,
	15545,
	3862,
	954,
	238,
};

enum adxl355_chans {
	chan_x, chan_y, chan_z,
};

struct adxl355_chan_info {
	u8 data_reg;
	u8 offset_reg;
};

static const struct adxl355_chan_info adxl355_chans[] = {
	[chan_x] = {
		.data_reg = ADXL355_XDATA3_REG,
		.offset_reg = ADXL355_OFFSET_X_H_REG
	},
	[chan_y] = {
		.data_reg = ADXL355_YDATA3_REG,
		.offset_reg = ADXL355_OFFSET_Y_H_REG
	},
	[chan_z] = {
		.data_reg = ADXL355_ZDATA3_REG,
		.offset_reg = ADXL355_OFFSET_Z_H_REG
	},
};

struct adxl355_data {
	const struct adxl355_chip_info *chip_info;
	struct regmap *regmap;
	struct device *dev;
	struct mutex lock; /* lock to protect op_mode */
	enum adxl355_op_mode op_mode;
	enum adxl355_odr odr;
	enum adxl355_hpf_3db hpf_3db;
	int calibbias[3];
	int adxl355_hpf_3db_table[7][2];
	struct iio_trigger *dready_trig;
	union {
		u8 transf_buf[3];
		struct {
			u8 buf[14];
			s64 ts;
		} buffer;
	} __aligned(IIO_DMA_MINALIGN);
};

static int adxl355_set_op_mode(struct adxl355_data *data,
			       enum adxl355_op_mode op_mode)
{
	int ret;

	if (data->op_mode == op_mode)
		return 0;

	ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG,
				 ADXL355_POWER_CTL_MODE_MSK, op_mode);
	if (ret)
		return ret;

	data->op_mode = op_mode;

	return ret;
}

static int adxl355_data_rdy_trigger_set_state(struct iio_trigger *trig,
					      bool state)
{
	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
	struct adxl355_data *data = iio_priv(indio_dev);
	int ret;

	mutex_lock(&data->lock);
	ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG,
				 ADXL355_POWER_CTL_DRDY_MSK,
				 FIELD_PREP(ADXL355_POWER_CTL_DRDY_MSK,
					    state ? 0 : 1));
	mutex_unlock(&data->lock);

	return ret;
}

static void adxl355_fill_3db_frequency_table(struct adxl355_data *data)
{
	u32 multiplier;
	u64 div, rem;
	u64 odr;
	int i;

	odr = mul_u64_u32_shr(adxl355_odr_table[data->odr][0], MEGA, 0) +
			      adxl355_odr_table[data->odr][1];

	for (i = 0; i < ARRAY_SIZE(adxl355_hpf_3db_multipliers); i++) {
		multiplier = adxl355_hpf_3db_multipliers[i];
		div = div64_u64_rem(mul_u64_u32_shr(odr, multiplier, 0),
				    TERA * 100, &rem);

		data->adxl355_hpf_3db_table[i][0] = div;
		data->adxl355_hpf_3db_table[i][1] = div_u64(rem, MEGA * 100);
	}
}

static int adxl355_setup(struct adxl355_data *data)
{
	unsigned int regval;
	int ret;

	ret = regmap_read(data->regmap, ADXL355_DEVID_AD_REG, &regval);
	if (ret)
		return ret;

	if (regval != ADXL355_DEVID_AD_VAL) {
		dev_err(data->dev, "Invalid ADI ID 0x%02x\n", regval);
		return -ENODEV;
	}

	ret = regmap_read(data->regmap, ADXL355_DEVID_MST_REG, &regval);
	if (ret)
		return ret;

	if (regval != ADXL355_DEVID_MST_VAL) {
		dev_err(data->dev, "Invalid MEMS ID 0x%02x\n", regval);
		return -ENODEV;
	}

	ret = regmap_read(data->regmap, ADXL355_PARTID_REG, &regval);
	if (ret)
		return ret;

	if (regval != ADXL355_PARTID_VAL)
		dev_warn(data->dev, "Invalid DEV ID 0x%02x\n", regval);

	/*
	 * Perform a software reset to make sure the device is in a consistent
	 * state after start-up.
	 */
	ret = regmap_write(data->regmap, ADXL355_RESET_REG, ADXL355_RESET_CODE);
	if (ret)
		return ret;

	ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG,
				 ADXL355_POWER_CTL_DRDY_MSK,
				 FIELD_PREP(ADXL355_POWER_CTL_DRDY_MSK, 1));
	if (ret)
		return ret;

	adxl355_fill_3db_frequency_table(data);

	return adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
}

static int adxl355_get_temp_data(struct adxl355_data *data, u8 addr)
{
	return regmap_bulk_read(data->regmap, addr, data->transf_buf, 2);
}

static int adxl355_read_axis(struct adxl355_data *data, u8 addr)
{
	int ret;

	ret = regmap_bulk_read(data->regmap, addr, data->transf_buf,
			       ARRAY_SIZE(data->transf_buf));
	if (ret)
		return ret;

	return get_unaligned_be24(data->transf_buf);
}

static int adxl355_find_match(const int (*freq_tbl)[2], const int n,
			      const int val, const int val2)
{
	int i;

	for (i = 0; i < n; i++) {
		if (freq_tbl[i][0] == val && freq_tbl[i][1] == val2)
			return i;
	}

	return -EINVAL;
}

static int adxl355_set_odr(struct adxl355_data *data,
			   enum adxl355_odr odr)
{
	int ret;

	mutex_lock(&data->lock);

	if (data->odr == odr) {
		mutex_unlock(&data->lock);
		return 0;
	}

	ret = adxl355_set_op_mode(data, ADXL355_STANDBY);
	if (ret)
		goto err_unlock;

	ret = regmap_update_bits(data->regmap, ADXL355_FILTER_REG,
				 ADXL355_FILTER_ODR_MSK,
				 FIELD_PREP(ADXL355_FILTER_ODR_MSK, odr));
	if (ret)
		goto err_set_opmode;

	data->odr = odr;
	adxl355_fill_3db_frequency_table(data);

	ret = adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
	if (ret)
		goto err_set_opmode;

	mutex_unlock(&data->lock);
	return 0;

err_set_opmode:
	adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
err_unlock:
	mutex_unlock(&data->lock);
	return ret;
}

static int adxl355_set_hpf_3db(struct adxl355_data *data,
			       enum adxl355_hpf_3db hpf)
{
	int ret;

	mutex_lock(&data->lock);

	if (data->hpf_3db == hpf) {
		mutex_unlock(&data->lock);
		return 0;
	}

	ret = adxl355_set_op_mode(data, ADXL355_STANDBY);
	if (ret)
		goto err_unlock;

	ret = regmap_update_bits(data->regmap, ADXL355_FILTER_REG,
				 ADXL355_FILTER_HPF_MSK,
				 FIELD_PREP(ADXL355_FILTER_HPF_MSK, hpf));
	if (ret)
		goto err_set_opmode;

	data->hpf_3db = hpf;

	ret = adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
	if (ret)
		goto err_set_opmode;

	mutex_unlock(&data->lock);
	return 0;

err_set_opmode:
	adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
err_unlock:
	mutex_unlock(&data->lock);
	return ret;
}

static int adxl355_set_calibbias(struct adxl355_data *data,
				 enum adxl355_chans chan, int calibbias)
{
	int ret;

	mutex_lock(&data->lock);

	ret = adxl355_set_op_mode(data, ADXL355_STANDBY);
	if (ret)
		goto err_unlock;

	put_unaligned_be16(calibbias, data->transf_buf);
	ret = regmap_bulk_write(data->regmap,
				adxl355_chans[chan].offset_reg,
				data->transf_buf, 2);
	if (ret)
		goto err_set_opmode;

	data->calibbias[chan] = calibbias;

	ret = adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
	if (ret)
		goto err_set_opmode;

	mutex_unlock(&data->lock);
	return 0;

err_set_opmode:
	adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
err_unlock:
	mutex_unlock(&data->lock);
	return ret;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		switch (chan->type) {
		case IIO_TEMP:
			ret = adxl355_get_temp_data(data, chan->address);
			if (ret < 0)
				return ret;
			*val = get_unaligned_be16(data->transf_buf);

			return IIO_VAL_INT;
		case IIO_ACCEL:
			ret = adxl355_read_axis(data, adxl355_chans[
						chan->address].data_reg);
			if (ret < 0)
				return ret;
			*val = sign_extend32(ret >> chan->scan_type.shift,
					     chan->scan_type.realbits - 1);
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}

	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_TEMP:
			/*
			 * Temperature scale is -110.497238.
			 * See the detailed explanation in adxl35x_chip_info
			 * definition above.
			 */
			*val = -110;
			*val2 = 497238;
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_ACCEL:
			*val = data->chip_info->accel_scale.integer;
			*val2 = data->chip_info->accel_scale.decimal;
			return IIO_VAL_INT_PLUS_NANO;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_OFFSET:
		*val = data->chip_info->temp_offset.integer;
		*val2 = data->chip_info->temp_offset.decimal;
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_CALIBBIAS:
		*val = sign_extend32(data->calibbias[chan->address], 15);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SAMP_FREQ:
		*val = adxl355_odr_table[data->odr][0];
		*val2 = adxl355_odr_table[data->odr][1];
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
		*val = data->adxl355_hpf_3db_table[data->hpf_3db][0];
		*val2 = data->adxl355_hpf_3db_table[data->hpf_3db][1];
		return IIO_VAL_INT_PLUS_MICRO;
	default:
		return -EINVAL;
	}
}

static int adxl355_write_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     int val, int val2, long mask)
{
	struct adxl355_data *data = iio_priv(indio_dev);
	int odr_idx, hpf_idx, calibbias;

	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		odr_idx = adxl355_find_match(adxl355_odr_table,
					     ARRAY_SIZE(adxl355_odr_table),
					     val, val2);
		if (odr_idx < 0)
			return odr_idx;

		return adxl355_set_odr(data, odr_idx);
	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
		hpf_idx = adxl355_find_match(data->adxl355_hpf_3db_table,
					ARRAY_SIZE(data->adxl355_hpf_3db_table),
					     val, val2);
		if (hpf_idx < 0)
			return hpf_idx;

		return adxl355_set_hpf_3db(data, hpf_idx);
	case IIO_CHAN_INFO_CALIBBIAS:
		calibbias = clamp_t(int, val, S16_MIN, S16_MAX);

		return adxl355_set_calibbias(data, chan->address, calibbias);
	default:
		return -EINVAL;
	}
}

static int adxl355_read_avail(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan,
			      const int **vals, int *type, int *length,
			      long mask)
{
	struct adxl355_data *data = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		*vals = (const int *)adxl355_odr_table;
		*type = IIO_VAL_INT_PLUS_MICRO;
		/* Values are stored in a 2D matrix */
		*length = ARRAY_SIZE(adxl355_odr_table) * 2;

		return IIO_AVAIL_LIST;
	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
		*vals = (const int *)data->adxl355_hpf_3db_table;
		*type = IIO_VAL_INT_PLUS_MICRO;
		/* Values are stored in a 2D matrix */
		*length = ARRAY_SIZE(data->adxl355_hpf_3db_table) * 2;

		return IIO_AVAIL_LIST;
	default:
		return -EINVAL;
	}
}

static const unsigned long adxl355_avail_scan_masks[] = {
	GENMASK(3, 0),
	0
};

static const struct iio_info adxl355_info = {
	.read_raw	= adxl355_read_raw,
	.write_raw	= adxl355_write_raw,
	.read_avail	= &adxl355_read_avail,
};

static const struct iio_trigger_ops adxl355_trigger_ops = {
	.set_trigger_state = &adxl355_data_rdy_trigger_set_state,
	.validate_device = &iio_trigger_validate_own_device,
};

static irqreturn_t adxl355_trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct adxl355_data *data = iio_priv(indio_dev);
	int ret;

	mutex_lock(&data->lock);

	/*
	 * data->buffer is used both for triggered buffer support
	 * and read/write_raw(), hence, it has to be zeroed here before usage.
	 */
	data->buffer.buf[0] = 0;

	/*
	 * The acceleration data is 24 bits and big endian. It has to be saved
	 * in 32 bits, hence, it is saved in the 2nd byte of the 4 byte buffer.
	 * The buf array is 14 bytes as it includes 3x4=12 bytes for
	 * accelaration data of x, y, and z axis. It also includes 2 bytes for
	 * temperature data.
	 */
	ret = regmap_bulk_read(data->regmap, ADXL355_XDATA3_REG,
			       &data->buffer.buf[1], 3);
	if (ret)
		goto out_unlock_notify;

	ret = regmap_bulk_read(data->regmap, ADXL355_YDATA3_REG,
			       &data->buffer.buf[5], 3);
	if (ret)
		goto out_unlock_notify;

	ret = regmap_bulk_read(data->regmap, ADXL355_ZDATA3_REG,
			       &data->buffer.buf[9], 3);
	if (ret)
		goto out_unlock_notify;

	ret = regmap_bulk_read(data->regmap, ADXL355_TEMP2_REG,
			       &data->buffer.buf[12], 2);
	if (ret)
		goto out_unlock_notify;

	iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
					   pf->timestamp);

out_unlock_notify:
	mutex_unlock(&data->lock);
	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

#define ADXL355_ACCEL_CHANNEL(index, reg, axis) {			\
	.type = IIO_ACCEL,						\
	.address = reg,							\
	.modified = 1,							\
	.channel2 = IIO_MOD_##axis,					\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |			\
			      BIT(IIO_CHAN_INFO_CALIBBIAS),		\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |		\
				    BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
		BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY),	\
	.info_mask_shared_by_type_available =				\
		BIT(IIO_CHAN_INFO_SAMP_FREQ) |				\
		BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY),	\
	.scan_index = index,						\
	.scan_type = {							\
		.sign = 's',						\
		.realbits = 20,						\
		.storagebits = 32,					\
		.shift = 4,						\
		.endianness = IIO_BE,					\
	}								\
}

static const struct iio_chan_spec adxl355_channels[] = {
	ADXL355_ACCEL_CHANNEL(0, chan_x, X),
	ADXL355_ACCEL_CHANNEL(1, chan_y, Y),
	ADXL355_ACCEL_CHANNEL(2, chan_z, Z),
	{
		.type = IIO_TEMP,
		.address = ADXL355_TEMP2_REG,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE) |
				      BIT(IIO_CHAN_INFO_OFFSET),
		.scan_index = 3,
		.scan_type = {
			.sign = 's',
			.realbits = 12,
			.storagebits = 16,
			.endianness = IIO_BE,
		},
	},
	IIO_CHAN_SOFT_TIMESTAMP(4),
};

static int adxl355_probe_trigger(struct iio_dev *indio_dev, int irq)
{
	struct adxl355_data *data = iio_priv(indio_dev);
	int ret;

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

	data->dready_trig->ops = &adxl355_trigger_ops;
	iio_trigger_set_drvdata(data->dready_trig, indio_dev);

	ret = devm_request_irq(data->dev, irq,
			       &iio_trigger_generic_data_rdy_poll,
			       IRQF_ONESHOT, "adxl355_irq", data->dready_trig);
	if (ret)
		return dev_err_probe(data->dev, ret, "request irq %d failed\n",
				     irq);

	ret = devm_iio_trigger_register(data->dev, data->dready_trig);
	if (ret) {
		dev_err(data->dev, "iio trigger register failed\n");
		return ret;
	}

	indio_dev->trig = iio_trigger_get(data->dready_trig);

	return 0;
}

int adxl355_core_probe(struct device *dev, struct regmap *regmap,
		       const struct adxl355_chip_info *chip_info)
{
	struct adxl355_data *data;
	struct iio_dev *indio_dev;
	int ret;
	int irq;

	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
	if (!indio_dev)
		return -ENOMEM;

	data = iio_priv(indio_dev);
	data->regmap = regmap;
	data->dev = dev;
	data->op_mode = ADXL355_STANDBY;
	data->chip_info = chip_info;
	mutex_init(&data->lock);

	indio_dev->name = chip_info->name;
	indio_dev->info = &adxl355_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = adxl355_channels;
	indio_dev->num_channels = ARRAY_SIZE(adxl355_channels);
	indio_dev->available_scan_masks = adxl355_avail_scan_masks;

	ret = adxl355_setup(data);
	if (ret) {
		dev_err(dev, "ADXL355 setup failed\n");
		return ret;
	}

	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
					      &iio_pollfunc_store_time,
					      &adxl355_trigger_handler, NULL);
	if (ret) {
		dev_err(dev, "iio triggered buffer setup failed\n");
		return ret;
	}

	irq = fwnode_irq_get_byname(dev_fwnode(dev), "DRDY");
	if (irq > 0) {
		ret = adxl355_probe_trigger(indio_dev, irq);
		if (ret)
			return ret;
	}

	return devm_iio_device_register(dev, indio_dev);
}
EXPORT_SYMBOL_NS_GPL(adxl355_core_probe, IIO_ADXL355);

MODULE_AUTHOR("Puranjay Mohan <puranjay12@gmail.com>");
MODULE_DESCRIPTION("ADXL355 3-Axis Digital Accelerometer core driver");
MODULE_LICENSE("GPL v2");
