// SPDX-License-Identifier: GPL-2.0-only
/*
 * Core IIO driver for Bosch BMA400 triaxial acceleration sensor.
 *
 * Copyright 2019 Dan Robertson <dan@dlrobertson.com>
 *
 * TODO:
 *  - Support for power management
 *  - Support events and interrupts
 *  - Create channel for step count
 *  - Create channel for sensor time
 */

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>

#include <asm/unaligned.h>

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

#include "bma400.h"

/*
 * The G-range selection may be one of 2g, 4g, 8, or 16g. The scale may
 * be selected with the acc_range bits of the ACC_CONFIG1 register.
 * NB: This buffer is populated in the device init.
 */
static int bma400_scales[8];

/*
 * See the ACC_CONFIG1 section of the datasheet.
 * NB: This buffer is populated in the device init.
 */
static int bma400_sample_freqs[14];

static const int bma400_osr_range[] = { 0, 1, 3 };

static int tap_reset_timeout[BMA400_TAP_TIM_LIST_LEN] = {
	300000,
	400000,
	500000,
	600000
};

static int tap_max2min_time[BMA400_TAP_TIM_LIST_LEN] = {
	30000,
	45000,
	60000,
	90000
};

static int double_tap2_min_delay[BMA400_TAP_TIM_LIST_LEN] = {
	20000,
	40000,
	60000,
	80000
};

/* See the ACC_CONFIG0 section of the datasheet */
enum bma400_power_mode {
	POWER_MODE_SLEEP   = 0x00,
	POWER_MODE_LOW     = 0x01,
	POWER_MODE_NORMAL  = 0x02,
	POWER_MODE_INVALID = 0x03,
};

enum bma400_scan {
	BMA400_ACCL_X,
	BMA400_ACCL_Y,
	BMA400_ACCL_Z,
	BMA400_TEMP,
};

struct bma400_sample_freq {
	int hz;
	int uhz;
};

enum bma400_activity {
	BMA400_STILL,
	BMA400_WALKING,
	BMA400_RUNNING,
};

struct bma400_data {
	struct device *dev;
	struct regmap *regmap;
	struct regulator_bulk_data regulators[BMA400_NUM_REGULATORS];
	struct mutex mutex; /* data register lock */
	struct iio_mount_matrix orientation;
	enum bma400_power_mode power_mode;
	struct bma400_sample_freq sample_freq;
	int oversampling_ratio;
	int scale;
	struct iio_trigger *trig;
	int steps_enabled;
	bool step_event_en;
	bool activity_event_en;
	unsigned int generic_event_en;
	unsigned int tap_event_en_bitmask;
	/* Correct time stamp alignment */
	struct {
		__le16 buff[3];
		u8 temperature;
		s64 ts __aligned(8);
	} buffer __aligned(IIO_DMA_MINALIGN);
	__le16 status;
	__be16 duration;
};

static bool bma400_is_writable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case BMA400_CHIP_ID_REG:
	case BMA400_ERR_REG:
	case BMA400_STATUS_REG:
	case BMA400_X_AXIS_LSB_REG:
	case BMA400_X_AXIS_MSB_REG:
	case BMA400_Y_AXIS_LSB_REG:
	case BMA400_Y_AXIS_MSB_REG:
	case BMA400_Z_AXIS_LSB_REG:
	case BMA400_Z_AXIS_MSB_REG:
	case BMA400_SENSOR_TIME0:
	case BMA400_SENSOR_TIME1:
	case BMA400_SENSOR_TIME2:
	case BMA400_EVENT_REG:
	case BMA400_INT_STAT0_REG:
	case BMA400_INT_STAT1_REG:
	case BMA400_INT_STAT2_REG:
	case BMA400_TEMP_DATA_REG:
	case BMA400_FIFO_LENGTH0_REG:
	case BMA400_FIFO_LENGTH1_REG:
	case BMA400_FIFO_DATA_REG:
	case BMA400_STEP_CNT0_REG:
	case BMA400_STEP_CNT1_REG:
	case BMA400_STEP_CNT3_REG:
	case BMA400_STEP_STAT_REG:
		return false;
	default:
		return true;
	}
}

static bool bma400_is_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case BMA400_ERR_REG:
	case BMA400_STATUS_REG:
	case BMA400_X_AXIS_LSB_REG:
	case BMA400_X_AXIS_MSB_REG:
	case BMA400_Y_AXIS_LSB_REG:
	case BMA400_Y_AXIS_MSB_REG:
	case BMA400_Z_AXIS_LSB_REG:
	case BMA400_Z_AXIS_MSB_REG:
	case BMA400_SENSOR_TIME0:
	case BMA400_SENSOR_TIME1:
	case BMA400_SENSOR_TIME2:
	case BMA400_EVENT_REG:
	case BMA400_INT_STAT0_REG:
	case BMA400_INT_STAT1_REG:
	case BMA400_INT_STAT2_REG:
	case BMA400_TEMP_DATA_REG:
	case BMA400_FIFO_LENGTH0_REG:
	case BMA400_FIFO_LENGTH1_REG:
	case BMA400_FIFO_DATA_REG:
	case BMA400_STEP_CNT0_REG:
	case BMA400_STEP_CNT1_REG:
	case BMA400_STEP_CNT3_REG:
	case BMA400_STEP_STAT_REG:
		return true;
	default:
		return false;
	}
}

const struct regmap_config bma400_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = BMA400_CMD_REG,
	.cache_type = REGCACHE_RBTREE,
	.writeable_reg = bma400_is_writable_reg,
	.volatile_reg = bma400_is_volatile_reg,
};
EXPORT_SYMBOL_NS(bma400_regmap_config, IIO_BMA400);

static const struct iio_mount_matrix *
bma400_accel_get_mount_matrix(const struct iio_dev *indio_dev,
			      const struct iio_chan_spec *chan)
{
	struct bma400_data *data = iio_priv(indio_dev);

	return &data->orientation;
}

static const struct iio_chan_spec_ext_info bma400_ext_info[] = {
	IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma400_accel_get_mount_matrix),
	{ }
};

static const struct iio_event_spec bma400_step_detect_event = {
	.type = IIO_EV_TYPE_CHANGE,
	.dir = IIO_EV_DIR_NONE,
	.mask_separate = BIT(IIO_EV_INFO_ENABLE),
};

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

