// SPDX-License-Identifier: GPL-2.0-only
/*
 * MAX1241 low-power, 12-bit serial ADC
 *
 * Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX1240-MAX1241.pdf
 */

#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/iio/iio.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>

#define MAX1241_VAL_MASK GENMASK(11, 0)
#define MAX1241_SHUTDOWN_DELAY_USEC 4

enum max1241_id {
	max1241,
};

struct max1241 {
	struct spi_device *spi;
	struct mutex lock;
	struct regulator *vdd;
	struct regulator *vref;
	struct gpio_desc *shutdown;

	__be16 data ____cacheline_aligned;
};

static const struct iio_chan_spec max1241_channels[] = {
	{
		.type = IIO_VOLTAGE,
		.indexed = 1,
		.channel = 0,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				BIT(IIO_CHAN_INFO_SCALE),
	},
};

static int max1241_read(struct max1241 *adc)
{
	struct spi_transfer xfers[] = {
		/*
		 * Begin conversion by bringing /CS low for at least
		 * tconv us.
		 */
		{
			.len = 0,
			.delay.value = 8,
			.delay.unit = SPI_DELAY_UNIT_USECS,
		},
		/*
		 * Then read two bytes of data in our RX buffer.
		 */
		{
			.rx_buf = &adc->data,
			.len = 2,
		},
	};

	return spi_sync_transfer(adc->spi, xfers, ARRAY_SIZE(xfers));
}

static int max1241_read_raw(struct iio_dev *indio_dev,
			struct iio_chan_spec const *chan,
			int *val, int *val2, long mask)
{
	int ret, vref_uV;
	struct max1241 *adc = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&adc->lock);

		if (adc->shutdown) {
			gpiod_set_value(adc->shutdown, 0);
			udelay(MAX1241_SHUTDOWN_DELAY_USEC);
			ret = max1241_read(adc);
			gpiod_set_value(adc->shutdown, 1);
		} else
			ret = max1241_read(adc);

		if (ret) {
			mutex_unlock(&adc->lock);
			return ret;
		}

		*val = (be16_to_cpu(adc->data) >> 3) & MAX1241_VAL_MASK;

		mutex_unlock(&adc->lock);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		vref_uV = regulator_get_voltage(adc->vref);

		if (vref_uV < 0)
			return vref_uV;

		*val = vref_uV / 1000;
		*val2 = 12;

		return IIO_VAL_FRACTIONAL_LOG2;
	default:
		return -EINVAL;
	}
}

static const struct iio_info max1241_info = {
	.read_raw = max1241_read_raw,
};

static void max1241_disable_vdd_action(void *data)
{
	struct max1241 *adc = data;
	struct device *dev = &adc->spi->dev;
	int err;

	err = regulator_disable(adc->vdd);
	if (err)
		dev_err(dev, "could not disable vdd regulator.\n");
}

static void max1241_disable_vref_action(void *data)
{
	struct max1241 *adc = data;
	struct device *dev = &adc->spi->dev;
	int err;

	err = regulator_disable(adc->vref);
	if (err)
		dev_err(dev, "could not disable vref regulator.\n");
}

static int max1241_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	struct iio_dev *indio_dev;
	struct max1241 *adc;
	int ret;

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

	adc = iio_priv(indio_dev);
	adc->spi = spi;
	mutex_init(&adc->lock);

	adc->vdd = devm_regulator_get(dev, "vdd");
	if (IS_ERR(adc->vdd))
		return dev_err_probe(dev, PTR_ERR(adc->vdd),
				     "failed to get vdd regulator\n");

	ret = regulator_enable(adc->vdd);
	if (ret)
		return ret;

	ret = devm_add_action_or_reset(dev, max1241_disable_vdd_action, adc);
	if (ret) {
		dev_err(dev, "could not set up vdd regulator cleanup action\n");
		return ret;
	}

	adc->vref = devm_regulator_get(dev, "vref");
	if (IS_ERR(adc->vref))
		return dev_err_probe(dev, PTR_ERR(adc->vref),
				     "failed to get vref regulator\n");

	ret = regulator_enable(adc->vref);
	if (ret)
		return ret;

	ret = devm_add_action_or_reset(dev, max1241_disable_vref_action, adc);
	if (ret) {
		dev_err(dev, "could not set up vref regulator cleanup action\n");
		return ret;
	}

	adc->shutdown = devm_gpiod_get_optional(dev, "shutdown",
						GPIOD_OUT_HIGH);
	if (IS_ERR(adc->shutdown))
		return dev_err_probe(dev, PTR_ERR(adc->shutdown),
				     "cannot get shutdown gpio\n");

	if (adc->shutdown)
		dev_dbg(dev, "shutdown pin passed, low-power mode enabled");
	else
		dev_dbg(dev, "no shutdown pin passed, low-power mode disabled");

	indio_dev->name = spi_get_device_id(spi)->name;
	indio_dev->info = &max1241_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = max1241_channels;
	indio_dev->num_channels = ARRAY_SIZE(max1241_channels);

	return devm_iio_device_register(dev, indio_dev);
}

static const struct spi_device_id max1241_id[] = {
	{ "max1241", max1241 },
	{}
};

static const struct of_device_id max1241_dt_ids[] = {
	{ .compatible = "maxim,max1241" },
	{}
};
MODULE_DEVICE_TABLE(of, max1241_dt_ids);

static struct spi_driver max1241_spi_driver = {
	.driver = {
		.name = "max1241",
		.of_match_table = max1241_dt_ids,
	},
	.probe = max1241_probe,
	.id_table = max1241_id,
};
module_spi_driver(max1241_spi_driver);

MODULE_AUTHOR("Alexandru Lazar <alazar@startmail.com>");
MODULE_DESCRIPTION("MAX1241 ADC driver");
MODULE_LICENSE("GPL v2");
