// 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;
	struct regulator *vdd_reg;
	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 ret;

	ret = regulator_get_voltage(data->vdd_reg);
	if (ret < 0)
		return ret;

	mcp4728_init_scale_avail(MCP4728_SCALE_VDD, ret / 1000, 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 void mcp4728_reg_disable(void *reg)
{
	regulator_disable(reg);
}

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 err;

	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;

	data->vdd_reg = devm_regulator_get(&client->dev, "vdd");
	if (IS_ERR(data->vdd_reg))
		return PTR_ERR(data->vdd_reg);

	err = regulator_enable(data->vdd_reg);
	if (err)
		return err;

	err = devm_add_action_or_reset(&client->dev, mcp4728_reg_disable,
				       data->vdd_reg);
	if (err)
		return err;

	/*
	 * 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.
	 */
	err = mcp4728_init_channels_data(data);
	if (err) {
		return dev_err_probe(&client->dev, err,
			"failed to read mcp4728 current configuration\n");
	}

	err = mcp4728_init_scales_avail(data);
	if (err) {
		return dev_err_probe(&client->dev, err,
				     "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");
