// SPDX-License-Identifier: GPL-2.0
/*
 * Maxim MAX11205 16-Bit Delta-Sigma ADC
 *
 * Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX1240-max11205.pdf
 * Copyright (C) 2022 Analog Devices, Inc.
 * Author: Ramona Bolboaca <ramona.bolboaca@analog.com>
 */

#include <linux/device.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>

#include <linux/iio/iio.h>
#include <linux/iio/adc/ad_sigma_delta.h>

#define MAX11205_BIT_SCALE	15
#define MAX11205A_OUT_DATA_RATE	116
#define MAX11205B_OUT_DATA_RATE	13

enum max11205_chip_type {
	TYPE_MAX11205A,
	TYPE_MAX11205B,
};

struct max11205_chip_info {
	unsigned int	out_data_rate;
	const char	*name;
};

struct max11205_state {
	const struct max11205_chip_info	*chip_info;
	struct regulator		*vref;
	struct ad_sigma_delta		sd;
};

static const struct ad_sigma_delta_info max11205_sigma_delta_info = {
	.has_registers = false,
};

static int max11205_read_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     int *val, int *val2, long mask)
{
	struct max11205_state *st = iio_priv(indio_dev);
	int reg_mv;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		return ad_sigma_delta_single_conversion(indio_dev, chan, val);
	case IIO_CHAN_INFO_SCALE:
		reg_mv = regulator_get_voltage(st->vref);
		if (reg_mv < 0)
			return reg_mv;
		reg_mv /= 1000;
		*val = reg_mv;
		*val2 = MAX11205_BIT_SCALE;
		return IIO_VAL_FRACTIONAL_LOG2;
	case IIO_CHAN_INFO_SAMP_FREQ:
		*val = st->chip_info->out_data_rate;
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static const struct iio_info max11205_iio_info = {
	.read_raw = max11205_read_raw,
	.validate_trigger = ad_sd_validate_trigger,
};

static const struct iio_chan_spec max11205_channels[] = {
	{
		.type = IIO_VOLTAGE,
		.indexed = 1,
		.scan_type = {
			.sign = 's',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_BE,
		},
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SAMP_FREQ) |
				      BIT(IIO_CHAN_INFO_SCALE),
	},
};

static const struct max11205_chip_info max11205_chip_info[] = {
	[TYPE_MAX11205A] = {
		.out_data_rate = MAX11205A_OUT_DATA_RATE,
		.name = "max11205a",
	},
	[TYPE_MAX11205B] = {
		.out_data_rate = MAX11205B_OUT_DATA_RATE,
		.name = "max11205b",
	},
};

static void max11205_reg_disable(void *reg)
{
	regulator_disable(reg);
}

static int max11205_probe(struct spi_device *spi)
{
	struct max11205_state *st;
	struct iio_dev *indio_dev;
	int ret;

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

	st = iio_priv(indio_dev);

	ad_sd_init(&st->sd, indio_dev, spi, &max11205_sigma_delta_info);

	st->chip_info = device_get_match_data(&spi->dev);
	if (!st->chip_info)
		st->chip_info =
			(const struct max11205_chip_info *)spi_get_device_id(spi)->driver_data;

	indio_dev->name = st->chip_info->name;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = max11205_channels;
	indio_dev->num_channels = 1;
	indio_dev->info = &max11205_iio_info;

	st->vref = devm_regulator_get(&spi->dev, "vref");
	if (IS_ERR(st->vref))
		return dev_err_probe(&spi->dev, PTR_ERR(st->vref),
				     "Failed to get vref regulator\n");

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

	ret = devm_add_action_or_reset(&spi->dev, max11205_reg_disable, st->vref);
	if (ret)
		return ret;

	ret = devm_ad_sd_setup_buffer_and_trigger(&spi->dev, indio_dev);
	if (ret)
		return ret;

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

static const struct spi_device_id max11205_spi_ids[] = {
	{ "max11205a", (kernel_ulong_t)&max11205_chip_info[TYPE_MAX11205A] },
	{ "max11205b", (kernel_ulong_t)&max11205_chip_info[TYPE_MAX11205B] },
	{ }
};
MODULE_DEVICE_TABLE(spi, max11205_spi_ids);

static const struct of_device_id max11205_dt_ids[] = {
	{
		.compatible = "maxim,max11205a",
		.data = &max11205_chip_info[TYPE_MAX11205A],
	},
	{
		.compatible = "maxim,max11205b",
		.data = &max11205_chip_info[TYPE_MAX11205B],
	},
	{ }
};
MODULE_DEVICE_TABLE(of, max11205_dt_ids);

static struct spi_driver max11205_spi_driver = {
	.driver = {
		.name = "max11205",
		.of_match_table = max11205_dt_ids,
	},
	.probe = max11205_probe,
	.id_table = max11205_spi_ids,
};
module_spi_driver(max11205_spi_driver);

MODULE_AUTHOR("Ramona Bolboaca <ramona.bolboaca@analog.com>");
MODULE_DESCRIPTION("MAX11205 ADC driver");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA);
