// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Thermal device driver for DA9062 and DA9061
 * Copyright (C) 2017  Dialog Semiconductor
 */

/* When over-temperature is reached, an interrupt from the device will be
 * triggered. Following this event the interrupt will be disabled and
 * periodic transmission of uevents (HOT trip point) should define the
 * first level of temperature supervision. It is expected that any final
 * implementation of the thermal driver will include a .notify() function
 * to implement these uevents to userspace.
 *
 * These uevents are intended to indicate non-invasive temperature control
 * of the system, where the necessary measures for cooling are the
 * responsibility of the host software. Once the temperature falls again,
 * the IRQ is re-enabled so the start of a new over-temperature event can
 * be detected without constant software monitoring.
 */

#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/thermal.h>
#include <linux/workqueue.h>

#include <linux/mfd/da9062/core.h>
#include <linux/mfd/da9062/registers.h>

/* Minimum, maximum and default polling millisecond periods are provided
 * here as an example. It is expected that any final implementation to also
 * include a modification of these settings to match the required
 * application.
 */
#define DA9062_DEFAULT_POLLING_MS_PERIOD	3000
#define DA9062_MAX_POLLING_MS_PERIOD		10000
#define DA9062_MIN_POLLING_MS_PERIOD		1000

#define DA9062_MILLI_CELSIUS(t)			((t) * 1000)

static unsigned int pp_tmp = DA9062_DEFAULT_POLLING_MS_PERIOD;

struct da9062_thermal_config {
	const char *name;
};

struct da9062_thermal {
	struct da9062 *hw;
	struct delayed_work work;
	struct thermal_zone_device *zone;
	struct mutex lock; /* protection for da9062_thermal temperature */
	int temperature;
	int irq;
	const struct da9062_thermal_config *config;
	struct device *dev;
};

static void da9062_thermal_poll_on(struct work_struct *work)
{
	struct da9062_thermal *thermal = container_of(work,
						struct da9062_thermal,
						work.work);
	unsigned long delay;
	unsigned int val;
	int ret;

	/* clear E_TEMP */
	ret = regmap_write(thermal->hw->regmap,
			   DA9062AA_EVENT_B,
			   DA9062AA_E_TEMP_MASK);
	if (ret < 0) {
		dev_err(thermal->dev,
			"Cannot clear the TJUNC temperature status\n");
		goto err_enable_irq;
	}

	/* Now read E_TEMP again: it is acting like a status bit.
	 * If over-temperature, then this status will be true.
	 * If not over-temperature, this status will be false.
	 */
	ret = regmap_read(thermal->hw->regmap,
			  DA9062AA_EVENT_B,
			  &val);
	if (ret < 0) {
		dev_err(thermal->dev,
			"Cannot check the TJUNC temperature status\n");
		goto err_enable_irq;
	}

	if (val & DA9062AA_E_TEMP_MASK) {
		mutex_lock(&thermal->lock);
		thermal->temperature = DA9062_MILLI_CELSIUS(125);
		mutex_unlock(&thermal->lock);
		thermal_zone_device_update(thermal->zone,
					   THERMAL_EVENT_UNSPECIFIED);

		/*
		 * pp_tmp is between 1s and 10s, so we can round the jiffies
		 */
		delay = round_jiffies(msecs_to_jiffies(pp_tmp));
		queue_delayed_work(system_freezable_wq, &thermal->work, delay);
		return;
	}

	mutex_lock(&thermal->lock);
	thermal->temperature = DA9062_MILLI_CELSIUS(0);
	mutex_unlock(&thermal->lock);
	thermal_zone_device_update(thermal->zone,
				   THERMAL_EVENT_UNSPECIFIED);

err_enable_irq:
	enable_irq(thermal->irq);
}

static irqreturn_t da9062_thermal_irq_handler(int irq, void *data)
{
	struct da9062_thermal *thermal = data;

	disable_irq_nosync(thermal->irq);
	queue_delayed_work(system_freezable_wq, &thermal->work, 0);

	return IRQ_HANDLED;
}

static int da9062_thermal_get_temp(struct thermal_zone_device *z,
				   int *temp)
{
	struct da9062_thermal *thermal = thermal_zone_device_priv(z);

	mutex_lock(&thermal->lock);
	*temp = thermal->temperature;
	mutex_unlock(&thermal->lock);

	return 0;
}

