/*
 * Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
 *
 * 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/clk.h>
#include <linux/interrupt.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdesc.h>
#include <linux/irqdomain.h>
#include <linux/irq.h>
#include <linux/mfd/imx25-tsadc.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

static struct regmap_config mx25_tsadc_regmap_config = {
	.fast_io = true,
	.max_register = 8,
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
};

static void mx25_tsadc_irq_handler(struct irq_desc *desc)
{
	struct mx25_tsadc *tsadc = irq_desc_get_handler_data(desc);
	struct irq_chip *chip = irq_desc_get_chip(desc);
	u32 status;

	chained_irq_enter(chip, desc);

	regmap_read(tsadc->regs, MX25_TSC_TGSR, &status);

	if (status & MX25_TGSR_GCQ_INT)
		generic_handle_irq(irq_find_mapping(tsadc->domain, 1));

	if (status & MX25_TGSR_TCQ_INT)
		generic_handle_irq(irq_find_mapping(tsadc->domain, 0));

	chained_irq_exit(chip, desc);
}

static int mx25_tsadc_domain_map(struct irq_domain *d, unsigned int irq,
				 irq_hw_number_t hwirq)
{
	struct mx25_tsadc *tsadc = d->host_data;

	irq_set_chip_data(irq, tsadc);
	irq_set_chip_and_handler(irq, &dummy_irq_chip,
				 handle_level_irq);
	irq_modify_status(irq, IRQ_NOREQUEST, IRQ_NOPROBE);

	return 0;
}

static const struct irq_domain_ops mx25_tsadc_domain_ops = {
	.map = mx25_tsadc_domain_map,
	.xlate = irq_domain_xlate_onecell,
};

static int mx25_tsadc_setup_irq(struct platform_device *pdev,
				struct mx25_tsadc *tsadc)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	int irq;

	irq = platform_get_irq(pdev, 0);
	if (irq <= 0) {
		dev_err(dev, "Failed to get irq\n");
		return irq;
	}

	tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops,
					      tsadc);
	if (!tsadc->domain) {
		dev_err(dev, "Failed to add irq domain\n");
		return -ENOMEM;
	}

	irq_set_chained_handler_and_data(irq, mx25_tsadc_irq_handler, tsadc);

	return 0;
}

static int mx25_tsadc_unset_irq(struct platform_device *pdev)
{
	struct mx25_tsadc *tsadc = platform_get_drvdata(pdev);
	int irq = platform_get_irq(pdev, 0);

	if (irq) {
		irq_set_chained_handler_and_data(irq, NULL, NULL);
		irq_domain_remove(tsadc->domain);
	}

	return 0;
}

static void mx25_tsadc_setup_clk(struct platform_device *pdev,
				 struct mx25_tsadc *tsadc)
{
	unsigned clk_div;

	/*
	 * According to the datasheet the ADC clock should never
	 * exceed 1,75 MHz. Base clock is the IPG and the ADC unit uses
	 * a funny clock divider. To keep the ADC conversion time constant
	 * adapt the ADC internal clock divider to the IPG clock rate.
	 */

	dev_dbg(&pdev->dev, "Found master clock at %lu Hz\n",
		clk_get_rate(tsadc->clk));

	clk_div = DIV_ROUND_UP(clk_get_rate(tsadc->clk), 1750000);
	dev_dbg(&pdev->dev, "Setting up ADC clock divider to %u\n", clk_div);

	/* adc clock = IPG clock / (2 * div + 2) */
	clk_div -= 2;
	clk_div /= 2;

	/*
	 * the ADC clock divider changes its behaviour when values below 4
	 * are used: it is fixed to "/ 10" in this case
	 */
	clk_div = max_t(unsigned, 4, clk_div);

	dev_dbg(&pdev->dev, "Resulting ADC conversion clock at %lu Hz\n",
		clk_get_rate(tsadc->clk) / (2 * clk_div + 2));

	regmap_update_bits(tsadc->regs, MX25_TSC_TGCR,
			   MX25_TGCR_ADCCLKCFG(0x1f),
			   MX25_TGCR_ADCCLKCFG(clk_div));
}

static int mx25_tsadc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct mx25_tsadc *tsadc;
	struct resource *res;
	int ret;
	void __iomem *iomem;

	tsadc = devm_kzalloc(dev, sizeof(*tsadc), GFP_KERNEL);
	if (!tsadc)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	iomem = devm_ioremap_resource(dev, res);
	if (IS_ERR(iomem))
		return PTR_ERR(iomem);

	tsadc->regs = devm_regmap_init_mmio(dev, iomem,
					    &mx25_tsadc_regmap_config);
	if (IS_ERR(tsadc->regs)) {
		dev_err(dev, "Failed to initialize regmap\n");
		return PTR_ERR(tsadc->regs);
	}

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

	/* setup clock according to the datasheet */
	mx25_tsadc_setup_clk(pdev, tsadc);

	/* Enable clock and reset the component */
	regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_CLK_EN,
			   MX25_TGCR_CLK_EN);
	regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_TSC_RST,
			   MX25_TGCR_TSC_RST);

	/* Setup powersaving mode, but enable internal reference voltage */
	regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_POWERMODE_MASK,
			   MX25_TGCR_POWERMODE_SAVE);
	regmap_update_bits(tsadc->regs, MX25_TSC_TGCR, MX25_TGCR_INTREFEN,
			   MX25_TGCR_INTREFEN);

	ret = mx25_tsadc_setup_irq(pdev, tsadc);
	if (ret)
		return ret;

	platform_set_drvdata(pdev, tsadc);

	ret = devm_of_platform_populate(dev);
	if (ret)
		goto err_irq;

	return 0;

err_irq:
	mx25_tsadc_unset_irq(pdev);

	return ret;
}

static int mx25_tsadc_remove(struct platform_device *pdev)
{
	mx25_tsadc_unset_irq(pdev);

	return 0;
}

static const struct of_device_id mx25_tsadc_ids[] = {
	{ .compatible = "fsl,imx25-tsadc" },
	{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, mx25_tsadc_ids);

static struct platform_driver mx25_tsadc_driver = {
	.driver = {
		.name = "mx25-tsadc",
		.of_match_table = of_match_ptr(mx25_tsadc_ids),
	},
	.probe = mx25_tsadc_probe,
	.remove = mx25_tsadc_remove,
};
module_platform_driver(mx25_tsadc_driver);

MODULE_DESCRIPTION("MFD for ADC/TSC for Freescale mx25");
MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:mx25-tsadc");
