// SPDX-License-Identifier: GPL-2.0-only
/*
 * ZTE's zx2967 family thermal sensor driver
 *
 * Copyright (C) 2017 ZTE Ltd.
 *
 * Author: Baoyou Xie <baoyou.xie@linaro.org>
 */

#include <linux/clk.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>

/* Power Mode: 0->low 1->high */
#define ZX2967_THERMAL_POWER_MODE	0
#define ZX2967_POWER_MODE_LOW		0
#define ZX2967_POWER_MODE_HIGH		1

/* DCF Control Register */
#define ZX2967_THERMAL_DCF		0x4
#define ZX2967_DCF_EN			BIT(1)
#define ZX2967_DCF_FREEZE		BIT(0)

/* Selection Register */
#define ZX2967_THERMAL_SEL		0x8

/* Control Register */
#define ZX2967_THERMAL_CTRL		0x10

#define ZX2967_THERMAL_READY		BIT(12)
#define ZX2967_THERMAL_TEMP_MASK	GENMASK(11, 0)
#define ZX2967_THERMAL_ID_MASK		0x18
#define ZX2967_THERMAL_ID		0x10

#define ZX2967_GET_TEMP_TIMEOUT_US	(100 * 1024)

/**
 * struct zx2967_thermal_priv - zx2967 thermal sensor private structure
 * @tzd: struct thermal_zone_device where the sensor is registered
 * @lock: prevents read sensor in parallel
 * @clk_topcrm: topcrm clk structure
 * @clk_apb: apb clk structure
 * @regs: pointer to base address of the thermal sensor
 */

struct zx2967_thermal_priv {
	struct thermal_zone_device	*tzd;
	struct mutex			lock;
	struct clk			*clk_topcrm;
	struct clk			*clk_apb;
	void __iomem			*regs;
	struct device			*dev;
};

static int zx2967_thermal_get_temp(void *data, int *temp)
{
	void __iomem *regs;
	struct zx2967_thermal_priv *priv = data;
	u32 val;
	int ret;

	if (!priv->tzd)
		return -EAGAIN;

	regs = priv->regs;
	mutex_lock(&priv->lock);
	writel_relaxed(ZX2967_POWER_MODE_LOW,
		       regs + ZX2967_THERMAL_POWER_MODE);
	writel_relaxed(ZX2967_DCF_EN, regs + ZX2967_THERMAL_DCF);

	val = readl_relaxed(regs + ZX2967_THERMAL_SEL);
	val &= ~ZX2967_THERMAL_ID_MASK;
	val |= ZX2967_THERMAL_ID;
	writel_relaxed(val, regs + ZX2967_THERMAL_SEL);

	/*
	 * Must wait for a while, surely it's a bit odd.
	 * otherwise temperature value we got has a few deviation, even if
	 * the THERMAL_READY bit is set.
	 */
	usleep_range(100, 300);
	ret = readx_poll_timeout(readl, regs + ZX2967_THERMAL_CTRL,
				 val, val & ZX2967_THERMAL_READY, 300,
				 ZX2967_GET_TEMP_TIMEOUT_US);
	if (ret) {
		dev_err(priv->dev, "Thermal sensor data timeout\n");
		goto unlock;
	}

	writel_relaxed(ZX2967_DCF_FREEZE | ZX2967_DCF_EN,
		       regs + ZX2967_THERMAL_DCF);
	val = readl_relaxed(regs + ZX2967_THERMAL_CTRL)
			 & ZX2967_THERMAL_TEMP_MASK;
	writel_relaxed(ZX2967_POWER_MODE_HIGH,
		       regs + ZX2967_THERMAL_POWER_MODE);

	/*
	 * Calculate temperature
	 * In dts, slope is multiplied by 1000.
	 */
	*temp = DIV_ROUND_CLOSEST(((s32)val + priv->tzd->tzp->offset) * 1000,
				  priv->tzd->tzp->slope);

unlock:
	mutex_unlock(&priv->lock);
	return ret;
}

static const struct thermal_zone_of_device_ops zx2967_of_thermal_ops = {
	.get_temp = zx2967_thermal_get_temp,
};