static struct thermal_zone_device_ops da9062_thermal_ops = {
	.get_temp	= da9062_thermal_get_temp,
};

static struct thermal_trip trips[] = {
	{ .temperature = DA9062_MILLI_CELSIUS(125), .type = THERMAL_TRIP_HOT },
};

static const struct da9062_thermal_config da9062_config = {
	.name = "da9062-thermal",
};

static const struct of_device_id da9062_compatible_reg_id_table[] = {
	{ .compatible = "dlg,da9062-thermal", .data = &da9062_config },
	{ },
};

MODULE_DEVICE_TABLE(of, da9062_compatible_reg_id_table);

static int da9062_thermal_probe(struct platform_device *pdev)
{
	struct da9062 *chip = dev_get_drvdata(pdev->dev.parent);
	struct da9062_thermal *thermal;
	const struct of_device_id *match;
	int ret = 0;

	match = of_match_node(da9062_compatible_reg_id_table,
			      pdev->dev.of_node);
	if (!match)
		return -ENXIO;

	if (pdev->dev.of_node) {
		if (!of_property_read_u32(pdev->dev.of_node,
					  "polling-delay-passive",
					  &pp_tmp)) {
			if (pp_tmp < DA9062_MIN_POLLING_MS_PERIOD ||
			    pp_tmp > DA9062_MAX_POLLING_MS_PERIOD) {
				dev_warn(&pdev->dev,
					 "Out-of-range polling period %d ms\n",
					 pp_tmp);
				pp_tmp = DA9062_DEFAULT_POLLING_MS_PERIOD;
			}
		}
	}

	thermal = devm_kzalloc(&pdev->dev, sizeof(struct da9062_thermal),
			       GFP_KERNEL);
	if (!thermal) {
		ret = -ENOMEM;
		goto err;
	}

	thermal->config = match->data;
	thermal->hw = chip;
	thermal->dev = &pdev->dev;

	INIT_DELAYED_WORK(&thermal->work, da9062_thermal_poll_on);
	mutex_init(&thermal->lock);

	thermal->zone = thermal_zone_device_register_with_trips(thermal->config->name,
								trips, ARRAY_SIZE(trips), thermal,
								&da9062_thermal_ops, NULL, pp_tmp,
								0);
	if (IS_ERR(thermal->zone)) {
		dev_err(&pdev->dev, "Cannot register thermal zone device\n");
		ret = PTR_ERR(thermal->zone);
		goto err;
	}
	ret = thermal_zone_device_enable(thermal->zone);
	if (ret) {
		dev_err(&pdev->dev, "Cannot enable thermal zone device\n");
		goto err_zone;
	}

	dev_dbg(&pdev->dev,
		"TJUNC temperature polling period set at %d ms\n", pp_tmp);

	ret = platform_get_irq_byname(pdev, "THERMAL");
	if (ret < 0)
		goto err_zone;

	thermal->irq = ret;

	ret = request_threaded_irq(thermal->irq, NULL,
				   da9062_thermal_irq_handler,
				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				   "THERMAL", thermal);
	if (ret) {
		dev_err(&pdev->dev,
			"Failed to request thermal device IRQ.\n");
		goto err_zone;
	}

	platform_set_drvdata(pdev, thermal);
	return 0;

err_zone:
	thermal_zone_device_unregister(thermal->zone);
err:
	return ret;
}

static void da9062_thermal_remove(struct platform_device *pdev)
{
	struct	da9062_thermal *thermal = platform_get_drvdata(pdev);

	free_irq(thermal->irq, thermal);
	cancel_delayed_work_sync(&thermal->work);
	thermal_zone_device_unregister(thermal->zone);
}

static struct platform_driver da9062_thermal_driver = {
	.probe	= da9062_thermal_probe,
	.remove_new = da9062_thermal_remove,
	.driver	= {
		.name	= "da9062-thermal",
		.of_match_table = da9062_compatible_reg_id_table,
	},
};

module_platform_driver(da9062_thermal_driver);

MODULE_AUTHOR("Steve Twiss");
MODULE_DESCRIPTION("Thermal TJUNC device driver for Dialog DA9062 and DA9061");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:da9062-thermal");
