/*
 * sca3000_core.c -- support VTI sca3000 series accelerometers via SPI
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * Copyright (c) 2009 Jonathan Cameron <jic23@kernel.org>
 *
 * See industrialio/accels/sca3000.h for comments.
 */

#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/events.h>
#include <linux/iio/buffer.h>

#include "sca3000.h"

enum sca3000_variant {
	d01,
	e02,
	e04,
	e05,
};

/*
 * Note where option modes are not defined, the chip simply does not
 * support any.
 * Other chips in the sca3000 series use i2c and are not included here.
 *
 * Some of these devices are only listed in the family data sheet and
 * do not actually appear to be available.
 */
static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = {
	[d01] = {
		.scale = 7357,
		.temp_output = true,
		.measurement_mode_freq = 250,
		.option_mode_1 = SCA3000_OP_MODE_BYPASS,
		.option_mode_1_freq = 250,
		.mot_det_mult_xz = {50, 100, 200, 350, 650, 1300},
		.mot_det_mult_y = {50, 100, 150, 250, 450, 850, 1750},
	},
	[e02] = {
		.scale = 9810,
		.measurement_mode_freq = 125,
		.option_mode_1 = SCA3000_OP_MODE_NARROW,
		.option_mode_1_freq = 63,
		.mot_det_mult_xz = {100, 150, 300, 550, 1050, 2050},
		.mot_det_mult_y = {50, 100, 200, 350, 700, 1350, 2700},
	},
	[e04] = {
		.scale = 19620,
		.measurement_mode_freq = 100,
		.option_mode_1 = SCA3000_OP_MODE_NARROW,
		.option_mode_1_freq = 50,
		.option_mode_2 = SCA3000_OP_MODE_WIDE,
		.option_mode_2_freq = 400,
		.mot_det_mult_xz = {200, 300, 600, 1100, 2100, 4100},
		.mot_det_mult_y = {100, 200, 400, 7000, 1400, 2700, 54000},
	},
	[e05] = {
		.scale = 61313,
		.measurement_mode_freq = 200,
		.option_mode_1 = SCA3000_OP_MODE_NARROW,
		.option_mode_1_freq = 50,
		.option_mode_2 = SCA3000_OP_MODE_WIDE,
		.option_mode_2_freq = 400,
		.mot_det_mult_xz = {600, 900, 1700, 3200, 6100, 11900},
		.mot_det_mult_y = {300, 600, 1200, 2000, 4100, 7800, 15600},
	},
};

int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val)
{
	st->tx[0] = SCA3000_WRITE_REG(address);
	st->tx[1] = val;
	return spi_write(st->us, st->tx, 2);
}

int sca3000_read_data_short(struct sca3000_state *st,
			    u8 reg_address_high,
			    int len)
{
	struct spi_transfer xfer[2] = {
		{
			.len = 1,
			.tx_buf = st->tx,
		}, {
			.len = len,
			.rx_buf = st->rx,
		}
	};
	st->tx[0] = SCA3000_READ_REG(reg_address_high);

	return spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer));
}

/**
 * sca3000_reg_lock_on() test if the ctrl register lock is on
 *
 * Lock must be held.
 **/
static int sca3000_reg_lock_on(struct sca3000_state *st)
{
	int ret;

	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1);
	if (ret < 0)
		return ret;

	return !(st->rx[0] & SCA3000_LOCKED);
}

/**
 * __sca3000_unlock_reg_lock() unlock the control registers
 *
 * Note the device does not appear to support doing this in a single transfer.
 * This should only ever be used as part of ctrl reg read.
 * Lock must be held before calling this
 **/
static int __sca3000_unlock_reg_lock(struct sca3000_state *st)
{
	struct spi_transfer xfer[3] = {
		{
			.len = 2,
			.cs_change = 1,
			.tx_buf = st->tx,
		}, {
			.len = 2,
			.cs_change = 1,
			.tx_buf = st->tx + 2,
		}, {
			.len = 2,
			.tx_buf = st->tx + 4,
		},
	};
	st->tx[0] = SCA3000_WRITE_REG(SCA3000_REG_ADDR_UNLOCK);
	st->tx[1] = 0x00;
	st->tx[2] = SCA3000_WRITE_REG(SCA3000_REG_ADDR_UNLOCK);
	st->tx[3] = 0x50;
	st->tx[4] = SCA3000_WRITE_REG(SCA3000_REG_ADDR_UNLOCK);
	st->tx[5] = 0xA0;

	return spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer));
}