static const struct iio_event_spec bma400_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_VALUE) |
				       BIT(IIO_EV_INFO_ENABLE) |
				       BIT(IIO_EV_INFO_RESET_TIMEOUT),
	},
	{
		.type = IIO_EV_TYPE_GESTURE,
		.dir = IIO_EV_DIR_DOUBLETAP,
		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
				       BIT(IIO_EV_INFO_ENABLE) |
				       BIT(IIO_EV_INFO_RESET_TIMEOUT) |
				       BIT(IIO_EV_INFO_TAP2_MIN_DELAY),
	},
};

static int usec_to_tapreg_raw(int usec, const int *time_list)
{
	int index;

	for (index = 0; index < BMA400_TAP_TIM_LIST_LEN; index++) {
		if (usec == time_list[index])
			return index;
	}
	return -EINVAL;
}

static ssize_t in_accel_gesture_tap_maxtomin_time_show(struct device *dev,
						       struct device_attribute *attr,
						       char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct bma400_data *data = iio_priv(indio_dev);
	int ret, reg_val, raw, vals[2];

	ret = regmap_read(data->regmap, BMA400_TAP_CONFIG1, &reg_val);
	if (ret)
		return ret;

	raw = FIELD_GET(BMA400_TAP_TICSTH_MSK, reg_val);
	vals[0] = 0;
	vals[1] = tap_max2min_time[raw];

	return iio_format_value(buf, IIO_VAL_INT_PLUS_MICRO, 2, vals);
}

static ssize_t in_accel_gesture_tap_maxtomin_time_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 bma400_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 = usec_to_tapreg_raw(val_fract, tap_max2min_time);
	if (raw < 0)
		return -EINVAL;

	ret = regmap_update_bits(data->regmap, BMA400_TAP_CONFIG1,
				 BMA400_TAP_TICSTH_MSK,
				 FIELD_PREP(BMA400_TAP_TICSTH_MSK, raw));
	if (ret)
		return ret;

	return len;
}

static IIO_DEVICE_ATTR_RW(in_accel_gesture_tap_maxtomin_time, 0);

/*
 * Tap interrupts works with 200 Hz input data rate and the time based tap
 * controls are in the terms of data samples so the below calculation is
 * used to convert the configuration values into seconds.
 * e.g.:
 * 60 data samples * 0.005 ms = 0.3 seconds.
 * 80 data samples * 0.005 ms = 0.4 seconds.
 */

/* quiet configuration values in seconds */
static IIO_CONST_ATTR(in_accel_gesture_tap_reset_timeout_available,
		      "0.3 0.4 0.5 0.6");

/* tics_th configuration values in seconds */
static IIO_CONST_ATTR(in_accel_gesture_tap_maxtomin_time_available,
		      "0.03 0.045 0.06 0.09");

/* quiet_dt configuration values in seconds */
static IIO_CONST_ATTR(in_accel_gesture_doubletap_tap2_min_delay_available,
		      "0.02 0.04 0.06 0.08");

/* List of sensitivity values available to configure tap interrupts */
static IIO_CONST_ATTR(in_accel_gesture_tap_value_available, "0 1 2 3 4 5 6 7");

static struct attribute *bma400_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_tap_maxtomin_time_available.dev_attr.attr,
	&iio_const_attr_in_accel_gesture_doubletap_tap2_min_delay_available.dev_attr.attr,
	&iio_dev_attr_in_accel_gesture_tap_maxtomin_time.dev_attr.attr,
	NULL
};

static const struct attribute_group bma400_event_attribute_group = {
	.attrs = bma400_event_attributes,
};

#define BMA400_ACC_CHANNEL(_index, _axis) { \
	.type = IIO_ACCEL, \
	.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), \
	.ext_info = bma400_ext_info, \
	.scan_index = _index,	\
	.scan_type = {		\
		.sign = 's',	\
		.realbits = 12,		\
		.storagebits = 16,	\
		.endianness = IIO_LE,	\
	},				\
	.event_spec = bma400_accel_event,			\
	.num_event_specs = ARRAY_SIZE(bma400_accel_event)	\
}

#define BMA400_ACTIVITY_CHANNEL(_chan2) {	\
	.type = IIO_ACTIVITY,			\
	.modified = 1,				\
	.channel2 = _chan2,			\
	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
	.scan_index = -1, /* No buffer support */		\
	.event_spec = &bma400_activity_event,			\
	.num_event_specs = 1,					\
}

static const struct iio_chan_spec bma400_channels[] = {
	BMA400_ACC_CHANNEL(0, X),
	BMA400_ACC_CHANNEL(1, Y),
	BMA400_ACC_CHANNEL(2, Z),
	{
		.type = IIO_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),
		.scan_index = 3,
		.scan_type = {
			.sign = 's',
			.realbits = 8,
			.storagebits = 8,
			.endianness = IIO_LE,
		},
	},
	{
		.type = IIO_STEPS,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
				      BIT(IIO_CHAN_INFO_ENABLE),
		.scan_index = -1, /* No buffer support */
		.event_spec = &bma400_step_detect_event,
		.num_event_specs = 1,
	},
	BMA400_ACTIVITY_CHANNEL(IIO_MOD_STILL),
	BMA400_ACTIVITY_CHANNEL(IIO_MOD_WALKING),
	BMA400_ACTIVITY_CHANNEL(IIO_MOD_RUNNING),
	IIO_CHAN_SOFT_TIMESTAMP(4),
};

static int bma400_get_temp_reg(struct bma400_data *data, int *val, int *val2)
{
	unsigned int raw_temp;
	int host_temp;
	int ret;

	if (data->power_mode == POWER_MODE_SLEEP)
		return -EBUSY;

	ret = regmap_read(data->regmap, BMA400_TEMP_DATA_REG, &raw_temp);
	if (ret)
		return ret;

	host_temp = sign_extend32(raw_temp, 7);
	/*
	 * The formula for the TEMP_DATA register in the datasheet
	 * is: x * 0.5 + 23
	 */
	*val = (host_temp >> 1) + 23;
	*val2 = (host_temp & 0x1) * 500000;
	return IIO_VAL_INT_PLUS_MICRO;
}

