/*
 * Freescale MXS Low Resolution Analog-to-Digital Converter driver
 *
 * Copyright (c) 2012 DENX Software Engineering, GmbH.
 * Copyright (c) 2017 Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
 *
 * Authors:
 *  Marek Vasut <marex@denx.de>
 *  Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 */

#include <linux/clk.h>
#include <linux/device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/mxs-lradc.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#define ADC_CELL		0
#define TSC_CELL		1
#define RES_MEM			0

enum mx23_lradc_irqs {
	MX23_LRADC_TS_IRQ = 0,
	MX23_LRADC_CH0_IRQ,
	MX23_LRADC_CH1_IRQ,
	MX23_LRADC_CH2_IRQ,
	MX23_LRADC_CH3_IRQ,
	MX23_LRADC_CH4_IRQ,
	MX23_LRADC_CH5_IRQ,
	MX23_LRADC_CH6_IRQ,
	MX23_LRADC_CH7_IRQ,
};

enum mx28_lradc_irqs {
	MX28_LRADC_TS_IRQ = 0,
	MX28_LRADC_TRESH0_IRQ,
	MX28_LRADC_TRESH1_IRQ,
	MX28_LRADC_CH0_IRQ,
	MX28_LRADC_CH1_IRQ,
	MX28_LRADC_CH2_IRQ,
	MX28_LRADC_CH3_IRQ,
	MX28_LRADC_CH4_IRQ,
	MX28_LRADC_CH5_IRQ,
	MX28_LRADC_CH6_IRQ,
	MX28_LRADC_CH7_IRQ,
	MX28_LRADC_BUTTON0_IRQ,
	MX28_LRADC_BUTTON1_IRQ,
};

static struct resource mx23_adc_resources[] = {
	DEFINE_RES_MEM(0x0, 0x0),
	DEFINE_RES_IRQ_NAMED(MX23_LRADC_CH0_IRQ, "mxs-lradc-channel0"),
	DEFINE_RES_IRQ_NAMED(MX23_LRADC_CH1_IRQ, "mxs-lradc-channel1"),
	DEFINE_RES_IRQ_NAMED(MX23_LRADC_CH2_IRQ, "mxs-lradc-channel2"),
	DEFINE_RES_IRQ_NAMED(MX23_LRADC_CH3_IRQ, "mxs-lradc-channel3"),
	DEFINE_RES_IRQ_NAMED(MX23_LRADC_CH4_IRQ, "mxs-lradc-channel4"),
	DEFINE_RES_IRQ_NAMED(MX23_LRADC_CH5_IRQ, "mxs-lradc-channel5"),
};

static struct resource mx23_touchscreen_resources[] = {
	DEFINE_RES_MEM(0x0, 0x0),
	DEFINE_RES_IRQ_NAMED(MX23_LRADC_TS_IRQ, "mxs-lradc-touchscreen"),
	DEFINE_RES_IRQ_NAMED(MX23_LRADC_CH6_IRQ, "mxs-lradc-channel6"),
	DEFINE_RES_IRQ_NAMED(MX23_LRADC_CH7_IRQ, "mxs-lradc-channel7"),
};

static struct resource mx28_adc_resources[] = {
	DEFINE_RES_MEM(0x0, 0x0),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_TRESH0_IRQ, "mxs-lradc-thresh0"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_TRESH1_IRQ, "mxs-lradc-thresh1"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_CH0_IRQ, "mxs-lradc-channel0"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_CH1_IRQ, "mxs-lradc-channel1"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_CH2_IRQ, "mxs-lradc-channel2"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_CH3_IRQ, "mxs-lradc-channel3"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_CH4_IRQ, "mxs-lradc-channel4"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_CH5_IRQ, "mxs-lradc-channel5"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_BUTTON0_IRQ, "mxs-lradc-button0"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_BUTTON1_IRQ, "mxs-lradc-button1"),
};

static struct resource mx28_touchscreen_resources[] = {
	DEFINE_RES_MEM(0x0, 0x0),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_TS_IRQ, "mxs-lradc-touchscreen"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_CH6_IRQ, "mxs-lradc-channel6"),
	DEFINE_RES_IRQ_NAMED(MX28_LRADC_CH7_IRQ, "mxs-lradc-channel7"),
};

