// SPDX-License-Identifier: GPL-2.0
/*
 * RZ/G2L A/D Converter driver
 *
 *  Copyright (c) 2021 Renesas Electronics Europe GmbH
 *
 * Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/reset.h>

#define DRIVER_NAME		"rzg2l-adc"

#define RZG2L_ADM(n)			((n) * 0x4)
#define RZG2L_ADM0_ADCE			BIT(0)
#define RZG2L_ADM0_ADBSY		BIT(1)
#define RZG2L_ADM0_PWDWNB		BIT(2)
#define RZG2L_ADM0_SRESB		BIT(15)
#define RZG2L_ADM1_TRG			BIT(0)
#define RZG2L_ADM1_MS			BIT(2)
#define RZG2L_ADM1_BS			BIT(4)
#define RZG2L_ADM1_EGA_MASK		GENMASK(13, 12)
#define RZG2L_ADM2_CHSEL_MASK		GENMASK(7, 0)
#define RZG2L_ADM3_ADIL_MASK		GENMASK(31, 24)
#define RZG2L_ADM3_ADCMP_MASK		GENMASK(23, 16)
#define RZG2L_ADM3_ADCMP_E		FIELD_PREP(RZG2L_ADM3_ADCMP_MASK, 0xe)
#define RZG2L_ADM3_ADSMP_MASK		GENMASK(15, 0)

#define RZG2L_ADINT			0x20
#define RZG2L_ADINT_INTEN_MASK		GENMASK(7, 0)
#define RZG2L_ADINT_CSEEN		BIT(16)
#define RZG2L_ADINT_INTS		BIT(31)

#define RZG2L_ADSTS			0x24
#define RZG2L_ADSTS_CSEST		BIT(16)
#define RZG2L_ADSTS_INTST_MASK		GENMASK(7, 0)

#define RZG2L_ADIVC			0x28
#define RZG2L_ADIVC_DIVADC_MASK		GENMASK(8, 0)
#define RZG2L_ADIVC_DIVADC_4		FIELD_PREP(RZG2L_ADIVC_DIVADC_MASK, 0x4)

#define RZG2L_ADFIL			0x2c

#define RZG2L_ADCR(n)			(0x30 + ((n) * 0x4))
#define RZG2L_ADCR_AD_MASK		GENMASK(11, 0)

#define RZG2L_ADSMP_DEFAULT_SAMPLING	0x578

#define RZG2L_ADC_MAX_CHANNELS		8
#define RZG2L_ADC_CHN_MASK		0x7
#define RZG2L_ADC_TIMEOUT		usecs_to_jiffies(1 * 4)

struct rzg2l_adc_data {
	const struct iio_chan_spec *channels;
	u8 num_channels;
};

struct rzg2l_adc {
	void __iomem *base;
	struct clk *pclk;
	struct clk *adclk;
	struct reset_control *presetn;
	struct reset_control *adrstn;
	struct completion completion;
	const struct rzg2l_adc_data *data;
	struct mutex lock;
	u16 last_val[RZG2L_ADC_MAX_CHANNELS];
};

static const char * const rzg2l_adc_channel_name[] = {
	"adc0",
	"adc1",
	"adc2",
	"adc3",
	"adc4",
	"adc5",
	"adc6",
	"adc7",
};

static unsigned int rzg2l_adc_readl(struct rzg2l_adc *adc, u32 reg)
{
	return readl(adc->base + reg);
}

static void rzg2l_adc_writel(struct rzg2l_adc *adc, unsigned int reg, u32 val)
{
	writel(val, adc->base + reg);
}

static void rzg2l_adc_pwr(struct rzg2l_adc *adc, bool on)
{
	u32 reg;

	reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
	if (on)
		reg |= RZG2L_ADM0_PWDWNB;
	else
		reg &= ~RZG2L_ADM0_PWDWNB;
	rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);
	udelay(2);
}

static void rzg2l_adc_start_stop(struct rzg2l_adc *adc, bool start)
{
	int timeout = 5;
	u32 reg;

	reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
	if (start)
		reg |= RZG2L_ADM0_ADCE;
	else
		reg &= ~RZG2L_ADM0_ADCE;
	rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);

	if (start)
		return;

	do {
		usleep_range(100, 200);
		reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
		timeout--;
		if (!timeout) {
			pr_err("%s stopping ADC timed out\n", __func__);
			break;
		}
	} while (((reg & RZG2L_ADM0_ADBSY) || (reg & RZG2L_ADM0_ADCE)));
}

static void rzg2l_set_trigger(struct rzg2l_adc *adc)
{
	u32 reg;

	/*
	 * Setup ADM1 for SW trigger
	 * EGA[13:12] - Set 00 to indicate hardware trigger is invalid
	 * BS[4] - Enable 1-buffer mode
	 * MS[1] - Enable Select mode
	 * TRG[0] - Enable software trigger mode
	 */
	reg = rzg2l_adc_readl(adc, RZG2L_ADM(1));
	reg &= ~RZG2L_ADM1_EGA_MASK;
	reg &= ~RZG2L_ADM1_BS;
	reg &= ~RZG2L_ADM1_TRG;
	reg |= RZG2L_ADM1_MS;
	rzg2l_adc_writel(adc, RZG2L_ADM(1), reg);
}

