// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for the Nuvoton NAU7802 ADC
 *
 * Copyright 2013 Free Electrons
 */

#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/wait.h>
#include <linux/log2.h>
#include <linux/of.h>

#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

#define NAU7802_REG_PUCTRL	0x00
#define NAU7802_PUCTRL_RR(x)		(x << 0)
#define NAU7802_PUCTRL_RR_BIT		NAU7802_PUCTRL_RR(1)
#define NAU7802_PUCTRL_PUD(x)		(x << 1)
#define NAU7802_PUCTRL_PUD_BIT		NAU7802_PUCTRL_PUD(1)
#define NAU7802_PUCTRL_PUA(x)		(x << 2)
#define NAU7802_PUCTRL_PUA_BIT		NAU7802_PUCTRL_PUA(1)
#define NAU7802_PUCTRL_PUR(x)		(x << 3)
#define NAU7802_PUCTRL_PUR_BIT		NAU7802_PUCTRL_PUR(1)
#define NAU7802_PUCTRL_CS(x)		(x << 4)
#define NAU7802_PUCTRL_CS_BIT		NAU7802_PUCTRL_CS(1)
#define NAU7802_PUCTRL_CR(x)		(x << 5)
#define NAU7802_PUCTRL_CR_BIT		NAU7802_PUCTRL_CR(1)
#define NAU7802_PUCTRL_AVDDS(x)		(x << 7)
#define NAU7802_PUCTRL_AVDDS_BIT	NAU7802_PUCTRL_AVDDS(1)
#define NAU7802_REG_CTRL1	0x01
#define NAU7802_CTRL1_VLDO(x)		(x << 3)
#define NAU7802_CTRL1_GAINS(x)		(x)
#define NAU7802_CTRL1_GAINS_BITS	0x07
#define NAU7802_REG_CTRL2	0x02
#define NAU7802_CTRL2_CHS(x)		(x << 7)
#define NAU7802_CTRL2_CRS(x)		(x << 4)
#define NAU7802_SAMP_FREQ_320	0x07
#define NAU7802_CTRL2_CHS_BIT		NAU7802_CTRL2_CHS(1)
#define NAU7802_REG_ADC_B2	0x12
#define NAU7802_REG_ADC_B1	0x13
#define NAU7802_REG_ADC_B0	0x14
#define NAU7802_REG_ADC_CTRL	0x15

#define NAU7802_MIN_CONVERSIONS 6

struct nau7802_state {
	struct i2c_client	*client;
	s32			last_value;
	struct mutex		lock;
	struct mutex		data_lock;
	u32			vref_mv;
	u32			conversion_count;
	u32			min_conversions;
	u8			sample_rate;
	u32			scale_avail[8];
	struct completion	value_ok;
};

#define NAU7802_CHANNEL(chan) {					\
	.type = IIO_VOLTAGE,					\
	.indexed = 1,						\
	.channel = (chan),					\
	.scan_index = (chan),					\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
				BIT(IIO_CHAN_INFO_SAMP_FREQ)	\
}

static const struct iio_chan_spec nau7802_chan_array[] = {
	NAU7802_CHANNEL(0),
	NAU7802_CHANNEL(1),
};

static const u16 nau7802_sample_freq_avail[] = {10, 20, 40, 80,
						10, 10, 10, 320};

static ssize_t nau7802_show_scales(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct nau7802_state *st = iio_priv(dev_to_iio_dev(dev));
	int i, len = 0;

	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09d ",
				 st->scale_avail[i]);

	buf[len-1] = '\n';

	return len;
}

static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 40 80 320");

static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO, nau7802_show_scales,
		       NULL, 0);

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

static const struct attribute_group nau7802_attribute_group = {
	.attrs = nau7802_attributes,
};

static int nau7802_set_gain(struct nau7802_state *st, int gain)
{
	int ret;

	mutex_lock(&st->lock);
	st->conversion_count = 0;

	ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL1);
	if (ret < 0)
		goto nau7802_sysfs_set_gain_out;
	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL1,
					(ret & (~NAU7802_CTRL1_GAINS_BITS)) |
					gain);

nau7802_sysfs_set_gain_out:
	mutex_unlock(&st->lock);

	return ret;
}

static int nau7802_read_conversion(struct nau7802_state *st)
{
	int data;

	mutex_lock(&st->data_lock);
	data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B2);
	if (data < 0)
		goto nau7802_read_conversion_out;
	st->last_value = data << 16;

	data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B1);
	if (data < 0)
		goto nau7802_read_conversion_out;
	st->last_value |= data << 8;

	data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B0);
	if (data < 0)
		goto nau7802_read_conversion_out;
	st->last_value |= data;

	st->last_value = sign_extend32(st->last_value, 23);

nau7802_read_conversion_out:
	mutex_unlock(&st->data_lock);

	return data;
}

/*
 * Conversions are synchronised on the rising edge of NAU7802_PUCTRL_CS_BIT
 */
static int nau7802_sync(struct nau7802_state *st)
{
	int ret;

	ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
	if (ret < 0)
		return ret;
	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
				ret | NAU7802_PUCTRL_CS_BIT);

	return ret;
}