/**
 * sca3000_write_ctrl_reg() write to a lock protect ctrl register
 * @sel: selects which registers we wish to write to
 * @val: the value to be written
 *
 * Certain control registers are protected against overwriting by the lock
 * register and use a shared write address. This function allows writing of
 * these registers.
 * Lock must be held.
 **/
static int sca3000_write_ctrl_reg(struct sca3000_state *st,
				  u8 sel,
				  uint8_t val)
{
	int ret;

	ret = sca3000_reg_lock_on(st);
	if (ret < 0)
		goto error_ret;
	if (ret) {
		ret = __sca3000_unlock_reg_lock(st);
		if (ret)
			goto error_ret;
	}

	/* Set the control select register */
	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_SEL, sel);
	if (ret)
		goto error_ret;

	/* Write the actual value into the register */
	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_DATA, val);

error_ret:
	return ret;
}

/**
 * sca3000_read_ctrl_reg() read from lock protected control register.
 *
 * Lock must be held.
 **/
static int sca3000_read_ctrl_reg(struct sca3000_state *st,
				 u8 ctrl_reg)
{
	int ret;

	ret = sca3000_reg_lock_on(st);
	if (ret < 0)
		goto error_ret;
	if (ret) {
		ret = __sca3000_unlock_reg_lock(st);
		if (ret)
			goto error_ret;
	}
	/* Set the control select register */
	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_SEL, ctrl_reg);
	if (ret)
		goto error_ret;
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_CTRL_DATA, 1);
	if (ret)
		goto error_ret;
	return st->rx[0];
error_ret:
	return ret;
}

/**
 * sca3000_show_rev() - sysfs interface to read the chip revision number
 **/
static ssize_t sca3000_show_rev(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	int len = 0, ret;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct sca3000_state *st = iio_priv(indio_dev);

	mutex_lock(&st->lock);
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_REVID, 1);
	if (ret < 0)
		goto error_ret;
	len += sprintf(buf + len,
		       "major=%d, minor=%d\n",
		       st->rx[0] & SCA3000_REVID_MAJOR_MASK,
		       st->rx[0] & SCA3000_REVID_MINOR_MASK);
error_ret:
	mutex_unlock(&st->lock);

	return ret ? ret : len;
}

/**
 * sca3000_show_available_measurement_modes() display available modes
 *
 * This is all read from chip specific data in the driver. Not all
 * of the sca3000 series support modes other than normal.
 **/
static ssize_t
sca3000_show_available_measurement_modes(struct device *dev,
					 struct device_attribute *attr,
					 char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct sca3000_state *st = iio_priv(indio_dev);
	int len = 0;

	len += sprintf(buf + len, "0 - normal mode");
	switch (st->info->option_mode_1) {
	case SCA3000_OP_MODE_NARROW:
		len += sprintf(buf + len, ", 1 - narrow mode");
		break;
	case SCA3000_OP_MODE_BYPASS:
		len += sprintf(buf + len, ", 1 - bypass mode");
		break;
	}
	switch (st->info->option_mode_2) {
	case SCA3000_OP_MODE_WIDE:
		len += sprintf(buf + len, ", 2 - wide mode");
		break;
	}
	/* always supported */
	len += sprintf(buf + len, " 3 - motion detection\n");

	return len;
}

/**
 * sca3000_show_measurement_mode() sysfs read of current mode
 **/
