/*
 * lmp91000.c - Support for Texas Instruments digital potentiostats
 *
 * Copyright (C) 2016 Matt Ranostay <mranostay@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * TODO: bias voltage + polarity control, and multiple chip support
 */

#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/consumer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>

#define LMP91000_REG_LOCK		0x01
#define LMP91000_REG_TIACN		0x10
#define LMP91000_REG_TIACN_GAIN_SHIFT	2

#define LMP91000_REG_REFCN		0x11
#define LMP91000_REG_REFCN_EXT_REF	0x20
#define LMP91000_REG_REFCN_50_ZERO	0x80

#define LMP91000_REG_MODECN		0x12
#define LMP91000_REG_MODECN_3LEAD	0x03
#define LMP91000_REG_MODECN_TEMP	0x07

#define LMP91000_DRV_NAME	"lmp91000"

static const int lmp91000_tia_gain[] = { 0, 2750, 3500, 7000, 14000, 35000,
					 120000, 350000 };

static const int lmp91000_rload[] = { 10, 33, 50, 100 };

#define LMP91000_TEMP_BASE	-40

static const u16 lmp91000_temp_lut[] = {
	1875, 1867, 1860, 1852, 1844, 1836, 1828, 1821, 1813, 1805,
	1797, 1789, 1782, 1774, 1766, 1758, 1750, 1742, 1734, 1727,
	1719, 1711, 1703, 1695, 1687, 1679, 1671, 1663, 1656, 1648,
	1640, 1632, 1624, 1616, 1608, 1600, 1592, 1584, 1576, 1568,
	1560, 1552, 1544, 1536, 1528, 1520, 1512, 1504, 1496, 1488,
	1480, 1472, 1464, 1456, 1448, 1440, 1432, 1424, 1415, 1407,
	1399, 1391, 1383, 1375, 1367, 1359, 1351, 1342, 1334, 1326,
	1318, 1310, 1302, 1293, 1285, 1277, 1269, 1261, 1253, 1244,
	1236, 1228, 1220, 1212, 1203, 1195, 1187, 1179, 1170, 1162,
	1154, 1146, 1137, 1129, 1121, 1112, 1104, 1096, 1087, 1079,
	1071, 1063, 1054, 1046, 1038, 1029, 1021, 1012, 1004,  996,
	 987,  979,  971,  962,  954,  945,  937,  929,  920,  912,
	 903,  895,  886,  878,  870,  861 };

static const struct regmap_config lmp91000_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
};

struct lmp91000_data {
	struct regmap *regmap;
	struct device *dev;

	struct iio_trigger *trig;
	struct iio_cb_buffer *cb_buffer;
	struct iio_channel *adc_chan;

	struct completion completion;
	u8 chan_select;
	/* 64-bit data + 64-bit naturally aligned timestamp */
	u32 buffer[4] __aligned(8);
};

static const struct iio_chan_spec lmp91000_channels[] = {
	{ /* chemical channel mV */
		.type = IIO_VOLTAGE,
		.channel = 0,
		.address = LMP91000_REG_MODECN_3LEAD,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_OFFSET) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.scan_index = 0,
		.scan_type = {
			.sign = 's',
			.realbits = 32,
			.storagebits = 32,
		},
	},
	IIO_CHAN_SOFT_TIMESTAMP(1),
	{ /* temperature channel mV */
		.type = IIO_TEMP,
		.channel = 1,
		.address = LMP91000_REG_MODECN_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
		.scan_index = -1,
	},
};

static int lmp91000_read(struct lmp91000_data *data, int channel, int *val)
{
	int state, ret;

	ret = regmap_read(data->regmap, LMP91000_REG_MODECN, &state);
	if (ret)
		return -EINVAL;

	ret = regmap_write(data->regmap, LMP91000_REG_MODECN, channel);
	if (ret)
		return -EINVAL;

	/* delay till first temperature reading is complete */
	if ((state != channel) && (channel == LMP91000_REG_MODECN_TEMP))
		usleep_range(3000, 4000);

	data->chan_select = channel != LMP91000_REG_MODECN_3LEAD;

	iio_trigger_poll_chained(data->trig);

	ret = wait_for_completion_timeout(&data->completion, HZ);
	reinit_completion(&data->completion);

	if (!ret)
		return -ETIMEDOUT;

	*val = data->buffer[data->chan_select];

	return 0;
}

