// 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);

	spi_set_drvdata(spi, indio_dev);

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

	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)) {
		dev_err(dev, "failed to get vref regulator\n");
		return PTR_ERR(adc->vref);
	}

	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 PTR_ERR(adc->shutdown);

	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");
