// SPDX-License-Identifier: GPL-2.0-only
/*
 * Support for Microchip MCP4728
 *
 * Copyright (C) 2023 Andrea Collamati <andrea.collamati@gmail.com>
 *
 * Based on mcp4725 by Peter Meerwald <pmeerw@pmeerw.net>
 *
 * Driver for the Microchip I2C 12-bit digital-to-analog quad channels
 * converter (DAC).
 *
 * (7-bit I2C slave address 0x60, the three LSBs can be configured in
 * hardware)
 */

#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>

#define MCP4728_RESOLUTION	  12
#define MCP4728_N_CHANNELS	  4

#define MCP4728_CMD_MASK	  GENMASK(7, 3)
#define MCP4728_CHSEL_MASK	  GENMASK(2, 1)
#define MCP4728_UDAC_MASK	  BIT(0)

#define MCP4728_VREF_MASK	  BIT(7)
#define MCP4728_PDMODE_MASK	  GENMASK(6, 5)
#define MCP4728_GAIN_MASK	  BIT(4)

#define MCP4728_DAC_H_MASK	  GENMASK(3, 0)
#define MCP4728_DAC_L_MASK	  GENMASK(7, 0)

#define MCP4728_RDY_MASK	  BIT(7)

#define MCP4728_MW_CMD		  0x08 /* Multiwrite Command */
#define MCP4728_SW_CMD		  0x0A /* Sequential Write Command with EEPROM */

#define MCP4728_READ_RESPONSE_LEN (MCP4728_N_CHANNELS * 3 * 2)
#define MCP4728_WRITE_EEPROM_LEN  (1 + MCP4728_N_CHANNELS * 2)

enum vref_mode {
	MCP4728_VREF_EXTERNAL_VDD    = 0,
	MCP4728_VREF_INTERNAL_2048mV = 1,
};

enum gain_mode {
	MCP4728_GAIN_X1 = 0,
	MCP4728_GAIN_X2 = 1,
};

enum iio_powerdown_mode {
	MCP4728_IIO_1K,
	MCP4728_IIO_100K,
	MCP4728_IIO_500K,
};

struct mcp4728_channel_data {
	enum vref_mode ref_mode;
	enum iio_powerdown_mode pd_mode;
	enum gain_mode g_mode;
	u16 dac_value;
};

/* MCP4728 Full Scale Ranges
 * the device available ranges are
 * - VREF = VDD				FSR = from 0.0V to VDD
 * - VREF = Internal	Gain = 1	FSR = from 0.0V to VREF
 * - VREF = Internal	Gain = 2	FSR = from 0.0V to 2*VREF
 */
enum mcp4728_scale {
	MCP4728_SCALE_VDD,
	MCP4728_SCALE_VINT_NO_GAIN,
	MCP4728_SCALE_VINT_GAIN_X2,
	MCP4728_N_SCALES
};

struct mcp4728_data {
	struct i2c_client *client;
	bool powerdown;
	int scales_avail[MCP4728_N_SCALES * 2];
	struct mcp4728_channel_data chdata[MCP4728_N_CHANNELS];
};

#define MCP4728_CHAN(chan) {						\
	.type = IIO_VOLTAGE,						\
	.output = 1,							\
	.indexed = 1,							\
	.channel = chan,						\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW)	|		\
			      BIT(IIO_CHAN_INFO_SCALE),			\
	.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE),	\
	.ext_info = mcp4728_ext_info,					\
}

static int mcp4728_suspend(struct device *dev);
static int mcp4728_resume(struct device *dev);