static ssize_t
sca3000_show_measurement_mode(struct device *dev,
			      struct device_attribute *attr,
			      char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct sca3000_state *st = iio_priv(indio_dev);
	int len = 0, ret;

	mutex_lock(&st->lock);
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
	if (ret)
		goto error_ret;
	/* mask bottom 2 bits - only ones that are relevant */
	st->rx[0] &= 0x03;
	switch (st->rx[0]) {
	case SCA3000_MEAS_MODE_NORMAL:
		len += sprintf(buf + len, "0 - normal mode\n");
		break;
	case SCA3000_MEAS_MODE_MOT_DET:
		len += sprintf(buf + len, "3 - motion detection\n");
		break;
	case SCA3000_MEAS_MODE_OP_1:
		switch (st->info->option_mode_1) {
		case SCA3000_OP_MODE_NARROW:
			len += sprintf(buf + len, "1 - narrow mode\n");
			break;
		case SCA3000_OP_MODE_BYPASS:
			len += sprintf(buf + len, "1 - bypass mode\n");
			break;
		}
		break;
	case SCA3000_MEAS_MODE_OP_2:
		switch (st->info->option_mode_2) {
		case SCA3000_OP_MODE_WIDE:
			len += sprintf(buf + len, "2 - wide mode\n");
			break;
		}
		break;
	}

error_ret:
	mutex_unlock(&st->lock);

	return ret ? ret : len;
}

/**
 * sca3000_store_measurement_mode() set the current mode
 **/
static ssize_t
sca3000_store_measurement_mode(struct device *dev,
			       struct device_attribute *attr,
			       const char *buf,
			       size_t len)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct sca3000_state *st = iio_priv(indio_dev);
	int ret;
	u8 mask = 0x03;
	u8 val;

	mutex_lock(&st->lock);
	ret = kstrtou8(buf, 10, &val);
	if (ret)
		goto error_ret;
	if (val > 3) {
		ret = -EINVAL;
		goto error_ret;
	}
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
	if (ret)
		goto error_ret;
	st->rx[0] &= ~mask;
	st->rx[0] |= (val & mask);
	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, st->rx[0]);
	if (ret)
		goto error_ret;
	mutex_unlock(&st->lock);

	return len;

error_ret:
	mutex_unlock(&st->lock);

	return ret;
}

/*
 * Not even vaguely standard attributes so defined here rather than
 * in the relevant IIO core headers
 */
static IIO_DEVICE_ATTR(measurement_mode_available, S_IRUGO,
		       sca3000_show_available_measurement_modes,
		       NULL, 0);

static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR,
		       sca3000_show_measurement_mode,
		       sca3000_store_measurement_mode,
		       0);

/* More standard attributes */

static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);

static const struct iio_event_spec sca3000_event = {
	.type = IIO_EV_TYPE_MAG,
	.dir = IIO_EV_DIR_RISING,
	.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
};

#define SCA3000_CHAN(index, mod)				\
	{							\
		.type = IIO_ACCEL,				\
		.modified = 1,					\
		.channel2 = mod,				\
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
		.address = index,				\
		.scan_index = index,				\
		.scan_type = {					\
			.sign = 's',				\
			.realbits = 11,				\
			.storagebits = 16,			\
			.shift = 5,				\
		},						\
		.event_spec = &sca3000_event,			\
		.num_event_specs = 1,				\
	}

static const struct iio_chan_spec sca3000_channels[] = {
	SCA3000_CHAN(0, IIO_MOD_X),
	SCA3000_CHAN(1, IIO_MOD_Y),
	SCA3000_CHAN(2, IIO_MOD_Z),
};

static const struct iio_chan_spec sca3000_channels_with_temp[] = {
	SCA3000_CHAN(0, IIO_MOD_X),
	SCA3000_CHAN(1, IIO_MOD_Y),
	SCA3000_CHAN(2, IIO_MOD_Z),
	{
		.type = IIO_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
			BIT(IIO_CHAN_INFO_OFFSET),
		/* No buffer support */
		.scan_index = -1,
	},
};

static u8 sca3000_addresses[3][3] = {
	[0] = {SCA3000_REG_ADDR_X_MSB, SCA3000_REG_CTRL_SEL_MD_X_TH,
	       SCA3000_MD_CTRL_OR_X},
	[1] = {SCA3000_REG_ADDR_Y_MSB, SCA3000_REG_CTRL_SEL_MD_Y_TH,
	       SCA3000_MD_CTRL_OR_Y},
	[2] = {SCA3000_REG_ADDR_Z_MSB, SCA3000_REG_CTRL_SEL_MD_Z_TH,
	       SCA3000_MD_CTRL_OR_Z},
};

/**
 * __sca3000_get_base_freq() obtain mode specific base frequency
 *
 * lock must be held
 **/
