// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  m62332.c - Support for Mitsubishi m62332 DAC
 *
 *  Copyright (c) 2014 Dmitry Eremin-Solenikov
 *
 *  Based on max517 driver:
 *  Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de>
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/err.h>

#include <linux/iio/iio.h>
#include <linux/iio/driver.h>

#include <linux/regulator/consumer.h>

#define M62332_CHANNELS 2

struct m62332_data {
	struct i2c_client	*client;
	struct regulator	*vcc;
	struct mutex		mutex;
	u8			raw[M62332_CHANNELS];
#ifdef CONFIG_PM_SLEEP
	u8			save[M62332_CHANNELS];
#endif
};

static int m62332_set_value(struct iio_dev *indio_dev, u8 val, int channel)
{
	struct m62332_data *data = iio_priv(indio_dev);
	struct i2c_client *client = data->client;
	u8 outbuf[2];
	int res;

	if (val == data->raw[channel])
		return 0;

	outbuf[0] = channel;
	outbuf[1] = val;

	mutex_lock(&data->mutex);

	if (val) {
		res = regulator_enable(data->vcc);
		if (res)
			goto out;
	}

	res = i2c_master_send(client, outbuf, ARRAY_SIZE(outbuf));
	if (res >= 0 && res != ARRAY_SIZE(outbuf))
		res = -EIO;
	if (res < 0)
		goto out;

	data->raw[channel] = val;

	if (!val)
		regulator_disable(data->vcc);

	mutex_unlock(&data->mutex);

	return 0;

out:
	mutex_unlock(&data->mutex);

	return res;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
		/* Corresponds to Vref / 2^(bits) */
		ret = regulator_get_voltage(data->vcc);
		if (ret < 0)
			return ret;

		*val = ret / 1000; /* mV */
		*val2 = 8;

		return IIO_VAL_FRACTIONAL_LOG2;
	case IIO_CHAN_INFO_RAW:
		*val = data->raw[chan->channel];

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_OFFSET:
		*val = 1;

		return IIO_VAL_INT;
	default:
		break;
	}

	return -EINVAL;
}

static int m62332_write_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int val, int val2,
			    long mask)
{
	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (val < 0 || val > 255)
			return -EINVAL;

		return m62332_set_value(indio_dev, val, chan->channel);
	default:
		break;
	}

	return -EINVAL;
}

#ifdef CONFIG_PM_SLEEP
static int m62332_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct iio_dev *indio_dev = i2c_get_clientdata(client);
	struct m62332_data *data = iio_priv(indio_dev);
	int ret;

	data->save[0] = data->raw[0];
	data->save[1] = data->raw[1];

	ret = m62332_set_value(indio_dev, 0, 0);
	if (ret < 0)
		return ret;

	return m62332_set_value(indio_dev, 0, 1);
}

static int m62332_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct iio_dev *indio_dev = i2c_get_clientdata(client);
	struct m62332_data *data = iio_priv(indio_dev);
	int ret;

	ret = m62332_set_value(indio_dev, data->save[0], 0);
	if (ret < 0)
		return ret;

	return m62332_set_value(indio_dev, data->save[1], 1);
}

static SIMPLE_DEV_PM_OPS(m62332_pm_ops, m62332_suspend, m62332_resume);
#define M62332_PM_OPS (&m62332_pm_ops)
#else
#define M62332_PM_OPS NULL
#endif

static const struct iio_info m62332_info = {
	.read_raw = m62332_read_raw,
	.write_raw = m62332_write_raw,
};

#define M62332_CHANNEL(chan) {					\
	.type = IIO_VOLTAGE,					\
	.indexed = 1,						\
	.output = 1,						\
	.channel = (chan),					\
	.datasheet_name = "CH" #chan,				\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
				    BIT(IIO_CHAN_INFO_OFFSET),	\
}

static const struct iio_chan_spec m62332_channels[M62332_CHANNELS] = {
	M62332_CHANNEL(0),
	M62332_CHANNEL(1)
};

static int m62332_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct m62332_data *data;
	struct iio_dev *indio_dev;
	int ret;

	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;

	mutex_init(&data->mutex);

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

	/* establish that the iio_dev is a child of the i2c device */
	indio_dev->dev.parent = &client->dev;

	indio_dev->num_channels = ARRAY_SIZE(m62332_channels);
	indio_dev->channels = m62332_channels;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &m62332_info;

	ret = iio_map_array_register(indio_dev, client->dev.platform_data);
	if (ret < 0)
		return ret;

	ret = iio_device_register(indio_dev);
	if (ret < 0)
		goto err;

	return 0;

err:
	iio_map_array_unregister(indio_dev);

	return ret;
}

static int m62332_remove(struct i2c_client *client)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(client);

	iio_device_unregister(indio_dev);
	iio_map_array_unregister(indio_dev);
	m62332_set_value(indio_dev, 0, 0);
	m62332_set_value(indio_dev, 0, 1);

	return 0;
}

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

static struct i2c_driver m62332_driver = {
	.driver = {
		.name	= "m62332",
		.pm	= M62332_PM_OPS,
	},
	.probe		= m62332_probe,
	.remove		= m62332_remove,
	.id_table	= m62332_id,
};
module_i2c_driver(m62332_driver);

MODULE_AUTHOR("Dmitry Eremin-Solenikov");
MODULE_DESCRIPTION("M62332 8-bit DAC");
MODULE_LICENSE("GPL v2");
