// SPDX-License-Identifier: GPL-2.0
/*
 * ADC driver for the Ingenic JZ47xx SoCs
 * Copyright (c) 2019 Artur Rojek <contact@artur-rojek.eu>
 *
 * based on drivers/mfd/jz4740-adc.c
 */

#include <dt-bindings/iio/adc/ingenic,adc.h>
#include <linux/clk.h>
#include <linux/iio/iio.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>

#define JZ_ADC_REG_ENABLE		0x00
#define JZ_ADC_REG_CFG			0x04
#define JZ_ADC_REG_CTRL			0x08
#define JZ_ADC_REG_STATUS		0x0c
#define JZ_ADC_REG_ADTCH		0x18
#define JZ_ADC_REG_ADBDAT		0x1c
#define JZ_ADC_REG_ADSDAT		0x20
#define JZ_ADC_REG_ADCLK		0x28

#define JZ_ADC_REG_ENABLE_PD		BIT(7)
#define JZ_ADC_REG_CFG_AUX_MD		(BIT(0) | BIT(1))
#define JZ_ADC_REG_CFG_BAT_MD		BIT(4)
#define JZ_ADC_REG_ADCLK_CLKDIV_LSB	0
#define JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB	16
#define JZ4770_ADC_REG_ADCLK_CLKDIV10US_LSB	8
#define JZ4770_ADC_REG_ADCLK_CLKDIVMS_LSB	16

#define JZ_ADC_AUX_VREF				3300
#define JZ_ADC_AUX_VREF_BITS			12
#define JZ_ADC_BATTERY_LOW_VREF			2500
#define JZ_ADC_BATTERY_LOW_VREF_BITS		12
#define JZ4725B_ADC_BATTERY_HIGH_VREF		7500
#define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS	10
#define JZ4740_ADC_BATTERY_HIGH_VREF		(7500 * 0.986)
#define JZ4740_ADC_BATTERY_HIGH_VREF_BITS	12
#define JZ4770_ADC_BATTERY_VREF			6600
#define JZ4770_ADC_BATTERY_VREF_BITS		12

struct ingenic_adc;

struct ingenic_adc_soc_data {
	unsigned int battery_high_vref;
	unsigned int battery_high_vref_bits;
	const int *battery_raw_avail;
	size_t battery_raw_avail_size;
	const int *battery_scale_avail;
	size_t battery_scale_avail_size;
	unsigned int battery_vref_mode: 1;
	unsigned int has_aux2: 1;
	int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);
};

struct ingenic_adc {
	void __iomem *base;
	struct clk *clk;
	struct mutex lock;
	struct mutex aux_lock;
	const struct ingenic_adc_soc_data *soc_data;
	bool low_vref_mode;
};

static void ingenic_adc_set_config(struct ingenic_adc *adc,
				   uint32_t mask,
				   uint32_t val)
{
	uint32_t cfg;

	clk_enable(adc->clk);
	mutex_lock(&adc->lock);

	cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask;
	cfg |= val;
	writel(cfg, adc->base + JZ_ADC_REG_CFG);

	mutex_unlock(&adc->lock);
	clk_disable(adc->clk);
}

static void ingenic_adc_enable(struct ingenic_adc *adc,
			       int engine,
			       bool enabled)
{
	u8 val;

	mutex_lock(&adc->lock);
	val = readb(adc->base + JZ_ADC_REG_ENABLE);

	if (enabled)
		val |= BIT(engine);
	else
		val &= ~BIT(engine);

	writeb(val, adc->base + JZ_ADC_REG_ENABLE);
	mutex_unlock(&adc->lock);
}

static int ingenic_adc_capture(struct ingenic_adc *adc,
			       int engine)
{
	u8 val;
	int ret;

	ingenic_adc_enable(adc, engine, true);
	ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val,
				 !(val & BIT(engine)), 250, 1000);
	if (ret)
		ingenic_adc_enable(adc, engine, false);

	return ret;
}

