// 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);

	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");
