/*
 * 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(irq, mx25_tsadc_irq_handler);
	irq_set_handler_data(irq, 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");