static int ingenic_adc_write_raw(struct iio_dev *iio_dev,
				 struct iio_chan_spec const *chan,
				 int val,
				 int val2,
				 long m)
{
	struct ingenic_adc *adc = iio_priv(iio_dev);

	switch (m) {
	case IIO_CHAN_INFO_SCALE:
		switch (chan->channel) {
		case INGENIC_ADC_BATTERY:
			if (!adc->soc_data->battery_vref_mode)
				return -EINVAL;
			if (val > JZ_ADC_BATTERY_LOW_VREF) {
				ingenic_adc_set_config(adc,
						       JZ_ADC_REG_CFG_BAT_MD,
						       0);
				adc->low_vref_mode = false;
			} else {
				ingenic_adc_set_config(adc,
						       JZ_ADC_REG_CFG_BAT_MD,
						       JZ_ADC_REG_CFG_BAT_MD);
				adc->low_vref_mode = true;
			}
			return 0;
		default:
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

static const int jz4725b_adc_battery_raw_avail[] = {
	0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
};

static const int jz4725b_adc_battery_scale_avail[] = {
	JZ4725B_ADC_BATTERY_HIGH_VREF, JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,
	JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
};

static const int jz4740_adc_battery_raw_avail[] = {
	0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
};

static const int jz4740_adc_battery_scale_avail[] = {
	JZ4740_ADC_BATTERY_HIGH_VREF, JZ4740_ADC_BATTERY_HIGH_VREF_BITS,
	JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
};

static const int jz4770_adc_battery_raw_avail[] = {
	0, 1, (1 << JZ4770_ADC_BATTERY_VREF_BITS) - 1,
};

static const int jz4770_adc_battery_scale_avail[] = {
	JZ4770_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,
};

static int jz4725b_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)
{
	struct clk *parent_clk;
	unsigned long parent_rate, rate;
	unsigned int div_main, div_10us;

	parent_clk = clk_get_parent(adc->clk);
	if (!parent_clk) {
		dev_err(dev, "ADC clock has no parent\n");
		return -ENODEV;
	}
	parent_rate = clk_get_rate(parent_clk);

	/*
	 * The JZ4725B ADC works at 500 kHz to 8 MHz.
	 * We pick the highest rate possible.
	 * In practice we typically get 6 MHz, half of the 12 MHz EXT clock.
	 */
	div_main = DIV_ROUND_UP(parent_rate, 8000000);
	div_main = clamp(div_main, 1u, 64u);
	rate = parent_rate / div_main;
	if (rate < 500000 || rate > 8000000) {
		dev_err(dev, "No valid divider for ADC main clock\n");
		return -EINVAL;
	}

	/* We also need a divider that produces a 10us clock. */
	div_10us = DIV_ROUND_UP(rate, 100000);

	writel(((div_10us - 1) << JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB) |
	       (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB,
	       adc->base + JZ_ADC_REG_ADCLK);

	return 0;
}

static int jz4770_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)
{
	struct clk *parent_clk;
	unsigned long parent_rate, rate;
	unsigned int div_main, div_ms, div_10us;

	parent_clk = clk_get_parent(adc->clk);
	if (!parent_clk) {
		dev_err(dev, "ADC clock has no parent\n");
		return -ENODEV;
	}
	parent_rate = clk_get_rate(parent_clk);

	/*
	 * The JZ4770 ADC works at 20 kHz to 200 kHz.
	 * We pick the highest rate possible.
	 */
	div_main = DIV_ROUND_UP(parent_rate, 200000);
	div_main = clamp(div_main, 1u, 256u);
	rate = parent_rate / div_main;
	if (rate < 20000 || rate > 200000) {
		dev_err(dev, "No valid divider for ADC main clock\n");
		return -EINVAL;
	}

	/* We also need a divider that produces a 10us clock. */
	div_10us = DIV_ROUND_UP(rate, 10000);
	/* And another, which produces a 1ms clock. */
	div_ms = DIV_ROUND_UP(rate, 1000);

	writel(((div_ms - 1) << JZ4770_ADC_REG_ADCLK_CLKDIVMS_LSB) |
	       ((div_10us - 1) << JZ4770_ADC_REG_ADCLK_CLKDIV10US_LSB) |
	       (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB,
	       adc->base + JZ_ADC_REG_ADCLK);

	return 0;
}

static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = {
	.battery_high_vref = JZ4725B_ADC_BATTERY_HIGH_VREF,
	.battery_high_vref_bits = JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,
	.battery_raw_avail = jz4725b_adc_battery_raw_avail,
	.battery_raw_avail_size = ARRAY_SIZE(jz4725b_adc_battery_raw_avail),
	.battery_scale_avail = jz4725b_adc_battery_scale_avail,
	.battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail),
	.battery_vref_mode = true,
	.has_aux2 = false,
	.init_clk_div = jz4725b_adc_init_clk_div,
};

static const struct ingenic_adc_soc_data jz4740_adc_soc_data = {
	.battery_high_vref = JZ4740_ADC_BATTERY_HIGH_VREF,
	.battery_high_vref_bits = JZ4740_ADC_BATTERY_HIGH_VREF_BITS,
	.battery_raw_avail = jz4740_adc_battery_raw_avail,
	.battery_raw_avail_size = ARRAY_SIZE(jz4740_adc_battery_raw_avail),
	.battery_scale_avail = jz4740_adc_battery_scale_avail,
	.battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail),
	.battery_vref_mode = true,
	.has_aux2 = false,
	.init_clk_div = NULL, /* no ADCLK register on JZ4740 */
};

static const struct ingenic_adc_soc_data jz4770_adc_soc_data = {
	.battery_high_vref = JZ4770_ADC_BATTERY_VREF,
	.battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
	.battery_raw_avail = jz4770_adc_battery_raw_avail,
	.battery_raw_avail_size = ARRAY_SIZE(jz4770_adc_battery_raw_avail),
	.battery_scale_avail = jz4770_adc_battery_scale_avail,
	.battery_scale_avail_size = ARRAY_SIZE(jz4770_adc_battery_scale_avail),
	.battery_vref_mode = false,
	.has_aux2 = true,
	.init_clk_div = jz4770_adc_init_clk_div,
};

static int ingenic_adc_read_avail(struct iio_dev *iio_dev,
				  struct iio_chan_spec const *chan,
				  const int **vals,
				  int *type,
				  int *length,
				  long m)
{
	struct ingenic_adc *adc = iio_priv(iio_dev);

	switch (m) {
	case IIO_CHAN_INFO_RAW:
		*type = IIO_VAL_INT;
		*length = adc->soc_data->battery_raw_avail_size;
		*vals = adc->soc_data->battery_raw_avail;
		return IIO_AVAIL_RANGE;
	case IIO_CHAN_INFO_SCALE:
		*type = IIO_VAL_FRACTIONAL_LOG2;
		*length = adc->soc_data->battery_scale_avail_size;
		*vals = adc->soc_data->battery_scale_avail;
		return IIO_AVAIL_LIST;
	default:
		return -EINVAL;
	};
}

static int ingenic_adc_read_chan_info_raw(struct ingenic_adc *adc,
					  struct iio_chan_spec const *chan,
					  int *val)
{
	int bit, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);

	/* We cannot sample AUX/AUX2 in parallel. */
	mutex_lock(&adc->aux_lock);
	if (adc->soc_data->has_aux2 && engine == 0) {
		bit = BIT(chan->channel == INGENIC_ADC_AUX2);
		ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, bit);
	}

	clk_enable(adc->clk);
	ret = ingenic_adc_capture(adc, engine);
	if (ret)
		goto out;

	switch (chan->channel) {
	case INGENIC_ADC_AUX:
	case INGENIC_ADC_AUX2:
		*val = readw(adc->base + JZ_ADC_REG_ADSDAT);
		break;
	case INGENIC_ADC_BATTERY:
		*val = readw(adc->base + JZ_ADC_REG_ADBDAT);
		break;
	}

	ret = IIO_VAL_INT;