static inline int __sca3000_get_base_freq(struct sca3000_state *st,
					  const struct sca3000_chip_info *info,
					  int *base_freq)
{
	int ret;

	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
	if (ret)
		goto error_ret;
	switch (0x03 & st->rx[0]) {
	case SCA3000_MEAS_MODE_NORMAL:
		*base_freq = info->measurement_mode_freq;
		break;
	case SCA3000_MEAS_MODE_OP_1:
		*base_freq = info->option_mode_1_freq;
		break;
	case SCA3000_MEAS_MODE_OP_2:
		*base_freq = info->option_mode_2_freq;
		break;
	default:
		ret = -EINVAL;
	}
error_ret:
	return ret;
}

/**
 * read_raw handler for IIO_CHAN_INFO_SAMP_FREQ
 *
 * lock must be held
 **/
static int read_raw_samp_freq(struct sca3000_state *st, int *val)
{
	int ret;

	ret = __sca3000_get_base_freq(st, st->info, val);
	if (ret)
		return ret;

	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
	if (ret < 0)
		return ret;

	if (*val > 0) {
		ret &= SCA3000_OUT_CTRL_BUF_DIV_MASK;
		switch (ret) {
		case SCA3000_OUT_CTRL_BUF_DIV_2:
			*val /= 2;
			break;
		case SCA3000_OUT_CTRL_BUF_DIV_4:
			*val /= 4;
			break;
		}
	}

	return 0;
}

/**
 * write_raw handler for IIO_CHAN_INFO_SAMP_FREQ
 *
 * lock must be held
 **/
static int write_raw_samp_freq(struct sca3000_state *st, int val)
{
	int ret, base_freq, ctrlval;

	ret = __sca3000_get_base_freq(st, st->info, &base_freq);
	if (ret)
		return ret;

	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
	if (ret < 0)
		return ret;

	ctrlval = ret & ~SCA3000_OUT_CTRL_BUF_DIV_MASK;

	if (val == base_freq / 2)
		ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_2;
	if (val == base_freq / 4)
		ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_4;
	else if (val != base_freq)
		return -EINVAL;

	return sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL,
				     ctrlval);
}

static int sca3000_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int *val,
			    int *val2,
			    long mask)
{
	struct sca3000_state *st = iio_priv(indio_dev);
	int ret;
	u8 address;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&st->lock);
		if (chan->type == IIO_ACCEL) {
			if (st->mo_det_use_count) {
				mutex_unlock(&st->lock);
				return -EBUSY;
			}
			address = sca3000_addresses[chan->address][0];
			ret = sca3000_read_data_short(st, address, 2);
			if (ret < 0) {
				mutex_unlock(&st->lock);
				return ret;
			}
			*val = (be16_to_cpup((__be16 *)st->rx) >> 3) & 0x1FFF;
			*val = ((*val) << (sizeof(*val) * 8 - 13)) >>
				(sizeof(*val) * 8 - 13);
		} else {
			/* get the temperature when available */
			ret = sca3000_read_data_short(st,
						      SCA3000_REG_ADDR_TEMP_MSB,
						      2);
			if (ret < 0) {
				mutex_unlock(&st->lock);
				return ret;
			}
			*val = ((st->rx[0] & 0x3F) << 3) |
			       ((st->rx[1] & 0xE0) >> 5);
		}
		mutex_unlock(&st->lock);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = 0;
		if (chan->type == IIO_ACCEL)
			*val2 = st->info->scale;
		else /* temperature */
			*val2 = 555556;
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_OFFSET:
		*val = -214;
		*val2 = 600000;
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_SAMP_FREQ:
		mutex_lock(&st->lock);
		ret = read_raw_samp_freq(st, val);
		mutex_unlock(&st->lock);
		return ret ? ret : IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int sca3000_write_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     int val, int val2, long mask)
{
	struct sca3000_state *st = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		if (val2)
			return -EINVAL;
		mutex_lock(&st->lock);
		ret = write_raw_samp_freq(st, val);
		mutex_unlock(&st->lock);
		return ret;
	default:
		return -EINVAL;
	}

	return ret;
}

/**
 * sca3000_read_av_freq() sysfs function to get available frequencies
 *
 * The later modes are only relevant to the ring buffer - and depend on current
 * mode. Note that data sheet gives rather wide tolerances for these so integer
 * division will give good enough answer and not all chips have them specified
 * at all.
 **/
