// SPDX-License-Identifier: GPL-2.0+
/*
 * Analog Devices AD5272 digital potentiometer driver
 * Copyright (C) 2018 Phil Reid <preid@electromag.com.au>
 *
 * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/AD5272_5274.pdf
 *
 * DEVID	#Wipers	#Positions	Resistor Opts (kOhm)	i2c address
 * ad5272	1	1024		20, 50, 100		01011xx
 * ad5274	1	256		20, 100			01011xx
 */

#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/module.h>

#define  AD5272_RDAC_WR  1
#define  AD5272_RDAC_RD  2
#define  AD5272_RESET    4
#define  AD5272_CTL      7

#define  AD5272_RDAC_WR_EN  BIT(1)

struct ad5272_cfg {
	int max_pos;
	int kohms;
	int shift;
};

enum ad5272_type {
	AD5272_020,
	AD5272_050,
	AD5272_100,
	AD5274_020,
	AD5274_100,
};

static const struct ad5272_cfg ad5272_cfg[] = {
	[AD5272_020] = { .max_pos = 1024, .kohms = 20 },
	[AD5272_050] = { .max_pos = 1024, .kohms = 50 },
	[AD5272_100] = { .max_pos = 1024, .kohms = 100 },
	[AD5274_020] = { .max_pos = 256,  .kohms = 20,  .shift = 2 },
	[AD5274_100] = { .max_pos = 256,  .kohms = 100, .shift = 2 },
};

struct ad5272_data {
	struct i2c_client       *client;
	struct mutex            lock;
	const struct ad5272_cfg *cfg;
	u8                      buf[2] ____cacheline_aligned;
};

static const struct iio_chan_spec ad5272_channel = {
	.type = IIO_RESISTANCE,
	.output = 1,
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
};

static int ad5272_write(struct ad5272_data *data, int reg, int val)
{
	int ret;

	data->buf[0] = (reg << 2) | ((val >> 8) & 0x3);
	data->buf[1] = (u8)val;

	mutex_lock(&data->lock);
	ret = i2c_master_send(data->client, data->buf, sizeof(data->buf));
	mutex_unlock(&data->lock);
	return ret < 0 ? ret : 0;
}

static int ad5272_read(struct ad5272_data *data, int reg, int *val)
{
	int ret;

	data->buf[0] = reg << 2;
	data->buf[1] = 0;

	mutex_lock(&data->lock);
	ret = i2c_master_send(data->client, data->buf, sizeof(data->buf));
	if (ret < 0)
		goto error;

	ret = i2c_master_recv(data->client, data->buf, sizeof(data->buf));
	if (ret < 0)
		goto error;

	*val = ((data->buf[0] & 0x3) << 8) | data->buf[1];
	ret = 0;
error:
	mutex_unlock(&data->lock);
	return ret;
}

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

	switch (mask) {
	case IIO_CHAN_INFO_RAW: {
		ret = ad5272_read(data, AD5272_RDAC_RD, val);
		*val = *val >> data->cfg->shift;
		return ret ? ret : IIO_VAL_INT;
	}
	case IIO_CHAN_INFO_SCALE:
		*val = 1000 * data->cfg->kohms;
		*val2 = data->cfg->max_pos;
		return IIO_VAL_FRACTIONAL;
	}

	return -EINVAL;
}

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

	if (mask != IIO_CHAN_INFO_RAW)
		return -EINVAL;

	if (val >= data->cfg->max_pos || val < 0 || val2)
		return -EINVAL;

	return ad5272_write(data, AD5272_RDAC_WR, val << data->cfg->shift);
}

static const struct iio_info ad5272_info = {
	.read_raw = ad5272_read_raw,
	.write_raw = ad5272_write_raw,
};

static int ad5272_reset(struct ad5272_data *data)
{
	struct gpio_desc *reset_gpio;

	reset_gpio = devm_gpiod_get_optional(&data->client->dev, "reset",
		GPIOD_OUT_LOW);
	if (IS_ERR(reset_gpio))
		return PTR_ERR(reset_gpio);

	if (reset_gpio) {
		udelay(1);
		gpiod_set_value(reset_gpio, 1);
	} else {
		ad5272_write(data, AD5272_RESET, 0);
	}
	usleep_range(1000, 2000);

	return 0;
}

static int ad5272_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct iio_dev *indio_dev;
	struct ad5272_data *data;
	int ret;

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

	i2c_set_clientdata(client, indio_dev);

	data = iio_priv(indio_dev);
	data->client = client;
	mutex_init(&data->lock);
	data->cfg = &ad5272_cfg[id->driver_data];

	ret = ad5272_reset(data);
	if (ret)
		return ret;

	ret = ad5272_write(data, AD5272_CTL, AD5272_RDAC_WR_EN);
	if (ret < 0)
		return -ENODEV;

	indio_dev->info = &ad5272_info;
	indio_dev->channels = &ad5272_channel;
	indio_dev->num_channels = 1;
	indio_dev->name = client->name;

	return devm_iio_device_register(dev, indio_dev);
}

#if defined(CONFIG_OF)
static const struct of_device_id ad5272_dt_ids[] = {
	{ .compatible = "adi,ad5272-020", .data = (void *)AD5272_020 },
	{ .compatible = "adi,ad5272-050", .data = (void *)AD5272_050 },
	{ .compatible = "adi,ad5272-100", .data = (void *)AD5272_100 },
	{ .compatible = "adi,ad5274-020", .data = (void *)AD5274_020 },
	{ .compatible = "adi,ad5274-100", .data = (void *)AD5274_100 },
	{}
};
MODULE_DEVICE_TABLE(of, ad5272_dt_ids);
#endif /* CONFIG_OF */

static const struct i2c_device_id ad5272_id[] = {
	{ "ad5272-020", AD5272_020 },
	{ "ad5272-050", AD5272_050 },
	{ "ad5272-100", AD5272_100 },
	{ "ad5274-020", AD5274_020 },
	{ "ad5274-100", AD5274_100 },
	{}
};
MODULE_DEVICE_TABLE(i2c, ad5272_id);

static struct i2c_driver ad5272_driver = {
	.driver = {
		.name	= "ad5272",
		.of_match_table = of_match_ptr(ad5272_dt_ids),
	},
	.probe		= ad5272_probe,
	.id_table	= ad5272_id,
};

module_i2c_driver(ad5272_driver);

MODULE_AUTHOR("Phil Reid <preid@eletromag.com.au>");
MODULE_DESCRIPTION("AD5272 digital potentiometer");
MODULE_LICENSE("GPL v2");
