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

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

	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;

	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");
