/*
 * Dove thermal sensor driver
 *
 * Copyright (C) 2013 Andrew Lunn <andrew@lunn.ch>
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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/device.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>

#define DOVE_THERMAL_TEMP_OFFSET	1
#define DOVE_THERMAL_TEMP_MASK		0x1FF

/* Dove Thermal Manager Control and Status Register */
#define PMU_TM_DISABLE_OFFS		0
#define PMU_TM_DISABLE_MASK		(0x1 << PMU_TM_DISABLE_OFFS)

/* Dove Theraml Diode Control 0 Register */
#define PMU_TDC0_SW_RST_MASK		(0x1 << 1)
#define PMU_TDC0_SEL_VCAL_OFFS		5
#define PMU_TDC0_SEL_VCAL_MASK		(0x3 << PMU_TDC0_SEL_VCAL_OFFS)
#define PMU_TDC0_REF_CAL_CNT_OFFS	11
#define PMU_TDC0_REF_CAL_CNT_MASK	(0x1FF << PMU_TDC0_REF_CAL_CNT_OFFS)
#define PMU_TDC0_AVG_NUM_OFFS		25
#define PMU_TDC0_AVG_NUM_MASK		(0x7 << PMU_TDC0_AVG_NUM_OFFS)

/* Dove Thermal Diode Control 1 Register */
#define PMU_TEMP_DIOD_CTRL1_REG		0x04
#define PMU_TDC1_TEMP_VALID_MASK	(0x1 << 10)

/* Dove Thermal Sensor Dev Structure */
struct dove_thermal_priv {
	void __iomem *sensor;
	void __iomem *control;
};

static int dove_init_sensor(const struct dove_thermal_priv *priv)
{
	u32 reg;
	u32 i;

	/* Configure the Diode Control Register #0 */
	reg = readl_relaxed(priv->control);

	/* Use average of 2 */
	reg &= ~PMU_TDC0_AVG_NUM_MASK;
	reg |= (0x1 << PMU_TDC0_AVG_NUM_OFFS);

	/* Reference calibration value */
	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
	reg |= (0x0F1 << PMU_TDC0_REF_CAL_CNT_OFFS);

	/* Set the high level reference for calibration */
	reg &= ~PMU_TDC0_SEL_VCAL_MASK;
	reg |= (0x2 << PMU_TDC0_SEL_VCAL_OFFS);
	writel(reg, priv->control);

	/* Reset the sensor */
	reg = readl_relaxed(priv->control);
	writel((reg | PMU_TDC0_SW_RST_MASK), priv->control);
	writel(reg, priv->control);

	/* Enable the sensor */
	reg = readl_relaxed(priv->sensor);
	reg &= ~PMU_TM_DISABLE_MASK;
	writel(reg, priv->sensor);

	/* Poll the sensor for the first reading */
	for (i = 0; i < 1000000; i++) {
		reg = readl_relaxed(priv->sensor);
		if (reg & DOVE_THERMAL_TEMP_MASK)
			break;
	}

	if (i == 1000000)
		return -EIO;

	return 0;
}

static int dove_get_temp(struct thermal_zone_device *thermal,
			  unsigned long *temp)
{
	unsigned long reg;
	struct dove_thermal_priv *priv = thermal->devdata;

	/* Valid check */
	reg = readl_relaxed(priv->control + PMU_TEMP_DIOD_CTRL1_REG);
	if ((reg & PMU_TDC1_TEMP_VALID_MASK) == 0x0) {
		dev_err(&thermal->device,
			"Temperature sensor reading not valid\n");
		return -EIO;
	}

	/*
	 * Calculate temperature. See Section 8.10.1 of 88AP510,
	 * Documentation/arm/Marvell/README
	 */
	reg = readl_relaxed(priv->sensor);
	reg = (reg >> DOVE_THERMAL_TEMP_OFFSET) & DOVE_THERMAL_TEMP_MASK;
	*temp = ((2281638UL - (7298*reg)) / 10);

	return 0;
}

static struct thermal_zone_device_ops ops = {
	.get_temp = dove_get_temp,
};

static const struct of_device_id dove_thermal_id_table[] = {
	{ .compatible = "marvell,dove-thermal" },
	{}
};

static int dove_thermal_probe(struct platform_device *pdev)
{
	struct thermal_zone_device *thermal = NULL;
	struct dove_thermal_priv *priv;
	struct resource *res;
	int ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get platform resource\n");
		return -ENODEV;
	}

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

	priv->sensor = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(priv->sensor))
		return PTR_ERR(priv->sensor);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get platform resource\n");
		return -ENODEV;
	}
	priv->control = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(priv->control))
		return PTR_ERR(priv->control);

	ret = dove_init_sensor(priv);
	if (ret) {
		dev_err(&pdev->dev, "Failed to initialize sensor\n");
		return ret;
	}

	thermal = thermal_zone_device_register("dove_thermal", 0, 0,
					       priv, &ops, NULL, 0, 0);
	if (IS_ERR(thermal)) {
		dev_err(&pdev->dev,
			"Failed to register thermal zone device\n");
		return PTR_ERR(thermal);
	}

	platform_set_drvdata(pdev, thermal);

	return 0;
}

static int dove_thermal_exit(struct platform_device *pdev)
{
	struct thermal_zone_device *dove_thermal =
		platform_get_drvdata(pdev);

	thermal_zone_device_unregister(dove_thermal);
	platform_set_drvdata(pdev, NULL);

	return 0;
}

MODULE_DEVICE_TABLE(of, dove_thermal_id_table);

static struct platform_driver dove_thermal_driver = {
	.probe = dove_thermal_probe,
	.remove = dove_thermal_exit,
	.driver = {
		.name = "dove_thermal",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(dove_thermal_id_table),
	},
};

module_platform_driver(dove_thermal_driver);

MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
MODULE_DESCRIPTION("Dove thermal driver");
MODULE_LICENSE("GPL");