static irqreturn_t nau7802_eoc_trigger(int irq, void *private)
{
	struct iio_dev *indio_dev = private;
	struct nau7802_state *st = iio_priv(indio_dev);
	int status;

	status = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
	if (status < 0)
		return IRQ_HANDLED;

	if (!(status & NAU7802_PUCTRL_CR_BIT))
		return IRQ_NONE;

	if (nau7802_read_conversion(st) < 0)
		return IRQ_HANDLED;

	/*
	 * Because there is actually only one ADC for both channels, we have to
	 * wait for enough conversions to happen before getting a significant
	 * value when changing channels and the values are far apart.
	 */
	if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
		st->conversion_count++;
	if (st->conversion_count >= NAU7802_MIN_CONVERSIONS)
		complete(&st->value_ok);

	return IRQ_HANDLED;
}

static int nau7802_read_irq(struct iio_dev *indio_dev,
			struct iio_chan_spec const *chan,
			int *val)
{
	struct nau7802_state *st = iio_priv(indio_dev);
	int ret;

	reinit_completion(&st->value_ok);
	enable_irq(st->client->irq);

	nau7802_sync(st);

	/* read registers to ensure we flush everything */
	ret = nau7802_read_conversion(st);
	if (ret < 0)
		goto read_chan_info_failure;

	/* Wait for a conversion to finish */
	ret = wait_for_completion_interruptible_timeout(&st->value_ok,
			msecs_to_jiffies(1000));
	if (ret == 0)
		ret = -ETIMEDOUT;

	if (ret < 0)
		goto read_chan_info_failure;

	disable_irq(st->client->irq);

	*val = st->last_value;

	return IIO_VAL_INT;

read_chan_info_failure:
	disable_irq(st->client->irq);

	return ret;
}

static int nau7802_read_poll(struct iio_dev *indio_dev,
			struct iio_chan_spec const *chan,
			int *val)
{
	struct nau7802_state *st = iio_priv(indio_dev);
	int ret;

	nau7802_sync(st);

	/* read registers to ensure we flush everything */
	ret = nau7802_read_conversion(st);
	if (ret < 0)
		return ret;

	/*
	 * Because there is actually only one ADC for both channels, we have to
	 * wait for enough conversions to happen before getting a significant
	 * value when changing channels and the values are far appart.
	 */
	do {
		ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
		if (ret < 0)
			return ret;

		while (!(ret & NAU7802_PUCTRL_CR_BIT)) {
			if (st->sample_rate != NAU7802_SAMP_FREQ_320)
				msleep(20);
			else
				mdelay(4);
			ret = i2c_smbus_read_byte_data(st->client,
							NAU7802_REG_PUCTRL);
			if (ret < 0)
				return ret;
		}

		ret = nau7802_read_conversion(st);
		if (ret < 0)
			return ret;
		if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
			st->conversion_count++;
	} while (st->conversion_count < NAU7802_MIN_CONVERSIONS);

	*val = st->last_value;

	return IIO_VAL_INT;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&st->lock);
		/*
		 * Select the channel to use
		 *   - Channel 1 is value 0 in the CHS register
		 *   - Channel 2 is value 1 in the CHS register
		 */
		ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL2);
		if (ret < 0) {
			mutex_unlock(&st->lock);
			return ret;
		}

		if (((ret & NAU7802_CTRL2_CHS_BIT) && !chan->channel) ||
				(!(ret & NAU7802_CTRL2_CHS_BIT) &&
				 chan->channel)) {
			st->conversion_count = 0;
			ret = i2c_smbus_write_byte_data(st->client,
					NAU7802_REG_CTRL2,
					NAU7802_CTRL2_CHS(chan->channel) |
					NAU7802_CTRL2_CRS(st->sample_rate));

			if (ret < 0) {
				mutex_unlock(&st->lock);
				return ret;
			}
		}

		if (st->client->irq)
			ret = nau7802_read_irq(indio_dev, chan, val);
		else
			ret = nau7802_read_poll(indio_dev, chan, val);

		mutex_unlock(&st->lock);
		return ret;

	case IIO_CHAN_INFO_SCALE:
		ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL1);
		if (ret < 0)
			return ret;

		/*
		 * We have 24 bits of signed data, that means 23 bits of data
		 * plus the sign bit
		 */
		*val = st->vref_mv;
		*val2 = 23 + (ret & NAU7802_CTRL1_GAINS_BITS);

		return IIO_VAL_FRACTIONAL_LOG2;

	case IIO_CHAN_INFO_SAMP_FREQ:
		*val =  nau7802_sample_freq_avail[st->sample_rate];
		*val2 = 0;
		return IIO_VAL_INT;

	default:
		break;
	}

	return -EINVAL;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
		for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
			if (val2 == st->scale_avail[i])
				return nau7802_set_gain(st, i);

		break;

	case IIO_CHAN_INFO_SAMP_FREQ:
		for (i = 0; i < ARRAY_SIZE(nau7802_sample_freq_avail); i++)
			if (val == nau7802_sample_freq_avail[i]) {
				mutex_lock(&st->lock);
				st->sample_rate = i;
				st->conversion_count = 0;
				ret = i2c_smbus_write_byte_data(st->client,
					NAU7802_REG_CTRL2,
					NAU7802_CTRL2_CRS(st->sample_rate));
				mutex_unlock(&st->lock);
				return ret;
			}

		break;

	default:
		break;
	}

	return -EINVAL;
}