static ssize_t sca3000_read_av_freq(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct sca3000_state *st = iio_priv(indio_dev);
	int len = 0, ret, val;

	mutex_lock(&st->lock);
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
	val = st->rx[0];
	mutex_unlock(&st->lock);
	if (ret)
		goto error_ret;

	switch (val & 0x03) {
	case SCA3000_MEAS_MODE_NORMAL:
		len += sprintf(buf + len, "%d %d %d\n",
			       st->info->measurement_mode_freq,
			       st->info->measurement_mode_freq / 2,
			       st->info->measurement_mode_freq / 4);
		break;
	case SCA3000_MEAS_MODE_OP_1:
		len += sprintf(buf + len, "%d %d %d\n",
			       st->info->option_mode_1_freq,
			       st->info->option_mode_1_freq / 2,
			       st->info->option_mode_1_freq / 4);
		break;
	case SCA3000_MEAS_MODE_OP_2:
		len += sprintf(buf + len, "%d %d %d\n",
			       st->info->option_mode_2_freq,
			       st->info->option_mode_2_freq / 2,
			       st->info->option_mode_2_freq / 4);
		break;
	}
	return len;
error_ret:
	return ret;
}

/*
 * Should only really be registered if ring buffer support is compiled in.
 * Does no harm however and doing it right would add a fair bit of complexity
 */
static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(sca3000_read_av_freq);

/**
 * sca3000_read_thresh() - query of a threshold
 **/
static int sca3000_read_thresh(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)
{
	int ret, i;
	struct sca3000_state *st = iio_priv(indio_dev);
	int num = chan->channel2;

	mutex_lock(&st->lock);
	ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]);
	mutex_unlock(&st->lock);
	if (ret < 0)
		return ret;
	*val = 0;
	if (num == 1)
		for_each_set_bit(i, (unsigned long *)&ret,
				 ARRAY_SIZE(st->info->mot_det_mult_y))
			*val += st->info->mot_det_mult_y[i];
	else
		for_each_set_bit(i, (unsigned long *)&ret,
				 ARRAY_SIZE(st->info->mot_det_mult_xz))
			*val += st->info->mot_det_mult_xz[i];

	return IIO_VAL_INT;
}

/**
 * sca3000_write_thresh() control of threshold
 **/
static int sca3000_write_thresh(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 sca3000_state *st = iio_priv(indio_dev);
	int num = chan->channel2;
	int ret;
	int i;
	u8 nonlinear = 0;

	if (num == 1) {
		i = ARRAY_SIZE(st->info->mot_det_mult_y);
		while (i > 0)
			if (val >= st->info->mot_det_mult_y[--i]) {
				nonlinear |= (1 << i);
				val -= st->info->mot_det_mult_y[i];
			}
	} else {
		i = ARRAY_SIZE(st->info->mot_det_mult_xz);
		while (i > 0)
			if (val >= st->info->mot_det_mult_xz[--i]) {
				nonlinear |= (1 << i);
				val -= st->info->mot_det_mult_xz[i];
			}
	}

	mutex_lock(&st->lock);
	ret = sca3000_write_ctrl_reg(st, sca3000_addresses[num][1], nonlinear);
	mutex_unlock(&st->lock);

	return ret;
}

static struct attribute *sca3000_attributes[] = {
	&iio_dev_attr_revision.dev_attr.attr,
	&iio_dev_attr_measurement_mode_available.dev_attr.attr,
	&iio_dev_attr_measurement_mode.dev_attr.attr,
	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
	NULL,
};

static const struct attribute_group sca3000_attribute_group = {
	.attrs = sca3000_attributes,
};

/**
 * sca3000_event_handler() - handling ring and non ring events
 *
 * Ring related interrupt handler. Depending on event, push to
 * the ring buffer event chrdev or the event one.
 *
 * This function is complicated by the fact that the devices can signify ring
 * and non ring events via the same interrupt line and they can only
 * be distinguished via a read of the relevant status register.
 **/