static int bma400_get_accel_reg(struct bma400_data *data,
				const struct iio_chan_spec *chan,
				int *val)
{
	__le16 raw_accel;
	int lsb_reg;
	int ret;

	if (data->power_mode == POWER_MODE_SLEEP)
		return -EBUSY;

	switch (chan->channel2) {
	case IIO_MOD_X:
		lsb_reg = BMA400_X_AXIS_LSB_REG;
		break;
	case IIO_MOD_Y:
		lsb_reg = BMA400_Y_AXIS_LSB_REG;
		break;
	case IIO_MOD_Z:
		lsb_reg = BMA400_Z_AXIS_LSB_REG;
		break;
	default:
		dev_err(data->dev, "invalid axis channel modifier\n");
		return -EINVAL;
	}

	/* bulk read two registers, with the base being the LSB register */
	ret = regmap_bulk_read(data->regmap, lsb_reg, &raw_accel,
			       sizeof(raw_accel));
	if (ret)
		return ret;

	*val = sign_extend32(le16_to_cpu(raw_accel), 11);
	return IIO_VAL_INT;
}

static void bma400_output_data_rate_from_raw(int raw, unsigned int *val,
					     unsigned int *val2)
{
	*val = BMA400_ACC_ODR_MAX_HZ >> (BMA400_ACC_ODR_MAX_RAW - raw);
	if (raw > BMA400_ACC_ODR_MIN_RAW)
		*val2 = 0;
	else
		*val2 = 500000;
}

static int bma400_get_accel_output_data_rate(struct bma400_data *data)
{
	unsigned int val;
	unsigned int odr;
	int ret;

	switch (data->power_mode) {
	case POWER_MODE_LOW:
		/*
		 * Runs at a fixed rate in low-power mode. See section 4.3
		 * in the datasheet.
		 */
		bma400_output_data_rate_from_raw(BMA400_ACC_ODR_LP_RAW,
						 &data->sample_freq.hz,
						 &data->sample_freq.uhz);
		return 0;
	case POWER_MODE_NORMAL:
		/*
		 * In normal mode the ODR can be found in the ACC_CONFIG1
		 * register.
		 */
		ret = regmap_read(data->regmap, BMA400_ACC_CONFIG1_REG, &val);
		if (ret)
			goto error;

		odr = val & BMA400_ACC_ODR_MASK;
		if (odr < BMA400_ACC_ODR_MIN_RAW ||
		    odr > BMA400_ACC_ODR_MAX_RAW) {
			ret = -EINVAL;
			goto error;
		}

		bma400_output_data_rate_from_raw(odr, &data->sample_freq.hz,
						 &data->sample_freq.uhz);
		return 0;
	case POWER_MODE_SLEEP:
		data->sample_freq.hz = 0;
		data->sample_freq.uhz = 0;
		return 0;
	default:
		ret = 0;
		goto error;
	}
error:
	data->sample_freq.hz = -1;
	data->sample_freq.uhz = -1;
	return ret;
}

static int bma400_set_accel_output_data_rate(struct bma400_data *data,
					     int hz, int uhz)
{
	unsigned int idx;
	unsigned int odr;
	unsigned int val;
	int ret;

	if (hz >= BMA400_ACC_ODR_MIN_WHOLE_HZ) {
		if (uhz || hz > BMA400_ACC_ODR_MAX_HZ)
			return -EINVAL;

		/* Note this works because MIN_WHOLE_HZ is odd */
		idx = __ffs(hz);

		if (hz >> idx != BMA400_ACC_ODR_MIN_WHOLE_HZ)
			return -EINVAL;

		idx += BMA400_ACC_ODR_MIN_RAW + 1;
	} else if (hz == BMA400_ACC_ODR_MIN_HZ && uhz == 500000) {
		idx = BMA400_ACC_ODR_MIN_RAW;
	} else {
		return -EINVAL;
	}

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

	/* preserve the range and normal mode osr */
	odr = (~BMA400_ACC_ODR_MASK & val) | idx;

	ret = regmap_write(data->regmap, BMA400_ACC_CONFIG1_REG, odr);
	if (ret)
		return ret;

	bma400_output_data_rate_from_raw(idx, &data->sample_freq.hz,
					 &data->sample_freq.uhz);
	return 0;
}

static int bma400_get_accel_oversampling_ratio(struct bma400_data *data)
{
	unsigned int val;
	unsigned int osr;
	int ret;

	/*
	 * The oversampling ratio is stored in a different register
	 * based on the power-mode. In normal mode the OSR is stored
	 * in ACC_CONFIG1. In low-power mode it is stored in
	 * ACC_CONFIG0.
	 */
	switch (data->power_mode) {
	case POWER_MODE_LOW:
		ret = regmap_read(data->regmap, BMA400_ACC_CONFIG0_REG, &val);
		if (ret) {
			data->oversampling_ratio = -1;
			return ret;
		}

		osr = (val & BMA400_LP_OSR_MASK) >> BMA400_LP_OSR_SHIFT;

		data->oversampling_ratio = osr;
		return 0;
	case POWER_MODE_NORMAL:
		ret = regmap_read(data->regmap, BMA400_ACC_CONFIG1_REG, &val);
		if (ret) {
			data->oversampling_ratio = -1;
			return ret;
		}

		osr = (val & BMA400_NP_OSR_MASK) >> BMA400_NP_OSR_SHIFT;

		data->oversampling_ratio = osr;
		return 0;
	case POWER_MODE_SLEEP:
		data->oversampling_ratio = 0;
		return 0;
	default:
		data->oversampling_ratio = -1;
		return -EINVAL;
	}
}