static irqreturn_t lmp91000_buffer_handler(int irq, void *private)
{
	struct iio_poll_func *pf = private;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct lmp91000_data *data = iio_priv(indio_dev);
	int ret, val;

	memset(data->buffer, 0, sizeof(data->buffer));

	ret = lmp91000_read(data, LMP91000_REG_MODECN_3LEAD, &val);
	if (!ret) {
		data->buffer[0] = val;
		iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
						   iio_get_time_ns(indio_dev));
	}

	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
	case IIO_CHAN_INFO_PROCESSED: {
		int ret = iio_channel_start_all_cb(data->cb_buffer);

		if (ret)
			return ret;

		ret = lmp91000_read(data, chan->address, val);

		iio_channel_stop_all_cb(data->cb_buffer);

		if (ret)
			return ret;

		if (mask == IIO_CHAN_INFO_PROCESSED) {
			int tmp, i;

			ret = iio_convert_raw_to_processed(data->adc_chan,
							   *val, &tmp, 1);
			if (ret)
				return ret;

			for (i = 0; i < ARRAY_SIZE(lmp91000_temp_lut); i++)
				if (lmp91000_temp_lut[i] < tmp)
					break;

			*val = (LMP91000_TEMP_BASE + i) * 1000;
		}
		return IIO_VAL_INT;
	}
	case IIO_CHAN_INFO_OFFSET:
		return iio_read_channel_offset(data->adc_chan, val, val2);
	case IIO_CHAN_INFO_SCALE:
		return iio_read_channel_scale(data->adc_chan, val, val2);
	}

	return -EINVAL;
}

static const struct iio_info lmp91000_info = {
	.driver_module = THIS_MODULE,
	.read_raw = lmp91000_read_raw,
};

static int lmp91000_read_config(struct lmp91000_data *data)
{
	struct device *dev = data->dev;
	struct device_node *np = dev->of_node;
	unsigned int reg, val;
	int i, ret;

	ret = of_property_read_u32(np, "ti,tia-gain-ohm", &val);
	if (ret) {
		if (of_property_read_bool(np, "ti,external-tia-resistor"))
			val = 0;
		else {
			dev_err(dev, "no ti,tia-gain-ohm defined");
			return ret;
		}
	}

	ret = -EINVAL;
	for (i = 0; i < ARRAY_SIZE(lmp91000_tia_gain); i++) {
		if (lmp91000_tia_gain[i] == val) {
			reg = i << LMP91000_REG_TIACN_GAIN_SHIFT;
			ret = 0;
			break;
		}
	}

	if (ret) {
		dev_err(dev, "invalid ti,tia-gain-ohm %d\n", val);
		return ret;
	}

	ret = of_property_read_u32(np, "ti,rload-ohm", &val);
	if (ret) {
		val = 100;
		dev_info(dev, "no ti,rload-ohm defined, default to %d\n", val);
	}

	ret = -EINVAL;
	for (i = 0; i < ARRAY_SIZE(lmp91000_rload); i++) {
		if (lmp91000_rload[i] == val) {
			reg |= i;
			ret = 0;
			break;
		}
	}

	if (ret) {
		dev_err(dev, "invalid ti,rload-ohm %d\n", val);
		return ret;
	}

	regmap_write(data->regmap, LMP91000_REG_LOCK, 0);
	regmap_write(data->regmap, LMP91000_REG_TIACN, reg);
	regmap_write(data->regmap, LMP91000_REG_REFCN, LMP91000_REG_REFCN_EXT_REF
					| LMP91000_REG_REFCN_50_ZERO);
	regmap_write(data->regmap, LMP91000_REG_LOCK, 1);

	return 0;
}

static int lmp91000_buffer_cb(const void *val, void *private)
{
	struct iio_dev *indio_dev = private;
	struct lmp91000_data *data = iio_priv(indio_dev);

	data->buffer[data->chan_select] = *((int *)val);
	complete_all(&data->completion);

	return 0;
}

static const struct iio_trigger_ops lmp91000_trigger_ops = {
	.owner = THIS_MODULE,
};


static int lmp91000_buffer_preenable(struct iio_dev *indio_dev)
{
	struct lmp91000_data *data = iio_priv(indio_dev);

	return iio_channel_start_all_cb(data->cb_buffer);
}

