// SPDX-License-Identifier: GPL-2.0
/*
 * PNI RM3100 3-axis geomagnetic sensor driver core.
 *
 * Copyright (C) 2018 Song Qiang <songqiang1304521@gmail.com>
 *
 * User Manual available at
 * <https://www.pnicorp.com/download/rm3100-user-manual/>
 *
 * TODO: event generation, pm.
 */

#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>

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

#include <asm/unaligned.h>

#include "rm3100.h"

/* Cycle Count Registers. */
#define RM3100_REG_CC_X			0x05
#define RM3100_REG_CC_Y			0x07
#define RM3100_REG_CC_Z			0x09

/* Poll Measurement Mode register. */
#define RM3100_REG_POLL			0x00
#define		RM3100_POLL_X		BIT(4)
#define		RM3100_POLL_Y		BIT(5)
#define		RM3100_POLL_Z		BIT(6)

/* Continuous Measurement Mode register. */
#define RM3100_REG_CMM			0x01
#define		RM3100_CMM_START	BIT(0)
#define		RM3100_CMM_X		BIT(4)
#define		RM3100_CMM_Y		BIT(5)
#define		RM3100_CMM_Z		BIT(6)

/* TiMe Rate Configuration register. */
#define RM3100_REG_TMRC			0x0B
#define RM3100_TMRC_OFFSET		0x92

/* Result Status register. */
#define RM3100_REG_STATUS		0x34
#define		RM3100_STATUS_DRDY	BIT(7)

/* Measurement result registers. */
#define RM3100_REG_MX2			0x24
#define RM3100_REG_MY2			0x27
#define RM3100_REG_MZ2			0x2a

#define RM3100_W_REG_START		RM3100_REG_POLL
#define RM3100_W_REG_END		RM3100_REG_TMRC
#define RM3100_R_REG_START		RM3100_REG_POLL
#define RM3100_R_REG_END		RM3100_REG_STATUS
#define RM3100_V_REG_START		RM3100_REG_POLL
#define RM3100_V_REG_END		RM3100_REG_STATUS

/*
 * This is computed by hand, is the sum of channel storage bits and padding
 * bits, which is 4+4+4+12=24 in here.
 */
#define RM3100_SCAN_BYTES		24

#define RM3100_CMM_AXIS_SHIFT		4

struct rm3100_data {
	struct regmap *regmap;
	struct completion measuring_done;
	bool use_interrupt;
	int conversion_time;
	int scale;
	/* Ensure naturally aligned timestamp */
	u8 buffer[RM3100_SCAN_BYTES] __aligned(8);
	struct iio_trigger *drdy_trig;

	/*
	 * This lock is for protecting the consistency of series of i2c
	 * operations, that is, to make sure a measurement process will
	 * not be interrupted by a set frequency operation, which should
	 * be taken where a series of i2c operation starts, released where
	 * the operation ends.
	 */
	struct mutex lock;
};

static const struct regmap_range rm3100_readable_ranges[] = {
	regmap_reg_range(RM3100_R_REG_START, RM3100_R_REG_END),
};

const struct regmap_access_table rm3100_readable_table = {
	.yes_ranges = rm3100_readable_ranges,
	.n_yes_ranges = ARRAY_SIZE(rm3100_readable_ranges),
};
EXPORT_SYMBOL_GPL(rm3100_readable_table);

static const struct regmap_range rm3100_writable_ranges[] = {
	regmap_reg_range(RM3100_W_REG_START, RM3100_W_REG_END),
};

const struct regmap_access_table rm3100_writable_table = {
	.yes_ranges = rm3100_writable_ranges,
	.n_yes_ranges = ARRAY_SIZE(rm3100_writable_ranges),
};
EXPORT_SYMBOL_GPL(rm3100_writable_table);

static const struct regmap_range rm3100_volatile_ranges[] = {
	regmap_reg_range(RM3100_V_REG_START, RM3100_V_REG_END),
};

const struct regmap_access_table rm3100_volatile_table = {
	.yes_ranges = rm3100_volatile_ranges,
	.n_yes_ranges = ARRAY_SIZE(rm3100_volatile_ranges),
};
EXPORT_SYMBOL_GPL(rm3100_volatile_table);

static irqreturn_t rm3100_thread_fn(int irq, void *d)
{
	struct iio_dev *indio_dev = d;
	struct rm3100_data *data = iio_priv(indio_dev);

	/*
	 * Write operation to any register or read operation
	 * to first byte of results will clear the interrupt.
	 */
	regmap_write(data->regmap, RM3100_REG_POLL, 0);

	return IRQ_HANDLED;
}