static irqreturn_t sca3000_event_handler(int irq, void *private)
{
	struct iio_dev *indio_dev = private;
	struct sca3000_state *st = iio_priv(indio_dev);
	int ret, val;
	s64 last_timestamp = iio_get_time_ns(indio_dev);

	/*
	 * Could lead if badly timed to an extra read of status reg,
	 * but ensures no interrupt is missed.
	 */
	mutex_lock(&st->lock);
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_STATUS, 1);
	val = st->rx[0];
	mutex_unlock(&st->lock);
	if (ret)
		goto done;

	sca3000_ring_int_process(val, indio_dev->buffer);

	if (val & SCA3000_INT_STATUS_FREE_FALL)
		iio_push_event(indio_dev,
			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
						  0,
						  IIO_MOD_X_AND_Y_AND_Z,
						  IIO_EV_TYPE_MAG,
						  IIO_EV_DIR_FALLING),
			       last_timestamp);

	if (val & SCA3000_INT_STATUS_Y_TRIGGER)
		iio_push_event(indio_dev,
			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
						  0,
						  IIO_MOD_Y,
						  IIO_EV_TYPE_MAG,
						  IIO_EV_DIR_RISING),
			       last_timestamp);

	if (val & SCA3000_INT_STATUS_X_TRIGGER)
		iio_push_event(indio_dev,
			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
						  0,
						  IIO_MOD_X,
						  IIO_EV_TYPE_MAG,
						  IIO_EV_DIR_RISING),
			       last_timestamp);

	if (val & SCA3000_INT_STATUS_Z_TRIGGER)
		iio_push_event(indio_dev,
			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
						  0,
						  IIO_MOD_Z,
						  IIO_EV_TYPE_MAG,
						  IIO_EV_DIR_RISING),
			       last_timestamp);

done:
	return IRQ_HANDLED;
}

/**
 * sca3000_read_event_config() what events are enabled
 **/
static int sca3000_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 sca3000_state *st = iio_priv(indio_dev);
	int ret;
	u8 protect_mask = 0x03;
	int num = chan->channel2;

	/* read current value of mode register */
	mutex_lock(&st->lock);
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
	if (ret)
		goto error_ret;

	if ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET) {
		ret = 0;
	} else {
		ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
		if (ret < 0)
			goto error_ret;
		/* only supporting logical or's for now */
		ret = !!(ret & sca3000_addresses[num][2]);
	}
error_ret:
	mutex_unlock(&st->lock);

	return ret;
}

/**
 * sca3000_query_free_fall_mode() is free fall mode enabled
 **/
static ssize_t sca3000_query_free_fall_mode(struct device *dev,
					    struct device_attribute *attr,
					    char *buf)
{
	int ret;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct sca3000_state *st = iio_priv(indio_dev);
	int val;

	mutex_lock(&st->lock);
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
	val = st->rx[0];
	mutex_unlock(&st->lock);
	if (ret < 0)
		return ret;
	return sprintf(buf, "%d\n", !!(val & SCA3000_FREE_FALL_DETECT));
}

/**
 * sca3000_set_free_fall_mode() simple on off control for free fall int
 *
 * In these chips the free fall detector should send an interrupt if
 * the device falls more than 25cm.  This has not been tested due
 * to fragile wiring.
 **/
static ssize_t sca3000_set_free_fall_mode(struct device *dev,
					  struct device_attribute *attr,
					  const char *buf,
					  size_t len)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct sca3000_state *st = iio_priv(indio_dev);
	u8 val;
	int ret;
	u8 protect_mask = SCA3000_FREE_FALL_DETECT;

	mutex_lock(&st->lock);
	ret = kstrtou8(buf, 10, &val);
	if (ret)
		goto error_ret;

	/* read current value of mode register */
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
	if (ret)
		goto error_ret;

	/* if off and should be on */
	if (val && !(st->rx[0] & protect_mask))
		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
					(st->rx[0] | SCA3000_FREE_FALL_DETECT));
	/* if on and should be off */
	else if (!val && (st->rx[0] & protect_mask))
		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
					(st->rx[0] & ~protect_mask));
error_ret:
	mutex_unlock(&st->lock);

	return ret ? ret : len;
}

/**
 * sca3000_write_event_config() simple on off control for motion detector
 *
 * This is a per axis control, but enabling any will result in the
 * motion detector unit being enabled.
 * N.B. enabling motion detector stops normal data acquisition.
 * There is a complexity in knowing which mode to return to when
 * this mode is disabled.  Currently normal mode is assumed.
 **/