out:
	clk_disable(adc->clk);
	mutex_unlock(&adc->aux_lock);

	return ret;
}

static int ingenic_adc_read_raw(struct iio_dev *iio_dev,
				struct iio_chan_spec const *chan,
				int *val,
				int *val2,
				long m)
{
	struct ingenic_adc *adc = iio_priv(iio_dev);

	switch (m) {
	case IIO_CHAN_INFO_RAW:
		return ingenic_adc_read_chan_info_raw(adc, chan, val);
	case IIO_CHAN_INFO_SCALE:
		switch (chan->channel) {
		case INGENIC_ADC_AUX:
		case INGENIC_ADC_AUX2:
			*val = JZ_ADC_AUX_VREF;
			*val2 = JZ_ADC_AUX_VREF_BITS;
			break;
		case INGENIC_ADC_BATTERY:
			if (adc->low_vref_mode) {
				*val = JZ_ADC_BATTERY_LOW_VREF;
				*val2 = JZ_ADC_BATTERY_LOW_VREF_BITS;
			} else {
				*val = adc->soc_data->battery_high_vref;
				*val2 = adc->soc_data->battery_high_vref_bits;
			}
			break;
		}

		return IIO_VAL_FRACTIONAL_LOG2;
	default:
		return -EINVAL;
	}
}