static int lmp91000_buffer_predisable(struct iio_dev *indio_dev)
{
	struct lmp91000_data *data = iio_priv(indio_dev);

	iio_channel_stop_all_cb(data->cb_buffer);

	return 0;
}

static const struct iio_buffer_setup_ops lmp91000_buffer_setup_ops = {
	.preenable = lmp91000_buffer_preenable,
	.postenable = iio_triggered_buffer_postenable,
	.predisable = lmp91000_buffer_predisable,
};

static int lmp91000_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct lmp91000_data *data;
	struct iio_dev *indio_dev;
	int ret;

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

	indio_dev->info = &lmp91000_info;
	indio_dev->channels = lmp91000_channels;
	indio_dev->num_channels = ARRAY_SIZE(lmp91000_channels);
	indio_dev->name = LMP91000_DRV_NAME;
	indio_dev->dev.parent = &client->dev;
	indio_dev->modes = INDIO_DIRECT_MODE;
	i2c_set_clientdata(client, indio_dev);

	data = iio_priv(indio_dev);
	data->dev = dev;
	data->regmap = devm_regmap_init_i2c(client, &lmp91000_regmap_config);
	if (IS_ERR(data->regmap)) {
		dev_err(dev, "regmap initialization failed.\n");
		return PTR_ERR(data->regmap);
	}

	data->trig = devm_iio_trigger_alloc(data->dev, "%s-mux%d",
					    indio_dev->name, indio_dev->id);
	if (!data->trig) {
		dev_err(dev, "cannot allocate iio trigger.\n");
		return -ENOMEM;
	}

	data->trig->ops = &lmp91000_trigger_ops;
	data->trig->dev.parent = dev;
	init_completion(&data->completion);

	ret = lmp91000_read_config(data);
	if (ret)
		return ret;

	ret = iio_trigger_set_immutable(iio_channel_cb_get_iio_dev(data->cb_buffer),
					data->trig);
	if (ret) {
		dev_err(dev, "cannot set immutable trigger.\n");
		return ret;
	}

	ret = iio_trigger_register(data->trig);
	if (ret) {
		dev_err(dev, "cannot register iio trigger.\n");
		return ret;
	}

	ret = iio_triggered_buffer_setup(indio_dev, NULL,
					 &lmp91000_buffer_handler,
					 &lmp91000_buffer_setup_ops);
	if (ret)
		goto error_unreg_trigger;

	data->cb_buffer = iio_channel_get_all_cb(dev, &lmp91000_buffer_cb,
						 indio_dev);

	if (IS_ERR(data->cb_buffer)) {
		if (PTR_ERR(data->cb_buffer) == -ENODEV)
			ret = -EPROBE_DEFER;
		else
			ret = PTR_ERR(data->cb_buffer);

		goto error_unreg_buffer;
	}

	data->adc_chan = iio_channel_cb_get_channels(data->cb_buffer);

	ret = iio_device_register(indio_dev);
	if (ret)
		goto error_unreg_cb_buffer;

	return 0;

error_unreg_cb_buffer:
	iio_channel_release_all_cb(data->cb_buffer);

error_unreg_buffer:
	iio_triggered_buffer_cleanup(indio_dev);

error_unreg_trigger:
	iio_trigger_unregister(data->trig);

	return ret;
}

static int lmp91000_remove(struct i2c_client *client)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(client);
	struct lmp91000_data *data = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);

	iio_channel_stop_all_cb(data->cb_buffer);
	iio_channel_release_all_cb(data->cb_buffer);

	iio_triggered_buffer_cleanup(indio_dev);
	iio_trigger_unregister(data->trig);

	return 0;
}

static const struct of_device_id lmp91000_of_match[] = {
	{ .compatible = "ti,lmp91000", },
	{ },
};
MODULE_DEVICE_TABLE(of, lmp91000_of_match);

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

static struct i2c_driver lmp91000_driver = {
	.driver = {
		.name = LMP91000_DRV_NAME,
		.of_match_table = of_match_ptr(lmp91000_of_match),
	},
	.probe = lmp91000_probe,
	.remove = lmp91000_remove,
	.id_table = lmp91000_id,
};
module_i2c_driver(lmp91000_driver);

MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>");
MODULE_DESCRIPTION("LMP91000 digital potentiostat");
MODULE_LICENSE("GPL");