static int rzg2l_adc_conversion_setup(struct rzg2l_adc *adc, u8 ch)
{
	u32 reg;

	if (rzg2l_adc_readl(adc, RZG2L_ADM(0)) & RZG2L_ADM0_ADBSY)
		return -EBUSY;

	rzg2l_set_trigger(adc);

	/* Select analog input channel subjected to conversion. */
	reg = rzg2l_adc_readl(adc, RZG2L_ADM(2));
	reg &= ~RZG2L_ADM2_CHSEL_MASK;
	reg |= BIT(ch);
	rzg2l_adc_writel(adc, RZG2L_ADM(2), reg);

	/*
	 * Setup ADINT
	 * INTS[31] - Select pulse signal
	 * CSEEN[16] - Enable channel select error interrupt
	 * INTEN[7:0] - Select channel interrupt
	 */
	reg = rzg2l_adc_readl(adc, RZG2L_ADINT);
	reg &= ~RZG2L_ADINT_INTS;
	reg &= ~RZG2L_ADINT_INTEN_MASK;
	reg |= (RZG2L_ADINT_CSEEN | BIT(ch));
	rzg2l_adc_writel(adc, RZG2L_ADINT, reg);

	return 0;
}

static int rzg2l_adc_set_power(struct iio_dev *indio_dev, bool on)
{
	struct device *dev = indio_dev->dev.parent;

	if (on)
		return pm_runtime_resume_and_get(dev);

	return pm_runtime_put_sync(dev);
}

static int rzg2l_adc_conversion(struct iio_dev *indio_dev, struct rzg2l_adc *adc, u8 ch)
{
	int ret;

	ret = rzg2l_adc_set_power(indio_dev, true);
	if (ret)
		return ret;

	ret = rzg2l_adc_conversion_setup(adc, ch);
	if (ret) {
		rzg2l_adc_set_power(indio_dev, false);
		return ret;
	}

	reinit_completion(&adc->completion);

	rzg2l_adc_start_stop(adc, true);

	if (!wait_for_completion_timeout(&adc->completion, RZG2L_ADC_TIMEOUT)) {
		rzg2l_adc_writel(adc, RZG2L_ADINT,
				 rzg2l_adc_readl(adc, RZG2L_ADINT) & ~RZG2L_ADINT_INTEN_MASK);
		rzg2l_adc_start_stop(adc, false);
		rzg2l_adc_set_power(indio_dev, false);
		return -ETIMEDOUT;
	}

	return rzg2l_adc_set_power(indio_dev, false);
}

static int rzg2l_adc_read_raw(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan,
			      int *val, int *val2, long mask)
{
	struct rzg2l_adc *adc = iio_priv(indio_dev);
	int ret;
	u8 ch;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (chan->type != IIO_VOLTAGE)
			return -EINVAL;

		mutex_lock(&adc->lock);
		ch = chan->channel & RZG2L_ADC_CHN_MASK;
		ret = rzg2l_adc_conversion(indio_dev, adc, ch);
		if (ret) {
			mutex_unlock(&adc->lock);
			return ret;
		}
		*val = adc->last_val[ch];
		mutex_unlock(&adc->lock);

		return IIO_VAL_INT;

	default:
		return -EINVAL;
	}
}

static int rzg2l_adc_read_label(struct iio_dev *iio_dev,
				const struct iio_chan_spec *chan,
				char *label)
{
	return sysfs_emit(label, "%s\n", rzg2l_adc_channel_name[chan->channel]);
}

static const struct iio_info rzg2l_adc_iio_info = {
	.read_raw = rzg2l_adc_read_raw,
	.read_label = rzg2l_adc_read_label,
};