static irqreturn_t rm3100_irq_handler(int irq, void *d)
{
	struct iio_dev *indio_dev = d;
	struct rm3100_data *data = iio_priv(indio_dev);

	switch (indio_dev->currentmode) {
	case INDIO_DIRECT_MODE:
		complete(&data->measuring_done);
		break;
	case INDIO_BUFFER_TRIGGERED:
		iio_trigger_poll(data->drdy_trig);
		break;
	default:
		dev_err(indio_dev->dev.parent,
			"device mode out of control, current mode: %d",
			indio_dev->currentmode);
	}

	return IRQ_WAKE_THREAD;
}

static int rm3100_wait_measurement(struct rm3100_data *data)
{
	struct regmap *regmap = data->regmap;
	unsigned int val;
	int tries = 20;
	int ret;

	/*
	 * A read cycle of 400kbits i2c bus is about 20us, plus the time
	 * used for scheduling, a read cycle of fast mode of this device
	 * can reach 1.7ms, it may be possible for data to arrive just
	 * after we check the RM3100_REG_STATUS. In this case, irq_handler is
	 * called before measuring_done is reinitialized, it will wait
	 * forever for data that has already been ready.
	 * Reinitialize measuring_done before looking up makes sure we
	 * will always capture interrupt no matter when it happens.
	 */
	if (data->use_interrupt)
		reinit_completion(&data->measuring_done);

	ret = regmap_read(regmap, RM3100_REG_STATUS, &val);
	if (ret < 0)
		return ret;

	if ((val & RM3100_STATUS_DRDY) != RM3100_STATUS_DRDY) {
		if (data->use_interrupt) {
			ret = wait_for_completion_timeout(&data->measuring_done,
				msecs_to_jiffies(data->conversion_time));
			if (!ret)
				return -ETIMEDOUT;
		} else {
			do {
				usleep_range(1000, 5000);

				ret = regmap_read(regmap, RM3100_REG_STATUS,
						  &val);
				if (ret < 0)
					return ret;

				if (val & RM3100_STATUS_DRDY)
					break;
			} while (--tries);
			if (!tries)
				return -ETIMEDOUT;
		}
	}
	return 0;
}

static int rm3100_read_mag(struct rm3100_data *data, int idx, int *val)
{
	struct regmap *regmap = data->regmap;
	u8 buffer[3];
	int ret;

	mutex_lock(&data->lock);
	ret = regmap_write(regmap, RM3100_REG_POLL, BIT(4 + idx));
	if (ret < 0)
		goto unlock_return;

	ret = rm3100_wait_measurement(data);
	if (ret < 0)
		goto unlock_return;

	ret = regmap_bulk_read(regmap, RM3100_REG_MX2 + 3 * idx, buffer, 3);
	if (ret < 0)
		goto unlock_return;
	mutex_unlock(&data->lock);

	*val = sign_extend32(get_unaligned_be24(&buffer[0]), 23);

	return IIO_VAL_INT;

unlock_return:
	mutex_unlock(&data->lock);
	return ret;
}

#define RM3100_CHANNEL(axis, idx)					\
	{								\
		.type = IIO_MAGN,					\
		.modified = 1,						\
		.channel2 = IIO_MOD_##axis,				\
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
		.scan_index = idx,					\
		.scan_type = {						\
			.sign = 's',					\
			.realbits = 24,					\
			.storagebits = 32,				\
			.shift = 8,					\
			.endianness = IIO_BE,				\
		},							\
	}

static const struct iio_chan_spec rm3100_channels[] = {
	RM3100_CHANNEL(X, 0),
	RM3100_CHANNEL(Y, 1),
	RM3100_CHANNEL(Z, 2),
	IIO_CHAN_SOFT_TIMESTAMP(3),
};

static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
	"600 300 150 75 37 18 9 4.5 2.3 1.2 0.6 0.3 0.015 0.075"
);

static struct attribute *rm3100_attributes[] = {
	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
	NULL,
};

static const struct attribute_group rm3100_attribute_group = {
	.attrs = rm3100_attributes,
};

#define RM3100_SAMP_NUM			14

/*
 * Frequency : rm3100_samp_rates[][0].rm3100_samp_rates[][1]Hz.
 * Time between reading: rm3100_sam_rates[][2]ms.
 * The first one is actually 1.7ms.
 */
static const int rm3100_samp_rates[RM3100_SAMP_NUM][3] = {
	{600, 0, 2}, {300, 0, 3}, {150, 0, 7}, {75, 0, 13}, {37, 0, 27},
	{18, 0, 55}, {9, 0, 110}, {4, 500000, 220}, {2, 300000, 440},
	{1, 200000, 800}, {0, 600000, 1600}, {0, 300000, 3300},
	{0, 15000, 6700},  {0, 75000, 13000}
};

