/*
 * ad2s1200.c simple support for the ADI Resolver to Digital Converters:
 * AD2S1200/1205
 *
 * Copyright (c) 2018-2018 David Veenstra <davidjulianveenstra@gmail.com>
 * Copyright (c) 2010-2010 Analog Devices Inc.
 *
 * 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/bitops.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/spi/spi.h>
#include <linux/sysfs.h>
#include <linux/types.h>

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

#define DRV_NAME "ad2s1200"

/* input clock on serial interface */
#define AD2S1200_HZ	8192000
/* clock period in nano second */
#define AD2S1200_TSCLK	(1000000000 / AD2S1200_HZ)

/**
 * struct ad2s1200_state - driver instance specific data.
 * @lock:	protects both the GPIO pins and the rx buffer.
 * @sdev:	spi device.
 * @sample:	GPIO pin SAMPLE.
 * @rdvel:	GPIO pin RDVEL.
 * @rx:		buffer for spi transfers.
 */
struct ad2s1200_state {
	struct mutex lock;
	struct spi_device *sdev;
	struct gpio_desc *sample;
	struct gpio_desc *rdvel;
	__be16 rx ____cacheline_aligned;
};

static int ad2s1200_read_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     int *val,
			     int *val2,
			     long m)
{
	struct ad2s1200_state *st = iio_priv(indio_dev);
	int ret;

	switch (m) {
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_ANGL:
			/* 2 * Pi / (2^12 - 1) ~= 0.001534355 */
			*val = 0;
			*val2 = 1534355;
			return IIO_VAL_INT_PLUS_NANO;
		case IIO_ANGL_VEL:
			/* 2 * Pi ~= 6.283185 */
			*val = 6;
			*val2 = 283185;
			return IIO_VAL_INT_PLUS_MICRO;
		default:
			return -EINVAL;
		}
		break;
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&st->lock);
		gpiod_set_value(st->sample, 0);

		/* delay (6 * AD2S1200_TSCLK + 20) nano seconds */
		udelay(1);
		gpiod_set_value(st->sample, 1);
		gpiod_set_value(st->rdvel, !!(chan->type == IIO_ANGL));

		ret = spi_read(st->sdev, &st->rx, 2);
		if (ret < 0) {
			mutex_unlock(&st->lock);
			return ret;
		}

		switch (chan->type) {
		case IIO_ANGL:
			*val = be16_to_cpup(&st->rx) >> 4;
			break;
		case IIO_ANGL_VEL:
			*val = sign_extend32(be16_to_cpup(&st->rx) >> 4, 11);
			break;
		default:
			mutex_unlock(&st->lock);
			return -EINVAL;
		}

		/* delay (2 * AD2S1200_TSCLK + 20) ns for sample pulse */
		udelay(1);
		mutex_unlock(&st->lock);

		return IIO_VAL_INT;
	default:
		break;
	}

	return -EINVAL;
}

static const struct iio_chan_spec ad2s1200_channels[] = {
	{
		.type = IIO_ANGL,
		.indexed = 1,
		.channel = 0,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
	}, {
		.type = IIO_ANGL_VEL,
		.indexed = 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_info ad2s1200_info = {
	.read_raw = ad2s1200_read_raw,
};

static int ad2s1200_probe(struct spi_device *spi)
{
	struct ad2s1200_state *st;
	struct iio_dev *indio_dev;
	int ret;

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

	spi_set_drvdata(spi, indio_dev);
	st = iio_priv(indio_dev);
	mutex_init(&st->lock);
	st->sdev = spi;

	st->sample = devm_gpiod_get(&spi->dev, "adi,sample", GPIOD_OUT_LOW);
	if (IS_ERR(st->sample)) {
		dev_err(&spi->dev, "Failed to claim SAMPLE gpio: err=%ld\n",
			PTR_ERR(st->sample));
		return PTR_ERR(st->sample);
	}

	st->rdvel = devm_gpiod_get(&spi->dev, "adi,rdvel", GPIOD_OUT_LOW);
	if (IS_ERR(st->rdvel)) {
		dev_err(&spi->dev, "Failed to claim RDVEL gpio: err=%ld\n",
			PTR_ERR(st->rdvel));
		return PTR_ERR(st->rdvel);
	}

	indio_dev->dev.parent = &spi->dev;
	indio_dev->info = &ad2s1200_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = ad2s1200_channels;
	indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels);
	indio_dev->name = spi_get_device_id(spi)->name;

	spi->max_speed_hz = AD2S1200_HZ;
	spi->mode = SPI_MODE_3;
	ret = spi_setup(spi);

	if (ret < 0) {
		dev_err(&spi->dev, "spi_setup failed!\n");
		return ret;
	}

	return devm_iio_device_register(&spi->dev, indio_dev);
}

static const struct of_device_id ad2s1200_of_match[] = {
	{ .compatible = "adi,ad2s1200", },
	{ .compatible = "adi,ad2s1205", },
	{ }
};
MODULE_DEVICE_TABLE(of, ad2s1200_of_match);

static const struct spi_device_id ad2s1200_id[] = {
	{ "ad2s1200" },
	{ "ad2s1205" },
	{}
};
MODULE_DEVICE_TABLE(spi, ad2s1200_id);

static struct spi_driver ad2s1200_driver = {
	.driver = {
		.name = DRV_NAME,
		.of_match_table = of_match_ptr(ad2s1200_of_match),
	},
	.probe = ad2s1200_probe,
	.id_table = ad2s1200_id,
};
module_spi_driver(ad2s1200_driver);

MODULE_AUTHOR("David Veenstra <davidjulianveenstra@gmail.com>");
MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>");
MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver");
MODULE_LICENSE("GPL v2");
