/*
 * palmas_thermal.c -- TI PALMAS THERMAL.
 *
 * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
 *
 * Author: Pradeep Goudagunta <pgoudagunta@nvidia.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.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
 * whether express or implied; 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/module.h>
#include <linux/err.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/thermal.h>
#include <linux/mfd/palmas.h>

#define PALMAS_NORMAL_OPERATING_TEMP 100000
#define PALMAS_CRITICAL_DEFUALT_TEMP 108000

struct palmas_therm_zone {
	struct device			*dev;
	struct palmas			*palmas;
	struct thermal_zone_device	*tz_device;
	int				irq;
	int				is_crit_temp;
};

struct palmas_trip_point {
	unsigned long temp;
	 enum thermal_trip_type type;
};

static struct palmas_trip_point palmas_tpoint = {
		.temp = PALMAS_CRITICAL_DEFUALT_TEMP,
		.type = THERMAL_TRIP_CRITICAL,
};

static int palmas_thermal_get_crit_temp(struct thermal_zone_device *tz_device,
			unsigned long *temp)
{
	*temp = palmas_tpoint.temp;

	return 0;
}

static int palmas_thermal_get_temp(struct thermal_zone_device *tz_device,
			unsigned long *temp)
{
	struct palmas_therm_zone *ptherm_zone = tz_device->devdata;

	if (ptherm_zone->is_crit_temp) {
		/*
		 * Set temperature greater than Critical trip
		 * temp to trigger orderly power down sequence
		 */
		palmas_thermal_get_crit_temp(tz_device, temp);
		*temp += 1;
		return 0;
	}

	*temp = PALMAS_NORMAL_OPERATING_TEMP;
	return 0;
}

static int palmas_thermal_get_trip_type(struct thermal_zone_device *tz_device,
			int trip, enum thermal_trip_type *type)
{
	if (trip >= 1)
		return -EINVAL;

	*type = palmas_tpoint.type;
	return 0;
}

static int palmas_thermal_get_trip_temp(struct thermal_zone_device *tz_device,
			int trip, unsigned long *temp)
{
	if (trip >= 1)
		return -EINVAL;

	*temp = palmas_tpoint.temp;
	return 0;
}

static struct thermal_zone_device_ops palmas_tz_ops = {
	.get_temp = palmas_thermal_get_temp,
	.get_crit_temp = palmas_thermal_get_crit_temp,
	.get_trip_type = palmas_thermal_get_trip_type,
	.get_trip_temp = palmas_thermal_get_trip_temp,
};

static irqreturn_t palmas_thermal_irq(int irq, void *data)
{
	struct palmas_therm_zone *ptherm_zone = data;

	ptherm_zone->is_crit_temp = 1;
	/*
	 * Necessary action can be taken here
	 * e.g: thermal_zone_device_update(pz->tz_device);
	 * will trigger orderly power down sequence.
	 */

	return IRQ_HANDLED;
}

static int palmas_thermal_probe(struct platform_device *pdev)
{
	struct palmas_therm_zone *ptherm_zone;
	struct palmas_platform_data *pdata;
	struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
	char *default_tz_name = "palmas-junc-tz";
	int ret;
	u8 val;

	pdata = dev_get_platdata(pdev->dev.parent);

	if (!pdata || !(pdata->hd_threshold_temp)) {
		dev_err(&pdev->dev, "No platform data\n");
		return -ENODEV;
	}

	ptherm_zone = devm_kzalloc(&pdev->dev, sizeof(*ptherm_zone),
			GFP_KERNEL);
	if (!ptherm_zone) {
		dev_err(&pdev->dev, "No available free memory\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, ptherm_zone);
	ptherm_zone->dev = &pdev->dev;
	if (!(pdata->tz_name))
		pdata->tz_name = default_tz_name;

	ptherm_zone->tz_device = thermal_zone_device_register(pdata->tz_name,
					1, 0, ptherm_zone, &palmas_tz_ops,
					NULL, 0, 0);
	if (IS_ERR_OR_NULL(ptherm_zone->tz_device)) {
		dev_err(ptherm_zone->dev,
			"Register thermal zone device failed.\n");
		return PTR_ERR(ptherm_zone->tz_device);
	}

	palmas_tpoint.temp = pdata->hd_threshold_temp;

	ptherm_zone->irq = platform_get_irq(pdev, 0);
	ret = request_threaded_irq(ptherm_zone->irq, NULL,
			palmas_thermal_irq,
			IRQF_ONESHOT, dev_name(&pdev->dev),
			ptherm_zone);
	if (ret < 0) {
		dev_err(&pdev->dev,
			"request irq %d failed: %dn", ptherm_zone->irq, ret);
		goto int_req_failed;
	}

	switch (palmas_tpoint.temp) {
	case 108000:
		val = 0;
		break;
	case 112000:
		val = 1;
		break;
	case 116000:
		val = 2;
		break;
	case 120000:
		val = 3;
		break;
	default:
		dev_err(&pdev->dev, "%ld threshold is not supported",
				palmas_tpoint.temp);
		ret = -EINVAL;
		goto error;
	}

	val <<= PALMAS_OSC_THERM_CTRL_THERM_HD_SEL_SHIFT;
	ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
			PALMAS_OSC_THERM_CTRL,
			PALMAS_OSC_THERM_CTRL_THERM_HD_SEL_MASK, val);
	if (ret < 0) {
		dev_err(&pdev->dev, "osc_therm_ctrl reg update failed.\n");
		goto error;
	}

	return 0;

error:
	free_irq(ptherm_zone->irq, ptherm_zone);
int_req_failed:
	thermal_zone_device_unregister(ptherm_zone->tz_device);
	return ret;
}

static int palmas_thermal_remove(struct platform_device *pdev)
{
	struct palmas_therm_zone *ptherm_zone = platform_get_drvdata(pdev);

	thermal_zone_device_unregister(ptherm_zone->tz_device);
	free_irq(ptherm_zone->irq, ptherm_zone);
	kfree(ptherm_zone);
	return 0;
}

static struct platform_driver palmas_thermal_driver = {
	.probe = palmas_thermal_probe,
	.remove = palmas_thermal_remove,
	.driver = {
		.name = "palmas-thermal",
		.owner = THIS_MODULE,
	},
};

static int __init palmas_thermal_init(void)
{
	return platform_driver_register(&palmas_thermal_driver);
}
module_init(palmas_thermal_init);

static void __exit palmas_thermal_exit(void)
{
	platform_driver_unregister(&palmas_thermal_driver);
}
module_exit(palmas_thermal_exit);

MODULE_DESCRIPTION("Palmas Thermal driver");
MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>");
MODULE_ALIAS("platform:palmas-thermal");
MODULE_LICENSE("GPL v2");
