// 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/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 };

/* 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;
	/* 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),
	},
};

#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) {
		if (ret != -EPROBE_DEFER)
			dev_err(data->dev,
				"Failed to get regulators: %d\n",
				ret);

		return 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);
		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, field_value;

	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_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:
		mutex_lock(&data->mutex);
		ret = bma400_activity_event_en(data, dir, state);
		mutex_unlock(&data->mutex);
		return ret;
	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;

	switch (chan->type) {
	case IIO_ACCEL:
		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;
		}
	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;

	switch (chan->type) {
	case IIO_ACCEL:
		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;
		}
	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,
};

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;

	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_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor core");
MODULE_LICENSE("GPL");