static int bma400_set_accel_oversampling_ratio(struct bma400_data *data,
					       int val)
{
	unsigned int acc_config;
	int ret;

	if (val & ~BMA400_TWO_BITS_MASK)
		return -EINVAL;

	/*
	 * The oversampling ratio is stored in a different register
	 * based on the power-mode.
	 */
	switch (data->power_mode) {
	case POWER_MODE_LOW:
		ret = regmap_read(data->regmap, BMA400_ACC_CONFIG0_REG,
				  &acc_config);
		if (ret)
			return ret;

		ret = regmap_write(data->regmap, BMA400_ACC_CONFIG0_REG,
				   (acc_config & ~BMA400_LP_OSR_MASK) |
				   (val << BMA400_LP_OSR_SHIFT));
		if (ret) {
			dev_err(data->dev, "Failed to write out OSR\n");
			return ret;
		}

		data->oversampling_ratio = val;
		return 0;
	case POWER_MODE_NORMAL:
		ret = regmap_read(data->regmap, BMA400_ACC_CONFIG1_REG,
				  &acc_config);
		if (ret)
			return ret;

		ret = regmap_write(data->regmap, BMA400_ACC_CONFIG1_REG,
				   (acc_config & ~BMA400_NP_OSR_MASK) |
				   (val << BMA400_NP_OSR_SHIFT));
		if (ret) {
			dev_err(data->dev, "Failed to write out OSR\n");
			return ret;
		}

		data->oversampling_ratio = val;
		return 0;
	default:
		return -EINVAL;
	}
	return ret;
}

static int bma400_accel_scale_to_raw(struct bma400_data *data,
				     unsigned int val)
{
	int raw;

	if (val == 0)
		return -EINVAL;

	/* Note this works because BMA400_SCALE_MIN is odd */
	raw = __ffs(val);

	if (val >> raw != BMA400_SCALE_MIN)
		return -EINVAL;

	return raw;
}

static int bma400_get_accel_scale(struct bma400_data *data)
{
	unsigned int raw_scale;
	unsigned int val;
	int ret;

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

	raw_scale = (val & BMA400_ACC_SCALE_MASK) >> BMA400_SCALE_SHIFT;
	if (raw_scale > BMA400_TWO_BITS_MASK)
		return -EINVAL;

	data->scale = BMA400_SCALE_MIN << raw_scale;

	return 0;
}

static int bma400_set_accel_scale(struct bma400_data *data, unsigned int val)
{
	unsigned int acc_config;
	int raw;
	int ret;

	ret = regmap_read(data->regmap, BMA400_ACC_CONFIG1_REG, &acc_config);
	if (ret)
		return ret;

	raw = bma400_accel_scale_to_raw(data, val);
	if (raw < 0)
		return raw;

	ret = regmap_write(data->regmap, BMA400_ACC_CONFIG1_REG,
			   (acc_config & ~BMA400_ACC_SCALE_MASK) |
			   (raw << BMA400_SCALE_SHIFT));
	if (ret)
		return ret;

	data->scale = val;
	return 0;
}

static int bma400_get_power_mode(struct bma400_data *data)
{
	unsigned int val;
	int ret;

	ret = regmap_read(data->regmap, BMA400_STATUS_REG, &val);
	if (ret) {
		dev_err(data->dev, "Failed to read status register\n");
		return ret;
	}

	data->power_mode = (val >> 1) & BMA400_TWO_BITS_MASK;
	return 0;
}

static int bma400_set_power_mode(struct bma400_data *data,
				 enum bma400_power_mode mode)
{
	unsigned int val;
	int ret;

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

	if (data->power_mode == mode)
		return 0;

	if (mode == POWER_MODE_INVALID)
		return -EINVAL;

	/* Preserve the low-power oversample ratio etc */
	ret = regmap_write(data->regmap, BMA400_ACC_CONFIG0_REG,
			   mode | (val & ~BMA400_TWO_BITS_MASK));
	if (ret) {
		dev_err(data->dev, "Failed to write to power-mode\n");
		return ret;
	}

	data->power_mode = mode;

	/*
	 * Update our cached osr and odr based on the new
	 * power-mode.
	 */
	bma400_get_accel_output_data_rate(data);
	bma400_get_accel_oversampling_ratio(data);
	return 0;
}

static int bma400_enable_steps(struct bma400_data *data, int val)
{
	int ret;

	if (data->steps_enabled == val)
		return 0;

	ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG1_REG,
				 BMA400_STEP_INT_MSK,
				 FIELD_PREP(BMA400_STEP_INT_MSK, val ? 1 : 0));
	if (ret)
		return ret;
	data->steps_enabled = val;
	return ret;
}

static int bma400_get_steps_reg(struct bma400_data *data, int *val)
{
	u8 *steps_raw;
	int ret;

	steps_raw = kmalloc(BMA400_STEP_RAW_LEN, GFP_KERNEL);
	if (!steps_raw)
		return -ENOMEM;

	ret = regmap_bulk_read(data->regmap, BMA400_STEP_CNT0_REG,
			       steps_raw, BMA400_STEP_RAW_LEN);
	if (ret) {
		kfree(steps_raw);
		return ret;
	}
	*val = get_unaligned_le24(steps_raw);
	kfree(steps_raw);
	return IIO_VAL_INT;
}

static void bma400_init_tables(void)
{
	int raw;
	int i;

	for (i = 0; i + 1 < ARRAY_SIZE(bma400_sample_freqs); i += 2) {
		raw = (i / 2) + 5;
		bma400_output_data_rate_from_raw(raw, &bma400_sample_freqs[i],
						 &bma400_sample_freqs[i + 1]);
	}

	for (i = 0; i + 1 < ARRAY_SIZE(bma400_scales); i += 2) {
		raw = i / 2;
		bma400_scales[i] = 0;
		bma400_scales[i + 1] = BMA400_SCALE_MIN << raw;
	}
}

static void bma400_regulators_disable(void *data_ptr)
{
	struct bma400_data *data = data_ptr;

	regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators);
}

static void bma400_power_disable(void *data_ptr)
{
	struct bma400_data *data = data_ptr;
	int ret;

	mutex_lock(&data->mutex);
	ret = bma400_set_power_mode(data, POWER_MODE_SLEEP);
	mutex_unlock(&data->mutex);
	if (ret)
		dev_warn(data->dev, "Failed to put device into sleep mode (%pe)\n",
			 ERR_PTR(ret));
}

static enum iio_modifier bma400_act_to_mod(enum bma400_activity activity)
{
	switch (activity) {
	case BMA400_STILL:
		return IIO_MOD_STILL;
	case BMA400_WALKING:
		return IIO_MOD_WALKING;
	case BMA400_RUNNING:
		return IIO_MOD_RUNNING;
	default:
		return IIO_NO_MOD;
	}
}

