/*
 * Maxim Integrated MAX5481-MAX5484 digital potentiometer driver
 * Copyright 2016 Rockwell Collins
 *
 * Datasheet:
 * http://datasheets.maximintegrated.com/en/ds/MAX5481-MAX5484.pdf
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the gnu general public license version 2 as
 * published by the free software foundation.
 *
 */

#include <linux/acpi.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>

/* write wiper reg */
#define MAX5481_WRITE_WIPER (0 << 4)
/* copy wiper reg to NV reg */
#define MAX5481_COPY_AB_TO_NV (2 << 4)
/* copy NV reg to wiper reg */
#define MAX5481_COPY_NV_TO_AB (3 << 4)

#define MAX5481_MAX_POS    1023

enum max5481_variant {
	max5481,
	max5482,
	max5483,
	max5484,
};

struct max5481_cfg {
	int kohms;
};

static const struct max5481_cfg max5481_cfg[] = {
	[max5481] = { .kohms =  10, },
	[max5482] = { .kohms =  50, },
	[max5483] = { .kohms =  10, },
	[max5484] = { .kohms =  50, },
};

struct max5481_data {
	struct spi_device *spi;
	const struct max5481_cfg *cfg;
	u8 msg[3] ____cacheline_aligned;
};

#define MAX5481_CHANNEL {					\
	.type = IIO_RESISTANCE,					\
	.indexed = 1,						\
	.output = 1,						\
	.channel = 0,						\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
}

static const struct iio_chan_spec max5481_channels[] = {
	MAX5481_CHANNEL,
};

static int max5481_write_cmd(struct max5481_data *data, u8 cmd, u16 val)
{
	struct spi_device *spi = data->spi;

	data->msg[0] = cmd;

	switch (cmd) {
	case MAX5481_WRITE_WIPER:
		data->msg[1] = val >> 2;
		data->msg[2] = (val & 0x3) << 6;
		return spi_write(spi, data->msg, 3);

	case MAX5481_COPY_AB_TO_NV:
	case MAX5481_COPY_NV_TO_AB:
		return spi_write(spi, data->msg, 1);

	default:
		return -EIO;
	}
}

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

	if (mask != IIO_CHAN_INFO_SCALE)
		return -EINVAL;

	*val = 1000 * data->cfg->kohms;
	*val2 = MAX5481_MAX_POS;

	return IIO_VAL_FRACTIONAL;
}

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

	if (mask != IIO_CHAN_INFO_RAW)
		return -EINVAL;

	if (val < 0 || val > MAX5481_MAX_POS)
		return -EINVAL;

	return max5481_write_cmd(data, MAX5481_WRITE_WIPER, val);
}

static const struct iio_info max5481_info = {
	.read_raw = max5481_read_raw,
	.write_raw = max5481_write_raw,
};

#if defined(CONFIG_OF)
static const struct of_device_id max5481_match[] = {
	{ .compatible = "maxim,max5481", .data = &max5481_cfg[max5481] },
	{ .compatible = "maxim,max5482", .data = &max5481_cfg[max5482] },
	{ .compatible = "maxim,max5483", .data = &max5481_cfg[max5483] },
	{ .compatible = "maxim,max5484", .data = &max5481_cfg[max5484] },
	{ }
};
MODULE_DEVICE_TABLE(of, max5481_match);
#endif

static int max5481_probe(struct spi_device *spi)
{
	struct iio_dev *indio_dev;
	struct max5481_data *data;
	const struct spi_device_id *id = spi_get_device_id(spi);
	const struct of_device_id *match;
	int ret;

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

	dev_set_drvdata(&spi->dev, indio_dev);
	data = iio_priv(indio_dev);

	data->spi = spi;

	match = of_match_device(of_match_ptr(max5481_match), &spi->dev);
	if (match)
		data->cfg = of_device_get_match_data(&spi->dev);
	else
		data->cfg = &max5481_cfg[id->driver_data];

	indio_dev->name = id->name;
	indio_dev->dev.parent = &spi->dev;
	indio_dev->modes = INDIO_DIRECT_MODE;

	/* variant specific configuration */
	indio_dev->info = &max5481_info;
	indio_dev->channels = max5481_channels;
	indio_dev->num_channels = ARRAY_SIZE(max5481_channels);

	/* restore wiper from NV */
	ret = max5481_write_cmd(data, MAX5481_COPY_NV_TO_AB, 0);
	if (ret < 0)
		return ret;

	return iio_device_register(indio_dev);
}

static int max5481_remove(struct spi_device *spi)
{
	struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev);
	struct max5481_data *data = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);

	/* save wiper reg to NV reg */
	return max5481_write_cmd(data, MAX5481_COPY_AB_TO_NV, 0);
}

static const struct spi_device_id max5481_id_table[] = {
	{ "max5481", max5481 },
	{ "max5482", max5482 },
	{ "max5483", max5483 },
	{ "max5484", max5484 },
	{ }
};
MODULE_DEVICE_TABLE(spi, max5481_id_table);

#if defined(CONFIG_ACPI)
static const struct acpi_device_id max5481_acpi_match[] = {
	{ "max5481", max5481 },
	{ "max5482", max5482 },
	{ "max5483", max5483 },
	{ "max5484", max5484 },
	{ }
};
MODULE_DEVICE_TABLE(acpi, max5481_acpi_match);
#endif

static struct spi_driver max5481_driver = {
	.driver = {
		.name  = "max5481",
		.of_match_table = of_match_ptr(max5481_match),
		.acpi_match_table = ACPI_PTR(max5481_acpi_match),
	},
	.probe = max5481_probe,
	.remove = max5481_remove,
	.id_table = max5481_id_table,
};

module_spi_driver(max5481_driver);

MODULE_AUTHOR("Maury Anderson <maury.anderson@rockwellcollins.com>");
MODULE_DESCRIPTION("max5481 SPI driver");
MODULE_LICENSE("GPL v2");