static ssize_t mcp4728_store_eeprom(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t len)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct mcp4728_data *data = iio_priv(indio_dev);
	u8 outbuf[MCP4728_WRITE_EEPROM_LEN];
	int tries = 20;
	u8 inbuf[3];
	bool state;
	int ret;
	unsigned int i;

	ret = kstrtobool(buf, &state);
	if (ret < 0)
		return ret;

	if (!state)
		return 0;

	outbuf[0] = FIELD_PREP(MCP4728_CMD_MASK, MCP4728_SW_CMD);

	for (i = 0; i < MCP4728_N_CHANNELS; i++) {
		struct mcp4728_channel_data *ch = &data->chdata[i];
		int offset			= 1 + i * 2;

		outbuf[offset] = FIELD_PREP(MCP4728_VREF_MASK, ch->ref_mode);

		if (data->powerdown) {
			u8 mcp4728_pd_mode = ch->pd_mode + 1;

			outbuf[offset] |= FIELD_PREP(MCP4728_PDMODE_MASK,
						     mcp4728_pd_mode);
		}

		outbuf[offset] |= FIELD_PREP(MCP4728_GAIN_MASK, ch->g_mode);
		outbuf[offset] |=
			FIELD_PREP(MCP4728_DAC_H_MASK, ch->dac_value >> 8);
		outbuf[offset + 1] =
			FIELD_PREP(MCP4728_DAC_L_MASK, ch->dac_value);
	}

	ret = i2c_master_send(data->client, outbuf, MCP4728_WRITE_EEPROM_LEN);
	if (ret < 0)
		return ret;
	else if (ret != MCP4728_WRITE_EEPROM_LEN)
		return -EIO;

	/* wait RDY signal for write complete, takes up to 50ms */
	while (tries--) {
		msleep(20);
		ret = i2c_master_recv(data->client, inbuf, 3);
		if (ret < 0)
			return ret;
		else if (ret != 3)
			return -EIO;

		if (FIELD_GET(MCP4728_RDY_MASK, inbuf[0]))
			break;
	}

	if (tries < 0) {
		dev_err(&data->client->dev, "%s failed, incomplete\n",
			__func__);
		return -EIO;
	}
	return len;
}

static IIO_DEVICE_ATTR(store_eeprom, 0200, NULL, mcp4728_store_eeprom, 0);

static struct attribute *mcp4728_attributes[] = {
	&iio_dev_attr_store_eeprom.dev_attr.attr,
	NULL,
};

static const struct attribute_group mcp4728_attribute_group = {
	.attrs = mcp4728_attributes,
};

static int mcp4728_program_channel_cfg(int channel, struct iio_dev *indio_dev)
{
	struct mcp4728_data *data	= iio_priv(indio_dev);
	struct mcp4728_channel_data *ch = &data->chdata[channel];
	u8 outbuf[3];
	int ret;

	outbuf[0] = FIELD_PREP(MCP4728_CMD_MASK, MCP4728_MW_CMD);
	outbuf[0] |= FIELD_PREP(MCP4728_CHSEL_MASK, channel);
	outbuf[0] |= FIELD_PREP(MCP4728_UDAC_MASK, 0);

	outbuf[1] = FIELD_PREP(MCP4728_VREF_MASK, ch->ref_mode);

	if (data->powerdown)
		outbuf[1] |= FIELD_PREP(MCP4728_PDMODE_MASK, ch->pd_mode + 1);

	outbuf[1] |= FIELD_PREP(MCP4728_GAIN_MASK, ch->g_mode);
	outbuf[1] |= FIELD_PREP(MCP4728_DAC_H_MASK, ch->dac_value >> 8);
	outbuf[2] = FIELD_PREP(MCP4728_DAC_L_MASK, ch->dac_value);

	ret = i2c_master_send(data->client, outbuf, 3);
	if (ret < 0)
		return ret;
	else if (ret != 3)
		return -EIO;

	return 0;
}

static const char *const mcp4728_powerdown_modes[] = { "1kohm_to_gnd",
						       "100kohm_to_gnd",
						       "500kohm_to_gnd" };

static int mcp4728_get_powerdown_mode(struct iio_dev *indio_dev,
				      const struct iio_chan_spec *chan)
{
	struct mcp4728_data *data = iio_priv(indio_dev);

	return data->chdata[chan->channel].pd_mode;
}

