/*
 *  R-Car THS/TSC thermal sensor driver
 *
 * Copyright (C) 2012 Renesas Solutions Corp.
 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.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; version 2 of the License.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/thermal.h>

#define THSCR	0x2c
#define THSSR	0x30

/* THSCR */
#define CPTAP	0xf

/* THSSR */
#define CTEMP	0x3f


struct rcar_thermal_priv {
	void __iomem *base;
	struct device *dev;
	spinlock_t lock;
	u32 comp;
};

/*
 *		basic functions
 */
static u32 rcar_thermal_read(struct rcar_thermal_priv *priv, u32 reg)
{
	unsigned long flags;
	u32 ret;

	spin_lock_irqsave(&priv->lock, flags);

	ret = ioread32(priv->base + reg);

	spin_unlock_irqrestore(&priv->lock, flags);

	return ret;
}

#if 0 /* no user at this point */
static void rcar_thermal_write(struct rcar_thermal_priv *priv,
			       u32 reg, u32 data)
{
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);

	iowrite32(data, priv->base + reg);

	spin_unlock_irqrestore(&priv->lock, flags);
}
#endif

static void rcar_thermal_bset(struct rcar_thermal_priv *priv, u32 reg,
			      u32 mask, u32 data)
{
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&priv->lock, flags);

	val = ioread32(priv->base + reg);
	val &= ~mask;
	val |= (data & mask);
	iowrite32(val, priv->base + reg);

	spin_unlock_irqrestore(&priv->lock, flags);
}

/*
 *		zone device functions
 */
static int rcar_thermal_get_temp(struct thermal_zone_device *zone,
			   unsigned long *temp)
{
	struct rcar_thermal_priv *priv = zone->devdata;
	int val, min, max, tmp;

	tmp = -200; /* default */
	while (1) {
		if (priv->comp < 1 || priv->comp > 12) {
			dev_err(priv->dev,
				"THSSR invalid data (%d)\n", priv->comp);
			priv->comp = 4; /* for next thermal */
			return -EINVAL;
		}

		/*
		 * THS comparator offset and the reference temperature
		 *
		 * Comparator	| reference	| Temperature field
		 * offset	| temperature	| measurement
		 *		| (degrees C)	| (degrees C)
		 * -------------+---------------+-------------------
		 *  1		|  -45		|  -45 to  -30
		 *  2		|  -30		|  -30 to  -15
		 *  3		|  -15		|  -15 to    0
		 *  4		|    0		|    0 to  +15
		 *  5		|  +15		|  +15 to  +30
		 *  6		|  +30		|  +30 to  +45
		 *  7		|  +45		|  +45 to  +60
		 *  8		|  +60		|  +60 to  +75
		 *  9		|  +75		|  +75 to  +90
		 * 10		|  +90		|  +90 to +105
		 * 11		| +105		| +105 to +120
		 * 12		| +120		| +120 to +135
		 */

		/* calculate thermal limitation */
		min = (priv->comp * 15) - 60;
		max = min + 15;

		/*
		 * we need to wait 300us after changing comparator offset
		 * to get stable temperature.
		 * see "Usage Notes" on datasheet
		 */
		rcar_thermal_bset(priv, THSCR, CPTAP, priv->comp);
		udelay(300);

		/* calculate current temperature */
		val = rcar_thermal_read(priv, THSSR) & CTEMP;
		val = (val * 5) - 65;

		dev_dbg(priv->dev, "comp/min/max/val = %d/%d/%d/%d\n",
			priv->comp, min, max, val);

		/*
		 * If val is same as min/max, then,
		 * it should try again on next comparator.
		 * But the val might be correct temperature.
		 * Keep it on "tmp" and compare with next val.
		 */
		if (tmp == val)
			break;

		if (val <= min) {
			tmp = min;
			priv->comp--; /* try again */
		} else if (val >= max) {
			tmp = max;
			priv->comp++; /* try again */
		} else {
			tmp = val;
			break;
		}
	}

	*temp = tmp;
	return 0;
}

static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
	.get_temp = rcar_thermal_get_temp,
};

/*
 *		platform functions
 */
static int rcar_thermal_probe(struct platform_device *pdev)
{
	struct thermal_zone_device *zone;
	struct rcar_thermal_priv *priv;
	struct resource *res;
	int ret;

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

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "Could not allocate priv\n");
		return -ENOMEM;
	}

	priv->comp = 4; /* basic setup */
	priv->dev = &pdev->dev;
	spin_lock_init(&priv->lock);
	priv->base = devm_ioremap_nocache(&pdev->dev,
					  res->start, resource_size(res));
	if (!priv->base) {
		dev_err(&pdev->dev, "Unable to ioremap thermal register\n");
		ret = -ENOMEM;
		goto error_free_priv;
	}

	zone = thermal_zone_device_register("rcar_thermal", 0, 0, priv,
					    &rcar_thermal_zone_ops, 0, 0);
	if (IS_ERR(zone)) {
		dev_err(&pdev->dev, "thermal zone device is NULL\n");
		ret = PTR_ERR(zone);
		goto error_iounmap;
	}

	platform_set_drvdata(pdev, zone);

	dev_info(&pdev->dev, "proved\n");

	return 0;

error_iounmap:
	devm_iounmap(&pdev->dev, priv->base);
error_free_priv:
	devm_kfree(&pdev->dev, priv);

	return ret;
}

static int rcar_thermal_remove(struct platform_device *pdev)
{
	struct thermal_zone_device *zone = platform_get_drvdata(pdev);
	struct rcar_thermal_priv *priv = zone->devdata;

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

	devm_iounmap(&pdev->dev, priv->base);
	devm_kfree(&pdev->dev, priv);

	return 0;
}

static struct platform_driver rcar_thermal_driver = {
	.driver	= {
		.name	= "rcar_thermal",
	},
	.probe		= rcar_thermal_probe,
	.remove		= rcar_thermal_remove,
};
module_platform_driver(rcar_thermal_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("R-Car THS/TSC thermal sensor driver");
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