static irqreturn_t rzg2l_adc_isr(int irq, void *dev_id)
{
	struct rzg2l_adc *adc = dev_id;
	unsigned long intst;
	u32 reg;
	int ch;

	reg = rzg2l_adc_readl(adc, RZG2L_ADSTS);

	/* A/D conversion channel select error interrupt */
	if (reg & RZG2L_ADSTS_CSEST) {
		rzg2l_adc_writel(adc, RZG2L_ADSTS, reg);
		return IRQ_HANDLED;
	}

	intst = reg & RZG2L_ADSTS_INTST_MASK;
	if (!intst)
		return IRQ_NONE;

	for_each_set_bit(ch, &intst, RZG2L_ADC_MAX_CHANNELS)
		adc->last_val[ch] = rzg2l_adc_readl(adc, RZG2L_ADCR(ch)) & RZG2L_ADCR_AD_MASK;

	/* clear the channel interrupt */
	rzg2l_adc_writel(adc, RZG2L_ADSTS, reg);

	complete(&adc->completion);

	return IRQ_HANDLED;
}

static int rzg2l_adc_parse_properties(struct platform_device *pdev, struct rzg2l_adc *adc)
{
	struct iio_chan_spec *chan_array;
	struct fwnode_handle *fwnode;
	struct rzg2l_adc_data *data;
	unsigned int channel;
	int num_channels;
	int ret;
	u8 i;

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	num_channels = device_get_child_node_count(&pdev->dev);
	if (!num_channels) {
		dev_err(&pdev->dev, "no channel children\n");
		return -ENODEV;
	}

	if (num_channels > RZG2L_ADC_MAX_CHANNELS) {
		dev_err(&pdev->dev, "num of channel children out of range\n");
		return -EINVAL;
	}

	chan_array = devm_kcalloc(&pdev->dev, num_channels, sizeof(*chan_array),
				  GFP_KERNEL);
	if (!chan_array)
		return -ENOMEM;

	i = 0;
	device_for_each_child_node(&pdev->dev, fwnode) {
		ret = fwnode_property_read_u32(fwnode, "reg", &channel);
		if (ret) {
			fwnode_handle_put(fwnode);
			return ret;
		}

		if (channel >= RZG2L_ADC_MAX_CHANNELS) {
			fwnode_handle_put(fwnode);
			return -EINVAL;
		}

		chan_array[i].type = IIO_VOLTAGE;
		chan_array[i].indexed = 1;
		chan_array[i].channel = channel;
		chan_array[i].info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
		chan_array[i].datasheet_name = rzg2l_adc_channel_name[channel];
		i++;
	}

	data->num_channels = num_channels;
	data->channels = chan_array;
	adc->data = data;

	return 0;
}

static int rzg2l_adc_hw_init(struct rzg2l_adc *adc)
{
	int timeout = 5;
	u32 reg;
	int ret;

	ret = clk_prepare_enable(adc->pclk);
	if (ret)
		return ret;

	/* SW reset */
	reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
	reg |= RZG2L_ADM0_SRESB;
	rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);

	while (!(rzg2l_adc_readl(adc, RZG2L_ADM(0)) & RZG2L_ADM0_SRESB)) {
		if (!timeout) {
			ret = -EBUSY;
			goto exit_hw_init;
		}
		timeout--;
		usleep_range(100, 200);
	}

	/* Only division by 4 can be set */
	reg = rzg2l_adc_readl(adc, RZG2L_ADIVC);
	reg &= ~RZG2L_ADIVC_DIVADC_MASK;
	reg |= RZG2L_ADIVC_DIVADC_4;
	rzg2l_adc_writel(adc, RZG2L_ADIVC, reg);

	/*
	 * Setup AMD3
	 * ADIL[31:24] - Should be always set to 0
	 * ADCMP[23:16] - Should be always set to 0xe
	 * ADSMP[15:0] - Set default (0x578) sampling period
	 */
	reg = rzg2l_adc_readl(adc, RZG2L_ADM(3));
	reg &= ~RZG2L_ADM3_ADIL_MASK;
	reg &= ~RZG2L_ADM3_ADCMP_MASK;
	reg &= ~RZG2L_ADM3_ADSMP_MASK;
	reg |= (RZG2L_ADM3_ADCMP_E | RZG2L_ADSMP_DEFAULT_SAMPLING);
	rzg2l_adc_writel(adc, RZG2L_ADM(3), reg);

exit_hw_init:
	clk_disable_unprepare(adc->pclk);

	return ret;
}

static void rzg2l_adc_pm_runtime_disable(void *data)
{
	struct device *dev = data;

	pm_runtime_disable(dev->parent);
}

static void rzg2l_adc_pm_runtime_set_suspended(void *data)
{
	struct device *dev = data;

	pm_runtime_set_suspended(dev->parent);
}

static void rzg2l_adc_reset_assert(void *data)
{
	reset_control_assert(data);
}