static int mcp4728_set_powerdown_mode(struct iio_dev *indio_dev,
				      const struct iio_chan_spec *chan,
				      unsigned int mode)
{
	struct mcp4728_data *data = iio_priv(indio_dev);

	data->chdata[chan->channel].pd_mode = mode;

	return 0;
}

static ssize_t mcp4728_read_powerdown(struct iio_dev *indio_dev,
				      uintptr_t private,
				      const struct iio_chan_spec *chan,
				      char *buf)
{
	struct mcp4728_data *data = iio_priv(indio_dev);

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

static ssize_t mcp4728_write_powerdown(struct iio_dev *indio_dev,
				       uintptr_t private,
				       const struct iio_chan_spec *chan,
				       const char *buf, size_t len)
{
	struct mcp4728_data *data = iio_priv(indio_dev);
	bool state;
	int ret;

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

	if (state)
		ret = mcp4728_suspend(&data->client->dev);
	else
		ret = mcp4728_resume(&data->client->dev);

	if (ret < 0)
		return ret;

	return len;
}

static const struct iio_enum mcp4728_powerdown_mode_enum = {
	.items	   = mcp4728_powerdown_modes,
	.num_items = ARRAY_SIZE(mcp4728_powerdown_modes),
	.get	   = mcp4728_get_powerdown_mode,
	.set	   = mcp4728_set_powerdown_mode,
};

static const struct iio_chan_spec_ext_info mcp4728_ext_info[] = {
	{
		.name	= "powerdown",
		.read	= mcp4728_read_powerdown,
		.write	= mcp4728_write_powerdown,
		.shared = IIO_SEPARATE,
	},
	IIO_ENUM("powerdown_mode", IIO_SEPARATE, &mcp4728_powerdown_mode_enum),
	IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE,
			   &mcp4728_powerdown_mode_enum),
	{},
};

static const struct iio_chan_spec mcp4728_channels[MCP4728_N_CHANNELS] = {
	MCP4728_CHAN(0),
	MCP4728_CHAN(1),
	MCP4728_CHAN(2),
	MCP4728_CHAN(3),
};

static void mcp4728_get_scale_avail(enum mcp4728_scale scale,
				    struct mcp4728_data *data, int *val,
				    int *val2)
{
	*val  = data->scales_avail[scale * 2];
	*val2 = data->scales_avail[scale * 2 + 1];
}

static void mcp4728_get_scale(int channel, struct mcp4728_data *data, int *val,
			      int *val2)
{
	int ref_mode = data->chdata[channel].ref_mode;
	int g_mode   = data->chdata[channel].g_mode;

	if (ref_mode == MCP4728_VREF_EXTERNAL_VDD) {
		mcp4728_get_scale_avail(MCP4728_SCALE_VDD, data, val, val2);
	} else {
		if (g_mode == MCP4728_GAIN_X1) {
			mcp4728_get_scale_avail(MCP4728_SCALE_VINT_NO_GAIN,
						data, val, val2);
		} else {
			mcp4728_get_scale_avail(MCP4728_SCALE_VINT_GAIN_X2,
						data, val, val2);
		}
	}
}

static int mcp4728_find_matching_scale(struct mcp4728_data *data, int val,
				       int val2)
{
	for (int i = 0; i < MCP4728_N_SCALES; i++) {
		if (data->scales_avail[i * 2] == val &&
		    data->scales_avail[i * 2 + 1] == val2)
			return i;
	}
	return -EINVAL;
}

