// SPDX-License-Identifier: GPL-2.0
/* ti-dac7311.c - Texas Instruments 8/10/12-bit 1-channel DAC driver
 *
 * Copyright (C) 2018 CMC NV
 *
 * https://www.ti.com/lit/ds/symlink/dac7311.pdf
 */

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

enum {
	ID_DAC5311 = 0,
	ID_DAC6311,
	ID_DAC7311,
};

enum {
	POWER_1KOHM_TO_GND = 0,
	POWER_100KOHM_TO_GND,
	POWER_TRI_STATE,
};

struct ti_dac_spec {
	u8 resolution;
};

static const struct ti_dac_spec ti_dac_spec[] = {
	[ID_DAC5311] = { .resolution = 8 },
	[ID_DAC6311] = { .resolution = 10 },
	[ID_DAC7311] = { .resolution = 12 },
};

/**
 * struct ti_dac_chip - TI DAC chip
 * @lock: protects write sequences
 * @vref: regulator generating Vref
 * @spi: SPI device to send data to the device
 * @val: cached value
 * @powerdown: whether the chip is powered down
 * @powerdown_mode: selected by the user
 * @resolution: resolution of the chip
 * @buf: buffer for transfer data
 */
struct ti_dac_chip {
	struct mutex lock;
	struct regulator *vref;
	struct spi_device *spi;
	u16 val;
	bool powerdown;
	u8 powerdown_mode;
	u8 resolution;
	u8 buf[2] __aligned(IIO_DMA_MINALIGN);
};

static u8 ti_dac_get_power(struct ti_dac_chip *ti_dac, bool powerdown)
{
	if (powerdown)
		return ti_dac->powerdown_mode + 1;

	return 0;
}

static int ti_dac_cmd(struct ti_dac_chip *ti_dac, u8 power, u16 val)
{
	u8 shift = 14 - ti_dac->resolution;

	ti_dac->buf[0] = (val << shift) & 0xFF;
	ti_dac->buf[1] = (power << 6) | (val >> (8 - shift));
	return spi_write(ti_dac->spi, ti_dac->buf, 2);
}

static const char * const ti_dac_powerdown_modes[] = {
	"1kohm_to_gnd",
	"100kohm_to_gnd",
	"three_state",
};

static int ti_dac_get_powerdown_mode(struct iio_dev *indio_dev,
				     const struct iio_chan_spec *chan)
{
	struct ti_dac_chip *ti_dac = iio_priv(indio_dev);

	return ti_dac->powerdown_mode;
}

static int ti_dac_set_powerdown_mode(struct iio_dev *indio_dev,
				     const struct iio_chan_spec *chan,
				     unsigned int mode)
{
	struct ti_dac_chip *ti_dac = iio_priv(indio_dev);

	ti_dac->powerdown_mode = mode;
	return 0;
}

static const struct iio_enum ti_dac_powerdown_mode = {
	.items = ti_dac_powerdown_modes,
	.num_items = ARRAY_SIZE(ti_dac_powerdown_modes),
	.get = ti_dac_get_powerdown_mode,
	.set = ti_dac_set_powerdown_mode,
};

static ssize_t ti_dac_read_powerdown(struct iio_dev *indio_dev,
				     uintptr_t private,
				     const struct iio_chan_spec *chan,
				     char *buf)
{
	struct ti_dac_chip *ti_dac = iio_priv(indio_dev);

	return sysfs_emit(buf, "%d\n", ti_dac->powerdown);
}

static ssize_t ti_dac_write_powerdown(struct iio_dev *indio_dev,
				      uintptr_t private,
				      const struct iio_chan_spec *chan,
				      const char *buf, size_t len)
{
	struct ti_dac_chip *ti_dac = iio_priv(indio_dev);
	bool powerdown;
	u8 power;
	int ret;

	ret = kstrtobool(buf, &powerdown);
	if (ret)
		return ret;

	power = ti_dac_get_power(ti_dac, powerdown);

	mutex_lock(&ti_dac->lock);
	ret = ti_dac_cmd(ti_dac, power, 0);
	if (!ret)
		ti_dac->powerdown = powerdown;
	mutex_unlock(&ti_dac->lock);

	return ret ? ret : len;
}

static const struct iio_chan_spec_ext_info ti_dac_ext_info[] = {
	{
		.name	   = "powerdown",
		.read	   = ti_dac_read_powerdown,
		.write	   = ti_dac_write_powerdown,
		.shared	   = IIO_SHARED_BY_TYPE,
	},
	IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, &ti_dac_powerdown_mode),
	IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &ti_dac_powerdown_mode),
	{ },
};

#define TI_DAC_CHANNEL(chan) {					\
	.type = IIO_VOLTAGE,					\
	.channel = (chan),					\
	.output = true,						\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
	.ext_info = ti_dac_ext_info,				\
}