static void ingenic_adc_clk_cleanup(void *data)
{
	clk_unprepare(data);
}

static const struct iio_info ingenic_adc_info = {
	.write_raw = ingenic_adc_write_raw,
	.read_raw = ingenic_adc_read_raw,
	.read_avail = ingenic_adc_read_avail,
};

static const struct iio_chan_spec ingenic_channels[] = {
	{
		.extend_name = "aux",
		.type = IIO_VOLTAGE,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.indexed = 1,
		.channel = INGENIC_ADC_AUX,
	},
	{
		.extend_name = "battery",
		.type = IIO_VOLTAGE,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
						BIT(IIO_CHAN_INFO_SCALE),
		.indexed = 1,
		.channel = INGENIC_ADC_BATTERY,
	},
	{ /* Must always be last in the array. */
		.extend_name = "aux2",
		.type = IIO_VOLTAGE,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.indexed = 1,
		.channel = INGENIC_ADC_AUX2,
	},
};

static int ingenic_adc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct iio_dev *iio_dev;
	struct ingenic_adc *adc;
	const struct ingenic_adc_soc_data *soc_data;
	int ret;

	soc_data = device_get_match_data(dev);
	if (!soc_data)
		return -EINVAL;

	iio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
	if (!iio_dev)
		return -ENOMEM;

	adc = iio_priv(iio_dev);
	mutex_init(&adc->lock);
	mutex_init(&adc->aux_lock);
	adc->soc_data = soc_data;

	adc->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(adc->base))
		return PTR_ERR(adc->base);

	adc->clk = devm_clk_get(dev, "adc");
	if (IS_ERR(adc->clk)) {
		dev_err(dev, "Unable to get clock\n");
		return PTR_ERR(adc->clk);
	}

	ret = clk_prepare_enable(adc->clk);
	if (ret) {
		dev_err(dev, "Failed to enable clock\n");
		return ret;
	}

	/* Set clock dividers. */
	if (soc_data->init_clk_div) {
		ret = soc_data->init_clk_div(dev, adc);
		if (ret) {
			clk_disable_unprepare(adc->clk);
			return ret;
		}
	}

	/* Put hardware in a known passive state. */
	writeb(0x00, adc->base + JZ_ADC_REG_ENABLE);
	writeb(0xff, adc->base + JZ_ADC_REG_CTRL);
	usleep_range(2000, 3000); /* Must wait at least 2ms. */
	clk_disable(adc->clk);

	ret = devm_add_action_or_reset(dev, ingenic_adc_clk_cleanup, adc->clk);
	if (ret) {
		dev_err(dev, "Unable to add action\n");
		return ret;
	}

	iio_dev->dev.parent = dev;
	iio_dev->name = "jz-adc";
	iio_dev->modes = INDIO_DIRECT_MODE;
	iio_dev->channels = ingenic_channels;
	iio_dev->num_channels = ARRAY_SIZE(ingenic_channels);
	/* Remove AUX2 from the list of supported channels. */
	if (!adc->soc_data->has_aux2)
		iio_dev->num_channels -= 1;
	iio_dev->info = &ingenic_adc_info;

	ret = devm_iio_device_register(dev, iio_dev);
	if (ret)
		dev_err(dev, "Unable to register IIO device\n");

	return ret;
}

#ifdef CONFIG_OF
static const struct of_device_id ingenic_adc_of_match[] = {
	{ .compatible = "ingenic,jz4725b-adc", .data = &jz4725b_adc_soc_data, },
	{ .compatible = "ingenic,jz4740-adc", .data = &jz4740_adc_soc_data, },
	{ .compatible = "ingenic,jz4770-adc", .data = &jz4770_adc_soc_data, },
	{ },
};
MODULE_DEVICE_TABLE(of, ingenic_adc_of_match);
#endif

static struct platform_driver ingenic_adc_driver = {
	.driver = {
		.name = "ingenic-adc",
		.of_match_table = of_match_ptr(ingenic_adc_of_match),
	},
	.probe = ingenic_adc_probe,
};
module_platform_driver(ingenic_adc_driver);
MODULE_LICENSE("GPL v2");