static int mcp4728_set_scale(int channel, struct mcp4728_data *data, int val,
			     int val2)
{
	int scale = mcp4728_find_matching_scale(data, val, val2);

	if (scale < 0)
		return scale;

	switch (scale) {
	case MCP4728_SCALE_VDD:
		data->chdata[channel].ref_mode = MCP4728_VREF_EXTERNAL_VDD;
		return 0;
	case MCP4728_SCALE_VINT_NO_GAIN:
		data->chdata[channel].ref_mode = MCP4728_VREF_INTERNAL_2048mV;
		data->chdata[channel].g_mode   = MCP4728_GAIN_X1;
		return 0;
	case MCP4728_SCALE_VINT_GAIN_X2:
		data->chdata[channel].ref_mode = MCP4728_VREF_INTERNAL_2048mV;
		data->chdata[channel].g_mode   = MCP4728_GAIN_X2;
		return 0;
	default:
		return -EINVAL;
	}
}

static int mcp4728_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int *val,
			    int *val2, long mask)
{
	struct mcp4728_data *data = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		*val = data->chdata[chan->channel].dac_value;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		mcp4728_get_scale(chan->channel, data, val, val2);
		return IIO_VAL_INT_PLUS_MICRO;
	}
	return -EINVAL;
}

static int mcp4728_write_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan, int val,
			     int val2, long mask)
{
	struct mcp4728_data *data = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (val < 0 || val > GENMASK(MCP4728_RESOLUTION - 1, 0))
			return -EINVAL;
		data->chdata[chan->channel].dac_value = val;
		return mcp4728_program_channel_cfg(chan->channel, indio_dev);
	case IIO_CHAN_INFO_SCALE:
		ret = mcp4728_set_scale(chan->channel, data, val, val2);
		if (ret)
			return ret;

		return mcp4728_program_channel_cfg(chan->channel, indio_dev);
	default:
		return -EINVAL;
	}
}

static void mcp4728_init_scale_avail(enum mcp4728_scale scale, int vref_mv,
				     struct mcp4728_data *data)
{
	s64 tmp;
	int value_micro;
	int value_int;

	tmp	  = (s64)vref_mv * 1000000LL >> MCP4728_RESOLUTION;
	value_int = div_s64_rem(tmp, 1000000LL, &value_micro);

	data->scales_avail[scale * 2]	  = value_int;
	data->scales_avail[scale * 2 + 1] = value_micro;
}

static int mcp4728_init_scales_avail(struct mcp4728_data *data, int vdd_mv)
{
	mcp4728_init_scale_avail(MCP4728_SCALE_VDD, vdd_mv, data);
	mcp4728_init_scale_avail(MCP4728_SCALE_VINT_NO_GAIN, 2048, data);
	mcp4728_init_scale_avail(MCP4728_SCALE_VINT_GAIN_X2, 4096, data);

	return 0;
}