static const struct iio_chan_spec ti_dac_channels[] = {
	TI_DAC_CHANNEL(0),
};

static int ti_dac_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2, long mask)
{
	struct ti_dac_chip *ti_dac = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		*val = ti_dac->val;
		return IIO_VAL_INT;

	case IIO_CHAN_INFO_SCALE:
		ret = regulator_get_voltage(ti_dac->vref);
		if (ret < 0)
			return ret;

		*val = ret / 1000;
		*val2 = ti_dac->resolution;
		return IIO_VAL_FRACTIONAL_LOG2;
	}

	return -EINVAL;
}

static int ti_dac_write_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int val, int val2, long mask)
{
	struct ti_dac_chip *ti_dac = iio_priv(indio_dev);
	u8 power = ti_dac_get_power(ti_dac, ti_dac->powerdown);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (ti_dac->val == val)
			return 0;

		if (val >= (1 << ti_dac->resolution) || val < 0)
			return -EINVAL;

		if (ti_dac->powerdown)
			return -EBUSY;

		mutex_lock(&ti_dac->lock);
		ret = ti_dac_cmd(ti_dac, power, val);
		if (!ret)
			ti_dac->val = val;
		mutex_unlock(&ti_dac->lock);
		break;

	default:
		ret = -EINVAL;
	}

	return ret;
}

static int ti_dac_write_raw_get_fmt(struct iio_dev *indio_dev,
				    struct iio_chan_spec const *chan, long mask)
{
	return IIO_VAL_INT;
}

static const struct iio_info ti_dac_info = {
	.read_raw	   = ti_dac_read_raw,
	.write_raw	   = ti_dac_write_raw,
	.write_raw_get_fmt = ti_dac_write_raw_get_fmt,
};

static int ti_dac_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	const struct ti_dac_spec *spec;
	struct ti_dac_chip *ti_dac;
	struct iio_dev *indio_dev;
	int ret;

	indio_dev = devm_iio_device_alloc(dev, sizeof(*ti_dac));
	if (!indio_dev) {
		dev_err(dev, "can not allocate iio device\n");
		return -ENOMEM;
	}

	spi->mode = SPI_MODE_1;
	spi->bits_per_word = 16;
	ret = spi_setup(spi);
	if (ret < 0)
		return dev_err_probe(dev, ret, "spi_setup failed\n");

	indio_dev->info = &ti_dac_info;
	indio_dev->name = spi_get_device_id(spi)->name;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = ti_dac_channels;
	spi_set_drvdata(spi, indio_dev);

	ti_dac = iio_priv(indio_dev);
	ti_dac->powerdown = false;
	ti_dac->spi = spi;

	spec = &ti_dac_spec[spi_get_device_id(spi)->driver_data];
	indio_dev->num_channels = 1;
	ti_dac->resolution = spec->resolution;

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

	ret = regulator_enable(ti_dac->vref);
	if (ret < 0) {
		dev_err(dev, "can not enable regulator\n");
		return ret;
	}

	mutex_init(&ti_dac->lock);

	ret = iio_device_register(indio_dev);
	if (ret) {
		dev_err(dev, "fail to register iio device: %d\n", ret);
		goto err;
	}

	return 0;

err:
	mutex_destroy(&ti_dac->lock);
	regulator_disable(ti_dac->vref);
	return ret;
}

static void ti_dac_remove(struct spi_device *spi)
{
	struct iio_dev *indio_dev = spi_get_drvdata(spi);
	struct ti_dac_chip *ti_dac = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);
	mutex_destroy(&ti_dac->lock);
	regulator_disable(ti_dac->vref);
}

static const struct of_device_id ti_dac_of_id[] = {
	{ .compatible = "ti,dac5311" },
	{ .compatible = "ti,dac6311" },
	{ .compatible = "ti,dac7311" },
	{ }
};
MODULE_DEVICE_TABLE(of, ti_dac_of_id);

static const struct spi_device_id ti_dac_spi_id[] = {
	{ "dac5311", ID_DAC5311  },
	{ "dac6311", ID_DAC6311 },
	{ "dac7311", ID_DAC7311 },
	{ }
};
MODULE_DEVICE_TABLE(spi, ti_dac_spi_id);

static struct spi_driver ti_dac_driver = {
	.driver = {
		.name		= "ti-dac7311",
		.of_match_table	= ti_dac_of_id,
	},
	.probe	  = ti_dac_probe,
	.remove   = ti_dac_remove,
	.id_table = ti_dac_spi_id,
};
module_spi_driver(ti_dac_driver);

MODULE_AUTHOR("Charles-Antoine Couret <charles-antoine.couret@essensium.com>");
MODULE_DESCRIPTION("Texas Instruments 8/10/12-bit 1-channel DAC driver");
MODULE_LICENSE("GPL v2");