static int sca3000_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 sca3000_state *st = iio_priv(indio_dev);
	int ret, ctrlval;
	u8 protect_mask = 0x03;
	int num = chan->channel2;

	mutex_lock(&st->lock);
	/*
	 * First read the motion detector config to find out if
	 * this axis is on
	 */
	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
	if (ret < 0)
		goto exit_point;
	ctrlval = ret;
	/* if off and should be on */
	if (state && !(ctrlval & sca3000_addresses[num][2])) {
		ret = sca3000_write_ctrl_reg(st,
					     SCA3000_REG_CTRL_SEL_MD_CTRL,
					     ctrlval |
					     sca3000_addresses[num][2]);
		if (ret)
			goto exit_point;
		st->mo_det_use_count++;
	} else if (!state && (ctrlval & sca3000_addresses[num][2])) {
		ret = sca3000_write_ctrl_reg(st,
					     SCA3000_REG_CTRL_SEL_MD_CTRL,
					     ctrlval &
					     ~(sca3000_addresses[num][2]));
		if (ret)
			goto exit_point;
		st->mo_det_use_count--;
	}

	/* read current value of mode register */
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
	if (ret)
		goto exit_point;
	/* if off and should be on */
	if ((st->mo_det_use_count) &&
	    ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET))
		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
					(st->rx[0] & ~protect_mask)
					| SCA3000_MEAS_MODE_MOT_DET);
	/* if on and should be off */
	else if (!(st->mo_det_use_count) &&
		 ((st->rx[0] & protect_mask) == SCA3000_MEAS_MODE_MOT_DET))
		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
					(st->rx[0] & ~protect_mask));
exit_point:
	mutex_unlock(&st->lock);

	return ret;
}

/* Free fall detector related event attribute */
static IIO_DEVICE_ATTR_NAMED(accel_xayaz_mag_falling_en,
			     in_accel_x & y & z_mag_falling_en,
			     S_IRUGO | S_IWUSR,
			     sca3000_query_free_fall_mode,
			     sca3000_set_free_fall_mode,
			     0);

static IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period,
			    in_accel_x & y & z_mag_falling_period,
			    "0.226");

static struct attribute *sca3000_event_attributes[] = {
	&iio_dev_attr_accel_xayaz_mag_falling_en.dev_attr.attr,
	&iio_const_attr_accel_xayaz_mag_falling_period.dev_attr.attr,
	NULL,
};

static struct attribute_group sca3000_event_attribute_group = {
	.attrs = sca3000_event_attributes,
	.name = "events",
};

/**
 * sca3000_clean_setup() get the device into a predictable state
 *
 * Devices use flash memory to store many of the register values
 * and hence can come up in somewhat unpredictable states.
 * Hence reset everything on driver load.
 **/
static int sca3000_clean_setup(struct sca3000_state *st)
{
	int ret;

	mutex_lock(&st->lock);
	/* Ensure all interrupts have been acknowledged */
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_STATUS, 1);
	if (ret)
		goto error_ret;

	/* Turn off all motion detection channels */
	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
	if (ret < 0)
		goto error_ret;
	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL,
				     ret & SCA3000_MD_CTRL_PROT_MASK);
	if (ret)
		goto error_ret;

	/* Disable ring buffer */
	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
	if (ret < 0)
		goto error_ret;
	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL,
				     (ret & SCA3000_OUT_CTRL_PROT_MASK)
				     | SCA3000_OUT_CTRL_BUF_X_EN
				     | SCA3000_OUT_CTRL_BUF_Y_EN
				     | SCA3000_OUT_CTRL_BUF_Z_EN
				     | SCA3000_OUT_CTRL_BUF_DIV_4);
	if (ret)
		goto error_ret;
	/* Enable interrupts, relevant to mode and set up as active low */
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
	if (ret)
		goto error_ret;
	ret = sca3000_write_reg(st,
				SCA3000_REG_ADDR_INT_MASK,
				(ret & SCA3000_INT_MASK_PROT_MASK)
				| SCA3000_INT_MASK_ACTIVE_LOW);
	if (ret)
		goto error_ret;
	/*
	 * Select normal measurement mode, free fall off, ring off
	 * Ring in 12 bit mode - it is fine to overwrite reserved bits 3,5
	 * as that occurs in one of the example on the datasheet
	 */
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
	if (ret)
		goto error_ret;
	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
				(st->rx[0] & SCA3000_MODE_PROT_MASK));
	st->bpse = 11;