static int mcp4728_read_avail(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan,
			      const int **vals, int *type, int *length,
			      long info)
{
	struct mcp4728_data *data = iio_priv(indio_dev);

	switch (info) {
	case IIO_CHAN_INFO_SCALE:
		*type = IIO_VAL_INT_PLUS_MICRO;

		switch (chan->type) {
		case IIO_VOLTAGE:
			*vals	= data->scales_avail;
			*length = MCP4728_N_SCALES * 2;
			return IIO_AVAIL_LIST;
		default:
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

static const struct iio_info mcp4728_info = {
	.read_raw   = mcp4728_read_raw,
	.write_raw  = mcp4728_write_raw,
	.read_avail = &mcp4728_read_avail,
	.attrs	    = &mcp4728_attribute_group,
};

static int mcp4728_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct mcp4728_data *data = iio_priv(indio_dev);
	unsigned int i;

	data->powerdown = true;

	for (i = 0; i < MCP4728_N_CHANNELS; i++) {
		int err = mcp4728_program_channel_cfg(i, indio_dev);

		if (err)
			return err;
	}
	return 0;
}

static int mcp4728_resume(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct mcp4728_data *data = iio_priv(indio_dev);
	int err			  = 0;
	unsigned int i;

	data->powerdown = false;

	for (i = 0; i < MCP4728_N_CHANNELS; i++) {
		int ret = mcp4728_program_channel_cfg(i, indio_dev);

		if (ret)
			err = ret;
	}
	return err;
}

static DEFINE_SIMPLE_DEV_PM_OPS(mcp4728_pm_ops, mcp4728_suspend,
				mcp4728_resume);

static int mcp4728_init_channels_data(struct mcp4728_data *data)
{
	u8 inbuf[MCP4728_READ_RESPONSE_LEN];
	int ret;
	unsigned int i;

	ret = i2c_master_recv(data->client, inbuf, MCP4728_READ_RESPONSE_LEN);
	if (ret < 0) {
		return dev_err_probe(&data->client->dev, ret,
				     "failed to read mcp4728 conf.\n");
	} else if (ret != MCP4728_READ_RESPONSE_LEN) {
		return dev_err_probe(&data->client->dev, -EIO,
			"failed to read mcp4728 conf. Wrong Response Len ret=%d\n",
			ret);
	}

	for (i = 0; i < MCP4728_N_CHANNELS; i++) {
		struct mcp4728_channel_data *ch = &data->chdata[i];
		u8 r2				= inbuf[i * 6 + 1];
		u8 r3				= inbuf[i * 6 + 2];

		ch->dac_value = FIELD_GET(MCP4728_DAC_H_MASK, r2) << 8 |
				FIELD_GET(MCP4728_DAC_L_MASK, r3);
		ch->ref_mode = FIELD_GET(MCP4728_VREF_MASK, r2);
		ch->pd_mode  = FIELD_GET(MCP4728_PDMODE_MASK, r2);
		ch->g_mode   = FIELD_GET(MCP4728_GAIN_MASK, r2);
	}

	return 0;
}

static int mcp4728_probe(struct i2c_client *client)
{
	const struct i2c_device_id *id = i2c_client_get_device_id(client);
	struct mcp4728_data *data;
	struct iio_dev *indio_dev;
	int ret, vdd_mv;

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

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

	ret = devm_regulator_get_enable_read_voltage(&client->dev, "vdd");
	if (ret < 0)
		return ret;

	vdd_mv = ret / 1000;

	/*
	 * MCP4728 has internal EEPROM that save each channel boot
	 * configuration. It means that device configuration is unknown to the
	 * driver at kernel boot. mcp4728_init_channels_data() reads back DAC
	 * settings and stores them in data structure.
	 */
	ret = mcp4728_init_channels_data(data);
	if (ret) {
		return dev_err_probe(&client->dev, ret,
			"failed to read mcp4728 current configuration\n");
	}

	ret = mcp4728_init_scales_avail(data, vdd_mv);
	if (ret) {
		return dev_err_probe(&client->dev, ret,
				     "failed to init scales\n");
	}

	indio_dev->name		= id->name;
	indio_dev->info		= &mcp4728_info;
	indio_dev->channels	= mcp4728_channels;
	indio_dev->num_channels = MCP4728_N_CHANNELS;
	indio_dev->modes	= INDIO_DIRECT_MODE;

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

static const struct i2c_device_id mcp4728_id[] = {
	{ "mcp4728" },
	{}
};
MODULE_DEVICE_TABLE(i2c, mcp4728_id);

static const struct of_device_id mcp4728_of_match[] = {
	{ .compatible = "microchip,mcp4728" },
	{}
};
MODULE_DEVICE_TABLE(of, mcp4728_of_match);

static struct i2c_driver mcp4728_driver = {
	.driver = {
		.name = "mcp4728",
		.of_match_table = mcp4728_of_match,
		.pm = pm_sleep_ptr(&mcp4728_pm_ops),
	},
	.probe = mcp4728_probe,
	.id_table = mcp4728_id,
};
module_i2c_driver(mcp4728_driver);

MODULE_AUTHOR("Andrea Collamati <andrea.collamati@gmail.com>");
MODULE_DESCRIPTION("MCP4728 12-bit DAC");
MODULE_LICENSE("GPL");