static int rzg2l_adc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct iio_dev *indio_dev;
	struct rzg2l_adc *adc;
	int ret;
	int irq;

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

	adc = iio_priv(indio_dev);

	ret = rzg2l_adc_parse_properties(pdev, adc);
	if (ret)
		return ret;

	mutex_init(&adc->lock);

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

	adc->pclk = devm_clk_get(dev, "pclk");
	if (IS_ERR(adc->pclk)) {
		dev_err(dev, "Failed to get pclk");
		return PTR_ERR(adc->pclk);
	}

	adc->adclk = devm_clk_get(dev, "adclk");
	if (IS_ERR(adc->adclk)) {
		dev_err(dev, "Failed to get adclk");
		return PTR_ERR(adc->adclk);
	}

	adc->adrstn = devm_reset_control_get_exclusive(dev, "adrst-n");
	if (IS_ERR(adc->adrstn)) {
		dev_err(dev, "failed to get adrstn\n");
		return PTR_ERR(adc->adrstn);
	}

	adc->presetn = devm_reset_control_get_exclusive(dev, "presetn");
	if (IS_ERR(adc->presetn)) {
		dev_err(dev, "failed to get presetn\n");
		return PTR_ERR(adc->presetn);
	}

	ret = reset_control_deassert(adc->adrstn);
	if (ret) {
		dev_err(&pdev->dev, "failed to deassert adrstn pin, %d\n", ret);
		return ret;
	}

	ret = devm_add_action_or_reset(&pdev->dev,
				       rzg2l_adc_reset_assert, adc->adrstn);
	if (ret) {
		dev_err(&pdev->dev, "failed to register adrstn assert devm action, %d\n",
			ret);
		return ret;
	}

	ret = reset_control_deassert(adc->presetn);
	if (ret) {
		dev_err(&pdev->dev, "failed to deassert presetn pin, %d\n", ret);
		return ret;
	}

	ret = devm_add_action_or_reset(&pdev->dev,
				       rzg2l_adc_reset_assert, adc->presetn);
	if (ret) {
		dev_err(&pdev->dev, "failed to register presetn assert devm action, %d\n",
			ret);
		return ret;
	}

	ret = rzg2l_adc_hw_init(adc);
	if (ret) {
		dev_err(&pdev->dev, "failed to initialize ADC HW, %d\n", ret);
		return ret;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	ret = devm_request_irq(dev, irq, rzg2l_adc_isr,
			       0, dev_name(dev), adc);
	if (ret < 0)
		return ret;

	init_completion(&adc->completion);

	platform_set_drvdata(pdev, indio_dev);

	indio_dev->name = DRIVER_NAME;
	indio_dev->info = &rzg2l_adc_iio_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = adc->data->channels;
	indio_dev->num_channels = adc->data->num_channels;

	pm_runtime_set_suspended(dev);
	ret = devm_add_action_or_reset(&pdev->dev,
				       rzg2l_adc_pm_runtime_set_suspended, &indio_dev->dev);
	if (ret)
		return ret;

	pm_runtime_enable(dev);
	ret = devm_add_action_or_reset(&pdev->dev,
				       rzg2l_adc_pm_runtime_disable, &indio_dev->dev);
	if (ret)
		return ret;

	return devm_iio_device_register(dev, indio_dev);
}

static const struct of_device_id rzg2l_adc_match[] = {
	{ .compatible = "renesas,rzg2l-adc",},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rzg2l_adc_match);

static int __maybe_unused rzg2l_adc_pm_runtime_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct rzg2l_adc *adc = iio_priv(indio_dev);

	rzg2l_adc_pwr(adc, false);
	clk_disable_unprepare(adc->adclk);
	clk_disable_unprepare(adc->pclk);

	return 0;
}

static int __maybe_unused rzg2l_adc_pm_runtime_resume(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct rzg2l_adc *adc = iio_priv(indio_dev);
	int ret;

	ret = clk_prepare_enable(adc->pclk);
	if (ret)
		return ret;

	ret = clk_prepare_enable(adc->adclk);
	if (ret) {
		clk_disable_unprepare(adc->pclk);
		return ret;
	}

	rzg2l_adc_pwr(adc, true);

	return 0;
}

static const struct dev_pm_ops rzg2l_adc_pm_ops = {
	SET_RUNTIME_PM_OPS(rzg2l_adc_pm_runtime_suspend,
			   rzg2l_adc_pm_runtime_resume,
			   NULL)
};

static struct platform_driver rzg2l_adc_driver = {
	.probe		= rzg2l_adc_probe,
	.driver		= {
		.name		= DRIVER_NAME,
		.of_match_table = rzg2l_adc_match,
		.pm		= &rzg2l_adc_pm_ops,
	},
};

module_platform_driver(rzg2l_adc_driver);

MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
MODULE_DESCRIPTION("Renesas RZ/G2L ADC driver");
MODULE_LICENSE("GPL v2");