static int nau7802_write_raw_get_fmt(struct iio_dev *indio_dev,
				     struct iio_chan_spec const *chan,
				     long mask)
{
	return IIO_VAL_INT_PLUS_NANO;
}

static const struct iio_info nau7802_info = {
	.read_raw = &nau7802_read_raw,
	.write_raw = &nau7802_write_raw,
	.write_raw_get_fmt = nau7802_write_raw_get_fmt,
	.attrs = &nau7802_attribute_group,
};

static int nau7802_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct iio_dev *indio_dev;
	struct nau7802_state *st;
	struct device_node *np = client->dev.of_node;
	int i, ret;
	u8 data;
	u32 tmp = 0;

	if (!client->dev.of_node) {
		dev_err(&client->dev, "No device tree node available.\n");
		return -EINVAL;
	}

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

	st = iio_priv(indio_dev);

	indio_dev->name = dev_name(&client->dev);
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &nau7802_info;

	st->client = client;

	/* Reset the device */
	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
				  NAU7802_PUCTRL_RR_BIT);
	if (ret < 0)
		return ret;

	/* Enter normal operation mode */
	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
				  NAU7802_PUCTRL_PUD_BIT);
	if (ret < 0)
		return ret;

	/*
	 * After about 200 usecs, the device should be ready and then
	 * the Power Up bit will be set to 1. If not, wait for it.
	 */
	udelay(210);
	ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
	if (ret < 0)
		return ret;
	if (!(ret & NAU7802_PUCTRL_PUR_BIT))
		return ret;

	of_property_read_u32(np, "nuvoton,vldo", &tmp);
	st->vref_mv = tmp;

	data = NAU7802_PUCTRL_PUD_BIT | NAU7802_PUCTRL_PUA_BIT |
		NAU7802_PUCTRL_CS_BIT;
	if (tmp >= 2400)
		data |= NAU7802_PUCTRL_AVDDS_BIT;

	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL, data);
	if (ret < 0)
		return ret;
	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_ADC_CTRL, 0x30);
	if (ret < 0)
		return ret;

	if (tmp >= 2400) {
		data = NAU7802_CTRL1_VLDO((4500 - tmp) / 300);
		ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL1,
						data);
		if (ret < 0)
			return ret;
	}

	/* Populate available ADC input ranges */
	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
		st->scale_avail[i] = (((u64)st->vref_mv) * 1000000000ULL)
					   >> (23 + i);

	init_completion(&st->value_ok);

	/*
	 * The ADC fires continuously and we can't do anything about
	 * it. So we need to have the IRQ disabled by default, and we
	 * will enable them back when we will need them..
	 */
	if (client->irq) {
		ret = devm_request_threaded_irq(&client->dev, client->irq,
						NULL,
						nau7802_eoc_trigger,
						IRQF_TRIGGER_HIGH | IRQF_ONESHOT |
						IRQF_NO_AUTOEN,
						client->dev.driver->name,
						indio_dev);
		if (ret) {
			/*
			 * What may happen here is that our IRQ controller is
			 * not able to get level interrupt but this is required
			 * by this ADC as when going over 40 sample per second,
			 * the interrupt line may stay high between conversions.
			 * So, we continue no matter what but we switch to
			 * polling mode.
			 */
			dev_info(&client->dev,
				"Failed to allocate IRQ, using polling mode\n");
			client->irq = 0;
		}
	}

	if (!client->irq) {
		/*
		 * We are polling, use the fastest sample rate by
		 * default
		 */
		st->sample_rate = NAU7802_SAMP_FREQ_320;
		ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL2,
					  NAU7802_CTRL2_CRS(st->sample_rate));
		if (ret)
			return ret;
	}

	/* Setup the ADC channels available on the board */
	indio_dev->num_channels = ARRAY_SIZE(nau7802_chan_array);
	indio_dev->channels = nau7802_chan_array;

	mutex_init(&st->lock);
	mutex_init(&st->data_lock);

	return devm_iio_device_register(&client->dev, indio_dev);
}

static const struct i2c_device_id nau7802_i2c_id[] = {
	{ "nau7802", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, nau7802_i2c_id);

static const struct of_device_id nau7802_dt_ids[] = {
	{ .compatible = "nuvoton,nau7802" },
	{},
};
MODULE_DEVICE_TABLE(of, nau7802_dt_ids);

static struct i2c_driver nau7802_driver = {
	.probe = nau7802_probe,
	.id_table = nau7802_i2c_id,
	.driver = {
		   .name = "nau7802",
		   .of_match_table = nau7802_dt_ids,
	},
};

module_i2c_driver(nau7802_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Nuvoton NAU7802 ADC Driver");
MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
