// 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)

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);

		delay = thermal->zone->passive_delay_jiffies;
		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 = z->devdata;

	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;
	unsigned int pp_tmp = DA9062_DEFAULT_POLLING_MS_PERIOD;
	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), 0, 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",
		jiffies_to_msecs(thermal->zone->passive_delay_jiffies));

	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 int 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);
	return 0;
}

static struct platform_driver da9062_thermal_driver = {
	.probe	= da9062_thermal_probe,
	.remove	= 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");