static int zx2967_thermal_probe(struct platform_device *pdev)
{
	struct zx2967_thermal_priv *priv;
	struct resource *res;
	int ret;

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

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

	priv->clk_topcrm = devm_clk_get(&pdev->dev, "topcrm");
	if (IS_ERR(priv->clk_topcrm)) {
		ret = PTR_ERR(priv->clk_topcrm);
		dev_err(&pdev->dev, "failed to get topcrm clock: %d\n", ret);
		return ret;
	}

	ret = clk_prepare_enable(priv->clk_topcrm);
	if (ret) {
		dev_err(&pdev->dev, "failed to enable topcrm clock: %d\n",
			ret);
		return ret;
	}

	priv->clk_apb = devm_clk_get(&pdev->dev, "apb");
	if (IS_ERR(priv->clk_apb)) {
		ret = PTR_ERR(priv->clk_apb);
		dev_err(&pdev->dev, "failed to get apb clock: %d\n", ret);
		goto disable_clk_topcrm;
	}

	ret = clk_prepare_enable(priv->clk_apb);
	if (ret) {
		dev_err(&pdev->dev, "failed to enable apb clock: %d\n",
			ret);
		goto disable_clk_topcrm;
	}

	mutex_init(&priv->lock);
	priv->tzd = thermal_zone_of_sensor_register(&pdev->dev,
					0, priv, &zx2967_of_thermal_ops);

	if (IS_ERR(priv->tzd)) {
		ret = PTR_ERR(priv->tzd);
		dev_err(&pdev->dev, "failed to register sensor: %d\n", ret);
		goto disable_clk_all;
	}

	if (priv->tzd->tzp->slope == 0) {
		thermal_zone_of_sensor_unregister(&pdev->dev, priv->tzd);
		dev_err(&pdev->dev, "coefficients of sensor is invalid\n");
		ret = -EINVAL;
		goto disable_clk_all;
	}

	priv->dev = &pdev->dev;
	platform_set_drvdata(pdev, priv);

	return 0;

disable_clk_all:
	clk_disable_unprepare(priv->clk_apb);
disable_clk_topcrm:
	clk_disable_unprepare(priv->clk_topcrm);
	return ret;
}

static int zx2967_thermal_exit(struct platform_device *pdev)
{
	struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);

	thermal_zone_of_sensor_unregister(&pdev->dev, priv->tzd);
	clk_disable_unprepare(priv->clk_topcrm);
	clk_disable_unprepare(priv->clk_apb);

	return 0;
}

static const struct of_device_id zx2967_thermal_id_table[] = {
	{ .compatible = "zte,zx296718-thermal" },
	{}
};
MODULE_DEVICE_TABLE(of, zx2967_thermal_id_table);

#ifdef CONFIG_PM_SLEEP
static int zx2967_thermal_suspend(struct device *dev)
{
	struct zx2967_thermal_priv *priv = dev_get_drvdata(dev);

	if (priv && priv->clk_topcrm)
		clk_disable_unprepare(priv->clk_topcrm);

	if (priv && priv->clk_apb)
		clk_disable_unprepare(priv->clk_apb);

	return 0;
}

static int zx2967_thermal_resume(struct device *dev)
{
	struct zx2967_thermal_priv *priv = dev_get_drvdata(dev);
	int error;

	error = clk_prepare_enable(priv->clk_topcrm);
	if (error)
		return error;

	error = clk_prepare_enable(priv->clk_apb);
	if (error) {
		clk_disable_unprepare(priv->clk_topcrm);
		return error;
	}

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(zx2967_thermal_pm_ops,
			 zx2967_thermal_suspend, zx2967_thermal_resume);

static struct platform_driver zx2967_thermal_driver = {
	.probe = zx2967_thermal_probe,
	.remove = zx2967_thermal_exit,
	.driver = {
		.name = "zx2967_thermal",
		.of_match_table = zx2967_thermal_id_table,
		.pm = &zx2967_thermal_pm_ops,
	},
};
module_platform_driver(zx2967_thermal_driver);

MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
MODULE_DESCRIPTION("ZTE zx2967 thermal driver");
MODULE_LICENSE("GPL v2");