error_ret:
	mutex_unlock(&st->lock);
	return ret;
}

static const struct iio_info sca3000_info = {
	.attrs = &sca3000_attribute_group,
	.read_raw = &sca3000_read_raw,
	.write_raw = &sca3000_write_raw,
	.event_attrs = &sca3000_event_attribute_group,
	.read_event_value = &sca3000_read_thresh,
	.write_event_value = &sca3000_write_thresh,
	.read_event_config = &sca3000_read_event_config,
	.write_event_config = &sca3000_write_event_config,
	.driver_module = THIS_MODULE,
};

static int sca3000_probe(struct spi_device *spi)
{
	int ret;
	struct sca3000_state *st;
	struct iio_dev *indio_dev;

	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
	if (!indio_dev)
		return -ENOMEM;

	st = iio_priv(indio_dev);
	spi_set_drvdata(spi, indio_dev);
	st->us = spi;
	mutex_init(&st->lock);
	st->info = &sca3000_spi_chip_info_tbl[spi_get_device_id(spi)
					      ->driver_data];

	indio_dev->dev.parent = &spi->dev;
	indio_dev->name = spi_get_device_id(spi)->name;
	indio_dev->info = &sca3000_info;
	if (st->info->temp_output) {
		indio_dev->channels = sca3000_channels_with_temp;
		indio_dev->num_channels =
			ARRAY_SIZE(sca3000_channels_with_temp);
	} else {
		indio_dev->channels = sca3000_channels;
		indio_dev->num_channels = ARRAY_SIZE(sca3000_channels);
	}
	indio_dev->modes = INDIO_DIRECT_MODE;

	sca3000_configure_ring(indio_dev);
	ret = iio_device_register(indio_dev);
	if (ret < 0)
		return ret;

	if (spi->irq) {
		ret = request_threaded_irq(spi->irq,
					   NULL,
					   &sca3000_event_handler,
					   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
					   "sca3000",
					   indio_dev);
		if (ret)
			goto error_unregister_dev;
	}
	sca3000_register_ring_funcs(indio_dev);
	ret = sca3000_clean_setup(st);
	if (ret)
		goto error_free_irq;
	return 0;

error_free_irq:
	if (spi->irq)
		free_irq(spi->irq, indio_dev);
error_unregister_dev:
	iio_device_unregister(indio_dev);
	return ret;
}

static int sca3000_stop_all_interrupts(struct sca3000_state *st)
{
	int ret;

	mutex_lock(&st->lock);
	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
	if (ret)
		goto error_ret;
	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_INT_MASK,
				(st->rx[0] &
				 ~(SCA3000_INT_MASK_RING_THREE_QUARTER |
				   SCA3000_INT_MASK_RING_HALF |
				   SCA3000_INT_MASK_ALL_INTS)));
error_ret:
	mutex_unlock(&st->lock);
	return ret;
}

static int sca3000_remove(struct spi_device *spi)
{
	struct iio_dev *indio_dev = spi_get_drvdata(spi);
	struct sca3000_state *st = iio_priv(indio_dev);

	/* Must ensure no interrupts can be generated after this! */
	sca3000_stop_all_interrupts(st);
	if (spi->irq)
		free_irq(spi->irq, indio_dev);
	iio_device_unregister(indio_dev);
	sca3000_unconfigure_ring(indio_dev);

	return 0;
}

static const struct spi_device_id sca3000_id[] = {
	{"sca3000_d01", d01},
	{"sca3000_e02", e02},
	{"sca3000_e04", e04},
	{"sca3000_e05", e05},
	{}
};
MODULE_DEVICE_TABLE(spi, sca3000_id);

static struct spi_driver sca3000_driver = {
	.driver = {
		.name = "sca3000",
	},
	.probe = sca3000_probe,
	.remove = sca3000_remove,
	.id_table = sca3000_id,
};
module_spi_driver(sca3000_driver);

MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("VTI SCA3000 Series Accelerometers SPI driver");
MODULE_LICENSE("GPL v2");
