// SPDX-License-Identifier: GPL-2.0-only
/*
 * Driver for Linear Technology LTC2471 and LTC2473 voltage monitors
 * The LTC2473 is identical to the 2471, but reports a differential signal.
 *
 * Copyright (C) 2017 Topic Embedded Products
 * Author: Mike Looijmans <mike.looijmans@topic.nl>
 */

#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

enum ltc2471_chips {
	ltc2471,
	ltc2473,
};

struct ltc2471_data {
	struct i2c_client *client;
};

/* Reference voltage is 1.25V */
#define LTC2471_VREF 1250

/* Read two bytes from the I2C bus to obtain the ADC result */
static int ltc2471_get_value(struct i2c_client *client)
{
	int ret;
	__be16 buf;

	ret = i2c_master_recv(client, (char *)&buf, sizeof(buf));
	if (ret < 0)
		return ret;
	if (ret != sizeof(buf))
		return -EIO;

	/* MSB first */
	return be16_to_cpu(buf);
}

static int ltc2471_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int *val, int *val2, long info)
{
	struct ltc2471_data *data = iio_priv(indio_dev);
	int ret;

	switch (info) {
	case IIO_CHAN_INFO_RAW:
		ret = ltc2471_get_value(data->client);
		if (ret < 0)
			return ret;
		*val = ret;
		return IIO_VAL_INT;

	case IIO_CHAN_INFO_SCALE:
		if (chan->differential)
			/* Output ranges from -VREF to +VREF */
			*val = 2 * LTC2471_VREF;
		else
			/* Output ranges from 0 to VREF */
			*val = LTC2471_VREF;
		*val2 = 16;	/* 16 data bits */
		return IIO_VAL_FRACTIONAL_LOG2;

	case IIO_CHAN_INFO_OFFSET:
		/* Only differential chip has this property */
		*val = -LTC2471_VREF;
		return IIO_VAL_INT;

	default:
		return -EINVAL;
	}
}

static const struct iio_chan_spec ltc2471_channel[] = {
	{
		.type = IIO_VOLTAGE,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
	},
};

static const struct iio_chan_spec ltc2473_channel[] = {
	{
		.type = IIO_VOLTAGE,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
					    BIT(IIO_CHAN_INFO_OFFSET),
		.differential = 1,
	},
};

static const struct iio_info ltc2471_info = {
	.read_raw = ltc2471_read_raw,
};

static int ltc2471_i2c_probe(struct i2c_client *client)
{
	const struct i2c_device_id *id = i2c_client_get_device_id(client);
	struct iio_dev *indio_dev;
	struct ltc2471_data *data;
	int ret;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
		return -EOPNOTSUPP;

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

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

	indio_dev->name = id->name;
	indio_dev->info = &ltc2471_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	if (id->driver_data == ltc2473)
		indio_dev->channels = ltc2473_channel;
	else
		indio_dev->channels = ltc2471_channel;
	indio_dev->num_channels = 1;

	/* Trigger once to start conversion and check if chip is there */
	ret = ltc2471_get_value(client);
	if (ret < 0) {
		dev_err(&client->dev, "Cannot read from device.\n");
		return ret;
	}

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

static const struct i2c_device_id ltc2471_i2c_id[] = {
	{ "ltc2471", ltc2471 },
	{ "ltc2473", ltc2473 },
	{}
};
MODULE_DEVICE_TABLE(i2c, ltc2471_i2c_id);

static struct i2c_driver ltc2471_i2c_driver = {
	.driver = {
		.name = "ltc2471",
	},
	.probe = ltc2471_i2c_probe,
	.id_table = ltc2471_i2c_id,
};

module_i2c_driver(ltc2471_i2c_driver);

MODULE_DESCRIPTION("LTC2471/LTC2473 ADC driver");
MODULE_AUTHOR("Topic Embedded Products");
MODULE_LICENSE("GPL v2");
