#include <linux/io.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/thermal.h>
#include <linux/platform_device.h>

/*
 * According to a data sheet draft, "this temperature sensor uses a bandgap
 * type of circuit to compare a voltage which has a negative temperature
 * coefficient with a voltage that is proportional to absolute temperature.
 * A resistor bank allows 41 different temperature thresholds to be selected
 * and the logic output will then indicate whether the actual die temperature
 * lies above or below the selected threshold."
 */

#define TEMPSI_CMD	0
#define TEMPSI_RES	4
#define TEMPSI_CFG	8

#define CMD_OFF		0
#define CMD_ON		1
#define CMD_READ	2

#define IDX_MIN		15
#define IDX_MAX		40

struct tango_thermal_priv {
	void __iomem *base;
	int thresh_idx;
};

static bool temp_above_thresh(void __iomem *base, int thresh_idx)
{
	writel(CMD_READ | thresh_idx << 8, base + TEMPSI_CMD);
	usleep_range(10, 20);
	writel(CMD_READ | thresh_idx << 8, base + TEMPSI_CMD);

	return readl(base + TEMPSI_RES);
}

static int tango_get_temp(void *arg, int *res)
{
	struct tango_thermal_priv *priv = arg;
	int idx = priv->thresh_idx;

	if (temp_above_thresh(priv->base, idx)) {
		/* Search upward by incrementing thresh_idx */
		while (idx < IDX_MAX && temp_above_thresh(priv->base, ++idx))
			cpu_relax();
		idx = idx - 1; /* always return lower bound */
	} else {
		/* Search downward by decrementing thresh_idx */
		while (idx > IDX_MIN && !temp_above_thresh(priv->base, --idx))
			cpu_relax();
	}

	*res = (idx * 9 / 2 - 38) * 1000; /* millidegrees Celsius */
	priv->thresh_idx = idx;

	return 0;
}

static const struct thermal_zone_of_device_ops ops = {
	.get_temp	= tango_get_temp,
};

static void tango_thermal_init(struct tango_thermal_priv *priv)
{
	writel(0, priv->base + TEMPSI_CFG);
	writel(CMD_ON, priv->base + TEMPSI_CMD);
}

static int tango_thermal_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct tango_thermal_priv *priv;
	struct thermal_zone_device *tzdev;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	priv->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(priv->base))
		return PTR_ERR(priv->base);

	platform_set_drvdata(pdev, priv);
	priv->thresh_idx = IDX_MIN;
	tango_thermal_init(priv);

	tzdev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &ops);
	return PTR_ERR_OR_ZERO(tzdev);
}

static int __maybe_unused tango_thermal_resume(struct device *dev)
{
	tango_thermal_init(dev_get_drvdata(dev));
	return 0;
}

static SIMPLE_DEV_PM_OPS(tango_thermal_pm, NULL, tango_thermal_resume);

static const struct of_device_id tango_sensor_ids[] = {
	{
		.compatible = "sigma,smp8758-thermal",
	},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, tango_sensor_ids);

static struct platform_driver tango_thermal_driver = {
	.probe	= tango_thermal_probe,
	.driver	= {
		.name		= "tango-thermal",
		.of_match_table	= tango_sensor_ids,
		.pm		= &tango_thermal_pm,
	},
};

module_platform_driver(tango_thermal_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sigma Designs");
MODULE_DESCRIPTION("Tango temperature sensor");