static int rm3100_get_samp_freq(struct rm3100_data *data, int *val, int *val2)
{
	unsigned int tmp;
	int ret;

	mutex_lock(&data->lock);
	ret = regmap_read(data->regmap, RM3100_REG_TMRC, &tmp);
	mutex_unlock(&data->lock);
	if (ret < 0)
		return ret;
	*val = rm3100_samp_rates[tmp - RM3100_TMRC_OFFSET][0];
	*val2 = rm3100_samp_rates[tmp - RM3100_TMRC_OFFSET][1];

	return IIO_VAL_INT_PLUS_MICRO;
}

static int rm3100_set_cycle_count(struct rm3100_data *data, int val)
{
	int ret;
	u8 i;

	for (i = 0; i < 3; i++) {
		ret = regmap_write(data->regmap, RM3100_REG_CC_X + 2 * i, val);
		if (ret < 0)
			return ret;
	}

	/*
	 * The scale of this sensor depends on the cycle count value, these
	 * three values are corresponding to the cycle count value 50, 100,
	 * 200. scale = output / gain * 10^4.
	 */
	switch (val) {
	case 50:
		data->scale = 500;
		break;
	case 100:
		data->scale = 263;
		break;
	/*
	 * case 200:
	 * This function will never be called by users' code, so here we
	 * assume that it will never get a wrong parameter.
	 */
	default:
		data->scale = 133;
	}

	return 0;
}

static int rm3100_set_samp_freq(struct iio_dev *indio_dev, int val, int val2)
{
	struct rm3100_data *data = iio_priv(indio_dev);
	struct regmap *regmap = data->regmap;
	unsigned int cycle_count;
	int ret;
	int i;

	mutex_lock(&data->lock);
	/* All cycle count registers use the same value. */
	ret = regmap_read(regmap, RM3100_REG_CC_X, &cycle_count);
	if (ret < 0)
		goto unlock_return;

	for (i = 0; i < RM3100_SAMP_NUM; i++) {
		if (val == rm3100_samp_rates[i][0] &&
		    val2 == rm3100_samp_rates[i][1])
			break;
	}
	if (i == RM3100_SAMP_NUM) {
		ret = -EINVAL;
		goto unlock_return;
	}

	ret = regmap_write(regmap, RM3100_REG_TMRC, i + RM3100_TMRC_OFFSET);
	if (ret < 0)
		goto unlock_return;

	/* Checking if cycle count registers need changing. */
	if (val == 600 && cycle_count == 200) {
		ret = rm3100_set_cycle_count(data, 100);
		if (ret < 0)
			goto unlock_return;
	} else if (val != 600 && cycle_count == 100) {
		ret = rm3100_set_cycle_count(data, 200);
		if (ret < 0)
			goto unlock_return;
	}

	if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
		/* Writing TMRC registers requires CMM reset. */
		ret = regmap_write(regmap, RM3100_REG_CMM, 0);
		if (ret < 0)
			goto unlock_return;
		ret = regmap_write(data->regmap, RM3100_REG_CMM,
			(*indio_dev->active_scan_mask & 0x7) <<
			RM3100_CMM_AXIS_SHIFT | RM3100_CMM_START);
		if (ret < 0)
			goto unlock_return;
	}
	mutex_unlock(&data->lock);

	data->conversion_time = rm3100_samp_rates[i][2] * 2;
	return 0;

unlock_return:
	mutex_unlock(&data->lock);
	return ret;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		ret = iio_device_claim_direct_mode(indio_dev);
		if (ret < 0)
			return ret;

		ret = rm3100_read_mag(data, chan->scan_index, val);
		iio_device_release_direct_mode(indio_dev);

		return ret;
	case IIO_CHAN_INFO_SCALE:
		*val = 0;
		*val2 = data->scale;

		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_SAMP_FREQ:
		return rm3100_get_samp_freq(data, val, val2);
	default:
		return -EINVAL;
	}
}

static int rm3100_write_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int val, int val2, long mask)
{
	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		return rm3100_set_samp_freq(indio_dev, val, val2);
	default:
		return -EINVAL;
	}
}

static const struct iio_info rm3100_info = {
	.attrs = &rm3100_attribute_group,
	.read_raw = rm3100_read_raw,
	.write_raw = rm3100_write_raw,
};

static int rm3100_buffer_preenable(struct iio_dev *indio_dev)
{
	struct rm3100_data *data = iio_priv(indio_dev);

	/* Starting channels enabled. */
	return regmap_write(data->regmap, RM3100_REG_CMM,
		(*indio_dev->active_scan_mask & 0x7) << RM3100_CMM_AXIS_SHIFT |
		RM3100_CMM_START);
}

static int rm3100_buffer_postdisable(struct iio_dev *indio_dev)
{
	struct rm3100_data *data = iio_priv(indio_dev);

	return regmap_write(data->regmap, RM3100_REG_CMM, 0);
}