static int bma400_init(struct bma400_data *data)
{
	unsigned int val;
	int ret;

	data->regulators[BMA400_VDD_REGULATOR].supply = "vdd";
	data->regulators[BMA400_VDDIO_REGULATOR].supply = "vddio";
	ret = devm_regulator_bulk_get(data->dev,
				      ARRAY_SIZE(data->regulators),
				      data->regulators);
	if (ret)
		return dev_err_probe(data->dev, ret, "Failed to get regulators: %d\n",
				     ret);

	ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
				    data->regulators);
	if (ret) {
		dev_err(data->dev, "Failed to enable regulators: %d\n",
			ret);
		return ret;
	}

	ret = devm_add_action_or_reset(data->dev, bma400_regulators_disable, data);
	if (ret)
		return ret;

	/* Try to read chip_id register. It must return 0x90. */
	ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val);
	if (ret) {
		dev_err(data->dev, "Failed to read chip id register\n");
		return ret;
	}

	if (val != BMA400_ID_REG_VAL) {
		dev_err(data->dev, "Chip ID mismatch\n");
		return -ENODEV;
	}

	ret = bma400_get_power_mode(data);
	if (ret) {
		dev_err(data->dev, "Failed to get the initial power-mode\n");
		return ret;
	}

	if (data->power_mode != POWER_MODE_NORMAL) {
		ret = bma400_set_power_mode(data, POWER_MODE_NORMAL);
		if (ret) {
			dev_err(data->dev, "Failed to wake up the device\n");
			return ret;
		}
		/*
		 * TODO: The datasheet waits 1500us here in the example, but
		 * lists 2/ODR as the wakeup time.
		 */
		usleep_range(1500, 2000);
	}

	ret = devm_add_action_or_reset(data->dev, bma400_power_disable, data);
	if (ret)
		return ret;

	bma400_init_tables();

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

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

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

	/* Configure INT1 pin to open drain */
	ret = regmap_write(data->regmap, BMA400_INT_IO_CTRL_REG, 0x06);
	if (ret)
		return ret;
	/*
	 * Once the interrupt engine is supported we might use the
	 * data_src_reg, but for now ensure this is set to the
	 * variable ODR filter selectable by the sample frequency
	 * channel.
	 */
	return regmap_write(data->regmap, BMA400_ACC_CONFIG2_REG, 0x00);
}

static int bma400_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan, int *val,
			   int *val2, long mask)
{
	struct bma400_data *data = iio_priv(indio_dev);
	unsigned int activity;
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_PROCESSED:
		switch (chan->type) {
		case IIO_TEMP:
			mutex_lock(&data->mutex);
			ret = bma400_get_temp_reg(data, val, val2);
			mutex_unlock(&data->mutex);
			return ret;
		case IIO_STEPS:
			return bma400_get_steps_reg(data, val);
		case IIO_ACTIVITY:
			ret = regmap_read(data->regmap, BMA400_STEP_STAT_REG,
					  &activity);
			if (ret)
				return ret;
			/*
			 * The device does not support confidence value levels,
			 * so we will always have 100% for current activity and
			 * 0% for the others.
			 */
			if (chan->channel2 == bma400_act_to_mod(activity))
				*val = 100;
			else
				*val = 0;
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&data->mutex);
		ret = bma400_get_accel_reg(data, chan, val);
		mutex_unlock(&data->mutex);
		return ret;
	case IIO_CHAN_INFO_SAMP_FREQ:
		switch (chan->type) {
		case IIO_ACCEL:
			if (data->sample_freq.hz < 0)
				return -EINVAL;

			*val = data->sample_freq.hz;
			*val2 = data->sample_freq.uhz;
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_TEMP:
			/*
			 * Runs at a fixed sampling frequency. See Section 4.4
			 * of the datasheet.
			 */
			*val = 6;
			*val2 = 250000;
			return IIO_VAL_INT_PLUS_MICRO;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_SCALE:
		*val = 0;
		*val2 = data->scale;
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		/*
		 * TODO: We could avoid this logic and returning -EINVAL here if
		 * we set both the low-power and normal mode OSR registers when
		 * we configure the device.
		 */
		if (data->oversampling_ratio < 0)
			return -EINVAL;

		*val = data->oversampling_ratio;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_ENABLE:
		*val = data->steps_enabled;
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int bma400_read_avail(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     const int **vals, int *type, int *length,
			     long mask)
{
	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
		*type = IIO_VAL_INT_PLUS_MICRO;
		*vals = bma400_scales;
		*length = ARRAY_SIZE(bma400_scales);
		return IIO_AVAIL_LIST;
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		*type = IIO_VAL_INT;
		*vals = bma400_osr_range;
		*length = ARRAY_SIZE(bma400_osr_range);
		return IIO_AVAIL_RANGE;
	case IIO_CHAN_INFO_SAMP_FREQ:
		*type = IIO_VAL_INT_PLUS_MICRO;
		*vals = bma400_sample_freqs;
		*length = ARRAY_SIZE(bma400_sample_freqs);
		return IIO_AVAIL_LIST;
	default:
		return -EINVAL;
	}
}

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

	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		/*
		 * The sample frequency is readonly for the temperature
		 * register and a fixed value in low-power mode.
		 */
		if (chan->type != IIO_ACCEL)
			return -EINVAL;

		mutex_lock(&data->mutex);
		ret = bma400_set_accel_output_data_rate(data, val, val2);
		mutex_unlock(&data->mutex);
		return ret;
	case IIO_CHAN_INFO_SCALE:
		if (val != 0 ||
		    val2 < BMA400_SCALE_MIN || val2 > BMA400_SCALE_MAX)
			return -EINVAL;

		mutex_lock(&data->mutex);
		ret = bma400_set_accel_scale(data, val2);
		mutex_unlock(&data->mutex);
		return ret;
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		mutex_lock(&data->mutex);
		ret = bma400_set_accel_oversampling_ratio(data, val);
		mutex_unlock(&data->mutex);
		return ret;
	case IIO_CHAN_INFO_ENABLE:
		mutex_lock(&data->mutex);
		ret = bma400_enable_steps(data, val);
		mutex_unlock(&data->mutex);
		return ret;
	default:
		return -EINVAL;
	}
}