static struct mfd_cell mx23_cells[] = {
	{
		.name = "mxs-lradc-adc",
		.resources = mx23_adc_resources,
		.num_resources = ARRAY_SIZE(mx23_adc_resources),
	},
	{
		.name = "mxs-lradc-ts",
		.resources = mx23_touchscreen_resources,
		.num_resources = ARRAY_SIZE(mx23_touchscreen_resources),
	},
};

static struct mfd_cell mx28_cells[] = {
	{
		.name = "mxs-lradc-adc",
		.resources = mx28_adc_resources,
		.num_resources = ARRAY_SIZE(mx28_adc_resources),
	},
	{
		.name = "mxs-lradc-ts",
		.resources = mx28_touchscreen_resources,
		.num_resources = ARRAY_SIZE(mx28_touchscreen_resources),
	}
};

static const struct of_device_id mxs_lradc_dt_ids[] = {
	{ .compatible = "fsl,imx23-lradc", .data = (void *)IMX23_LRADC, },
	{ .compatible = "fsl,imx28-lradc", .data = (void *)IMX28_LRADC, },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids);

static int mxs_lradc_probe(struct platform_device *pdev)
{
	const struct of_device_id *of_id;
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	struct mxs_lradc *lradc;
	struct mfd_cell *cells = NULL;
	struct resource *res;
	int ret = 0;
	u32 ts_wires = 0;

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

	of_id = of_match_device(mxs_lradc_dt_ids, &pdev->dev);
	if (!of_id)
		return -EINVAL;

	lradc->soc = (enum mxs_lradc_id)of_id->data;

	lradc->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(lradc->clk)) {
		dev_err(dev, "Failed to get the delay unit clock\n");
		return PTR_ERR(lradc->clk);
	}

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

	ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
					 &ts_wires);

	if (!ret) {
		lradc->buffer_vchans = BUFFER_VCHANS_LIMITED;

		switch (ts_wires) {
		case 4:
			lradc->touchscreen_wire = MXS_LRADC_TOUCHSCREEN_4WIRE;
			break;
		case 5:
			if (lradc->soc == IMX28_LRADC) {
				lradc->touchscreen_wire =
					MXS_LRADC_TOUCHSCREEN_5WIRE;
				break;
			}
			/* fall through - to an error message for i.MX23 */
		default:
			dev_err(&pdev->dev,
				"Unsupported number of touchscreen wires (%d)\n"
				, ts_wires);
			ret = -EINVAL;
			goto err_clk;
		}
	} else {
		lradc->buffer_vchans = BUFFER_VCHANS_ALL;
	}

	platform_set_drvdata(pdev, lradc);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		ret = -ENOMEM;
		goto err_clk;
	}

	switch (lradc->soc) {
	case IMX23_LRADC:
		mx23_adc_resources[RES_MEM] = *res;
		mx23_touchscreen_resources[RES_MEM] = *res;
		cells = mx23_cells;
		break;
	case IMX28_LRADC:
		mx28_adc_resources[RES_MEM] = *res;
		mx28_touchscreen_resources[RES_MEM] = *res;
		cells = mx28_cells;
		break;
	default:
		dev_err(dev, "Unsupported SoC\n");
		ret = -ENODEV;
		goto err_clk;
	}

	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
				   &cells[ADC_CELL], 1, NULL, 0, NULL);
	if (ret) {
		dev_err(&pdev->dev, "Failed to add the ADC subdevice\n");
		goto err_clk;
	}

	if (!lradc->touchscreen_wire)
		return 0;

	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
				   &cells[TSC_CELL], 1, NULL, 0, NULL);
	if (ret) {
		dev_err(&pdev->dev,
			"Failed to add the touchscreen subdevice\n");
		goto err_clk;
	}

	return 0;

err_clk:
	clk_disable_unprepare(lradc->clk);

	return ret;
}

static int mxs_lradc_remove(struct platform_device *pdev)
{
	struct mxs_lradc *lradc = platform_get_drvdata(pdev);

	clk_disable_unprepare(lradc->clk);

	return 0;
}

static struct platform_driver mxs_lradc_driver = {
	.driver = {
		.name = "mxs-lradc",
		.of_match_table = mxs_lradc_dt_ids,
	},
	.probe = mxs_lradc_probe,
	.remove = mxs_lradc_remove,
};
module_platform_driver(mxs_lradc_driver);

MODULE_AUTHOR("Ksenija Stanojevic <ksenija.stanojevic@gmail.com>");
MODULE_DESCRIPTION("Freescale i.MX23/i.MX28 LRADC driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:mxs-lradc");