static const struct iio_buffer_setup_ops rm3100_buffer_ops = {
	.preenable = rm3100_buffer_preenable,
	.postdisable = rm3100_buffer_postdisable,
};

static irqreturn_t rm3100_trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	unsigned long scan_mask = *indio_dev->active_scan_mask;
	unsigned int mask_len = indio_dev->masklength;
	struct rm3100_data *data = iio_priv(indio_dev);
	struct regmap *regmap = data->regmap;
	int ret, i, bit;

	mutex_lock(&data->lock);
	switch (scan_mask) {
	case BIT(0) | BIT(1) | BIT(2):
		ret = regmap_bulk_read(regmap, RM3100_REG_MX2, data->buffer, 9);
		mutex_unlock(&data->lock);
		if (ret < 0)
			goto done;
		/* Convert XXXYYYZZZxxx to XXXxYYYxZZZx. x for paddings. */
		for (i = 2; i > 0; i--)
			memmove(data->buffer + i * 4, data->buffer + i * 3, 3);
		break;
	case BIT(0) | BIT(1):
		ret = regmap_bulk_read(regmap, RM3100_REG_MX2, data->buffer, 6);
		mutex_unlock(&data->lock);
		if (ret < 0)
			goto done;
		memmove(data->buffer + 4, data->buffer + 3, 3);
		break;
	case BIT(1) | BIT(2):
		ret = regmap_bulk_read(regmap, RM3100_REG_MY2, data->buffer, 6);
		mutex_unlock(&data->lock);
		if (ret < 0)
			goto done;
		memmove(data->buffer + 4, data->buffer + 3, 3);
		break;
	case BIT(0) | BIT(2):
		ret = regmap_bulk_read(regmap, RM3100_REG_MX2, data->buffer, 9);
		mutex_unlock(&data->lock);
		if (ret < 0)
			goto done;
		memmove(data->buffer + 4, data->buffer + 6, 3);
		break;
	default:
		for_each_set_bit(bit, &scan_mask, mask_len) {
			ret = regmap_bulk_read(regmap, RM3100_REG_MX2 + 3 * bit,
					       data->buffer, 3);
			if (ret < 0) {
				mutex_unlock(&data->lock);
				goto done;
			}
		}
		mutex_unlock(&data->lock);
	}
	/*
	 * Always using the same buffer so that we wouldn't need to set the
	 * paddings to 0 in case of leaking any data.
	 */
	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
					   pf->timestamp);
done:
	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

int rm3100_common_probe(struct device *dev, struct regmap *regmap, int irq)
{
	struct iio_dev *indio_dev;
	struct rm3100_data *data;
	unsigned int tmp;
	int ret;

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

	data = iio_priv(indio_dev);
	data->regmap = regmap;

	mutex_init(&data->lock);

	indio_dev->name = "rm3100";
	indio_dev->info = &rm3100_info;
	indio_dev->channels = rm3100_channels;
	indio_dev->num_channels = ARRAY_SIZE(rm3100_channels);
	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED;
	indio_dev->currentmode = INDIO_DIRECT_MODE;

	if (!irq)
		data->use_interrupt = false;
	else {
		data->use_interrupt = true;

		init_completion(&data->measuring_done);
		ret = devm_request_threaded_irq(dev,
						irq,
						rm3100_irq_handler,
						rm3100_thread_fn,
						IRQF_TRIGGER_HIGH |
						IRQF_ONESHOT,
						indio_dev->name,
						indio_dev);
		if (ret < 0) {
			dev_err(dev, "request irq line failed.\n");
			return ret;
		}

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

		ret = devm_iio_trigger_register(dev, data->drdy_trig);
		if (ret < 0)
			return ret;
	}

	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
					      &iio_pollfunc_store_time,
					      rm3100_trigger_handler,
					      &rm3100_buffer_ops);
	if (ret < 0)
		return ret;

	ret = regmap_read(regmap, RM3100_REG_TMRC, &tmp);
	if (ret < 0)
		return ret;
	/* Initializing max wait time, which is double conversion time. */
	data->conversion_time = rm3100_samp_rates[tmp - RM3100_TMRC_OFFSET][2]
				* 2;

	/* Cycle count values may not be what we want. */
	if ((tmp - RM3100_TMRC_OFFSET) == 0)
		rm3100_set_cycle_count(data, 100);
	else
		rm3100_set_cycle_count(data, 200);

	return devm_iio_device_register(dev, indio_dev);
}
EXPORT_SYMBOL_GPL(rm3100_common_probe);

MODULE_AUTHOR("Song Qiang <songqiang1304521@gmail.com>");
MODULE_DESCRIPTION("PNI RM3100 3-axis magnetometer i2c driver");
MODULE_LICENSE("GPL v2");