static int bma400_write_raw_get_fmt(struct iio_dev *indio_dev,
				    struct iio_chan_spec const *chan,
				    long mask)
{
	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_SCALE:
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_ENABLE:
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int bma400_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 bma400_data *data = iio_priv(indio_dev);

	switch (chan->type) {
	case IIO_ACCEL:
		switch (dir) {
		case IIO_EV_DIR_RISING:
			return FIELD_GET(BMA400_INT_GEN1_MSK,
					 data->generic_event_en);
		case IIO_EV_DIR_FALLING:
			return FIELD_GET(BMA400_INT_GEN2_MSK,
					 data->generic_event_en);
		case IIO_EV_DIR_SINGLETAP:
			return FIELD_GET(BMA400_S_TAP_MSK,
					 data->tap_event_en_bitmask);
		case IIO_EV_DIR_DOUBLETAP:
			return FIELD_GET(BMA400_D_TAP_MSK,
					 data->tap_event_en_bitmask);
		default:
			return -EINVAL;
		}
	case IIO_STEPS:
		return data->step_event_en;
	case IIO_ACTIVITY:
		return data->activity_event_en;
	default:
		return -EINVAL;
	}
}

static int bma400_steps_event_enable(struct bma400_data *data, int state)
{
	int ret;

	ret = bma400_enable_steps(data, 1);
	if (ret)
		return ret;

	ret = regmap_update_bits(data->regmap, BMA400_INT12_MAP_REG,
				 BMA400_STEP_INT_MSK,
				 FIELD_PREP(BMA400_STEP_INT_MSK,
					    state));
	if (ret)
		return ret;
	data->step_event_en = state;
	return 0;
}

static int bma400_activity_event_en(struct bma400_data *data,
				    enum iio_event_direction dir,
				    int state)
{
	int ret, reg, msk, value;
	int field_value = 0;

	switch (dir) {
	case IIO_EV_DIR_RISING:
		reg = BMA400_GEN1INT_CONFIG0;
		msk = BMA400_INT_GEN1_MSK;
		value = 2;
		set_mask_bits(&field_value, BMA400_INT_GEN1_MSK,
			      FIELD_PREP(BMA400_INT_GEN1_MSK, state));
		break;
	case IIO_EV_DIR_FALLING:
		reg = BMA400_GEN2INT_CONFIG0;
		msk = BMA400_INT_GEN2_MSK;
		value = 0;
		set_mask_bits(&field_value, BMA400_INT_GEN2_MSK,
			      FIELD_PREP(BMA400_INT_GEN2_MSK, state));
		break;
	default:
		return -EINVAL;
	}

	/* Enabling all axis for interrupt evaluation */
	ret = regmap_write(data->regmap, reg, 0xF8);
	if (ret)
		return ret;

	/* OR combination of all axis for interrupt evaluation */
	ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG1_OFF, value);
	if (ret)
		return ret;

	/* Initial value to avoid interrupts while enabling*/
	ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG2_OFF, 0x0A);
	if (ret)
		return ret;

	/* Initial duration value to avoid interrupts while enabling*/
	ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG31_OFF, 0x0F);
	if (ret)
		return ret;

	ret = regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, msk,
				 field_value);
	if (ret)
		return ret;

	ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG, msk,
				 field_value);
	if (ret)
		return ret;

	set_mask_bits(&data->generic_event_en, msk, field_value);
	return 0;
}

static int bma400_tap_event_en(struct bma400_data *data,
			       enum iio_event_direction dir, int state)
{
	unsigned int mask, field_value;
	int ret;

	/*
	 * Tap interrupts can be configured only in normal mode.
	 * See table in section 4.3 "Power modes - performance modes" of
	 * datasheet v1.2.
	 */
	if (data->power_mode != POWER_MODE_NORMAL)
		return -EINVAL;

	/*
	 * Tap interrupts are operating with a data rate of 200Hz.
	 * See section 4.7 "Tap sensing interrupt" in datasheet v1.2.
	 */
	if (data->sample_freq.hz != 200 && state) {
		dev_err(data->dev, "Invalid data rate for tap interrupts.\n");
		return -EINVAL;
	}

	ret = regmap_update_bits(data->regmap, BMA400_INT12_MAP_REG,
				 BMA400_S_TAP_MSK,
				 FIELD_PREP(BMA400_S_TAP_MSK, state));
	if (ret)
		return ret;

	switch (dir) {
	case IIO_EV_DIR_SINGLETAP:
		mask = BMA400_S_TAP_MSK;
		set_mask_bits(&field_value, BMA400_S_TAP_MSK,
			      FIELD_PREP(BMA400_S_TAP_MSK, state));
		break;
	case IIO_EV_DIR_DOUBLETAP:
		mask = BMA400_D_TAP_MSK;
		set_mask_bits(&field_value, BMA400_D_TAP_MSK,
			      FIELD_PREP(BMA400_D_TAP_MSK, state));
		break;
	default:
		return -EINVAL;
	}

	ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG1_REG, mask,
				 field_value);
	if (ret)
		return ret;

	set_mask_bits(&data->tap_event_en_bitmask, mask, field_value);

	return 0;
}

static int bma400_disable_adv_interrupt(struct bma400_data *data)
{
	int ret;

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

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

	data->tap_event_en_bitmask = 0;
	data->generic_event_en = 0;
	data->step_event_en = false;
	data->activity_event_en = false;

	return 0;
}

static int bma400_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 bma400_data *data = iio_priv(indio_dev);
	int ret;

	switch (chan->type) {
	case IIO_ACCEL:
		switch (type) {
		case IIO_EV_TYPE_MAG:
			mutex_lock(&data->mutex);
			ret = bma400_activity_event_en(data, dir, state);
			mutex_unlock(&data->mutex);
			return ret;
		case IIO_EV_TYPE_GESTURE:
			mutex_lock(&data->mutex);
			ret = bma400_tap_event_en(data, dir, state);
			mutex_unlock(&data->mutex);
			return ret;
		default:
			return -EINVAL;
		}
	case IIO_STEPS:
		mutex_lock(&data->mutex);
		ret = bma400_steps_event_enable(data, state);
		mutex_unlock(&data->mutex);
		return ret;
	case IIO_ACTIVITY:
		mutex_lock(&data->mutex);
		if (!data->step_event_en) {
			ret = bma400_steps_event_enable(data, true);
			if (ret) {
				mutex_unlock(&data->mutex);
				return ret;
			}
		}
		data->activity_event_en = state;
		mutex_unlock(&data->mutex);
		return 0;
	default:
		return -EINVAL;
	}
}

static int get_gen_config_reg(enum iio_event_direction dir)
{
	switch (dir) {
	case IIO_EV_DIR_FALLING:
		return BMA400_GEN2INT_CONFIG0;
	case IIO_EV_DIR_RISING:
		return BMA400_GEN1INT_CONFIG0;
	default:
		return -EINVAL;
	}
}

static int bma400_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 bma400_data *data = iio_priv(indio_dev);
	int ret, reg, reg_val, raw;

	if (chan->type != IIO_ACCEL)
		return -EINVAL;

	switch (type) {
	case IIO_EV_TYPE_MAG:
		reg = get_gen_config_reg(dir);
		if (reg < 0)
			return -EINVAL;

		*val2 = 0;
		switch (info) {
		case IIO_EV_INFO_VALUE:
			ret = regmap_read(data->regmap,
					  reg + BMA400_GEN_CONFIG2_OFF,
					  val);
			if (ret)
				return ret;
			return IIO_VAL_INT;
		case IIO_EV_INFO_PERIOD:
			mutex_lock(&data->mutex);
			ret = regmap_bulk_read(data->regmap,
					       reg + BMA400_GEN_CONFIG3_OFF,
					       &data->duration,
					       sizeof(data->duration));
			if (ret) {
				mutex_unlock(&data->mutex);
				return ret;
			}
			*val = be16_to_cpu(data->duration);
			mutex_unlock(&data->mutex);
			return IIO_VAL_INT;
		case IIO_EV_INFO_HYSTERESIS:
			ret = regmap_read(data->regmap, reg, val);
			if (ret)
				return ret;
			*val = FIELD_GET(BMA400_GEN_HYST_MSK, *val);
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
	case IIO_EV_TYPE_GESTURE:
		switch (info) {
		case IIO_EV_INFO_VALUE:
			ret = regmap_read(data->regmap, BMA400_TAP_CONFIG,
					  &reg_val);
			if (ret)
				return ret;

			*val = FIELD_GET(BMA400_TAP_SEN_MSK, reg_val);
			return IIO_VAL_INT;
		case IIO_EV_INFO_RESET_TIMEOUT:
			ret = regmap_read(data->regmap, BMA400_TAP_CONFIG1,
					  &reg_val);
			if (ret)
				return ret;

			raw = FIELD_GET(BMA400_TAP_QUIET_MSK, reg_val);
			*val = 0;
			*val2 = tap_reset_timeout[raw];
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_EV_INFO_TAP2_MIN_DELAY:
			ret = regmap_read(data->regmap, BMA400_TAP_CONFIG1,
					  &reg_val);
			if (ret)
				return ret;

			raw = FIELD_GET(BMA400_TAP_QUIETDT_MSK, reg_val);
			*val = 0;
			*val2 = double_tap2_min_delay[raw];
			return IIO_VAL_INT_PLUS_MICRO;
		default:
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

static int bma400_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 bma400_data *data = iio_priv(indio_dev);
	int reg, ret, raw;

	if (chan->type != IIO_ACCEL)
		return -EINVAL;

	switch (type) {
	case IIO_EV_TYPE_MAG:
		reg = get_gen_config_reg(dir);
		if (reg < 0)
			return -EINVAL;

		switch (info) {
		case IIO_EV_INFO_VALUE:
			if (val < 1 || val > 255)
				return -EINVAL;

			return regmap_write(data->regmap,
					    reg + BMA400_GEN_CONFIG2_OFF,
					    val);
		case IIO_EV_INFO_PERIOD:
			if (val < 1 || val > 65535)
				return -EINVAL;

			mutex_lock(&data->mutex);
			put_unaligned_be16(val, &data->duration);
			ret = regmap_bulk_write(data->regmap,
						reg + BMA400_GEN_CONFIG3_OFF,
						&data->duration,
						sizeof(data->duration));
			mutex_unlock(&data->mutex);
			return ret;
		case IIO_EV_INFO_HYSTERESIS:
			if (val < 0 || val > 3)
				return -EINVAL;

			return regmap_update_bits(data->regmap, reg,
						  BMA400_GEN_HYST_MSK,
						  FIELD_PREP(BMA400_GEN_HYST_MSK,
							     val));
		default:
			return -EINVAL;
		}
	case IIO_EV_TYPE_GESTURE:
		switch (info) {
		case IIO_EV_INFO_VALUE:
			if (val < 0 || val > 7)
				return -EINVAL;

			return regmap_update_bits(data->regmap,
						  BMA400_TAP_CONFIG,
						  BMA400_TAP_SEN_MSK,
						  FIELD_PREP(BMA400_TAP_SEN_MSK,
							     val));
		case IIO_EV_INFO_RESET_TIMEOUT:
			raw = usec_to_tapreg_raw(val2, tap_reset_timeout);
			if (raw < 0)
				return -EINVAL;

			return regmap_update_bits(data->regmap,
						  BMA400_TAP_CONFIG1,
						  BMA400_TAP_QUIET_MSK,
						  FIELD_PREP(BMA400_TAP_QUIET_MSK,
							     raw));
		case IIO_EV_INFO_TAP2_MIN_DELAY:
			raw = usec_to_tapreg_raw(val2, double_tap2_min_delay);
			if (raw < 0)
				return -EINVAL;

			return regmap_update_bits(data->regmap,
						  BMA400_TAP_CONFIG1,
						  BMA400_TAP_QUIETDT_MSK,
						  FIELD_PREP(BMA400_TAP_QUIETDT_MSK,
							     raw));
		default:
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

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

	ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG,
				 BMA400_INT_DRDY_MSK,
				 FIELD_PREP(BMA400_INT_DRDY_MSK, state));
	if (ret)
		return ret;

	return regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG,
				  BMA400_INT_DRDY_MSK,
				  FIELD_PREP(BMA400_INT_DRDY_MSK, state));
}

static const unsigned long bma400_avail_scan_masks[] = {
	BIT(BMA400_ACCL_X) | BIT(BMA400_ACCL_Y) | BIT(BMA400_ACCL_Z),
	BIT(BMA400_ACCL_X) | BIT(BMA400_ACCL_Y) | BIT(BMA400_ACCL_Z)
	| BIT(BMA400_TEMP),
	0
};

static const struct iio_info bma400_info = {
	.read_raw          = bma400_read_raw,
	.read_avail        = bma400_read_avail,
	.write_raw         = bma400_write_raw,
	.write_raw_get_fmt = bma400_write_raw_get_fmt,
	.read_event_config = bma400_read_event_config,
	.write_event_config = bma400_write_event_config,
	.write_event_value = bma400_write_event_value,
	.read_event_value = bma400_read_event_value,
	.event_attrs = &bma400_event_attribute_group,
};

static const struct iio_trigger_ops bma400_trigger_ops = {
	.set_trigger_state = &bma400_data_rdy_trigger_set_state,
	.validate_device = &iio_trigger_validate_own_device,
};

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

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

	/* bulk read six registers, with the base being the LSB register */
	ret = regmap_bulk_read(data->regmap, BMA400_X_AXIS_LSB_REG,
			       &data->buffer.buff, sizeof(data->buffer.buff));
	if (ret)
		goto unlock_err;

	if (test_bit(BMA400_TEMP, indio_dev->active_scan_mask)) {
		ret = regmap_read(data->regmap, BMA400_TEMP_DATA_REG, &temp);
		if (ret)
			goto unlock_err;

		data->buffer.temperature = temp;
	}

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

	mutex_unlock(&data->mutex);
	iio_trigger_notify_done(indio_dev->trig);
	return IRQ_HANDLED;

unlock_err:
	mutex_unlock(&data->mutex);
	return IRQ_NONE;
}

static irqreturn_t bma400_interrupt(int irq, void *private)
{
	struct iio_dev *indio_dev = private;
	struct bma400_data *data = iio_priv(indio_dev);
	s64 timestamp = iio_get_time_ns(indio_dev);
	unsigned int act, ev_dir = IIO_EV_DIR_NONE;
	int ret;

	/* Lock to protect the data->status */
	mutex_lock(&data->mutex);
	ret = regmap_bulk_read(data->regmap, BMA400_INT_STAT0_REG,
			       &data->status,
			       sizeof(data->status));
	/*
	 * if none of the bit is set in the status register then it is
	 * spurious interrupt.
	 */
	if (ret || !data->status)
		goto unlock_err;

	/*
	 * Disable all advance interrupts if interrupt engine overrun occurs.
	 * See section 4.7 "Interrupt engine overrun" in datasheet v1.2.
	 */
	if (FIELD_GET(BMA400_INT_ENG_OVRUN_MSK, le16_to_cpu(data->status))) {
		bma400_disable_adv_interrupt(data);
		dev_err(data->dev, "Interrupt engine overrun\n");
		goto unlock_err;
	}

	if (FIELD_GET(BMA400_INT_S_TAP_MSK, le16_to_cpu(data->status)))
		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(BMA400_INT_D_TAP_MSK, le16_to_cpu(data->status)))
		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);

	if (FIELD_GET(BMA400_INT_GEN1_MSK, le16_to_cpu(data->status)))
		ev_dir = IIO_EV_DIR_RISING;

	if (FIELD_GET(BMA400_INT_GEN2_MSK, le16_to_cpu(data->status)))
		ev_dir = IIO_EV_DIR_FALLING;

	if (ev_dir != IIO_EV_DIR_NONE) {
		iio_push_event(indio_dev,
			       IIO_MOD_EVENT_CODE(IIO_ACCEL, 0,
						  IIO_MOD_X_OR_Y_OR_Z,
						  IIO_EV_TYPE_MAG, ev_dir),
			       timestamp);
	}

	if (FIELD_GET(BMA400_STEP_STAT_MASK, le16_to_cpu(data->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 (data->activity_event_en) {
			ret = regmap_read(data->regmap, BMA400_STEP_STAT_REG,
					  &act);
			if (ret)
				goto unlock_err;

			iio_push_event(indio_dev,
				       IIO_MOD_EVENT_CODE(IIO_ACTIVITY, 0,
							  bma400_act_to_mod(act),
							  IIO_EV_TYPE_CHANGE,
							  IIO_EV_DIR_NONE),
				       timestamp);
		}
	}

	if (FIELD_GET(BMA400_INT_DRDY_MSK, le16_to_cpu(data->status))) {
		mutex_unlock(&data->mutex);
		iio_trigger_poll_chained(data->trig);
		return IRQ_HANDLED;
	}

	mutex_unlock(&data->mutex);
	return IRQ_HANDLED;

unlock_err:
	mutex_unlock(&data->mutex);
	return IRQ_NONE;
}

int bma400_probe(struct device *dev, struct regmap *regmap, int irq,
		 const char *name)
{
	struct iio_dev *indio_dev;
	struct bma400_data *data;
	int ret;

	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;

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

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

	mutex_init(&data->mutex);
	indio_dev->name = name;
	indio_dev->info = &bma400_info;
	indio_dev->channels = bma400_channels;
	indio_dev->num_channels = ARRAY_SIZE(bma400_channels);
	indio_dev->available_scan_masks = bma400_avail_scan_masks;
	indio_dev->modes = INDIO_DIRECT_MODE;

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

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

		ret = devm_iio_trigger_register(data->dev, data->trig);
		if (ret)
			return dev_err_probe(data->dev, ret,
					     "iio trigger register fail\n");

		indio_dev->trig = iio_trigger_get(data->trig);
		ret = devm_request_threaded_irq(dev, irq, NULL,
						&bma400_interrupt,
						IRQF_TRIGGER_RISING | IRQF_ONESHOT,
						indio_dev->name, indio_dev);
		if (ret)
			return dev_err_probe(data->dev, ret,
					     "request irq %d failed\n", irq);
	}

	ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
					      &bma400_trigger_handler, NULL);
	if (ret)
		return dev_err_probe(data->dev, ret,
				     "iio triggered buffer setup failed\n");

	return devm_iio_device_register(dev, indio_dev);
}
EXPORT_SYMBOL_NS(bma400_probe, IIO_BMA400);

MODULE_AUTHOR("Dan Robertson <dan@dlrobertson.com>");
MODULE_AUTHOR("Jagath Jog J <jagathjog1996@gmail.com>");
MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor core");
MODULE_LICENSE("GPL");
